src/share/vm/opto/escape.cpp
Print this page
rev 3419 : 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
Summary: use shorter instruction sequences for atomic add and atomic exchange when possible.
Reviewed-by:
*** 280,289 ****
--- 280,309 ----
#endif
}
return has_non_escaping_obj;
}
+ // Utility function for nodes that load an object
+ void ConnectionGraph::add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
+ // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
+ // ThreadLocal has RawPtr type.
+ const Type* t = _igvn->type(n);
+ if (t->make_ptr() != NULL) {
+ Node* adr = n->in(MemNode::Address);
+ #ifdef ASSERT
+ if (!adr->is_AddP()) {
+ assert(_igvn->type(adr)->isa_rawptr(), "sanity");
+ } else {
+ assert((ptnode_adr(adr->_idx) == NULL ||
+ ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
+ }
+ #endif
+ add_local_var_and_edge(n, PointsToNode::NoEscape,
+ adr, delayed_worklist);
+ }
+ }
+
// Populate Connection Graph with PointsTo nodes and create simple
// connection graph edges.
void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
assert(!_verify, "this method sould not be called for verification");
PhaseGVN* igvn = _igvn;
*** 385,410 ****
break;
}
case Op_LoadP:
case Op_LoadN:
case Op_LoadPLocked: {
! // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
! // ThreadLocal has RawPrt type.
! const Type* t = igvn->type(n);
! if (t->make_ptr() != NULL) {
! Node* adr = n->in(MemNode::Address);
! #ifdef ASSERT
! if (!adr->is_AddP()) {
! assert(igvn->type(adr)->isa_rawptr(), "sanity");
! } else {
! assert((ptnode_adr(adr->_idx) == NULL ||
! ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
! }
! #endif
! add_local_var_and_edge(n, PointsToNode::NoEscape,
! adr, delayed_worklist);
! }
break;
}
case Op_Parm: {
map_ideal_node(n, phantom_obj);
break;
--- 405,415 ----
break;
}
case Op_LoadP:
case Op_LoadN:
case Op_LoadPLocked: {
! add_objload_to_connection_graph(n, delayed_worklist);
break;
}
case Op_Parm: {
map_ideal_node(n, phantom_obj);
break;
*** 415,425 ****
map_ideal_node(n, phantom_obj); // Result is unknown
break;
}
case Op_Phi: {
// Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
! // ThreadLocal has RawPrt type.
const Type* t = n->as_Phi()->type();
if (t->make_ptr() != NULL) {
add_local_var(n, PointsToNode::NoEscape);
// Do not add edges during first iteration because some could be
// not defined yet.
--- 420,430 ----
map_ideal_node(n, phantom_obj); // Result is unknown
break;
}
case Op_Phi: {
// Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
! // ThreadLocal has RawPtr type.
const Type* t = n->as_Phi()->type();
if (t->make_ptr() != NULL) {
add_local_var(n, PointsToNode::NoEscape);
// Do not add edges during first iteration because some could be
// not defined yet.
*** 444,453 ****
--- 449,463 ----
add_local_var_and_edge(n, PointsToNode::GlobalEscape,
n->in(TypeFunc::Parms), delayed_worklist);
}
break;
}
+ case Op_GetAndSetP:
+ case Op_GetAndSetN: {
+ add_objload_to_connection_graph(n, delayed_worklist);
+ // fallthrough
+ }
case Op_StoreP:
case Op_StoreN:
case Op_StorePConditional:
case Op_CompareAndSwapP:
case Op_CompareAndSwapN: {
*** 583,604 ****
}
case Op_LoadP:
case Op_LoadN:
case Op_LoadPLocked: {
// Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
! // ThreadLocal has RawPrt type.
const Type* t = _igvn->type(n);
if (t->make_ptr() != NULL) {
Node* adr = n->in(MemNode::Address);
add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
break;
}
ELSE_FAIL("Op_LoadP");
}
case Op_Phi: {
// Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
! // ThreadLocal has RawPrt type.
const Type* t = n->as_Phi()->type();
if (t->make_ptr() != NULL) {
for (uint i = 1; i < n->req(); i++) {
Node* in = n->in(i);
if (in == NULL)
--- 593,614 ----
}
case Op_LoadP:
case Op_LoadN:
case Op_LoadPLocked: {
// Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
! // ThreadLocal has RawPtr type.
const Type* t = _igvn->type(n);
if (t->make_ptr() != NULL) {
Node* adr = n->in(MemNode::Address);
add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
break;
}
ELSE_FAIL("Op_LoadP");
}
case Op_Phi: {
// Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
! // ThreadLocal has RawPtr type.
const Type* t = n->as_Phi()->type();
if (t->make_ptr() != NULL) {
for (uint i = 1; i < n->req(); i++) {
Node* in = n->in(i);
if (in == NULL)
*** 636,647 ****
}
case Op_StoreP:
case Op_StoreN:
case Op_StorePConditional:
case Op_CompareAndSwapP:
! case Op_CompareAndSwapN: {
Node* adr = n->in(MemNode::Address);
const Type *adr_type = _igvn->type(adr);
adr_type = adr_type->make_ptr();
if (adr_type->isa_oopptr() ||
(opcode == Op_StoreP || opcode == Op_StoreN) &&
(adr_type == TypeRawPtr::NOTNULL &&
--- 646,665 ----
}
case Op_StoreP:
case Op_StoreN:
case Op_StorePConditional:
case Op_CompareAndSwapP:
! case Op_CompareAndSwapN:
! case Op_GetAndSetP:
! case Op_GetAndSetN: {
Node* adr = n->in(MemNode::Address);
+ if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
+ const Type* t = _igvn->type(n);
+ if (t->make_ptr() != NULL) {
+ add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
+ }
+ }
const Type *adr_type = _igvn->type(adr);
adr_type = adr_type->make_ptr();
if (adr_type->isa_oopptr() ||
(opcode == Op_StoreP || opcode == Op_StoreN) &&
(adr_type == TypeRawPtr::NOTNULL &&