--- old/src/share/vm/opto/ifg.cpp 2014-02-21 17:40:44.569272543 +0100 +++ new/src/share/vm/opto/ifg.cpp 2014-02-21 17:40:44.465272538 +0100 @@ -703,7 +703,7 @@ assert(int_pressure._current_pressure == count_int_pressure(liveout), "the int pressure is incorrect"); assert(float_pressure._current_pressure == count_float_pressure(liveout), "the float pressure is incorrect"); } - assert(!(lrg._area < 0.0), "negative spill area" ); + assert(lrg._area >= 0.0, "negative spill area" ); } } @@ -772,7 +772,7 @@ int inst_count = last_inst - first_inst; double cost = (inst_count <= 0) ? 0.0 : block->_freq * double(inst_count); - assert(!(cost < 0.0), "negative spill cost" ); + assert(cost >= 0.0, "negative spill cost" ); compute_initial_block_pressure(block, &liveout, int_pressure, float_pressure, cost); @@ -799,7 +799,11 @@ } } else { // A live range ends at its definition, remove the remaining area. - lrg._area -= cost; + // If the cost is +Inf (which might happen in extreme cases), the lrg area will also be +Inf, + // and +Inf - +Inf = NaN. So let's not do that subtraction. + if (g_isfinite(cost)) { + lrg._area -= cost; + } assert(lrg._area >= 0.0, "negative spill area" ); assign_high_score_to_immediate_copies(block, n, lrg, location + 1, last_inst); --- old/src/share/vm/opto/gcm.cpp 2014-02-21 17:40:44.565272543 +0100 +++ new/src/share/vm/opto/gcm.cpp 2014-02-21 17:40:44.453272538 +0100 @@ -1661,10 +1661,10 @@ } assert (_members.length() > 0, "no empty loops"); Block* hd = head(); - hd->_freq = 1.0f; + hd->_freq = 1.0; for (int i = 0; i < _members.length(); i++) { CFGElement* s = _members.at(i); - float freq = s->_freq; + double freq = s->_freq; if (s->is_block()) { Block* b = s->as_Block(); for (uint j = 0; j < b->_num_succs; j++) { @@ -1676,7 +1676,7 @@ assert(lp->_parent == this, "immediate child"); for (int k = 0; k < lp->_exits.length(); k++) { Block* eb = lp->_exits.at(k).get_target(); - float prob = lp->_exits.at(k).get_prob(); + double prob = lp->_exits.at(k).get_prob(); update_succ_freq(eb, freq * prob); } } @@ -1688,7 +1688,7 @@ // inner blocks do not get erroneously scaled. if (_depth != 0) { // Total the exit probabilities for this loop. - float exits_sum = 0.0f; + double exits_sum = 0.0f; for (int i = 0; i < _exits.length(); i++) { exits_sum += _exits.at(i).get_prob(); } @@ -1935,7 +1935,7 @@ //------------------------------update_succ_freq------------------------------- // Update the appropriate frequency associated with block 'b', a successor of // a block in this loop. -void CFGLoop::update_succ_freq(Block* b, float freq) { +void CFGLoop::update_succ_freq(Block* b, double freq) { if (b->_loop == this) { if (b == head()) { // back branch within the loop @@ -1976,11 +1976,11 @@ // Scale frequency of loops and blocks by trip counts from outer loops // Do a top down traversal of loop tree (visit outer loops first.) void CFGLoop::scale_freq() { - float loop_freq = _freq * trip_count(); + double loop_freq = _freq * trip_count(); _freq = loop_freq; for (int i = 0; i < _members.length(); i++) { CFGElement* s = _members.at(i); - float block_freq = s->_freq * loop_freq; + double block_freq = s->_freq * loop_freq; if (g_isnan(block_freq) || block_freq < MIN_BLOCK_FREQUENCY) block_freq = MIN_BLOCK_FREQUENCY; s->_freq = block_freq; @@ -1993,7 +1993,7 @@ } // Frequency of outer loop -float CFGLoop::outer_loop_freq() const { +double CFGLoop::outer_loop_freq() const { if (_child != NULL) { return _child->_freq; } @@ -2042,7 +2042,7 @@ k = 0; } Block *blk = _exits.at(i).get_target(); - float prob = _exits.at(i).get_prob(); + double prob = _exits.at(i).get_prob(); tty->print(" ->%d@%d%%", blk->_pre_order, (int)(prob*100)); } tty->print("\n"); --- old/src/share/vm/runtime/vmStructs.cpp 2014-02-21 17:40:44.569272543 +0100 +++ new/src/share/vm/runtime/vmStructs.cpp 2014-02-21 17:40:44.461272538 +0100 @@ -1177,9 +1177,9 @@ c2_nonstatic_field(Block, _pre_order, uint) \ c2_nonstatic_field(Block, _dom_depth, uint) \ c2_nonstatic_field(Block, _idom, Block*) \ - c2_nonstatic_field(Block, _freq, jfloat) \ + c2_nonstatic_field(Block, _freq, jdouble) \ \ - c2_nonstatic_field(CFGElement, _freq, jfloat) \ + c2_nonstatic_field(CFGElement, _freq, jdouble) \ \ c2_nonstatic_field(Block_List, _cnt, uint) \ \ --- old/src/share/vm/opto/block.hpp 2014-02-21 17:40:44.577272544 +0100 +++ new/src/share/vm/opto/block.hpp 2014-02-21 17:40:44.461272538 +0100 @@ -90,9 +90,9 @@ class CFGElement : public ResourceObj { friend class VMStructs; public: - float _freq; // Execution frequency (estimate) + double _freq; // Execution frequency (estimate) - CFGElement() : _freq(0.0f) {} + CFGElement() : _freq(0.0) {} virtual bool is_block() { return false; } virtual bool is_loop() { return false; } Block* as_Block() { assert(is_block(), "must be block"); return (Block*)this; } @@ -202,7 +202,7 @@ // BLOCK_FREQUENCY is a sentinel to mark uses of constant block frequencies. // It is currently also used to scale such frequencies relative to // FreqCountInvocations relative to the old value of 1500. -#define BLOCK_FREQUENCY(f) ((f * (float) 1500) / FreqCountInvocations) +#define BLOCK_FREQUENCY(f) ((f * (double) 1500) / FreqCountInvocations) // Register Pressure (estimate) for Splitting heuristic uint _reg_pressure; @@ -393,7 +393,7 @@ CFGLoop* _root_loop; // Outmost loop frequency - float _outer_loop_frequency; + double _outer_loop_frequency; // Per node latency estimation, valid only during GCM GrowableArray* _node_latency; @@ -508,7 +508,7 @@ } // Get the outer most frequency - float get_outer_loop_frequency() const { + double get_outer_loop_frequency() const { return _outer_loop_frequency; } @@ -656,13 +656,13 @@ class BlockProbPair VALUE_OBJ_CLASS_SPEC { protected: Block* _target; // block target - float _prob; // probability of edge to block + double _prob; // probability of edge to block public: BlockProbPair() : _target(NULL), _prob(0.0) {} - BlockProbPair(Block* b, float p) : _target(b), _prob(p) {} + BlockProbPair(Block* b, double p) : _target(b), _prob(p) {} Block* get_target() const { return _target; } - float get_prob() const { return _prob; } + double get_prob() const { return _prob; } }; //------------------------------CFGLoop------------------------------------------- @@ -675,8 +675,8 @@ CFGLoop *_child; // first child, use child's sibling to visit all immediately nested loops GrowableArray _members; // list of members of loop GrowableArray _exits; // list of successor blocks and their probabilities - float _exit_prob; // probability any loop exit is taken on a single loop iteration - void update_succ_freq(Block* b, float freq); + double _exit_prob; // probability any loop exit is taken on a single loop iteration + void update_succ_freq(Block* b, double freq); public: CFGLoop(int id) : @@ -702,9 +702,9 @@ void compute_loop_depth(int depth); void compute_freq(); // compute frequency with loop assuming head freq 1.0f void scale_freq(); // scale frequency by loop trip count (including outer loops) - float outer_loop_freq() const; // frequency of outer loop + double outer_loop_freq() const; // frequency of outer loop bool in_loop_nest(Block* b); - float trip_count() const { return 1.0f / _exit_prob; } + double trip_count() const { return 1.0 / _exit_prob; } virtual bool is_loop() { return true; } int id() { return _id; } @@ -723,7 +723,7 @@ private: Block * _from; // Source basic block Block * _to; // Destination basic block - float _freq; // Execution frequency (estimate) + double _freq; // Execution frequency (estimate) int _state; bool _infrequent; int _from_pct; @@ -742,13 +742,13 @@ interior // edge is interior to trace (could be backedge) }; - CFGEdge(Block *from, Block *to, float freq, int from_pct, int to_pct) : + CFGEdge(Block *from, Block *to, double freq, int from_pct, int to_pct) : _from(from), _to(to), _freq(freq), _from_pct(from_pct), _to_pct(to_pct), _state(open) { _infrequent = from_infrequent() || to_infrequent(); } - float freq() const { return _freq; } + double freq() const { return _freq; } Block* from() const { return _from; } Block* to () const { return _to; } int infrequent() const { return _infrequent; } --- old/agent/src/share/classes/sun/jvm/hotspot/opto/Block.java 2014-02-21 17:40:44.577272544 +0100 +++ new/agent/src/share/classes/sun/jvm/hotspot/opto/Block.java 2014-02-21 17:40:44.465272538 +0100 @@ -48,7 +48,7 @@ preOrderField = new CIntField(type.getCIntegerField("_pre_order"), 0); domDepthField = new CIntField(type.getCIntegerField("_dom_depth"), 0); idomField = type.getAddressField("_idom"); - freqField = type.getJFloatField("_freq"); + freqField = type.getJDoubleField("_freq"); } private static AddressField nodesField; @@ -57,7 +57,7 @@ private static CIntField preOrderField; private static CIntField domDepthField; private static AddressField idomField; - private static JFloatField freqField; + private static JDoubleField freqField; public Block(Address addr) { super(addr); @@ -67,8 +67,8 @@ return (int)preOrderField.getValue(getAddress()); } - public float freq() { - return (float)freqField.getValue(getAddress()); + public double freq() { + return (double)freqField.getValue(getAddress()); } public Node_List nodes() { --- old/src/share/vm/opto/chaitin.cpp 2014-02-21 17:40:44.585272544 +0100 +++ new/src/share/vm/opto/chaitin.cpp 2014-02-21 17:40:44.473272539 +0100 @@ -210,7 +210,7 @@ { NOT_PRODUCT( Compile::TracePhase t3("ctorChaitin", &_t_ctorChaitin, TimeCompiler); ) - _high_frequency_lrg = MIN2(float(OPTO_LRG_HIGH_FREQ), _cfg.get_outer_loop_frequency()); + _high_frequency_lrg = MIN2(double(OPTO_LRG_HIGH_FREQ), _cfg.get_outer_loop_frequency()); // Build a list of basic blocks, sorted by frequency _blks = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks());