This commit is contained in:
Vladimir Kozlov 2015-09-16 20:33:16 +02:00
commit a402bebf6e
22 changed files with 64 additions and 590 deletions

View File

@ -67,9 +67,6 @@ public class ImmutableOopMapSet extends VMObject {
}
}
public void visitValueLocation(Address valueAddr) {
}
public void visitNarrowOopLocation(Address narrowOopAddr) {
addressVisitor.visitCompOopAddress(narrowOopAddr);
}
@ -216,9 +213,9 @@ public class ImmutableOopMapSet extends VMObject {
}
}
// We want narow oop, value and oop oop_types
OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[]{
OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
// We want narow oop and oop oop_types
OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[] {
OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
};
{
@ -231,8 +228,6 @@ public class ImmutableOopMapSet extends VMObject {
// to detect in the debugging system
// assert(Universe::is_heap_or_null(*loc), "found non oop pointer");
visitor.visitOopLocation(loc);
} else if (omv.getType() == OopMapValue.OopTypes.VALUE_VALUE) {
visitor.visitValueLocation(loc);
} else if (omv.getType() == OopMapValue.OopTypes.NARROWOOP_VALUE) {
visitor.visitNarrowOopLocation(loc);
}

View File

@ -49,7 +49,6 @@ public class OopMapValue {
// Types of OopValues
static int UNUSED_VALUE;
static int OOP_VALUE;
static int VALUE_VALUE;
static int NARROWOOP_VALUE;
static int CALLEE_SAVED_VALUE;
static int DERIVED_OOP_VALUE;
@ -73,7 +72,6 @@ public class OopMapValue {
REGISTER_MASK_IN_PLACE = db.lookupIntConstant("OopMapValue::register_mask_in_place").intValue();
UNUSED_VALUE = db.lookupIntConstant("OopMapValue::unused_value").intValue();
OOP_VALUE = db.lookupIntConstant("OopMapValue::oop_value").intValue();
VALUE_VALUE = db.lookupIntConstant("OopMapValue::value_value").intValue();
NARROWOOP_VALUE = db.lookupIntConstant("OopMapValue::narrowoop_value").intValue();
CALLEE_SAVED_VALUE = db.lookupIntConstant("OopMapValue::callee_saved_value").intValue();
DERIVED_OOP_VALUE = db.lookupIntConstant("OopMapValue::derived_oop_value").intValue();
@ -82,7 +80,6 @@ public class OopMapValue {
public static abstract class OopTypes {
public static final OopTypes UNUSED_VALUE = new OopTypes() { int getValue() { return OopMapValue.UNUSED_VALUE; }};
public static final OopTypes OOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.OOP_VALUE; }};
public static final OopTypes VALUE_VALUE = new OopTypes() { int getValue() { return OopMapValue.VALUE_VALUE; }};
public static final OopTypes NARROWOOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.NARROWOOP_VALUE; }};
public static final OopTypes CALLEE_SAVED_VALUE = new OopTypes() { int getValue() { return OopMapValue.CALLEE_SAVED_VALUE; }};
public static final OopTypes DERIVED_OOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.DERIVED_OOP_VALUE; }};
@ -105,7 +102,6 @@ public class OopMapValue {
// Querying
public boolean isOop() { return (getValue() & TYPE_MASK_IN_PLACE) == OOP_VALUE; }
public boolean isValue() { return (getValue() & TYPE_MASK_IN_PLACE) == VALUE_VALUE; }
public boolean isNarrowOop() { return (getValue() & TYPE_MASK_IN_PLACE) == NARROWOOP_VALUE; }
public boolean isCalleeSaved() { return (getValue() & TYPE_MASK_IN_PLACE) == CALLEE_SAVED_VALUE; }
public boolean isDerivedOop() { return (getValue() & TYPE_MASK_IN_PLACE) == DERIVED_OOP_VALUE; }
@ -117,7 +113,6 @@ public class OopMapValue {
int which = (getValue() & TYPE_MASK_IN_PLACE);
if (which == UNUSED_VALUE) return OopTypes.UNUSED_VALUE;
else if (which == OOP_VALUE) return OopTypes.OOP_VALUE;
else if (which == VALUE_VALUE) return OopTypes.VALUE_VALUE;
else if (which == NARROWOOP_VALUE) return OopTypes.NARROWOOP_VALUE;
else if (which == CALLEE_SAVED_VALUE) return OopTypes.CALLEE_SAVED_VALUE;
else if (which == DERIVED_OOP_VALUE) return OopTypes.DERIVED_OOP_VALUE;

View File

@ -31,6 +31,5 @@ import sun.jvm.hotspot.debugger.*;
public interface OopMapVisitor {
public void visitOopLocation(Address oopAddr);
public void visitDerivedOopLocation(Address baseOopAddr, Address derivedOopAddr);
public void visitValueLocation(Address valueAddr);
public void visitNarrowOopLocation(Address narrowOopAddr);
}

View File

@ -536,9 +536,6 @@ public abstract class Frame implements Cloneable {
}
}
public void visitValueLocation(Address valueAddr) {
}
public void visitNarrowOopLocation(Address compOopAddr) {
addressVisitor.visitCompOopAddress(compOopAddr);
}

View File

@ -1220,9 +1220,6 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
buf.append(omvIterator.iterate(oms, "NarrowOops:", false));
oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
buf.append(omvIterator.iterate(oms, "Values:", false));
oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE);
buf.append(omvIterator.iterate(oms, "Callee saved:", true));

