1509 assert((ptnode_adr(adr->_idx) == nullptr ||
1510 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
1511 }
1512 #endif
1513 add_local_var_and_edge(n, PointsToNode::NoEscape,
1514 adr, delayed_worklist);
1515 }
1516 }
1517
1518 // Populate Connection Graph with PointsTo nodes and create simple
1519 // connection graph edges.
1520 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
1521 assert(!_verify, "this method should not be called for verification");
1522 PhaseGVN* igvn = _igvn;
1523 uint n_idx = n->_idx;
1524 PointsToNode* n_ptn = ptnode_adr(n_idx);
1525 if (n_ptn != nullptr) {
1526 return; // No need to redefine PointsTo node during first iteration.
1527 }
1528 int opcode = n->Opcode();
1529 bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_to_con_graph(this, igvn, delayed_worklist, n, opcode);
1530 if (gc_handled) {
1531 return; // Ignore node if already handled by GC.
1532 }
1533
1534 if (n->is_Call()) {
1535 // Arguments to allocation and locking don't escape.
1536 if (n->is_AbstractLock()) {
1537 // Put Lock and Unlock nodes on IGVN worklist to process them during
1538 // first IGVN optimization when escape information is still available.
1539 record_for_optimizer(n);
1540 } else if (n->is_Allocate()) {
1541 add_call_node(n->as_Call());
1542 record_for_optimizer(n);
1543 } else {
1544 if (n->is_CallStaticJava()) {
1545 const char* name = n->as_CallStaticJava()->_name;
1546 if (name != nullptr && strcmp(name, "uncommon_trap") == 0) {
1547 return; // Skip uncommon traps
1548 }
1549 }
1550 // Don't mark as processed since call's arguments have to be processed.
1551 delayed_worklist->push(n);
1552 // Check if a call returns an object.
1553 if ((n->as_Call()->returns_pointer() &&
1731 }
1732 return;
1733 }
1734
1735 // Add final simple edges to graph.
1736 void ConnectionGraph::add_final_edges(Node *n) {
1737 PointsToNode* n_ptn = ptnode_adr(n->_idx);
1738 #ifdef ASSERT
1739 if (_verify && n_ptn->is_JavaObject())
1740 return; // This method does not change graph for JavaObject.
1741 #endif
1742
1743 if (n->is_Call()) {
1744 process_call_arguments(n->as_Call());
1745 return;
1746 }
1747 assert(n->is_Store() || n->is_LoadStore() ||
1748 ((n_ptn != nullptr) && (n_ptn->ideal_node() != nullptr)),
1749 "node should be registered already");
1750 int opcode = n->Opcode();
1751 bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_final_edges(this, _igvn, n, opcode);
1752 if (gc_handled) {
1753 return; // Ignore node if already handled by GC.
1754 }
1755 switch (opcode) {
1756 case Op_AddP: {
1757 Node* base = get_addp_base(n);
1758 PointsToNode* ptn_base = ptnode_adr(base->_idx);
1759 assert(ptn_base != nullptr, "field's base should be registered");
1760 add_base(n_ptn->as_Field(), ptn_base);
1761 break;
1762 }
1763 case Op_CastPP:
1764 case Op_CheckCastPP:
1765 case Op_EncodeP:
1766 case Op_DecodeN:
1767 case Op_EncodePKlass:
1768 case Op_DecodeNKlass: {
1769 add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), nullptr);
1770 break;
1771 }
1772 case Op_CMoveP: {
1773 for (uint i = CMoveNode::IfFalse; i < n->req(); i++) {
1774 Node* in = n->in(i);
3465 BasicType bt = T_INT;
3466 if (offset == Type::OffsetBot) {
3467 // Check only oop fields.
3468 if (!adr_type->isa_aryptr() ||
3469 adr_type->isa_aryptr()->elem() == Type::BOTTOM ||
3470 adr_type->isa_aryptr()->elem()->make_oopptr() != nullptr) {
3471 // OffsetBot is used to reference array's element. Ignore first AddP.
3472 if (find_second_addp(n, n->in(AddPNode::Base)) == nullptr) {
3473 bt = T_OBJECT;
3474 }
3475 }
3476 } else if (offset != oopDesc::klass_offset_in_bytes()) {
3477 if (adr_type->isa_instptr()) {
3478 ciField* field = _compile->alias_type(adr_type->isa_instptr())->field();
3479 if (field != nullptr) {
3480 bt = field->layout_type();
3481 } else {
3482 // Check for unsafe oop field access
3483 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3484 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3485 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN) ||
3486 BarrierSet::barrier_set()->barrier_set_c2()->escape_has_out_with_unsafe_object(n)) {
3487 bt = T_OBJECT;
3488 (*unsafe) = true;
3489 }
3490 }
3491 } else if (adr_type->isa_aryptr()) {
3492 if (offset == arrayOopDesc::length_offset_in_bytes()) {
3493 // Ignore array length load.
3494 } else if (find_second_addp(n, n->in(AddPNode::Base)) != nullptr) {
3495 // Ignore first AddP.
3496 } else {
3497 const Type* elemtype = adr_type->isa_aryptr()->elem();
3498 bt = elemtype->array_element_basic_type();
3499 }
3500 } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
3501 // Allocation initialization, ThreadLocal field access, unsafe access
3502 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3503 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3504 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN) ||
3505 BarrierSet::barrier_set()->barrier_set_c2()->escape_has_out_with_unsafe_object(n)) {
3506 bt = T_OBJECT;
3507 }
3508 }
3509 }
3510 // Note: T_NARROWOOP is not classed as a real reference type
3511 return (is_reference_type(bt) || bt == T_NARROWOOP);
3512 }
3513
3514 // Returns unique pointed java object or null.
3515 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) const {
3516 // If the node was created after the escape computation we can't answer.
3517 uint idx = n->_idx;
3518 if (idx >= nodes_size()) {
3519 return nullptr;
3520 }
3521 PointsToNode* ptn = ptnode_adr(idx);
3522 if (ptn == nullptr) {
3523 return nullptr;
3524 }
3525 if (ptn->is_JavaObject()) {
4169 } else if (proj_in->is_Call()) {
4170 // ArrayCopy node processed here as well
4171 CallNode *call = proj_in->as_Call();
4172 if (!call->may_modify(toop, igvn)) {
4173 result = call->in(TypeFunc::Memory);
4174 }
4175 } else if (proj_in->is_Initialize()) {
4176 AllocateNode* alloc = proj_in->as_Initialize()->allocation();
4177 // Stop if this is the initialization for the object instance which
4178 // which contains this memory slice, otherwise skip over it.
4179 if (alloc == nullptr || alloc->_idx != (uint)toop->instance_id()) {
4180 result = proj_in->in(TypeFunc::Memory);
4181 } else if (C->get_alias_index(result->adr_type()) != alias_idx) {
4182 assert(C->get_general_index(alias_idx) == C->get_alias_index(result->adr_type()), "should be projection for the same field/array element");
4183 result = get_map(result->_idx);
4184 assert(result != nullptr, "new projection should have been allocated");
4185 break;
4186 }
4187 } else if (proj_in->is_MemBar()) {
4188 // Check if there is an array copy for a clone
4189 // Step over GC barrier when ReduceInitialCardMarks is disabled
4190 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
4191 Node* control_proj_ac = bs->step_over_gc_barrier(proj_in->in(0));
4192
4193 if (control_proj_ac->is_Proj() && control_proj_ac->in(0)->is_ArrayCopy()) {
4194 // Stop if it is a clone
4195 ArrayCopyNode* ac = control_proj_ac->in(0)->as_ArrayCopy();
4196 if (ac->may_modify(toop, igvn)) {
4197 break;
4198 }
4199 }
4200 result = proj_in->in(TypeFunc::Memory);
4201 }
4202 } else if (result->is_MergeMem()) {
4203 MergeMemNode *mmem = result->as_MergeMem();
4204 result = step_through_mergemem(mmem, alias_idx, toop);
4205 if (result == mmem->base_memory()) {
4206 // Didn't find instance memory, search through general slice recursively.
4207 result = mmem->memory_at(C->get_general_index(alias_idx));
4208 result = find_inst_mem(result, alias_idx, orig_phis, rec_depth + 1);
4209 if (C->failing()) {
4210 return nullptr;
4211 }
|
1509 assert((ptnode_adr(adr->_idx) == nullptr ||
1510 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
1511 }
1512 #endif
1513 add_local_var_and_edge(n, PointsToNode::NoEscape,
1514 adr, delayed_worklist);
1515 }
1516 }
1517
1518 // Populate Connection Graph with PointsTo nodes and create simple
1519 // connection graph edges.
1520 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
1521 assert(!_verify, "this method should not be called for verification");
1522 PhaseGVN* igvn = _igvn;
1523 uint n_idx = n->_idx;
1524 PointsToNode* n_ptn = ptnode_adr(n_idx);
1525 if (n_ptn != nullptr) {
1526 return; // No need to redefine PointsTo node during first iteration.
1527 }
1528 int opcode = n->Opcode();
1529 if (n->is_Call()) {
1530 // Arguments to allocation and locking don't escape.
1531 if (n->is_AbstractLock()) {
1532 // Put Lock and Unlock nodes on IGVN worklist to process them during
1533 // first IGVN optimization when escape information is still available.
1534 record_for_optimizer(n);
1535 } else if (n->is_Allocate()) {
1536 add_call_node(n->as_Call());
1537 record_for_optimizer(n);
1538 } else {
1539 if (n->is_CallStaticJava()) {
1540 const char* name = n->as_CallStaticJava()->_name;
1541 if (name != nullptr && strcmp(name, "uncommon_trap") == 0) {
1542 return; // Skip uncommon traps
1543 }
1544 }
1545 // Don't mark as processed since call's arguments have to be processed.
1546 delayed_worklist->push(n);
1547 // Check if a call returns an object.
1548 if ((n->as_Call()->returns_pointer() &&
1726 }
1727 return;
1728 }
1729
1730 // Add final simple edges to graph.
1731 void ConnectionGraph::add_final_edges(Node *n) {
1732 PointsToNode* n_ptn = ptnode_adr(n->_idx);
1733 #ifdef ASSERT
1734 if (_verify && n_ptn->is_JavaObject())
1735 return; // This method does not change graph for JavaObject.
1736 #endif
1737
1738 if (n->is_Call()) {
1739 process_call_arguments(n->as_Call());
1740 return;
1741 }
1742 assert(n->is_Store() || n->is_LoadStore() ||
1743 ((n_ptn != nullptr) && (n_ptn->ideal_node() != nullptr)),
1744 "node should be registered already");
1745 int opcode = n->Opcode();
1746 switch (opcode) {
1747 case Op_AddP: {
1748 Node* base = get_addp_base(n);
1749 PointsToNode* ptn_base = ptnode_adr(base->_idx);
1750 assert(ptn_base != nullptr, "field's base should be registered");
1751 add_base(n_ptn->as_Field(), ptn_base);
1752 break;
1753 }
1754 case Op_CastPP:
1755 case Op_CheckCastPP:
1756 case Op_EncodeP:
1757 case Op_DecodeN:
1758 case Op_EncodePKlass:
1759 case Op_DecodeNKlass: {
1760 add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), nullptr);
1761 break;
1762 }
1763 case Op_CMoveP: {
1764 for (uint i = CMoveNode::IfFalse; i < n->req(); i++) {
1765 Node* in = n->in(i);
3456 BasicType bt = T_INT;
3457 if (offset == Type::OffsetBot) {
3458 // Check only oop fields.
3459 if (!adr_type->isa_aryptr() ||
3460 adr_type->isa_aryptr()->elem() == Type::BOTTOM ||
3461 adr_type->isa_aryptr()->elem()->make_oopptr() != nullptr) {
3462 // OffsetBot is used to reference array's element. Ignore first AddP.
3463 if (find_second_addp(n, n->in(AddPNode::Base)) == nullptr) {
3464 bt = T_OBJECT;
3465 }
3466 }
3467 } else if (offset != oopDesc::klass_offset_in_bytes()) {
3468 if (adr_type->isa_instptr()) {
3469 ciField* field = _compile->alias_type(adr_type->isa_instptr())->field();
3470 if (field != nullptr) {
3471 bt = field->layout_type();
3472 } else {
3473 // Check for unsafe oop field access
3474 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3475 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3476 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
3477 bt = T_OBJECT;
3478 (*unsafe) = true;
3479 }
3480 }
3481 } else if (adr_type->isa_aryptr()) {
3482 if (offset == arrayOopDesc::length_offset_in_bytes()) {
3483 // Ignore array length load.
3484 } else if (find_second_addp(n, n->in(AddPNode::Base)) != nullptr) {
3485 // Ignore first AddP.
3486 } else {
3487 const Type* elemtype = adr_type->isa_aryptr()->elem();
3488 bt = elemtype->array_element_basic_type();
3489 }
3490 } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
3491 // Allocation initialization, ThreadLocal field access, unsafe access
3492 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3493 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3494 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
3495 bt = T_OBJECT;
3496 }
3497 }
3498 }
3499 // Note: T_NARROWOOP is not classed as a real reference type
3500 return (is_reference_type(bt) || bt == T_NARROWOOP);
3501 }
3502
3503 // Returns unique pointed java object or null.
3504 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) const {
3505 // If the node was created after the escape computation we can't answer.
3506 uint idx = n->_idx;
3507 if (idx >= nodes_size()) {
3508 return nullptr;
3509 }
3510 PointsToNode* ptn = ptnode_adr(idx);
3511 if (ptn == nullptr) {
3512 return nullptr;
3513 }
3514 if (ptn->is_JavaObject()) {
4158 } else if (proj_in->is_Call()) {
4159 // ArrayCopy node processed here as well
4160 CallNode *call = proj_in->as_Call();
4161 if (!call->may_modify(toop, igvn)) {
4162 result = call->in(TypeFunc::Memory);
4163 }
4164 } else if (proj_in->is_Initialize()) {
4165 AllocateNode* alloc = proj_in->as_Initialize()->allocation();
4166 // Stop if this is the initialization for the object instance which
4167 // which contains this memory slice, otherwise skip over it.
4168 if (alloc == nullptr || alloc->_idx != (uint)toop->instance_id()) {
4169 result = proj_in->in(TypeFunc::Memory);
4170 } else if (C->get_alias_index(result->adr_type()) != alias_idx) {
4171 assert(C->get_general_index(alias_idx) == C->get_alias_index(result->adr_type()), "should be projection for the same field/array element");
4172 result = get_map(result->_idx);
4173 assert(result != nullptr, "new projection should have been allocated");
4174 break;
4175 }
4176 } else if (proj_in->is_MemBar()) {
4177 // Check if there is an array copy for a clone
4178 Node* control_proj_ac = proj_in->in(0);
4179
4180 if (control_proj_ac->is_Proj() && control_proj_ac->in(0)->is_ArrayCopy()) {
4181 // Stop if it is a clone
4182 ArrayCopyNode* ac = control_proj_ac->in(0)->as_ArrayCopy();
4183 if (ac->may_modify(toop, igvn)) {
4184 break;
4185 }
4186 }
4187 result = proj_in->in(TypeFunc::Memory);
4188 }
4189 } else if (result->is_MergeMem()) {
4190 MergeMemNode *mmem = result->as_MergeMem();
4191 result = step_through_mergemem(mmem, alias_idx, toop);
4192 if (result == mmem->base_memory()) {
4193 // Didn't find instance memory, search through general slice recursively.
4194 result = mmem->memory_at(C->get_general_index(alias_idx));
4195 result = find_inst_mem(result, alias_idx, orig_phis, rec_depth + 1);
4196 if (C->failing()) {
4197 return nullptr;
4198 }
|