8136406: Remove ZapDeadCompiledLocals code
Dead code elimination.
Reviewed-by: roland, twisti
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java
index c8b771d..ca0b982 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java
@@ -67,9 +67,6 @@
}
}
- public void visitValueLocation(Address valueAddr) {
- }
-
public void visitNarrowOopLocation(Address narrowOopAddr) {
addressVisitor.visitCompOopAddress(narrowOopAddr);
}
@@ -216,9 +213,9 @@
}
}
- // 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 @@
// 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);
}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java
index 2fa04b9..3d6e125 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java
@@ -49,7 +49,6 @@
// 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 @@
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 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 @@
// 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 @@
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;
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java
index 6153fba..3170b24 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java
@@ -31,6 +31,5 @@
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);
}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java
index b1ee998..ab536d2 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java
@@ -536,9 +536,6 @@
}
}
- public void visitValueLocation(Address valueAddr) {
- }
-
public void visitNarrowOopLocation(Address compOopAddr) {
addressVisitor.visitCompOopAddress(compOopAddr);
}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
index 9f4c2d2..342a96d 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
@@ -1220,9 +1220,6 @@
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));
diff --git a/hotspot/src/share/vm/compiler/oopMap.cpp b/hotspot/src/share/vm/compiler/oopMap.cpp
index cb5dfc7..5131a61 100644
--- a/hotspot/src/share/vm/compiler/oopMap.cpp
+++ b/hotspot/src/share/vm/compiler/oopMap.cpp
@@ -58,7 +58,6 @@
_valid_omv = false;
}
-
void OopMapStream::find_next() {
while(_position++ < _size) {
_omv.read_from(_stream);
@@ -156,9 +155,7 @@
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 @@
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 @@
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 @@
case OopMapValue::oop_value:
st->print("Oop");
break;
- case OopMapValue::value_value:
- st->print("Value");
- break;
case OopMapValue::narrowoop_value:
st->print("NarrowOop");
break;
diff --git a/hotspot/src/share/vm/compiler/oopMap.hpp b/hotspot/src/share/vm/compiler/oopMap.hpp
index f2639c8..5dc35d3 100644
--- a/hotspot/src/share/vm/compiler/oopMap.hpp
+++ b/hotspot/src/share/vm/compiler/oopMap.hpp
@@ -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 @@
public:
// Constants
- enum { type_bits = 5,
+ enum { type_bits = 4,
register_bits = BitsPerShort - type_bits };
enum { type_shift = 0,
@@ -68,10 +67,9 @@
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 @@
// 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); }
diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.cpp b/hotspot/src/share/vm/interpreter/oopMapCache.cpp
index 14985be..1d76649 100644
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp
@@ -213,31 +213,6 @@
}
}
-
-#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 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 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;
diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.hpp b/hotspot/src/share/vm/interpreter/oopMapCache.hpp
index dbdd4cb..19bf004 100644
--- a/hotspot/src/share/vm/interpreter/oopMapCache.hpp
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.hpp
@@ -141,9 +141,6 @@
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> {
diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp
index 61abb9c..ef53225 100644
--- a/hotspot/src/share/vm/opto/c2_globals.hpp
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp
@@ -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") \
diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp
index bb8dc44..5a1df20 100644
--- a/hotspot/src/share/vm/opto/compile.hpp
+++ b/hotspot/src/share/vm/opto/compile.hpp
@@ -1208,12 +1208,6 @@
// 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
diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp
index 7423155..712a422 100644
--- a/hotspot/src/share/vm/opto/output.cpp
+++ b/hotspot/src/share/vm/opto/output.cpp
@@ -116,12 +116,6 @@
}
}
-# 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 @@
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 @@
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 @@
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 @@
// !!!!! 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 @@
// !!!!! 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;
}
diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp
index 3d56ea1..9bcc730 100644
--- a/hotspot/src/share/vm/opto/runtime.cpp
+++ b/hotspot/src/share/vm/opto/runtime.cpp
@@ -102,11 +102,6 @@
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 @@
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 @@
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 @@
#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
diff --git a/hotspot/src/share/vm/opto/runtime.hpp b/hotspot/src/share/vm/opto/runtime.hpp
index 24fd658..8e38f3f 100644
--- a/hotspot/src/share/vm/opto/runtime.hpp
+++ b/hotspot/src/share/vm/opto/runtime.hpp
@@ -152,12 +152,6 @@
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 @@
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 @@
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 @@
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;
diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp
index c48cc28..1f5a494 100644
--- a/hotspot/src/share/vm/runtime/frame.cpp
+++ b/hotspot/src/share/vm/runtime/frame.cpp
@@ -1111,104 +1111,6 @@
}
}
-# 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()) {
diff --git a/hotspot/src/share/vm/runtime/frame.hpp b/hotspot/src/share/vm/runtime/frame.hpp
index df5d3b2..0b208d2 100644
--- a/hotspot/src/share/vm/runtime/frame.hpp
+++ b/hotspot/src/share/vm/runtime/frame.hpp
@@ -405,39 +405,6 @@
// 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);
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index bfe44ed..900d54e 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -937,16 +937,6 @@
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 @@
develop(bool, TraceCompiledIC, false, \
"Trace changes of compiled IC") \
\
- notproduct(bool, TraceZapDeadLocals, false, \
- "Trace zapping dead locals") \
- \
develop(bool, TraceStartupTime, false, \
"Trace setup time") \
\
diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.cpp b/hotspot/src/share/vm/runtime/interfaceSupport.cpp
index 337fb59..d6c1b2a 100644
--- a/hotspot/src/share/vm/runtime/interfaceSupport.cpp
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.cpp
@@ -167,25 +167,6 @@
walk_stack_from(thread->last_java_vframe(®_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;
diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.hpp b/hotspot/src/share/vm/runtime/interfaceSupport.hpp
index 590b772..206d101 100644
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp
@@ -84,10 +84,6 @@
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 @@
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) {
diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
index 43f61f7..036e862 100644
--- a/hotspot/src/share/vm/runtime/java.cpp
+++ b/hotspot/src/share/vm/runtime/java.cpp
@@ -331,14 +331,6 @@
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);
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index 335f1df5..356e5c4 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -2581,7 +2581,6 @@
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) \
diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
index 3b84a89..64b2e08 100644
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
@@ -1413,14 +1413,6 @@
#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