View File

@ -58,7 +58,6 @@ OopMapStream::OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask) {
_valid_omv = false;
}
void OopMapStream::find_next() {
while(_position++ < _size) {
_omv.read_from(_stream);
@ -156,9 +155,7 @@ void OopMap::set_oop(VMReg reg) {
void OopMap::set_value(VMReg reg) {
// At this time, we only need value entries in our OopMap when ZapDeadCompiledLocals is active.
if (ZapDeadCompiledLocals)
set_xxx(reg, OopMapValue::value_value, VMRegImpl::Bad());
// At this time, we don't need value entries in our OopMap.
}
@ -199,7 +196,6 @@ void OopMapSet::grow_om_data() {
set_om_data(new_data);
}
void OopMapSet::add_gc_map(int pc_offset, OopMap *map ) {
assert(om_size() != -1,"Cannot grow a fixed OopMapSet");
@ -345,72 +341,73 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
do {
omv = oms.current();
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
if ( loc != NULL ) {
oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
oop *derived_loc = loc;
oop val = *base_loc;
if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
// Ignore NULL oops and decoded NULL narrow oops which
// equal to Universe::narrow_oop_base when a narrow oop
// implicit null check is used in compiled code.
// The narrow_oop_base could be NULL or be the address
// of the page below heap depending on compressed oops mode.
} else
derived_oop_fn(base_loc, derived_loc);
guarantee(loc != NULL, "missing saved register");
oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
oop *derived_loc = loc;
oop val = *base_loc;
if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
// Ignore NULL oops and decoded NULL narrow oops which
// equal to Universe::narrow_oop_base when a narrow oop
// implicit null check is used in compiled code.
// The narrow_oop_base could be NULL or be the address
// of the page below heap depending on compressed oops mode.
} else {
derived_oop_fn(base_loc, derived_loc);
}
oms.next();
} while (!oms.is_done());
}
}
// We want coop, value and oop oop_types
int mask = OopMapValue::oop_value | OopMapValue::value_value | OopMapValue::narrowoop_value;
// We want coop and oop oop_types
int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
{
for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
omv = oms.current();
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
if ( loc != NULL ) {
if ( omv.type() == OopMapValue::oop_value ) {
oop val = *loc;
if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
// Ignore NULL oops and decoded NULL narrow oops which
// equal to Universe::narrow_oop_base when a narrow oop
// implicit null check is used in compiled code.
// The narrow_oop_base could be NULL or be the address
// of the page below heap depending on compressed oops mode.
continue;
}
#ifdef ASSERT
if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
!Universe::heap()->is_in_or_null(*loc)) {
tty->print_cr("# Found non oop pointer. Dumping state at failure");
// try to dump out some helpful debugging information
trace_codeblob_maps(fr, reg_map);
omv.print();
tty->print_cr("register r");
omv.reg()->print();
tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
// do the real assert.
assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
}
#endif // ASSERT
oop_fn->do_oop(loc);
} else if ( omv.type() == OopMapValue::value_value ) {
assert((*loc) == (oop)NULL || !Universe::is_narrow_oop_base(*loc),
"found invalid value pointer");
value_fn->do_oop(loc);
} else if ( omv.type() == OopMapValue::narrowoop_value ) {
narrowOop *nl = (narrowOop*)loc;
#ifndef VM_LITTLE_ENDIAN
if (!omv.reg()->is_stack()) {
// compressed oops in registers only take up 4 bytes of an
// 8 byte register but they are in the wrong part of the
// word so adjust loc to point at the right place.
nl = (narrowOop*)((address)nl + 4);
}
#endif
oop_fn->do_oop(nl);
// It should be an error if no location can be found for a
// register mentioned as contained an oop of some kind. Maybe
// this was allowed previously because value_value items might
// be missing?
guarantee(loc != NULL, "missing saved register");
if ( omv.type() == OopMapValue::oop_value ) {
oop val = *loc;
if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
// Ignore NULL oops and decoded NULL narrow oops which
// equal to Universe::narrow_oop_base when a narrow oop
// implicit null check is used in compiled code.
// The narrow_oop_base could be NULL or be the address
// of the page below heap depending on compressed oops mode.
continue;
}
#ifdef ASSERT
if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
!Universe::heap()->is_in_or_null(*loc)) {
tty->print_cr("# Found non oop pointer. Dumping state at failure");
// try to dump out some helpful debugging information
trace_codeblob_maps(fr, reg_map);
omv.print();
tty->print_cr("register r");
omv.reg()->print();
tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
// do the real assert.
assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
}
#endif // ASSERT
oop_fn->do_oop(loc);
} else if ( omv.type() == OopMapValue::narrowoop_value ) {
narrowOop *nl = (narrowOop*)loc;
#ifndef VM_LITTLE_ENDIAN
VMReg vmReg = omv.reg();
// Don't do this on SPARC float registers as they can be individually addressed
if (!vmReg->is_stack() SPARC_ONLY(&& !vmReg->is_FloatRegister())) {
// compressed oops in registers only take up 4 bytes of an
// 8 byte register but they are in the wrong part of the
// word so adjust loc to point at the right place.
nl = (narrowOop*)((address)nl + 4);
}
#endif
oop_fn->do_oop(nl);
}
}
}
@ -485,9 +482,6 @@ void print_register_type(OopMapValue::oop_types x, VMReg optional,
case OopMapValue::oop_value:
st->print("Oop");
break;
case OopMapValue::value_value:
st->print("Value");
break;
case OopMapValue::narrowoop_value:
st->print("NarrowOop");
break;

View File

@ -33,7 +33,6 @@
// Interface for generating the frame map for compiled code. A frame map
// describes for a specific pc whether each register and frame stack slot is:
// Oop - A GC root for current frame
// Value - Live non-oop, non-float value: int, either half of double
// Dead - Dead; can be Zapped for debugging
// CalleeXX - Callee saved; also describes which caller register is saved
// DerivedXX - A derived oop; original oop is described.
@ -54,7 +53,7 @@ private:
public:
// Constants
enum { type_bits = 5,
enum { type_bits = 4,
register_bits = BitsPerShort - type_bits };
enum { type_shift = 0,
@ -68,10 +67,9 @@ public:
enum oop_types { // must fit in type_bits
unused_value =0, // powers of 2, for masking OopMapStream
oop_value = 1,
value_value = 2,
narrowoop_value = 4,
callee_saved_value = 8,
derived_oop_value= 16 };
narrowoop_value = 2,
callee_saved_value = 4,
derived_oop_value= 8 };
// Constructors
OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
@ -96,13 +94,11 @@ public:
// Querying
bool is_oop() { return mask_bits(value(), type_mask_in_place) == oop_value; }
bool is_value() { return mask_bits(value(), type_mask_in_place) == value_value; }
bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
void set_oop() { set_value((value() & register_mask_in_place) | oop_value); }
void set_value() { set_value((value() & register_mask_in_place) | value_value); }
void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); }
void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); }
void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); }

View File

@ -213,31 +213,6 @@ void InterpreterOopMap::iterate_oop(OffsetClosure* oop_closure) const {
}
}
#ifdef ENABLE_ZAP_DEAD_LOCALS
void InterpreterOopMap::iterate_all(OffsetClosure* oop_closure, OffsetClosure* value_closure, OffsetClosure* dead_closure) {
int n = number_of_entries();
int word_index = 0;
uintptr_t value = 0;
uintptr_t mask = 0;
// iterate over entries
for (int i = 0; i < n; i++, mask <<= bits_per_entry) {
// get current word
if (mask == 0) {
value = bit_mask()[word_index++];
mask = 1;
}
// test for dead values & oops, and for live values
if ((value & (mask << dead_bit_number)) != 0) dead_closure->offset_do(i); // call this for all dead values or oops
else if ((value & (mask << oop_bit_number)) != 0) oop_closure->offset_do(i); // call this for all live oops
else value_closure->offset_do(i); // call this for all live values
}
}
#endif
void InterpreterOopMap::print() const {
int n = number_of_entries();
tty->print("oop map for ");
@ -297,12 +272,6 @@ bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, in
bool v2 = vars[i].is_reference() ? true : false;
assert(v1 == v2, "locals oop mask generation error");
if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0);
#ifdef ENABLE_ZAP_DEAD_LOCALS
bool v3 = is_dead(i) ? true : false;
bool v4 = !vars[i].is_live() ? true : false;
assert(v3 == v4, "locals live mask generation error");
assert(!(v1 && v3), "dead value marked as oop");
#endif
}
if (TraceOopMapGeneration && Verbose) { tty->cr(); tty->print("Stack (%d): ", stack_top); }
@ -311,12 +280,6 @@ bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, in
bool v2 = stack[j].is_reference() ? true : false;
assert(v1 == v2, "stack oop mask generation error");
if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0);
#ifdef ENABLE_ZAP_DEAD_LOCALS
bool v3 = is_dead(max_locals + j) ? true : false;
bool v4 = !stack[j].is_live() ? true : false;
assert(v3 == v4, "stack live mask generation error");
assert(!(v1 && v3), "dead value marked as oop");
#endif
}
if (TraceOopMapGeneration && Verbose) tty->cr();
return true;

