提交 0f778da5 编写于 作者: K kvn

6671807: (Escape Analysis) Add new ideal node to represent the state of a...

6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
Summary: Values of non-static fields of a scalarized object should be saved in debug info to reallocate the object during deoptimization.
Reviewed-by: never
上级 6e4d9370
......@@ -230,6 +230,7 @@ JVMState::JVMState(ciMethod* method, JVMState* caller) {
_locoff = TypeFunc::Parms;
_stkoff = _locoff + _method->max_locals();
_monoff = _stkoff + _method->max_stack();
_scloff = _monoff;
_endoff = _monoff;
_sp = 0;
}
......@@ -242,6 +243,7 @@ JVMState::JVMState(int stack_size) {
_locoff = TypeFunc::Parms;
_stkoff = _locoff;
_monoff = _stkoff + stack_size;
_scloff = _monoff;
_endoff = _monoff;
_sp = 0;
}
......@@ -297,12 +299,22 @@ uint JVMState::debug_depth() const {
return total;
}
#ifndef PRODUCT
//------------------------------format_helper----------------------------------
// Given an allocation (a Chaitin object) and a Node decide if the Node carries
// any defined value or not. If it does, print out the register or constant.
#ifndef PRODUCT
static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i ) {
static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i, GrowableArray<SafePointScalarObjectNode*> *scobjs ) {
if (n == NULL) { st->print(" NULL"); return; }
if (n->is_SafePointScalarObject()) {
// Scalar replacement.
SafePointScalarObjectNode* spobj = n->as_SafePointScalarObject();
scobjs->append_if_missing(spobj);
int sco_n = scobjs->find(spobj);
assert(sco_n >= 0, "");
st->print(" %s%d]=#ScObj" INT32_FORMAT, msg, i, sco_n);
return;
}
if( OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined
char buf[50];
regalloc->dump_register(n,buf);
......@@ -342,10 +354,8 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c
}
}
}
#endif
//------------------------------format-----------------------------------------
#ifndef PRODUCT
void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const {
st->print(" #");
if( _method ) {
......@@ -356,24 +366,25 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
return;
}
if (n->is_MachSafePoint()) {
GrowableArray<SafePointScalarObjectNode*> scobjs;
MachSafePointNode *mcall = n->as_MachSafePoint();
uint i;
// Print locals
for( i = 0; i < (uint)loc_size(); i++ )
format_helper( regalloc, st, mcall->local(this, i), "L[", i );
format_helper( regalloc, st, mcall->local(this, i), "L[", i, &scobjs );
// Print stack
for (i = 0; i < (uint)stk_size(); i++) {
if ((uint)(_stkoff + i) >= mcall->len())
st->print(" oob ");
else
format_helper( regalloc, st, mcall->stack(this, i), "STK[", i );
format_helper( regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs );
}
for (i = 0; (int)i < nof_monitors(); i++) {
Node *box = mcall->monitor_box(this, i);
Node *obj = mcall->monitor_obj(this, i);
if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
while( !box->is_BoxLock() ) box = box->in(1);
format_helper( regalloc, st, box, "MON-BOX[", i );
format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
} else {
OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
st->print(" MON-BOX%d=%s+%d",
......@@ -381,15 +392,71 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
OptoReg::regname(OptoReg::c_frame_pointer),
regalloc->reg2offset(box_reg));
}
format_helper( regalloc, st, obj, "MON-OBJ[", i );
format_helper( regalloc, st, obj, "MON-OBJ[", i, &scobjs );
}
for (i = 0; i < (uint)scobjs.length(); i++) {
// Scalar replaced objects.
st->print_cr("");
st->print(" # ScObj" INT32_FORMAT " ", i);
SafePointScalarObjectNode* spobj = scobjs.at(i);
ciKlass* cik = spobj->bottom_type()->is_oopptr()->klass();
assert(cik->is_instance_klass() ||
cik->is_array_klass(), "Not supported allocation.");
ciInstanceKlass *iklass = NULL;
if (cik->is_instance_klass()) {
cik->print_name_on(st);
iklass = cik->as_instance_klass();
} else if (cik->is_type_array_klass()) {
cik->as_array_klass()->base_element_type()->print_name_on(st);
st->print("[%d]=", spobj->n_fields());
} else if (cik->is_obj_array_klass()) {
ciType* cie = cik->as_array_klass()->base_element_type();
int ndim = 1;
while (cie->is_obj_array_klass()) {
ndim += 1;
cie = cie->as_array_klass()->base_element_type();
}
cie->print_name_on(st);
while (ndim-- > 0) {
st->print("[]");
}
st->print("[%d]=", spobj->n_fields());
}
st->print("{");
uint nf = spobj->n_fields();
if (nf > 0) {
uint first_ind = spobj->first_index();
Node* fld_node = mcall->in(first_ind);
ciField* cifield;
if (iklass != NULL) {
st->print(" [");
cifield = iklass->nonstatic_field_at(0);
cifield->print_name_on(st);
format_helper( regalloc, st, fld_node, ":", 0, &scobjs );
} else {
format_helper( regalloc, st, fld_node, "[", 0, &scobjs );
}
for (uint j = 1; j < nf; j++) {
fld_node = mcall->in(first_ind+j);
if (iklass != NULL) {
st->print(", [");
cifield = iklass->nonstatic_field_at(j);
cifield->print_name_on(st);
format_helper( regalloc, st, fld_node, ":", j, &scobjs );
} else {
format_helper( regalloc, st, fld_node, ", [", j, &scobjs );
}
}
}
st->print(" }");
}
}
st->print_cr("");
if (caller() != NULL) caller()->format(regalloc, n, st);
}
#endif
#ifndef PRODUCT
void JVMState::dump_spec(outputStream *st) const {
if (_method != NULL) {
bool printed = false;
......@@ -419,9 +486,8 @@ void JVMState::dump_spec(outputStream *st) const {
}
if (caller() != NULL) caller()->dump_spec(st);
}
#endif
#ifndef PRODUCT
void JVMState::dump_on(outputStream* st) const {
if (_map && !((uintptr_t)_map & 1)) {
if (_map->len() > _map->req()) { // _map->has_exceptions()
......@@ -434,8 +500,8 @@ void JVMState::dump_on(outputStream* st) const {
}
_map->dump(2);
}
st->print("JVMS depth=%d loc=%d stk=%d mon=%d end=%d mondepth=%d sp=%d bci=%d method=",
depth(), locoff(), stkoff(), monoff(), endoff(), monitor_depth(), sp(), bci());
st->print("JVMS depth=%d loc=%d stk=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d method=",
depth(), locoff(), stkoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci());
if (_method == NULL) {
st->print_cr("(none)");
} else {
......@@ -465,6 +531,7 @@ JVMState* JVMState::clone_shallow(Compile* C) const {
n->set_locoff(_locoff);
n->set_stkoff(_stkoff);
n->set_monoff(_monoff);
n->set_scloff(_scloff);
n->set_endoff(_endoff);
n->set_sp(_sp);
n->set_map(_map);
......@@ -765,6 +832,7 @@ const RegMask &SafePointNode::out_RegMask() const {
void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) {
assert((int)grow_by > 0, "sanity");
int monoff = jvms->monoff();
int scloff = jvms->scloff();
int endoff = jvms->endoff();
assert(endoff == (int)req(), "no other states or debug info after me");
Node* top = Compile::current()->top();
......@@ -772,6 +840,7 @@ void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) {
ins_req(monoff, top);
}
jvms->set_monoff(monoff + grow_by);
jvms->set_scloff(scloff + grow_by);
jvms->set_endoff(endoff + grow_by);
}
......@@ -781,6 +850,7 @@ void SafePointNode::push_monitor(const FastLockNode *lock) {
const int MonitorEdges = 2;
assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
assert(req() == jvms()->endoff(), "correct sizing");
int nextmon = jvms()->scloff();
if (GenerateSynchronizationCode) {
add_req(lock->box_node());
add_req(lock->obj_node());
......@@ -788,6 +858,7 @@ void SafePointNode::push_monitor(const FastLockNode *lock) {
add_req(NULL);
add_req(NULL);
}
jvms()->set_scloff(nextmon+MonitorEdges);
jvms()->set_endoff(req());
}
......@@ -795,10 +866,13 @@ void SafePointNode::pop_monitor() {
// Delete last monitor from debug info
debug_only(int num_before_pop = jvms()->nof_monitors());
const int MonitorEdges = (1<<JVMState::logMonitorEdges);
int scloff = jvms()->scloff();
int endoff = jvms()->endoff();
int new_scloff = scloff - MonitorEdges;
int new_endoff = endoff - MonitorEdges;
jvms()->set_scloff(new_scloff);
jvms()->set_endoff(new_endoff);
while (endoff > new_endoff) del_req(--endoff);
while (scloff > new_scloff) del_req(--scloff);
assert(jvms()->nof_monitors() == num_before_pop-1, "");
}
......@@ -822,6 +896,63 @@ uint SafePointNode::match_edge(uint idx) const {
return (TypeFunc::Parms == idx);
}
//============== SafePointScalarObjectNode ==============
SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp,
#ifdef ASSERT
AllocateNode* alloc,
#endif
uint first_index,
uint n_fields) :
TypeNode(tp, 1), // 1 control input -- seems required. Get from root.
#ifdef ASSERT
_alloc(alloc),
#endif
_first_index(first_index),
_n_fields(n_fields)
{
init_class_id(Class_SafePointScalarObject);
}
uint SafePointScalarObjectNode::ideal_reg() const {
return 0; // No matching to machine instruction
}
const RegMask &SafePointScalarObjectNode::in_RegMask(uint idx) const {
return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]);
}
const RegMask &SafePointScalarObjectNode::out_RegMask() const {
return RegMask::Empty;
}
uint SafePointScalarObjectNode::match_edge(uint idx) const {
return 0;
}
SafePointScalarObjectNode*
SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) const {
void* cached = (*sosn_map)[(void*)this];
if (cached != NULL) {
return (SafePointScalarObjectNode*)cached;
}
Compile* C = Compile::current();
SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone();
res->_first_index += jvms_adj;
sosn_map->Insert((void*)this, (void*)res);
return res;
}
#ifndef PRODUCT
void SafePointScalarObjectNode::dump_spec(outputStream *st) const {
st->print(" # fields@[%d..%d]", first_index(),
first_index() + n_fields() - 1);
}
#endif
//=============================================================================
uint AllocateNode::size_of() const { return sizeof(*this); }
......
......@@ -184,6 +184,7 @@ private:
uint _locoff; // Offset to locals in input edge mapping
uint _stkoff; // Offset to stack in input edge mapping
uint _monoff; // Offset to monitors in input edge mapping
uint _scloff; // Offset to fields of scalar objs in input edge mapping
uint _endoff; // Offset to end of input edge mapping
uint _sp; // Jave Expression Stack Pointer for this state
int _bci; // Byte Code Index of this JVM point
......@@ -207,16 +208,19 @@ public:
uint stkoff() const { return _stkoff; }
uint argoff() const { return _stkoff + _sp; }
uint monoff() const { return _monoff; }
uint scloff() const { return _scloff; }
uint endoff() const { return _endoff; }
uint oopoff() const { return debug_end(); }
int loc_size() const { return _stkoff - _locoff; }
int stk_size() const { return _monoff - _stkoff; }
int mon_size() const { return _endoff - _monoff; }
int mon_size() const { return _scloff - _monoff; }
int scl_size() const { return _endoff - _scloff; }
bool is_loc(uint i) const { return i >= _locoff && i < _stkoff; }
bool is_stk(uint i) const { return i >= _stkoff && i < _monoff; }
bool is_mon(uint i) const { return i >= _monoff && i < _endoff; }
bool is_mon(uint i) const { return i >= _monoff && i < _scloff; }
bool is_scl(uint i) const { return i >= _scloff && i < _endoff; }
uint sp() const { return _sp; }
int bci() const { return _bci; }
......@@ -227,7 +231,9 @@ public:
uint depth() const { return _depth; }
uint debug_start() const; // returns locoff of root caller
uint debug_end() const; // returns endoff of self
uint debug_size() const { return loc_size() + sp() + mon_size(); }
uint debug_size() const {
return loc_size() + sp() + mon_size() + scl_size();
}
uint debug_depth() const; // returns sum of debug_size values at all depths
// Returns the JVM state at the desired depth (1 == root).
......@@ -254,8 +260,11 @@ public:
void set_locoff(uint off) { _locoff = off; }
void set_stkoff(uint off) { _stkoff = off; }
void set_monoff(uint off) { _monoff = off; }
void set_scloff(uint off) { _scloff = off; }
void set_endoff(uint off) { _endoff = off; }
void set_offsets(uint off) { _locoff = _stkoff = _monoff = _endoff = off; }
void set_offsets(uint off) {
_locoff = _stkoff = _monoff = _scloff = _endoff = off;
}
void set_map(SafePointNode *map) { _map = map; }
void set_sp(uint sp) { _sp = sp; }
void set_bci(int bci) { _bci = bci; }
......@@ -399,6 +408,47 @@ public:
#endif
};
//------------------------------SafePointScalarObjectNode----------------------
// A SafePointScalarObjectNode represents the state of a scalarized object
// at a safepoint.
class SafePointScalarObjectNode: public TypeNode {
uint _first_index; // First input edge index of a SafePoint node where
// states of the scalarized object fields are collected.
uint _n_fields; // Number of non-static fields of the scalarized object.
DEBUG_ONLY(AllocateNode* _alloc);
public:
SafePointScalarObjectNode(const TypeOopPtr* tp,
#ifdef ASSERT
AllocateNode* alloc,
#endif
uint first_index, uint n_fields);
virtual int Opcode() const;
virtual uint ideal_reg() const;
virtual const RegMask &in_RegMask(uint) const;
virtual const RegMask &out_RegMask() const;
virtual uint match_edge(uint idx) const;
uint first_index() const { return _first_index; }
uint n_fields() const { return _n_fields; }
DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; })
virtual uint size_of() const { return sizeof(*this); }
// Assumes that "this" is an argument to a safepoint node "s", and that
// "new_call" is being created to correspond to "s". But the difference
// between the start index of the jvmstates of "new_call" and "s" is
// "jvms_adj". Produce and return a SafePointScalarObjectNode that
// corresponds appropriately to "this" in "new_call". Assumes that
// "sosn_map" is a map, specific to the translation of "s" to "new_call",
// mapping old SafePointScalarObjectNodes to new, to avoid multiple copies.
SafePointScalarObjectNode* clone(int jvms_adj, Dict* sosn_map) const;
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
#endif
};
//------------------------------CallNode---------------------------------------
// Call nodes now subsume the function of debug nodes at callsites, so they
// contain the functionality of a full scope chain of debug nodes.
......
......@@ -185,6 +185,7 @@ macro(Root)
macro(RoundDouble)
macro(RoundFloat)
macro(SafePoint)
macro(SafePointScalarObject)
macro(SCMemProj)
macro(SinD)
macro(SqrtD)
......
......@@ -606,8 +606,20 @@ class Compile : public Phase {
// Build OopMaps for each GC point
void BuildOopMaps();
// Append debug info for the node to the array
void FillLocArray( int idx, Node *local, GrowableArray<ScopeValue*> *array );
// Append debug info for the node "local" at safepoint node "sfpt" to the
// "array", May also consult and add to "objs", which describes the
// scalar-replaced objects.
void FillLocArray( int idx, MachSafePointNode* sfpt,
Node *local, GrowableArray<ScopeValue*> *array,
GrowableArray<ScopeValue*> *objs );
// If "objs" contains an ObjectValue whose id is "id", returns it, else NULL.
static ObjectValue* sv_for_node_id(GrowableArray<ScopeValue*> *objs, int id);
// Requres that "objs" does not contains an ObjectValue whose id matches
// that of "sv. Appends "sv".
static void set_sv_for_object_node(GrowableArray<ScopeValue*> *objs,
ObjectValue* sv );
// Process an OopMap Element while emitting nodes
void Process_OopMap_Node(MachNode *mach, int code_offset);
......
......@@ -857,6 +857,13 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) {
for (j = 0; j < l; j++)
call->set_req(p++, in_map->in(k+j));
// Copy any scalar object fields.
k = in_jvms->scloff();
l = in_jvms->scl_size();
out_jvms->set_scloff(p);
for (j = 0; j < l; j++)
call->set_req(p++, in_map->in(k+j));
// Finish the new jvms.
out_jvms->set_endoff(p);
......@@ -864,6 +871,7 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) {
assert(out_jvms->depth() == in_jvms->depth(), "depth must match");
assert(out_jvms->loc_size() == in_jvms->loc_size(), "size must match");
assert(out_jvms->mon_size() == in_jvms->mon_size(), "size must match");
assert(out_jvms->scl_size() == in_jvms->scl_size(), "size must match");
assert(out_jvms->debug_size() == in_jvms->debug_size(), "size must match");
// Update the two tail pointers in parallel.
......
......@@ -54,15 +54,30 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal
uint new_dbg_start = newcall->tf()->domain()->cnt();
int jvms_adj = new_dbg_start - old_dbg_start;
assert (new_dbg_start == newcall->req(), "argument count mismatch");
Dict* sosn_map = new Dict(cmpkey,hashkey);
for (uint i = old_dbg_start; i < oldcall->req(); i++) {
newcall->add_req(oldcall->in(i));
Node* old_in = oldcall->in(i);
// Clone old SafePointScalarObjectNodes, adjusting their field contents.
if (old_in->is_SafePointScalarObject()) {
SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject();
uint old_unique = C->unique();
Node* new_in = old_sosn->clone(jvms_adj, sosn_map);
if (old_unique != C->unique()) {
new_in = transform_later(new_in); // Register new node.
}
old_in = new_in;
}
newcall->add_req(old_in);
}
newcall->set_jvms(oldcall->jvms());
for (JVMState *jvms = newcall->jvms(); jvms != NULL; jvms = jvms->caller()) {
jvms->set_map(newcall);
jvms->set_locoff(jvms->locoff()+jvms_adj);
jvms->set_stkoff(jvms->stkoff()+jvms_adj);
jvms->set_monoff(jvms->monoff()+jvms_adj);
jvms->set_scloff(jvms->scloff()+jvms_adj);
jvms->set_endoff(jvms->endoff()+jvms_adj);
}
}
......
......@@ -1647,6 +1647,7 @@ void Matcher::find_shared( Node *n ) {
case Op_Phi: // Treat Phis as shared roots
case Op_Parm:
case Op_Proj: // All handled specially during matching
case Op_SafePointScalarObject:
set_shared(n);
set_dontcare(n);
break;
......
......@@ -106,6 +106,7 @@ class RegMask;
class RegionNode;
class RootNode;
class SafePointNode;
class SafePointScalarObjectNode;
class StartNode;
class State;
class StoreNode;
......@@ -575,6 +576,7 @@ public:
DEFINE_CLASS_ID(ConstraintCast, Type, 1)
DEFINE_CLASS_ID(CheckCastPP, Type, 2)
DEFINE_CLASS_ID(CMove, Type, 3)
DEFINE_CLASS_ID(SafePointScalarObject, Type, 4)
DEFINE_CLASS_ID(Mem, Node, 6)
DEFINE_CLASS_ID(Load, Mem, 0)
......@@ -721,6 +723,7 @@ public:
DEFINE_CLASS_QUERY(Region)
DEFINE_CLASS_QUERY(Root)
DEFINE_CLASS_QUERY(SafePoint)
DEFINE_CLASS_QUERY(SafePointScalarObject)
DEFINE_CLASS_QUERY(Start)
DEFINE_CLASS_QUERY(Store)
DEFINE_CLASS_QUERY(Sub)
......
......@@ -561,7 +561,30 @@ static LocationValue *new_loc_value( PhaseRegAlloc *ra, OptoReg::Name regnum, Lo
: new LocationValue(Location::new_stk_loc(l_type, ra->reg2offset(regnum)));
}
void Compile::FillLocArray( int idx, Node *local, GrowableArray<ScopeValue*> *array ) {
ObjectValue*
Compile::sv_for_node_id(GrowableArray<ScopeValue*> *objs, int id) {
for (int i = 0; i < objs->length(); i++) {
assert(objs->at(i)->is_object(), "corrupt object cache");
ObjectValue* sv = (ObjectValue*) objs->at(i);
if (sv->id() == id) {
return sv;
}
}
// Otherwise..
return NULL;
}
void Compile::set_sv_for_object_node(GrowableArray<ScopeValue*> *objs,
ObjectValue* sv ) {
assert(sv_for_node_id(objs, sv->id()) == NULL, "Precondition");
objs->append(sv);
}
void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local,
GrowableArray<ScopeValue*> *array,
GrowableArray<ScopeValue*> *objs ) {
assert( local, "use _top instead of null" );
if (array->length() != idx) {
assert(array->length() == idx + 1, "Unexpected array count");
......@@ -578,6 +601,29 @@ void Compile::FillLocArray( int idx, Node *local, GrowableArray<ScopeValue*> *ar
}
const Type *t = local->bottom_type();
// Is it a safepoint scalar object node?
if (local->is_SafePointScalarObject()) {
SafePointScalarObjectNode* spobj = local->as_SafePointScalarObject();
ObjectValue* sv = Compile::sv_for_node_id(objs, spobj->_idx);
if (sv == NULL) {
ciKlass* cik = t->is_oopptr()->klass();
assert(cik->is_instance_klass() ||
cik->is_array_klass(), "Not supported allocation.");
sv = new ObjectValue(spobj->_idx,
new ConstantOopWriteValue(cik->encoding()));
Compile::set_sv_for_object_node(objs, sv);
uint first_ind = spobj->first_index();
for (uint i = 0; i < spobj->n_fields(); i++) {
Node* fld_node = sfpt->in(first_ind+i);
(void)FillLocArray(sv->field_values()->length(), sfpt, fld_node, sv->field_values(), objs);
}
}
array->append(sv);
return;
}
// Grab the register number for the local
OptoReg::Name regnum = _regalloc->get_reg_first(local);
if( OptoReg::is_valid(regnum) ) {// Got a register/stack?
......@@ -755,6 +801,11 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
JVMState* youngest_jvms = sfn->jvms();
int max_depth = youngest_jvms->depth();
// Allocate the object pool for scalar-replaced objects -- the map from
// small-integer keys (which can be recorded in the local and ostack
// arrays) to descriptions of the object state.
GrowableArray<ScopeValue*> *objs = new GrowableArray<ScopeValue*>();
// Visit scopes from oldest to youngest.
for (int depth = 1; depth <= max_depth; depth++) {
JVMState* jvms = youngest_jvms->of_depth(depth);
......@@ -773,13 +824,13 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
// Insert locals into the locarray
GrowableArray<ScopeValue*> *locarray = new GrowableArray<ScopeValue*>(num_locs);
for( idx = 0; idx < num_locs; idx++ ) {
FillLocArray( idx, sfn->local(jvms, idx), locarray );
FillLocArray( idx, sfn, sfn->local(jvms, idx), locarray, objs );
}
// Insert expression stack entries into the exparray
GrowableArray<ScopeValue*> *exparray = new GrowableArray<ScopeValue*>(num_exps);
for( idx = 0; idx < num_exps; idx++ ) {
FillLocArray( idx, sfn->stack(jvms, idx), exparray );
FillLocArray( idx, sfn, sfn->stack(jvms, idx), exparray, objs );
}
// Add in mappings of the monitors
......@@ -803,7 +854,27 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
// Create ScopeValue for object
ScopeValue *scval = NULL;
if( !obj_node->is_Con() ) {
if( obj_node->is_SafePointScalarObject() ) {
SafePointScalarObjectNode* spobj = obj_node->as_SafePointScalarObject();
scval = Compile::sv_for_node_id(objs, spobj->_idx);
if (scval == NULL) {
const Type *t = obj_node->bottom_type();
ciKlass* cik = t->is_oopptr()->klass();
assert(cik->is_instance_klass() ||
cik->is_array_klass(), "Not supported allocation.");
ObjectValue* sv = new ObjectValue(spobj->_idx,
new ConstantOopWriteValue(cik->encoding()));
Compile::set_sv_for_object_node(objs, sv);
uint first_ind = spobj->first_index();
for (uint i = 0; i < spobj->n_fields(); i++) {
Node* fld_node = sfn->in(first_ind+i);
(void)FillLocArray(sv->field_values()->length(), sfn, fld_node, sv->field_values(), objs);
}
scval = sv;
}
} else if( !obj_node->is_Con() ) {
OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node);
scval = new_loc_value( _regalloc, obj_reg, Location::oop );
} else {
......@@ -814,6 +885,9 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
monarray->append(new MonitorValue(scval, Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg))));
}
// We dump the object pool first, since deoptimization reads it in first.
debug_info()->dump_object_pool(objs);
// Build first class objects to pass to scope
DebugToken *locvals = debug_info()->create_scope_values(locarray);
DebugToken *expvals = debug_info()->create_scope_values(exparray);
......@@ -823,6 +897,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
ciMethod* scope_method = method ? method : _method;
// Describe the scope here
assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI");
// Now we can describe the scope.
debug_info()->describe_scope(safepoint_pc_offset,scope_method,jvms->bci(),locvals,expvals,monvals);
} // End jvms loop
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册