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 &&