View File

@ -141,9 +141,6 @@ class InterpreterOopMap: ResourceObj {
int expression_stack_size() const { return _expression_stack_size; }
#ifdef ENABLE_ZAP_DEAD_LOCALS
void iterate_all(OffsetClosure* oop_closure, OffsetClosure* value_closure, OffsetClosure* dead_closure);
#endif
};
class OopMapCache : public CHeapObj<mtClass> {

View File

@ -69,22 +69,6 @@
develop(bool, StressGCM, false, \
"Randomize instruction scheduling in GCM") \
\
notproduct(intx, CompileZapFirst, 0, \
"If +ZapDeadCompiledLocals, " \
"skip this many before compiling in zap calls") \
\
notproduct(intx, CompileZapLast, -1, \
"If +ZapDeadCompiledLocals, " \
"compile this many after skipping (incl. skip count, -1 = all)") \
\
notproduct(intx, ZapDeadCompiledLocalsFirst, 0, \
"If +ZapDeadCompiledLocals, " \
"skip this many before really doing it") \
\
notproduct(intx, ZapDeadCompiledLocalsLast, -1, \
"If +ZapDeadCompiledLocals, " \
"do this many after skipping (incl. skip count, -1 = all)") \
\
develop(intx, OptoPrologueNops, 0, \
"Insert this many extra nop instructions " \
"in the prologue of every nmethod") \

View File

@ -1208,12 +1208,6 @@ class Compile : public Phase {
// Compute the name of old_SP. See <arch>.ad for frame layout.
OptoReg::Name compute_old_SP();
#ifdef ENABLE_ZAP_DEAD_LOCALS
static bool is_node_getting_a_safepoint(Node*);
void Insert_zap_nodes();
Node* call_zap_node(MachSafePointNode* n, int block_no);
#endif
private:
// Phase control:
void Init(int aliaslevel); // Prepare for a single compilation

View File

@ -116,12 +116,6 @@ void Compile::Output() {
}
}
# ifdef ENABLE_ZAP_DEAD_LOCALS
if (ZapDeadCompiledLocals) {
Insert_zap_nodes();
}
# endif
uint* blk_starts = NEW_RESOURCE_ARRAY(uint, _cfg->number_of_blocks() + 1);
blk_starts[0] = 0;
@ -184,113 +178,6 @@ bool Compile::need_register_stack_bang() const {
return (stub_function() == NULL && has_java_calls());
}
# ifdef ENABLE_ZAP_DEAD_LOCALS
// In order to catch compiler oop-map bugs, we have implemented
// a debugging mode called ZapDeadCompilerLocals.
// This mode causes the compiler to insert a call to a runtime routine,
// "zap_dead_locals", right before each place in compiled code
// that could potentially be a gc-point (i.e., a safepoint or oop map point).
// The runtime routine checks that locations mapped as oops are really
// oops, that locations mapped as values do not look like oops,
// and that locations mapped as dead are not used later
// (by zapping them to an invalid address).
int Compile::_CompiledZap_count = 0;
void Compile::Insert_zap_nodes() {
bool skip = false;
// Dink with static counts because code code without the extra
// runtime calls is MUCH faster for debugging purposes
if ( CompileZapFirst == 0 ) ; // nothing special
else if ( CompileZapFirst > CompiledZap_count() ) skip = true;
else if ( CompileZapFirst == CompiledZap_count() )
warning("starting zap compilation after skipping");
if ( CompileZapLast == -1 ) ; // nothing special
else if ( CompileZapLast < CompiledZap_count() ) skip = true;
else if ( CompileZapLast == CompiledZap_count() )
warning("about to compile last zap");
++_CompiledZap_count; // counts skipped zaps, too
if ( skip ) return;
if ( _method == NULL )
return; // no safepoints/oopmaps emitted for calls in stubs,so we don't care
// Insert call to zap runtime stub before every node with an oop map
for( uint i=0; i<_cfg->number_of_blocks(); i++ ) {
Block *b = _cfg->get_block(i);
for ( uint j = 0; j < b->number_of_nodes(); ++j ) {
Node *n = b->get_node(j);
// Determining if we should insert a zap-a-lot node in output.
// We do that for all nodes that has oopmap info, except for calls
// to allocation. Calls to allocation passes in the old top-of-eden pointer
// and expect the C code to reset it. Hence, there can be no safepoints between
// the inlined-allocation and the call to new_Java, etc.
// We also cannot zap monitor calls, as they must hold the microlock
// during the call to Zap, which also wants to grab the microlock.
bool insert = n->is_MachSafePoint() && (n->as_MachSafePoint()->oop_map() != NULL);
if ( insert ) { // it is MachSafePoint
if ( !n->is_MachCall() ) {
insert = false;
} else if ( n->is_MachCall() ) {
MachCallNode* call = n->as_MachCall();
if (call->entry_point() == OptoRuntime::new_instance_Java() ||
call->entry_point() == OptoRuntime::new_array_Java() ||
call->entry_point() == OptoRuntime::multianewarray2_Java() ||
call->entry_point() == OptoRuntime::multianewarray3_Java() ||
call->entry_point() == OptoRuntime::multianewarray4_Java() ||
call->entry_point() == OptoRuntime::multianewarray5_Java() ||
call->entry_point() == OptoRuntime::slow_arraycopy_Java() ||
call->entry_point() == OptoRuntime::complete_monitor_locking_Java()
) {
insert = false;
}
}
if (insert) {
Node *zap = call_zap_node(n->as_MachSafePoint(), i);
b->insert_node(zap, j);
_cfg->map_node_to_block(zap, b);
++j;
}
}
}
}
}
Node* Compile::call_zap_node(MachSafePointNode* node_to_check, int block_no) {
const TypeFunc *tf = OptoRuntime::zap_dead_locals_Type();
CallStaticJavaNode* ideal_node =
new CallStaticJavaNode( tf,
OptoRuntime::zap_dead_locals_stub(_method->flags().is_native()),
"call zap dead locals stub", 0, TypePtr::BOTTOM);
// We need to copy the OopMap from the site we're zapping at.
// We have to make a copy, because the zap site might not be
// a call site, and zap_dead is a call site.
OopMap* clone = node_to_check->oop_map()->deep_copy();
// Add the cloned OopMap to the zap node
ideal_node->set_oop_map(clone);
return _matcher->match_sfpt(ideal_node);
}
bool Compile::is_node_getting_a_safepoint( Node* n) {
// This code duplicates the logic prior to the call of add_safepoint
// below in this file.
if( n->is_MachSafePoint() ) return true;
return false;
}
# endif // ENABLE_ZAP_DEAD_LOCALS
// Compute the size of first NumberOfLoopInstrToAlign instructions at the top
// of a loop. When aligning a loop we need to provide enough instructions
@ -834,10 +721,6 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
MachSafePointNode *sfn = mach->as_MachSafePoint();
MachCallNode *mcall;
#ifdef ENABLE_ZAP_DEAD_LOCALS
assert( is_node_getting_a_safepoint(mach), "logic does not match; false negative");
#endif
int safepoint_pc_offset = current_offset;
bool is_method_handle_invoke = false;
bool return_oop = false;
@ -1294,10 +1177,6 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
if (Pipeline::requires_bundling() && starts_bundle(n))
cb->flush_bundle(false);
// The following logic is duplicated in the code ifdeffed for
// ENABLE_ZAP_DEAD_LOCALS which appears above in this file. It
// should be factored out. Or maybe dispersed to the nodes?
// Special handling for SafePoint/Call Nodes
bool is_mcall = false;
if (n->is_Mach()) {
@ -1364,9 +1243,6 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
// !!!!! Stubs only need an oopmap right now, so bail out
if (sfn->jvms()->method() == NULL) {
// Write the oopmap directly to the code blob??!!
# ifdef ENABLE_ZAP_DEAD_LOCALS
assert( !is_node_getting_a_safepoint(sfn), "logic does not match; false positive");
# endif
continue;
}
} // End synchronization
@ -1554,9 +1430,6 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
// !!!!! Stubs only need an oopmap right now, so bail out
if (!mach->is_MachCall() && mach->as_MachSafePoint()->jvms()->method() == NULL) {
// Write the oopmap directly to the code blob??!!
# ifdef ENABLE_ZAP_DEAD_LOCALS
assert( !is_node_getting_a_safepoint(mach), "logic does not match; false positive");
# endif
delay_slot = NULL;
continue;
}

View File

@ -102,11 +102,6 @@ address OptoRuntime::_rethrow_Java = NULL;
address OptoRuntime::_slow_arraycopy_Java = NULL;
address OptoRuntime::_register_finalizer_Java = NULL;
# ifdef ENABLE_ZAP_DEAD_LOCALS
address OptoRuntime::_zap_dead_Java_locals_Java = NULL;
address OptoRuntime::_zap_dead_native_locals_Java = NULL;
# endif
ExceptionBlob* OptoRuntime::_exception_blob;
// This should be called in an assertion at the start of OptoRuntime routines
@ -152,10 +147,6 @@ bool OptoRuntime::generate(ciEnv* env) {
gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false, false);
gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false, false);
# ifdef ENABLE_ZAP_DEAD_LOCALS
gen(env, _zap_dead_Java_locals_Java , zap_dead_locals_Type , zap_dead_Java_locals_C , 0 , false, true , false );
gen(env, _zap_dead_native_locals_Java , zap_dead_locals_Type , zap_dead_native_locals_C , 0 , false, true , false );
# endif
return true;
}
@ -604,23 +595,6 @@ const TypeFunc *OptoRuntime::uncommon_trap_Type() {
return TypeFunc::make(domain, range);
}
# ifdef ENABLE_ZAP_DEAD_LOCALS
// Type used for stub generation for zap_dead_locals.
// No inputs or outputs
const TypeFunc *OptoRuntime::zap_dead_locals_Type() {
// create input type (domain)
const Type **fields = TypeTuple::fields(0);
const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms,fields);
// create result type (range)
fields = TypeTuple::fields(0);
const TypeTuple *range = TypeTuple::make(TypeFunc::Parms,fields);
return TypeFunc::make(domain,range);
}
# endif
//-----------------------------------------------------------------------------
// Monitor Handling
const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
@ -1648,67 +1622,3 @@ static void trace_exception(oop exception_oop, address exception_pc, const char*
#endif // PRODUCT
# ifdef ENABLE_ZAP_DEAD_LOCALS
// Called from call sites in compiled code with oop maps (actually safepoints)
// Zaps dead locals in first java frame.
// Is entry because may need to lock to generate oop maps
// Currently, only used for compiler frames, but someday may be used
// for interpreter frames, too.
int OptoRuntime::ZapDeadCompiledLocals_count = 0;
// avoid pointers to member funcs with these helpers
static bool is_java_frame( frame* f) { return f->is_java_frame(); }
static bool is_native_frame(frame* f) { return f->is_native_frame(); }
void OptoRuntime::zap_dead_java_or_native_locals(JavaThread* thread,
bool (*is_this_the_right_frame_to_zap)(frame*)) {
assert(JavaThread::current() == thread, "is this needed?");
if ( !ZapDeadCompiledLocals ) return;
bool skip = false;
if ( ZapDeadCompiledLocalsFirst == 0 ) ; // nothing special
else if ( ZapDeadCompiledLocalsFirst > ZapDeadCompiledLocals_count ) skip = true;
else if ( ZapDeadCompiledLocalsFirst == ZapDeadCompiledLocals_count )
warning("starting zapping after skipping");
if ( ZapDeadCompiledLocalsLast == -1 ) ; // nothing special
else if ( ZapDeadCompiledLocalsLast < ZapDeadCompiledLocals_count ) skip = true;
else if ( ZapDeadCompiledLocalsLast == ZapDeadCompiledLocals_count )
warning("about to zap last zap");
++ZapDeadCompiledLocals_count; // counts skipped zaps, too
if ( skip ) return;
// find java frame and zap it
for (StackFrameStream sfs(thread); !sfs.is_done(); sfs.next()) {
if (is_this_the_right_frame_to_zap(sfs.current()) ) {
sfs.current()->zap_dead_locals(thread, sfs.register_map());
return;
}
}
warning("no frame found to zap in zap_dead_Java_locals_C");
}
JRT_LEAF(void, OptoRuntime::zap_dead_Java_locals_C(JavaThread* thread))
zap_dead_java_or_native_locals(thread, is_java_frame);
JRT_END
// The following does not work because for one thing, the
// thread state is wrong; it expects java, but it is native.
// Also, the invariants in a native stub are different and
// I'm not sure it is safe to have a MachCalRuntimeDirectNode
// in there.
// So for now, we do not zap in native stubs.
JRT_LEAF(void, OptoRuntime::zap_dead_native_locals_C(JavaThread* thread))
zap_dead_java_or_native_locals(thread, is_native_frame);
JRT_END
# endif

View File

@ -152,12 +152,6 @@ class OptoRuntime : public AllStatic {
static address _slow_arraycopy_Java;
static address _register_finalizer_Java;
# ifdef ENABLE_ZAP_DEAD_LOCALS
static address _zap_dead_Java_locals_Java;
static address _zap_dead_native_locals_Java;
# endif
//
// Implementation of runtime methods
// =================================
@ -212,19 +206,6 @@ private:
static void register_finalizer(oopDesc* obj, JavaThread* thread);
// zaping dead locals, either from Java frames or from native frames
# ifdef ENABLE_ZAP_DEAD_LOCALS
static void zap_dead_Java_locals_C( JavaThread* thread);
static void zap_dead_native_locals_C( JavaThread* thread);
static void zap_dead_java_or_native_locals( JavaThread*, bool (*)(frame*));
public:
static int ZapDeadCompiledLocals_count;
# endif
public:
static bool is_callee_saved_register(MachRegisterNumbers reg);
@ -256,14 +237,6 @@ private:
static address slow_arraycopy_Java() { return _slow_arraycopy_Java; }
static address register_finalizer_Java() { return _register_finalizer_Java; }
# ifdef ENABLE_ZAP_DEAD_LOCALS
static address zap_dead_locals_stub(bool is_native) { return is_native
? _zap_dead_native_locals_Java
: _zap_dead_Java_locals_Java; }
static MachNode* node_to_call_zap_dead_locals(Node* n, int block_num, bool is_native);
# endif
static ExceptionBlob* exception_blob() { return _exception_blob; }
// Leaf routines helping with method data update
@ -353,10 +326,6 @@ private:
static const TypeFunc* dtrace_method_entry_exit_Type();
static const TypeFunc* dtrace_object_alloc_Type();
# ifdef ENABLE_ZAP_DEAD_LOCALS
static const TypeFunc* zap_dead_locals_Type();
# endif
private:
static NamedCounter * volatile _named_counters;

View File

@ -1111,104 +1111,6 @@ void frame::metadata_do(void f(Metadata*)) {
}
}
# ifdef ENABLE_ZAP_DEAD_LOCALS
void frame::CheckValueClosure::do_oop(oop* p) {
if (CheckOopishValues && Universe::heap()->is_in_reserved(*p)) {
warning("value @ " INTPTR_FORMAT " looks oopish (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current());
}
}
frame::CheckValueClosure frame::_check_value;
void frame::CheckOopClosure::do_oop(oop* p) {
if (*p != NULL && !(*p)->is_oop()) {
warning("value @ " INTPTR_FORMAT " should be an oop (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current());
}
}
frame::CheckOopClosure frame::_check_oop;
void frame::check_derived_oop(oop* base, oop* derived) {
_check_oop.do_oop(base);
}
void frame::ZapDeadClosure::do_oop(oop* p) {
if (TraceZapDeadLocals) tty->print_cr("zapping @ " INTPTR_FORMAT " containing " INTPTR_FORMAT, p, (address)*p);
*p = cast_to_oop<intptr_t>(0xbabebabe);
}
frame::ZapDeadClosure frame::_zap_dead;
void frame::zap_dead_locals(JavaThread* thread, const RegisterMap* map) {
assert(thread == Thread::current(), "need to synchronize to do this to another thread");
// Tracing - part 1
if (TraceZapDeadLocals) {
ResourceMark rm(thread);
tty->print_cr("--------------------------------------------------------------------------------");
tty->print("Zapping dead locals in ");
print_on(tty);
tty->cr();
}
// Zapping
if (is_entry_frame ()) zap_dead_entry_locals (thread, map);
else if (is_interpreted_frame()) zap_dead_interpreted_locals(thread, map);
else if (is_compiled_frame()) zap_dead_compiled_locals (thread, map);
else
// could be is_runtime_frame
// so remove error: ShouldNotReachHere();
;
// Tracing - part 2
if (TraceZapDeadLocals) {
tty->cr();
}
}
void frame::zap_dead_interpreted_locals(JavaThread *thread, const RegisterMap* map) {
// get current interpreter 'pc'
assert(is_interpreted_frame(), "Not an interpreted frame");
Method* m = interpreter_frame_method();
int bci = interpreter_frame_bci();
int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
// process dynamic part
InterpreterFrameClosure value_blk(this, max_locals, m->max_stack(),
&_check_value);
InterpreterFrameClosure oop_blk(this, max_locals, m->max_stack(),
&_check_oop );
InterpreterFrameClosure dead_blk(this, max_locals, m->max_stack(),
&_zap_dead );
// get frame map
InterpreterOopMap mask;
m->mask_for(bci, &mask);
mask.iterate_all( &oop_blk, &value_blk, &dead_blk);
}
void frame::zap_dead_compiled_locals(JavaThread* thread, const RegisterMap* reg_map) {
ResourceMark rm(thread);
assert(_cb != NULL, "sanity check");
if (_cb->oop_maps() != NULL) {
OopMapSet::all_do(this, reg_map, &_check_oop, check_derived_oop, &_check_value);
}
}
void frame::zap_dead_entry_locals(JavaThread*, const RegisterMap*) {
if (TraceZapDeadLocals) warning("frame::zap_dead_entry_locals unimplemented");
}
void frame::zap_dead_deoptimized_locals(JavaThread*, const RegisterMap*) {
if (TraceZapDeadLocals) warning("frame::zap_dead_deoptimized_locals unimplemented");
}
# endif // ENABLE_ZAP_DEAD_LOCALS
void frame::verify(const RegisterMap* map) {
// for now make sure receiver type is correct
if (is_interpreted_frame()) {

View File

@ -405,39 +405,6 @@ class frame VALUE_OBJ_CLASS_SPEC {
// RedefineClasses support for finding live interpreted methods on the stack
void metadata_do(void f(Metadata*));
# ifdef ENABLE_ZAP_DEAD_LOCALS
private:
class CheckValueClosure: public OopClosure {
public:
void do_oop(oop* p);
void do_oop(narrowOop* p) { ShouldNotReachHere(); }
};
static CheckValueClosure _check_value;
class CheckOopClosure: public OopClosure {
public:
void do_oop(oop* p);
void do_oop(narrowOop* p) { ShouldNotReachHere(); }
};
static CheckOopClosure _check_oop;
static void check_derived_oop(oop* base, oop* derived);
class ZapDeadClosure: public OopClosure {
public:
void do_oop(oop* p);
void do_oop(narrowOop* p) { ShouldNotReachHere(); }
};
static ZapDeadClosure _zap_dead;
public:
// Zapping
void zap_dead_locals (JavaThread* thread, const RegisterMap* map);
void zap_dead_interpreted_locals(JavaThread* thread, const RegisterMap* map);
void zap_dead_compiled_locals (JavaThread* thread, const RegisterMap* map);
void zap_dead_entry_locals (JavaThread* thread, const RegisterMap* map);
void zap_dead_deoptimized_locals(JavaThread* thread, const RegisterMap* map);
# endif
// Verification
void verify(const RegisterMap* map);
static bool verify_return_pc(address x);

View File

@ -937,16 +937,6 @@ public:
notproduct(bool, VerifyCodeCache, false, \
"Verify code cache on memory allocation/deallocation") \
\
develop(bool, ZapDeadCompiledLocals, false, \
"Zap dead locals in compiler frames") \
\
notproduct(bool, ZapDeadLocalsOld, false, \
"Zap dead locals (old version, zaps all frames when " \
"entering the VM") \
\
notproduct(bool, CheckOopishValues, false, \
"Warn if value contains oop (requires ZapDeadLocals)") \
\
develop(bool, UseMallocOnly, false, \
"Use only malloc/free for allocation (no resource area/arena)") \
\
@ -1489,9 +1479,6 @@ public:
develop(bool, TraceCompiledIC, false, \
"Trace changes of compiled IC") \
\
notproduct(bool, TraceZapDeadLocals, false, \
"Trace zapping dead locals") \
\
develop(bool, TraceStartupTime, false, \
"Trace setup time") \
\

View File

@ -167,25 +167,6 @@ void InterfaceSupport::walk_stack() {
walk_stack_from(thread->last_java_vframe(&reg_map));
}
# ifdef ENABLE_ZAP_DEAD_LOCALS
static int zap_traversals = 0;
void InterfaceSupport::zap_dead_locals_old() {
JavaThread* thread = JavaThread::current();
if (zap_traversals == -1) // edit constant for debugging
warning("I am here");
int zap_frame_count = 0; // count frames to help debugging
for (StackFrameStream sfs(thread); !sfs.is_done(); sfs.next()) {
sfs.current()->zap_dead_locals(thread, sfs.register_map());
++zap_frame_count;
}
++zap_traversals;
}
# endif
// invocation counter for InterfaceSupport::deoptimizeAll/zombieAll functions
int deoptimizeAllCounter = 0;
int zombieAllCounter = 0;

View File

@ -84,10 +84,6 @@ class InterfaceSupport: AllStatic {
static void walk_stack_from(vframe* start_vf);
static void walk_stack();
# ifdef ENABLE_ZAP_DEAD_LOCALS
static void zap_dead_locals_old();
# endif
static void zombieAll();
static void unlinkSymbols();
static void deoptimizeAll();
@ -357,11 +353,6 @@ class VMEntryWrapper {
if (WalkStackALot) {
InterfaceSupport::walk_stack();
}
#ifdef ENABLE_ZAP_DEAD_LOCALS
if (ZapDeadLocalsOld) {
InterfaceSupport::zap_dead_locals_old();
}
#endif
#ifdef COMPILER2
// This option is not used by Compiler 1
if (StressDerivedPointers) {

View File

@ -331,14 +331,6 @@ void print_statistics() {
BiasedLocking::print_counters();
}
#ifdef ENABLE_ZAP_DEAD_LOCALS
#ifdef COMPILER2
if (ZapDeadCompiledLocals) {
tty->print_cr("Compile::CompiledZap_count = %d", Compile::CompiledZap_count);
tty->print_cr("OptoRuntime::ZapDeadCompiledLocals_count = %d", OptoRuntime::ZapDeadCompiledLocals_count);
}
#endif // COMPILER2
#endif // ENABLE_ZAP_DEAD_LOCALS
// Native memory tracking data
if (PrintNMTStatistics) {
MemTracker::final_report(tty);

View File

@ -2581,7 +2581,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
declare_constant(OopMapValue::register_mask_in_place) \
declare_constant(OopMapValue::unused_value) \
declare_constant(OopMapValue::oop_value) \
declare_constant(OopMapValue::value_value) \
declare_constant(OopMapValue::narrowoop_value) \
declare_constant(OopMapValue::callee_saved_value) \
declare_constant(OopMapValue::derived_oop_value) \

View File

@ -1413,14 +1413,6 @@ template<class T> static void swap(T& a, T& b) {
#define UINTX_FORMAT_W(width) "%" #width PRIuPTR
// Enable zap-a-lot if in debug version.
# ifdef ASSERT
# ifdef COMPILER2
# define ENABLE_ZAP_DEAD_LOCALS
#endif /* COMPILER2 */
# endif /* ASSERT */
#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0]))
// Dereference vptr