1489 assert((ptnode_adr(adr->_idx) == nullptr ||
1490 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
1491 }
1492 #endif
1493 add_local_var_and_edge(n, PointsToNode::NoEscape,
1494 adr, delayed_worklist);
1495 }
1496 }
1497
1498 // Populate Connection Graph with PointsTo nodes and create simple
1499 // connection graph edges.
1500 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
1501 assert(!_verify, "this method should not be called for verification");
1502 PhaseGVN* igvn = _igvn;
1503 uint n_idx = n->_idx;
1504 PointsToNode* n_ptn = ptnode_adr(n_idx);
1505 if (n_ptn != nullptr) {
1506 return; // No need to redefine PointsTo node during first iteration.
1507 }
1508 int opcode = n->Opcode();
1509 bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_to_con_graph(this, igvn, delayed_worklist, n, opcode);
1510 if (gc_handled) {
1511 return; // Ignore node if already handled by GC.
1512 }
1513
1514 if (n->is_Call()) {
1515 // Arguments to allocation and locking don't escape.
1516 if (n->is_AbstractLock()) {
1517 // Put Lock and Unlock nodes on IGVN worklist to process them during
1518 // first IGVN optimization when escape information is still available.
1519 record_for_optimizer(n);
1520 } else if (n->is_Allocate()) {
1521 add_call_node(n->as_Call());
1522 record_for_optimizer(n);
1523 } else {
1524 if (n->is_CallStaticJava()) {
1525 const char* name = n->as_CallStaticJava()->_name;
1526 if (name != nullptr && strcmp(name, "uncommon_trap") == 0) {
1527 return; // Skip uncommon traps
1528 }
1529 }
1530 // Don't mark as processed since call's arguments have to be processed.
1531 delayed_worklist->push(n);
1532 // Check if a call returns an object.
1533 if ((n->as_Call()->returns_pointer() &&
1711 }
1712 return;
1713 }
1714
1715 // Add final simple edges to graph.
1716 void ConnectionGraph::add_final_edges(Node *n) {
1717 PointsToNode* n_ptn = ptnode_adr(n->_idx);
1718 #ifdef ASSERT
1719 if (_verify && n_ptn->is_JavaObject())
1720 return; // This method does not change graph for JavaObject.
1721 #endif
1722
1723 if (n->is_Call()) {
1724 process_call_arguments(n->as_Call());
1725 return;
1726 }
1727 assert(n->is_Store() || n->is_LoadStore() ||
1728 ((n_ptn != nullptr) && (n_ptn->ideal_node() != nullptr)),
1729 "node should be registered already");
1730 int opcode = n->Opcode();
1731 bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_final_edges(this, _igvn, n, opcode);
1732 if (gc_handled) {
1733 return; // Ignore node if already handled by GC.
1734 }
1735 switch (opcode) {
1736 case Op_AddP: {
1737 Node* base = get_addp_base(n);
1738 PointsToNode* ptn_base = ptnode_adr(base->_idx);
1739 assert(ptn_base != nullptr, "field's base should be registered");
1740 add_base(n_ptn->as_Field(), ptn_base);
1741 break;
1742 }
1743 case Op_CastPP:
1744 case Op_CheckCastPP:
1745 case Op_EncodeP:
1746 case Op_DecodeN:
1747 case Op_EncodePKlass:
1748 case Op_DecodeNKlass: {
1749 add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), nullptr);
1750 break;
1751 }
1752 case Op_CMoveP: {
1753 for (uint i = CMoveNode::IfFalse; i < n->req(); i++) {
1754 Node* in = n->in(i);
3439 BasicType bt = T_INT;
3440 if (offset == Type::OffsetBot) {
3441 // Check only oop fields.
3442 if (!adr_type->isa_aryptr() ||
3443 adr_type->isa_aryptr()->elem() == Type::BOTTOM ||
3444 adr_type->isa_aryptr()->elem()->make_oopptr() != nullptr) {
3445 // OffsetBot is used to reference array's element. Ignore first AddP.
3446 if (find_second_addp(n, n->in(AddPNode::Base)) == nullptr) {
3447 bt = T_OBJECT;
3448 }
3449 }
3450 } else if (offset != oopDesc::klass_offset_in_bytes()) {
3451 if (adr_type->isa_instptr()) {
3452 ciField* field = _compile->alias_type(adr_type->isa_instptr())->field();
3453 if (field != nullptr) {
3454 bt = field->layout_type();
3455 } else {
3456 // Check for unsafe oop field access
3457 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3458 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3459 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN) ||
3460 BarrierSet::barrier_set()->barrier_set_c2()->escape_has_out_with_unsafe_object(n)) {
3461 bt = T_OBJECT;
3462 (*unsafe) = true;
3463 }
3464 }
3465 } else if (adr_type->isa_aryptr()) {
3466 if (offset == arrayOopDesc::length_offset_in_bytes()) {
3467 // Ignore array length load.
3468 } else if (find_second_addp(n, n->in(AddPNode::Base)) != nullptr) {
3469 // Ignore first AddP.
3470 } else {
3471 const Type* elemtype = adr_type->isa_aryptr()->elem();
3472 bt = elemtype->array_element_basic_type();
3473 }
3474 } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
3475 // Allocation initialization, ThreadLocal field access, unsafe access
3476 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3477 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3478 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN) ||
3479 BarrierSet::barrier_set()->barrier_set_c2()->escape_has_out_with_unsafe_object(n)) {
3480 bt = T_OBJECT;
3481 }
3482 }
3483 }
3484 // Note: T_NARROWOOP is not classed as a real reference type
3485 return (is_reference_type(bt) || bt == T_NARROWOOP);
3486 }
3487
3488 // Returns unique pointed java object or null.
3489 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) const {
3490 // If the node was created after the escape computation we can't answer.
3491 uint idx = n->_idx;
3492 if (idx >= nodes_size()) {
3493 return nullptr;
3494 }
3495 PointsToNode* ptn = ptnode_adr(idx);
3496 if (ptn == nullptr) {
3497 return nullptr;
3498 }
3499 if (ptn->is_JavaObject()) {
4138 // skip over a call which does not affect this memory slice
4139 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
4140 Node *proj_in = result->in(0);
4141 if (proj_in->is_Allocate() && proj_in->_idx == (uint)toop->instance_id()) {
4142 break; // hit one of our sentinels
4143 } else if (proj_in->is_Call()) {
4144 // ArrayCopy node processed here as well
4145 CallNode *call = proj_in->as_Call();
4146 if (!call->may_modify(toop, igvn)) {
4147 result = call->in(TypeFunc::Memory);
4148 }
4149 } else if (proj_in->is_Initialize()) {
4150 AllocateNode* alloc = proj_in->as_Initialize()->allocation();
4151 // Stop if this is the initialization for the object instance which
4152 // which contains this memory slice, otherwise skip over it.
4153 if (alloc == nullptr || alloc->_idx != (uint)toop->instance_id()) {
4154 result = proj_in->in(TypeFunc::Memory);
4155 }
4156 } else if (proj_in->is_MemBar()) {
4157 // Check if there is an array copy for a clone
4158 // Step over GC barrier when ReduceInitialCardMarks is disabled
4159 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
4160 Node* control_proj_ac = bs->step_over_gc_barrier(proj_in->in(0));
4161
4162 if (control_proj_ac->is_Proj() && control_proj_ac->in(0)->is_ArrayCopy()) {
4163 // Stop if it is a clone
4164 ArrayCopyNode* ac = control_proj_ac->in(0)->as_ArrayCopy();
4165 if (ac->may_modify(toop, igvn)) {
4166 break;
4167 }
4168 }
4169 result = proj_in->in(TypeFunc::Memory);
4170 }
4171 } else if (result->is_MergeMem()) {
4172 MergeMemNode *mmem = result->as_MergeMem();
4173 result = step_through_mergemem(mmem, alias_idx, toop);
4174 if (result == mmem->base_memory()) {
4175 // Didn't find instance memory, search through general slice recursively.
4176 result = mmem->memory_at(C->get_general_index(alias_idx));
4177 result = find_inst_mem(result, alias_idx, orig_phis, rec_depth + 1);
4178 if (C->failing()) {
4179 return nullptr;
4180 }
|
1489 assert((ptnode_adr(adr->_idx) == nullptr ||
1490 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
1491 }
1492 #endif
1493 add_local_var_and_edge(n, PointsToNode::NoEscape,
1494 adr, delayed_worklist);
1495 }
1496 }
1497
1498 // Populate Connection Graph with PointsTo nodes and create simple
1499 // connection graph edges.
1500 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
1501 assert(!_verify, "this method should not be called for verification");
1502 PhaseGVN* igvn = _igvn;
1503 uint n_idx = n->_idx;
1504 PointsToNode* n_ptn = ptnode_adr(n_idx);
1505 if (n_ptn != nullptr) {
1506 return; // No need to redefine PointsTo node during first iteration.
1507 }
1508 int opcode = n->Opcode();
1509 if (n->is_Call()) {
1510 // Arguments to allocation and locking don't escape.
1511 if (n->is_AbstractLock()) {
1512 // Put Lock and Unlock nodes on IGVN worklist to process them during
1513 // first IGVN optimization when escape information is still available.
1514 record_for_optimizer(n);
1515 } else if (n->is_Allocate()) {
1516 add_call_node(n->as_Call());
1517 record_for_optimizer(n);
1518 } else {
1519 if (n->is_CallStaticJava()) {
1520 const char* name = n->as_CallStaticJava()->_name;
1521 if (name != nullptr && strcmp(name, "uncommon_trap") == 0) {
1522 return; // Skip uncommon traps
1523 }
1524 }
1525 // Don't mark as processed since call's arguments have to be processed.
1526 delayed_worklist->push(n);
1527 // Check if a call returns an object.
1528 if ((n->as_Call()->returns_pointer() &&
1706 }
1707 return;
1708 }
1709
1710 // Add final simple edges to graph.
1711 void ConnectionGraph::add_final_edges(Node *n) {
1712 PointsToNode* n_ptn = ptnode_adr(n->_idx);
1713 #ifdef ASSERT
1714 if (_verify && n_ptn->is_JavaObject())
1715 return; // This method does not change graph for JavaObject.
1716 #endif
1717
1718 if (n->is_Call()) {
1719 process_call_arguments(n->as_Call());
1720 return;
1721 }
1722 assert(n->is_Store() || n->is_LoadStore() ||
1723 ((n_ptn != nullptr) && (n_ptn->ideal_node() != nullptr)),
1724 "node should be registered already");
1725 int opcode = n->Opcode();
1726 switch (opcode) {
1727 case Op_AddP: {
1728 Node* base = get_addp_base(n);
1729 PointsToNode* ptn_base = ptnode_adr(base->_idx);
1730 assert(ptn_base != nullptr, "field's base should be registered");
1731 add_base(n_ptn->as_Field(), ptn_base);
1732 break;
1733 }
1734 case Op_CastPP:
1735 case Op_CheckCastPP:
1736 case Op_EncodeP:
1737 case Op_DecodeN:
1738 case Op_EncodePKlass:
1739 case Op_DecodeNKlass: {
1740 add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), nullptr);
1741 break;
1742 }
1743 case Op_CMoveP: {
1744 for (uint i = CMoveNode::IfFalse; i < n->req(); i++) {
1745 Node* in = n->in(i);
3430 BasicType bt = T_INT;
3431 if (offset == Type::OffsetBot) {
3432 // Check only oop fields.
3433 if (!adr_type->isa_aryptr() ||
3434 adr_type->isa_aryptr()->elem() == Type::BOTTOM ||
3435 adr_type->isa_aryptr()->elem()->make_oopptr() != nullptr) {
3436 // OffsetBot is used to reference array's element. Ignore first AddP.
3437 if (find_second_addp(n, n->in(AddPNode::Base)) == nullptr) {
3438 bt = T_OBJECT;
3439 }
3440 }
3441 } else if (offset != oopDesc::klass_offset_in_bytes()) {
3442 if (adr_type->isa_instptr()) {
3443 ciField* field = _compile->alias_type(adr_type->isa_instptr())->field();
3444 if (field != nullptr) {
3445 bt = field->layout_type();
3446 } else {
3447 // Check for unsafe oop field access
3448 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3449 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3450 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
3451 bt = T_OBJECT;
3452 (*unsafe) = true;
3453 }
3454 }
3455 } else if (adr_type->isa_aryptr()) {
3456 if (offset == arrayOopDesc::length_offset_in_bytes()) {
3457 // Ignore array length load.
3458 } else if (find_second_addp(n, n->in(AddPNode::Base)) != nullptr) {
3459 // Ignore first AddP.
3460 } else {
3461 const Type* elemtype = adr_type->isa_aryptr()->elem();
3462 bt = elemtype->array_element_basic_type();
3463 }
3464 } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
3465 // Allocation initialization, ThreadLocal field access, unsafe access
3466 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3467 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3468 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
3469 bt = T_OBJECT;
3470 }
3471 }
3472 }
3473 // Note: T_NARROWOOP is not classed as a real reference type
3474 return (is_reference_type(bt) || bt == T_NARROWOOP);
3475 }
3476
3477 // Returns unique pointed java object or null.
3478 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) const {
3479 // If the node was created after the escape computation we can't answer.
3480 uint idx = n->_idx;
3481 if (idx >= nodes_size()) {
3482 return nullptr;
3483 }
3484 PointsToNode* ptn = ptnode_adr(idx);
3485 if (ptn == nullptr) {
3486 return nullptr;
3487 }
3488 if (ptn->is_JavaObject()) {
4127 // skip over a call which does not affect this memory slice
4128 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
4129 Node *proj_in = result->in(0);
4130 if (proj_in->is_Allocate() && proj_in->_idx == (uint)toop->instance_id()) {
4131 break; // hit one of our sentinels
4132 } else if (proj_in->is_Call()) {
4133 // ArrayCopy node processed here as well
4134 CallNode *call = proj_in->as_Call();
4135 if (!call->may_modify(toop, igvn)) {
4136 result = call->in(TypeFunc::Memory);
4137 }
4138 } else if (proj_in->is_Initialize()) {
4139 AllocateNode* alloc = proj_in->as_Initialize()->allocation();
4140 // Stop if this is the initialization for the object instance which
4141 // which contains this memory slice, otherwise skip over it.
4142 if (alloc == nullptr || alloc->_idx != (uint)toop->instance_id()) {
4143 result = proj_in->in(TypeFunc::Memory);
4144 }
4145 } else if (proj_in->is_MemBar()) {
4146 // Check if there is an array copy for a clone
4147 Node* control_proj_ac = proj_in->in(0);
4148
4149 if (control_proj_ac->is_Proj() && control_proj_ac->in(0)->is_ArrayCopy()) {
4150 // Stop if it is a clone
4151 ArrayCopyNode* ac = control_proj_ac->in(0)->as_ArrayCopy();
4152 if (ac->may_modify(toop, igvn)) {
4153 break;
4154 }
4155 }
4156 result = proj_in->in(TypeFunc::Memory);
4157 }
4158 } else if (result->is_MergeMem()) {
4159 MergeMemNode *mmem = result->as_MergeMem();
4160 result = step_through_mergemem(mmem, alias_idx, toop);
4161 if (result == mmem->base_memory()) {
4162 // Didn't find instance memory, search through general slice recursively.
4163 result = mmem->memory_at(C->get_general_index(alias_idx));
4164 result = find_inst_mem(result, alias_idx, orig_phis, rec_depth + 1);
4165 if (C->failing()) {
4166 return nullptr;
4167 }
|