提交 689f0a18 编写于 作者: K kvn

8012972: Incremental Inlining should support scalar replaced object in debug info

Summary: store in _first_index not absolute index but an index relative to the last (youngest) jvms->_scloff value
Reviewed-by: roland, twisti
上级 ac93da8d
...@@ -1718,7 +1718,7 @@ static void codecache_print(bool detailed) ...@@ -1718,7 +1718,7 @@ static void codecache_print(bool detailed)
CodeCache::print_summary(&s, detailed); CodeCache::print_summary(&s, detailed);
} }
ttyLocker ttyl; ttyLocker ttyl;
tty->print_cr(s.as_string()); tty->print(s.as_string());
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------
......
...@@ -458,7 +458,7 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) ...@@ -458,7 +458,7 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
st->print("={"); st->print("={");
uint nf = spobj->n_fields(); uint nf = spobj->n_fields();
if (nf > 0) { if (nf > 0) {
uint first_ind = spobj->first_index(); uint first_ind = spobj->first_index(mcall->jvms());
Node* fld_node = mcall->in(first_ind); Node* fld_node = mcall->in(first_ind);
ciField* cifield; ciField* cifield;
if (iklass != NULL) { if (iklass != NULL) {
...@@ -1063,7 +1063,6 @@ void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) { ...@@ -1063,7 +1063,6 @@ void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) {
int scloff = jvms->scloff(); int scloff = jvms->scloff();
int endoff = jvms->endoff(); int endoff = jvms->endoff();
assert(endoff == (int)req(), "no other states or debug info after me"); assert(endoff == (int)req(), "no other states or debug info after me");
assert(jvms->scl_size() == 0, "parsed code should not have scalar objects");
Node* top = Compile::current()->top(); Node* top = Compile::current()->top();
for (uint i = 0; i < grow_by; i++) { for (uint i = 0; i < grow_by; i++) {
ins_req(monoff, top); ins_req(monoff, top);
...@@ -1079,32 +1078,31 @@ void SafePointNode::push_monitor(const FastLockNode *lock) { ...@@ -1079,32 +1078,31 @@ void SafePointNode::push_monitor(const FastLockNode *lock) {
const int MonitorEdges = 2; const int MonitorEdges = 2;
assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges"); assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
assert(req() == jvms()->endoff(), "correct sizing"); assert(req() == jvms()->endoff(), "correct sizing");
assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects");
int nextmon = jvms()->scloff(); int nextmon = jvms()->scloff();
if (GenerateSynchronizationCode) { if (GenerateSynchronizationCode) {
add_req(lock->box_node()); ins_req(nextmon, lock->box_node());
add_req(lock->obj_node()); ins_req(nextmon+1, lock->obj_node());
} else { } else {
Node* top = Compile::current()->top(); Node* top = Compile::current()->top();
add_req(top); ins_req(nextmon, top);
add_req(top); ins_req(nextmon, top);
} }
jvms()->set_scloff(nextmon+MonitorEdges); jvms()->set_scloff(nextmon + MonitorEdges);
jvms()->set_endoff(req()); jvms()->set_endoff(req());
} }
void SafePointNode::pop_monitor() { void SafePointNode::pop_monitor() {
// Delete last monitor from debug info // Delete last monitor from debug info
assert((jvms()->scl_size() == 0), "parsed code should not have scalar objects");
debug_only(int num_before_pop = jvms()->nof_monitors()); debug_only(int num_before_pop = jvms()->nof_monitors());
const int MonitorEdges = (1<<JVMState::logMonitorEdges); const int MonitorEdges = 2;
assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
int scloff = jvms()->scloff(); int scloff = jvms()->scloff();
int endoff = jvms()->endoff(); int endoff = jvms()->endoff();
int new_scloff = scloff - MonitorEdges; int new_scloff = scloff - MonitorEdges;
int new_endoff = endoff - MonitorEdges; int new_endoff = endoff - MonitorEdges;
jvms()->set_scloff(new_scloff); jvms()->set_scloff(new_scloff);
jvms()->set_endoff(new_endoff); jvms()->set_endoff(new_endoff);
while (scloff > new_scloff) del_req(--scloff); while (scloff > new_scloff) del_req_ordered(--scloff);
assert(jvms()->nof_monitors() == num_before_pop-1, ""); assert(jvms()->nof_monitors() == num_before_pop-1, "");
} }
...@@ -1169,13 +1167,12 @@ uint SafePointScalarObjectNode::match_edge(uint idx) const { ...@@ -1169,13 +1167,12 @@ uint SafePointScalarObjectNode::match_edge(uint idx) const {
} }
SafePointScalarObjectNode* SafePointScalarObjectNode*
SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) const { SafePointScalarObjectNode::clone(Dict* sosn_map) const {
void* cached = (*sosn_map)[(void*)this]; void* cached = (*sosn_map)[(void*)this];
if (cached != NULL) { if (cached != NULL) {
return (SafePointScalarObjectNode*)cached; return (SafePointScalarObjectNode*)cached;
} }
SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone(); SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone();
res->_first_index += jvms_adj;
sosn_map->Insert((void*)this, (void*)res); sosn_map->Insert((void*)this, (void*)res);
return res; return res;
} }
......
...@@ -449,14 +449,17 @@ public: ...@@ -449,14 +449,17 @@ public:
// at a safepoint. // at a safepoint.
class SafePointScalarObjectNode: public TypeNode { class SafePointScalarObjectNode: public TypeNode {
uint _first_index; // First input edge index of a SafePoint node where uint _first_index; // First input edge relative index of a SafePoint node where
// states of the scalarized object fields are collected. // states of the scalarized object fields are collected.
// It is relative to the last (youngest) jvms->_scloff.
uint _n_fields; // Number of non-static fields of the scalarized object. uint _n_fields; // Number of non-static fields of the scalarized object.
DEBUG_ONLY(AllocateNode* _alloc;) DEBUG_ONLY(AllocateNode* _alloc;)
virtual uint hash() const ; // { return NO_HASH; } virtual uint hash() const ; // { return NO_HASH; }
virtual uint cmp( const Node &n ) const; virtual uint cmp( const Node &n ) const;
uint first_index() const { return _first_index; }
public: public:
SafePointScalarObjectNode(const TypeOopPtr* tp, SafePointScalarObjectNode(const TypeOopPtr* tp,
#ifdef ASSERT #ifdef ASSERT
...@@ -469,7 +472,10 @@ public: ...@@ -469,7 +472,10 @@ public:
virtual const RegMask &out_RegMask() const; virtual const RegMask &out_RegMask() const;
virtual uint match_edge(uint idx) const; virtual uint match_edge(uint idx) const;
uint first_index() const { return _first_index; } uint first_index(JVMState* jvms) const {
assert(jvms != NULL, "missed JVMS");
return jvms->scloff() + _first_index;
}
uint n_fields() const { return _n_fields; } uint n_fields() const { return _n_fields; }
#ifdef ASSERT #ifdef ASSERT
...@@ -485,7 +491,7 @@ public: ...@@ -485,7 +491,7 @@ public:
// corresponds appropriately to "this" in "new_call". Assumes that // corresponds appropriately to "this" in "new_call". Assumes that
// "sosn_map" is a map, specific to the translation of "s" to "new_call", // "sosn_map" is a map, specific to the translation of "s" to "new_call",
// mapping old SafePointScalarObjectNodes to new, to avoid multiple copies. // mapping old SafePointScalarObjectNodes to new, to avoid multiple copies.
SafePointScalarObjectNode* clone(int jvms_adj, Dict* sosn_map) const; SafePointScalarObjectNode* clone(Dict* sosn_map) const;
#ifndef PRODUCT #ifndef PRODUCT
virtual void dump_spec(outputStream *st) const; virtual void dump_spec(outputStream *st) const;
......
...@@ -61,6 +61,7 @@ void GraphKit::gen_stub(address C_function, ...@@ -61,6 +61,7 @@ void GraphKit::gen_stub(address C_function,
JVMState* jvms = new (C) JVMState(0); JVMState* jvms = new (C) JVMState(0);
jvms->set_bci(InvocationEntryBci); jvms->set_bci(InvocationEntryBci);
jvms->set_monoff(max_map); jvms->set_monoff(max_map);
jvms->set_scloff(max_map);
jvms->set_endoff(max_map); jvms->set_endoff(max_map);
{ {
SafePointNode *map = new (C) SafePointNode( max_map, jvms ); SafePointNode *map = new (C) SafePointNode( max_map, jvms );
......
...@@ -72,6 +72,8 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal ...@@ -72,6 +72,8 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal
int jvms_adj = new_dbg_start - old_dbg_start; int jvms_adj = new_dbg_start - old_dbg_start;
assert (new_dbg_start == newcall->req(), "argument count mismatch"); assert (new_dbg_start == newcall->req(), "argument count mismatch");
// SafePointScalarObject node could be referenced several times in debug info.
// Use Dict to record cloned nodes.
Dict* sosn_map = new Dict(cmpkey,hashkey); Dict* sosn_map = new Dict(cmpkey,hashkey);
for (uint i = old_dbg_start; i < oldcall->req(); i++) { for (uint i = old_dbg_start; i < oldcall->req(); i++) {
Node* old_in = oldcall->in(i); Node* old_in = oldcall->in(i);
...@@ -79,8 +81,8 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal ...@@ -79,8 +81,8 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal
if (old_in != NULL && old_in->is_SafePointScalarObject()) { if (old_in != NULL && old_in->is_SafePointScalarObject()) {
SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject(); SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject();
uint old_unique = C->unique(); uint old_unique = C->unique();
Node* new_in = old_sosn->clone(jvms_adj, sosn_map); Node* new_in = old_sosn->clone(sosn_map);
if (old_unique != C->unique()) { if (old_unique != C->unique()) { // New node?
new_in->set_req(0, C->root()); // reset control edge new_in->set_req(0, C->root()); // reset control edge
new_in = transform_later(new_in); // Register new node. new_in = transform_later(new_in); // Register new node.
} }
...@@ -725,7 +727,11 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa ...@@ -725,7 +727,11 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa
while (safepoints.length() > 0) { while (safepoints.length() > 0) {
SafePointNode* sfpt = safepoints.pop(); SafePointNode* sfpt = safepoints.pop();
Node* mem = sfpt->memory(); Node* mem = sfpt->memory();
uint first_ind = sfpt->req(); assert(sfpt->jvms() != NULL, "missed JVMS");
// Fields of scalar objs are referenced only at the end
// of regular debuginfo at the last (youngest) JVMS.
// Record relative start index.
uint first_ind = (sfpt->req() - sfpt->jvms()->scloff());
SafePointScalarObjectNode* sobj = new (C) SafePointScalarObjectNode(res_type, SafePointScalarObjectNode* sobj = new (C) SafePointScalarObjectNode(res_type,
#ifdef ASSERT #ifdef ASSERT
alloc, alloc,
...@@ -799,7 +805,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa ...@@ -799,7 +805,7 @@ bool PhaseMacroExpand::scalar_replacement(AllocateNode *alloc, GrowableArray <Sa
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
if (sfpt_done->in(i)->is_SafePointScalarObject()) { if (sfpt_done->in(i)->is_SafePointScalarObject()) {
SafePointScalarObjectNode* scobj = sfpt_done->in(i)->as_SafePointScalarObject(); SafePointScalarObjectNode* scobj = sfpt_done->in(i)->as_SafePointScalarObject();
if (scobj->first_index() == sfpt_done->req() && if (scobj->first_index(jvms) == sfpt_done->req() &&
scobj->n_fields() == (uint)nfields) { scobj->n_fields() == (uint)nfields) {
assert(scobj->alloc() == alloc, "sanity"); assert(scobj->alloc() == alloc, "sanity");
sfpt_done->set_req(i, res); sfpt_done->set_req(i, res);
......
...@@ -773,6 +773,21 @@ void Node::del_req( uint idx ) { ...@@ -773,6 +773,21 @@ void Node::del_req( uint idx ) {
_in[_cnt] = NULL; // NULL out emptied slot _in[_cnt] = NULL; // NULL out emptied slot
} }
//------------------------------del_req_ordered--------------------------------
// Delete the required edge and compact the edge array with preserved order
void Node::del_req_ordered( uint idx ) {
assert( idx < _cnt, "oob");
assert( !VerifyHashTableKeys || _hash_lock == 0,
"remove node from hash table before modifying it");
// First remove corresponding def-use edge
Node *n = in(idx);
if (n != NULL) n->del_out((Node *)this);
if (idx < _cnt - 1) { // Not last edge ?
Copy::conjoint_words_to_lower((HeapWord*)&_in[idx+1], (HeapWord*)&_in[idx], ((_cnt-idx-1)*sizeof(Node*)));
}
_in[--_cnt] = NULL; // NULL out emptied slot
}
//------------------------------ins_req---------------------------------------- //------------------------------ins_req----------------------------------------
// Insert a new required input at the end // Insert a new required input at the end
void Node::ins_req( uint idx, Node *n ) { void Node::ins_req( uint idx, Node *n ) {
......
...@@ -384,6 +384,7 @@ protected: ...@@ -384,6 +384,7 @@ protected:
void add_req( Node *n ); // Append a NEW required input void add_req( Node *n ); // Append a NEW required input
void add_req_batch( Node* n, uint m ); // Append m NEW required inputs (all n). void add_req_batch( Node* n, uint m ); // Append m NEW required inputs (all n).
void del_req( uint idx ); // Delete required edge & compact void del_req( uint idx ); // Delete required edge & compact
void del_req_ordered( uint idx ); // Delete required edge & compact with preserved order
void ins_req( uint i, Node *n ); // Insert a NEW required input void ins_req( uint i, Node *n ); // Insert a NEW required input
void set_req( uint i, Node *n ) { void set_req( uint i, Node *n ) {
assert( is_not_dead(n), "can not use dead node"); assert( is_not_dead(n), "can not use dead node");
......
...@@ -639,7 +639,7 @@ void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, ...@@ -639,7 +639,7 @@ void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local,
new ConstantOopWriteValue(cik->java_mirror()->constant_encoding())); new ConstantOopWriteValue(cik->java_mirror()->constant_encoding()));
Compile::set_sv_for_object_node(objs, sv); Compile::set_sv_for_object_node(objs, sv);
uint first_ind = spobj->first_index(); uint first_ind = spobj->first_index(sfpt->jvms());
for (uint i = 0; i < spobj->n_fields(); i++) { for (uint i = 0; i < spobj->n_fields(); i++) {
Node* fld_node = sfpt->in(first_ind+i); Node* fld_node = sfpt->in(first_ind+i);
(void)FillLocArray(sv->field_values()->length(), sfpt, fld_node, sv->field_values(), objs); (void)FillLocArray(sv->field_values()->length(), sfpt, fld_node, sv->field_values(), objs);
...@@ -894,7 +894,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { ...@@ -894,7 +894,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
GrowableArray<MonitorValue*> *monarray = new GrowableArray<MonitorValue*>(num_mon); GrowableArray<MonitorValue*> *monarray = new GrowableArray<MonitorValue*>(num_mon);
// Loop over monitors and insert into array // Loop over monitors and insert into array
for(idx = 0; idx < num_mon; idx++) { for (idx = 0; idx < num_mon; idx++) {
// Grab the node that defines this monitor // Grab the node that defines this monitor
Node* box_node = sfn->monitor_box(jvms, idx); Node* box_node = sfn->monitor_box(jvms, idx);
Node* obj_node = sfn->monitor_obj(jvms, idx); Node* obj_node = sfn->monitor_obj(jvms, idx);
...@@ -902,11 +902,11 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { ...@@ -902,11 +902,11 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
// Create ScopeValue for object // Create ScopeValue for object
ScopeValue *scval = NULL; ScopeValue *scval = NULL;
if( obj_node->is_SafePointScalarObject() ) { if (obj_node->is_SafePointScalarObject()) {
SafePointScalarObjectNode* spobj = obj_node->as_SafePointScalarObject(); SafePointScalarObjectNode* spobj = obj_node->as_SafePointScalarObject();
scval = Compile::sv_for_node_id(objs, spobj->_idx); scval = Compile::sv_for_node_id(objs, spobj->_idx);
if (scval == NULL) { if (scval == NULL) {
const Type *t = obj_node->bottom_type(); const Type *t = spobj->bottom_type();
ciKlass* cik = t->is_oopptr()->klass(); ciKlass* cik = t->is_oopptr()->klass();
assert(cik->is_instance_klass() || assert(cik->is_instance_klass() ||
cik->is_array_klass(), "Not supported allocation."); cik->is_array_klass(), "Not supported allocation.");
...@@ -914,14 +914,14 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { ...@@ -914,14 +914,14 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
new ConstantOopWriteValue(cik->java_mirror()->constant_encoding())); new ConstantOopWriteValue(cik->java_mirror()->constant_encoding()));
Compile::set_sv_for_object_node(objs, sv); Compile::set_sv_for_object_node(objs, sv);
uint first_ind = spobj->first_index(); uint first_ind = spobj->first_index(youngest_jvms);
for (uint i = 0; i < spobj->n_fields(); i++) { for (uint i = 0; i < spobj->n_fields(); i++) {
Node* fld_node = sfn->in(first_ind+i); Node* fld_node = sfn->in(first_ind+i);
(void)FillLocArray(sv->field_values()->length(), sfn, fld_node, sv->field_values(), objs); (void)FillLocArray(sv->field_values()->length(), sfn, fld_node, sv->field_values(), objs);
} }
scval = sv; scval = sv;
} }
} else if( !obj_node->is_Con() ) { } else if (!obj_node->is_Con()) {
OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node); OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node);
if( obj_node->bottom_type()->base() == Type::NarrowOop ) { if( obj_node->bottom_type()->base() == Type::NarrowOop ) {
scval = new_loc_value( _regalloc, obj_reg, Location::narrowoop ); scval = new_loc_value( _regalloc, obj_reg, Location::narrowoop );
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册