diff --git a/src/share/vm/opto/chaitin.cpp b/src/share/vm/opto/chaitin.cpp index d19cf1709d799d942077335aa1ca8fc28dd02122..c2f8d40b2025f673a04364b4f0e1dcf4e49d5596 100644 --- a/src/share/vm/opto/chaitin.cpp +++ b/src/share/vm/opto/chaitin.cpp @@ -287,21 +287,26 @@ void PhaseChaitin::new_lrg(const Node *x, uint lrg) { } -bool PhaseChaitin::clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id) { - Block* bcon = _cfg.get_block_for_node(con); - uint cindex = bcon->find_node(con); - Node *con_next = bcon->_nodes[cindex+1]; - if (con_next->in(0) != con || !con_next->is_MachProj()) { - return false; // No MachProj's follow - } - - // Copy kills after the cloned constant - Node *kills = con_next->clone(); - kills->set_req(0, copy); - b->_nodes.insert(idx, kills); - _cfg.map_node_to_block(kills, b); - new_lrg(kills, max_lrg_id); - return true; +int PhaseChaitin::clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id) { + assert(b->find_node(copy) == (idx - 1), "incorrect insert index for copy kill projections"); + DEBUG_ONLY( Block* borig = _cfg.get_block_for_node(orig); ) + int found_projs = 0; + uint cnt = orig->outcnt(); + for (uint i = 0; i < cnt; i++) { + Node* proj = orig->raw_out(i); + if (proj->is_MachProj()) { + assert(proj->outcnt() == 0, "only kill projections are expected here"); + assert(_cfg.get_block_for_node(proj) == borig, "incorrect block for kill projections"); + found_projs++; + // Copy kill projections after the cloned node + Node* kills = proj->clone(); + kills->set_req(0, copy); + b->_nodes.insert(idx++, kills); + _cfg.map_node_to_block(kills, b); + new_lrg(kills, max_lrg_id++); + } + } + return found_projs; } // Renumber the live ranges to compact them. Makes the IFG smaller. diff --git a/src/share/vm/opto/chaitin.hpp b/src/share/vm/opto/chaitin.hpp index 3455005f330d6ca3548a473d4b0b5cb2f3757eb1..c951024ee75e95f8d83d472c2d04dfded8712a1a 100644 --- a/src/share/vm/opto/chaitin.hpp +++ b/src/share/vm/opto/chaitin.hpp @@ -412,33 +412,22 @@ class PhaseChaitin : public PhaseRegAlloc { uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray splits, int slidx ); uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray splits, int slidx ); - bool clone_projs(Block *b, uint idx, Node *con, Node *copy, LiveRangeMap &lrg_map) { - bool found_projs = clone_projs_shared(b, idx, con, copy, lrg_map.max_lrg_id()); - - if(found_projs) { - uint max_lrg_id = lrg_map.max_lrg_id(); - lrg_map.set_max_lrg_id(max_lrg_id + 1); - } - - return found_projs; - } - //------------------------------clone_projs------------------------------------ // After cloning some rematerialized instruction, clone any MachProj's that // follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants // use G3 as an address temp. - bool clone_projs(Block *b, uint idx, Node *con, Node *copy, uint &max_lrg_id) { - bool found_projs = clone_projs_shared(b, idx, con, copy, max_lrg_id); - - if(found_projs) { - max_lrg_id++; + int clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id); + + int clone_projs(Block* b, uint idx, Node* orig, Node* copy, LiveRangeMap& lrg_map) { + uint max_lrg_id = lrg_map.max_lrg_id(); + int found_projs = clone_projs(b, idx, orig, copy, max_lrg_id); + if (found_projs > 0) { + // max_lrg_id is updated during call above + lrg_map.set_max_lrg_id(max_lrg_id); } - return found_projs; } - bool clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id); - Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray splits, int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru); // True if lidx is used before any real register is def'd in the block diff --git a/src/share/vm/opto/coalesce.cpp b/src/share/vm/opto/coalesce.cpp index 4d84bd42181cdd3e60bd14187e5a539899a97712..66fd988c27361ebb6b40631be01d42fffb3918eb 100644 --- a/src/share/vm/opto/coalesce.cpp +++ b/src/share/vm/opto/coalesce.cpp @@ -322,9 +322,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { copy = m->clone(); // Insert the copy in the basic block, just before us b->_nodes.insert(l++, copy); - if(_phc.clone_projs(b, l, m, copy, _phc._lrg_map)) { - l++; - } + l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map); } else { const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()]; copy = new (C) MachSpillCopyNode(m, *rm, *rm); diff --git a/src/share/vm/opto/reg_split.cpp b/src/share/vm/opto/reg_split.cpp index d4df3016d8cf5d12d23db9bd189226f4106165f1..ac4f8e35824422ee9466f1c3a53b608734a0d933 100644 --- a/src/share/vm/opto/reg_split.cpp +++ b/src/share/vm/opto/reg_split.cpp @@ -397,10 +397,15 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint #endif // See if the cloned def kills any flags, and copy those kills as well uint i = insidx+1; - if( clone_projs( b, i, def, spill, maxlrg) ) { + int found_projs = clone_projs( b, i, def, spill, maxlrg); + if (found_projs > 0) { // Adjust the point where we go hi-pressure - if( i <= b->_ihrp_index ) b->_ihrp_index++; - if( i <= b->_fhrp_index ) b->_fhrp_index++; + if (i <= b->_ihrp_index) { + b->_ihrp_index += found_projs; + } + if (i <= b->_fhrp_index) { + b->_fhrp_index += found_projs; + } } return spill; diff --git a/src/share/vm/runtime/frame.cpp b/src/share/vm/runtime/frame.cpp index 9ea7421cf06d42fc0d0c9ac538c283968e6c13d8..6f5724323cdec48e3604bc081ba9b78026aadbae 100644 --- a/src/share/vm/runtime/frame.cpp +++ b/src/share/vm/runtime/frame.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "compiler/abstractCompiler.hpp" #include "compiler/disassembler.hpp" #include "gc_interface/collectedHeap.inline.hpp" #include "interpreter/interpreter.hpp" @@ -559,7 +560,7 @@ void frame::print_value_on(outputStream* st, JavaThread *thread) const { st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp()); if (sp() != NULL) - st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc()); + st->print(", fp=" INTPTR_FORMAT ", real_fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), real_fp(), pc()); if (StubRoutines::contains(pc())) { st->print_cr(")"); @@ -720,11 +721,14 @@ void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose } else if (_cb->is_buffer_blob()) { st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name()); } else if (_cb->is_nmethod()) { - Method* m = ((nmethod *)_cb)->method(); + nmethod* nm = (nmethod*)_cb; + Method* m = nm->method(); if (m != NULL) { m->name_and_sig_as_C_string(buf, buflen); - st->print("J %s @ " PTR_FORMAT " [" PTR_FORMAT "+" SIZE_FORMAT "]", - buf, _pc, _cb->code_begin(), _pc - _cb->code_begin()); + st->print("J %d%s %s %s (%d bytes) @ " PTR_FORMAT " [" PTR_FORMAT "+0x%x]", + nm->compile_id(), (nm->is_osr_method() ? "%" : ""), + ((nm->compiler() != NULL) ? nm->compiler()->name() : ""), + buf, m->code_size(), _pc, _cb->code_begin(), _pc - _cb->code_begin()); } else { st->print("J " PTR_FORMAT, pc()); } diff --git a/src/share/vm/utilities/vmError.cpp b/src/share/vm/utilities/vmError.cpp index 873f479d609024c524bb6bb63cb3697257c3993c..b07404dc9b78c41dbdb36f571198c856384a08db 100644 --- a/src/share/vm/utilities/vmError.cpp +++ b/src/share/vm/utilities/vmError.cpp @@ -586,6 +586,13 @@ void VMError::report(outputStream* st) { while (count++ < StackPrintLimit) { fr.print_on_error(st, buf, sizeof(buf)); st->cr(); + // Compiled code may use EBP register on x86 so it looks like + // non-walkable C frame. Use frame.sender() for java frames. + if (_thread && _thread->is_Java_thread() && fr.is_java_frame()) { + RegisterMap map((JavaThread*)_thread, false); // No update + fr = fr.sender(&map); + continue; + } if (os::is_first_C_frame(&fr)) break; fr = os::get_sender_for_C_frame(&fr); }