mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 03:24:38 +02:00
6706829: Compressed Oops: add debug info for narrow oops
Add support for narrow oops in debug info to avoid decoding. Reviewed-by: rasbold, never
This commit is contained in:
parent
63c98ed888
commit
659ca734bb
11 changed files with 169 additions and 48 deletions
|
@ -1967,6 +1967,7 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
|
|||
!n->is_Proj() &&
|
||||
nop != Op_CreateEx &&
|
||||
nop != Op_CheckCastPP &&
|
||||
nop != Op_DecodeN &&
|
||||
!n->is_Mem() ) {
|
||||
Node *x = n->clone();
|
||||
call->set_req( TypeFunc::Parms, x );
|
||||
|
@ -2075,20 +2076,27 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
|
|||
case Op_CmpP:
|
||||
// Do this transformation here to preserve CmpPNode::sub() and
|
||||
// other TypePtr related Ideal optimizations (for example, ptr nullness).
|
||||
if( n->in(1)->is_DecodeN() ) {
|
||||
if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) {
|
||||
Node* in1 = n->in(1);
|
||||
Node* in2 = n->in(2);
|
||||
if (!in1->is_DecodeN()) {
|
||||
in2 = in1;
|
||||
in1 = n->in(2);
|
||||
}
|
||||
assert(in1->is_DecodeN(), "sanity");
|
||||
|
||||
Compile* C = Compile::current();
|
||||
Node* in2 = NULL;
|
||||
if( n->in(2)->is_DecodeN() ) {
|
||||
in2 = n->in(2)->in(1);
|
||||
} else if ( n->in(2)->Opcode() == Op_ConP ) {
|
||||
const Type* t = n->in(2)->bottom_type();
|
||||
Node* new_in2 = NULL;
|
||||
if (in2->is_DecodeN()) {
|
||||
new_in2 = in2->in(1);
|
||||
} else if (in2->Opcode() == Op_ConP) {
|
||||
const Type* t = in2->bottom_type();
|
||||
if (t == TypePtr::NULL_PTR) {
|
||||
Node *in1 = n->in(1);
|
||||
if (Matcher::clone_shift_expressions) {
|
||||
// x86, ARM and friends can handle 2 adds in addressing mode.
|
||||
// Decode a narrow oop and do implicit NULL check in address
|
||||
// [R12 + narrow_oop_reg<<3 + offset]
|
||||
in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
|
||||
new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
|
||||
} else {
|
||||
// Don't replace CmpP(o ,null) if 'o' is used in AddP
|
||||
// to generate implicit NULL check on Sparc where
|
||||
|
@ -2099,16 +2107,22 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
|
|||
break;
|
||||
}
|
||||
if (i >= in1->outcnt()) {
|
||||
in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
|
||||
new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
|
||||
}
|
||||
}
|
||||
} else if (t->isa_oopptr()) {
|
||||
in2 = ConNode::make(C, t->make_narrowoop());
|
||||
new_in2 = ConNode::make(C, t->make_narrowoop());
|
||||
}
|
||||
}
|
||||
if( in2 != NULL ) {
|
||||
Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2);
|
||||
if (new_in2 != NULL) {
|
||||
Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2);
|
||||
n->subsume_by( cmpN );
|
||||
if (in1->outcnt() == 0) {
|
||||
in1->disconnect_inputs(NULL);
|
||||
}
|
||||
if (in2->outcnt() == 0) {
|
||||
in2->disconnect_inputs(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2214,6 +2228,9 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &fpu ) {
|
|||
// Replacing Opaque nodes with their input in final_graph_reshaping_impl(),
|
||||
// requires that the walk visits a node's inputs before visiting the node.
|
||||
static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &fpu ) {
|
||||
ResourceArea *area = Thread::current()->resource_area();
|
||||
Unique_Node_List sfpt(area);
|
||||
|
||||
fpu._visited.set(root->_idx); // first, mark node as visited
|
||||
uint cnt = root->req();
|
||||
Node *n = root;
|
||||
|
@ -2224,6 +2241,8 @@ static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Re
|
|||
Node* m = n->in(i);
|
||||
++i;
|
||||
if (m != NULL && !fpu._visited.test_set(m->_idx)) {
|
||||
if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL)
|
||||
sfpt.push(m);
|
||||
cnt = m->req();
|
||||
nstack.push(n, i); // put on stack parent and next input's index
|
||||
n = m;
|
||||
|
@ -2240,6 +2259,41 @@ static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Re
|
|||
nstack.pop(); // Shift to the next node on stack
|
||||
}
|
||||
}
|
||||
|
||||
// Go over safepoints nodes to skip DecodeN nodes for debug edges.
|
||||
// It could be done for an uncommon traps or any safepoints/calls
|
||||
// if the DecodeN node is referenced only in a debug info.
|
||||
while (sfpt.size() > 0) {
|
||||
n = sfpt.pop();
|
||||
JVMState *jvms = n->as_SafePoint()->jvms();
|
||||
assert(jvms != NULL, "sanity");
|
||||
int start = jvms->debug_start();
|
||||
int end = n->req();
|
||||
bool is_uncommon = (n->is_CallStaticJava() &&
|
||||
n->as_CallStaticJava()->uncommon_trap_request() != 0);
|
||||
for (int j = start; j < end; j++) {
|
||||
Node* in = n->in(j);
|
||||
if (in->is_DecodeN()) {
|
||||
bool safe_to_skip = true;
|
||||
if (!is_uncommon ) {
|
||||
// Is it safe to skip?
|
||||
for (uint i = 0; i < in->outcnt(); i++) {
|
||||
Node* u = in->raw_out(i);
|
||||
if (!u->is_SafePoint() ||
|
||||
u->is_Call() && u->as_Call()->has_non_debug_use(n)) {
|
||||
safe_to_skip = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (safe_to_skip) {
|
||||
n->set_req(j, in->in(1));
|
||||
}
|
||||
if (in->outcnt() == 0) {
|
||||
in->disconnect_inputs(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------final_graph_reshaping--------------------------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue