1411 // a corresponding NULL if field's value if it is not recorded. |
1411 // a corresponding NULL if field's value if it is not recorded. |
1412 // Connection Graph does not record a default initialization by NULL |
1412 // Connection Graph does not record a default initialization by NULL |
1413 // captured by Initialize node. |
1413 // captured by Initialize node. |
1414 // |
1414 // |
1415 for (EdgeIterator i(pta); i.has_next(); i.next()) { |
1415 for (EdgeIterator i(pta); i.has_next(); i.next()) { |
1416 PointsToNode* ptn = i.get(); // Field (AddP) |
1416 PointsToNode* field = i.get(); // Field (AddP) |
1417 if (!ptn->is_Field() || !ptn->as_Field()->is_oop()) |
1417 if (!field->is_Field() || !field->as_Field()->is_oop()) |
1418 continue; // Not oop field |
1418 continue; // Not oop field |
1419 int offset = ptn->as_Field()->offset(); |
1419 int offset = field->as_Field()->offset(); |
1420 if (offset == Type::OffsetBot) { |
1420 if (offset == Type::OffsetBot) { |
1421 if (!visited_bottom_offset) { |
1421 if (!visited_bottom_offset) { |
1422 // OffsetBot is used to reference array's element, |
1422 // OffsetBot is used to reference array's element, |
1423 // always add reference to NULL to all Field nodes since we don't |
1423 // always add reference to NULL to all Field nodes since we don't |
1424 // known which element is referenced. |
1424 // known which element is referenced. |
1425 if (add_edge(ptn, null_obj)) { |
1425 if (add_edge(field, null_obj)) { |
1426 // New edge was added |
1426 // New edge was added |
1427 new_edges++; |
1427 new_edges++; |
1428 add_field_uses_to_worklist(ptn->as_Field()); |
1428 add_field_uses_to_worklist(field->as_Field()); |
1429 visited_bottom_offset = true; |
1429 visited_bottom_offset = true; |
1430 } |
1430 } |
1431 } |
1431 } |
1432 } else { |
1432 } else { |
1433 // Check only oop fields. |
1433 // Check only oop fields. |
1434 const Type* adr_type = ptn->ideal_node()->as_AddP()->bottom_type(); |
1434 const Type* adr_type = field->ideal_node()->as_AddP()->bottom_type(); |
1435 if (adr_type->isa_rawptr()) { |
1435 if (adr_type->isa_rawptr()) { |
1436 #ifdef ASSERT |
1436 #ifdef ASSERT |
1437 // Raw pointers are used for initializing stores so skip it |
1437 // Raw pointers are used for initializing stores so skip it |
1438 // since it should be recorded already |
1438 // since it should be recorded already |
1439 Node* base = get_addp_base(ptn->ideal_node()); |
1439 Node* base = get_addp_base(field->ideal_node()); |
1440 assert(adr_type->isa_rawptr() && base->is_Proj() && |
1440 assert(adr_type->isa_rawptr() && base->is_Proj() && |
1441 (base->in(0) == alloc),"unexpected pointer type"); |
1441 (base->in(0) == alloc),"unexpected pointer type"); |
1442 #endif |
1442 #endif |
1443 continue; |
1443 continue; |
1444 } |
1444 } |
1445 if (!offsets_worklist.contains(offset)) { |
1445 if (!offsets_worklist.contains(offset)) { |
1446 offsets_worklist.append(offset); |
1446 offsets_worklist.append(offset); |
1447 Node* value = NULL; |
1447 Node* value = NULL; |
1448 if (ini != NULL) { |
1448 if (ini != NULL) { |
1449 BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT; |
1449 // StoreP::memory_type() == T_ADDRESS |
1450 Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase); |
1450 BasicType ft = UseCompressedOops ? T_NARROWOOP : T_ADDRESS; |
1451 if (store != NULL && store->is_Store()) { |
1451 Node* store = ini->find_captured_store(offset, type2aelembytes(ft, true), phase); |
|
1452 // Make sure initializing store has the same type as this AddP. |
|
1453 // This AddP may reference non existing field because it is on a |
|
1454 // dead branch of bimorphic call which is not eliminated yet. |
|
1455 if (store != NULL && store->is_Store() && |
|
1456 store->as_Store()->memory_type() == ft) { |
1452 value = store->in(MemNode::ValueIn); |
1457 value = store->in(MemNode::ValueIn); |
|
1458 #ifdef ASSERT |
|
1459 if (VerifyConnectionGraph) { |
|
1460 // Verify that AddP already points to all objects the value points to. |
|
1461 PointsToNode* val = ptnode_adr(value->_idx); |
|
1462 assert((val != NULL), "should be processed already"); |
|
1463 PointsToNode* missed_obj = NULL; |
|
1464 if (val->is_JavaObject()) { |
|
1465 if (!field->points_to(val->as_JavaObject())) { |
|
1466 missed_obj = val; |
|
1467 } |
|
1468 } else { |
|
1469 if (!val->is_LocalVar() || (val->edge_count() == 0)) { |
|
1470 tty->print_cr("----------init store has invalid value -----"); |
|
1471 store->dump(); |
|
1472 val->dump(); |
|
1473 assert(val->is_LocalVar() && (val->edge_count() > 0), "should be processed already"); |
|
1474 } |
|
1475 for (EdgeIterator j(val); j.has_next(); j.next()) { |
|
1476 PointsToNode* obj = j.get(); |
|
1477 if (obj->is_JavaObject()) { |
|
1478 if (!field->points_to(obj->as_JavaObject())) { |
|
1479 missed_obj = obj; |
|
1480 break; |
|
1481 } |
|
1482 } |
|
1483 } |
|
1484 } |
|
1485 if (missed_obj != NULL) { |
|
1486 tty->print_cr("----------field---------------------------------"); |
|
1487 field->dump(); |
|
1488 tty->print_cr("----------missed referernce to object-----------"); |
|
1489 missed_obj->dump(); |
|
1490 tty->print_cr("----------object referernced by init store -----"); |
|
1491 store->dump(); |
|
1492 val->dump(); |
|
1493 assert(!field->points_to(missed_obj->as_JavaObject()), "missed JavaObject reference"); |
|
1494 } |
|
1495 } |
|
1496 #endif |
1453 } else { |
1497 } else { |
1454 // There could be initializing stores which follow allocation. |
1498 // There could be initializing stores which follow allocation. |
1455 // For example, a volatile field store is not collected |
1499 // For example, a volatile field store is not collected |
1456 // by Initialize node. |
1500 // by Initialize node. |
1457 // |
1501 // |
3125 if (print_state) { |
3188 if (print_state) { |
3126 EscapeState es = escape_state(); |
3189 EscapeState es = escape_state(); |
3127 EscapeState fields_es = fields_escape_state(); |
3190 EscapeState fields_es = fields_escape_state(); |
3128 tty->print("%s(%s) ", esc_names[(int)es], esc_names[(int)fields_es]); |
3191 tty->print("%s(%s) ", esc_names[(int)es], esc_names[(int)fields_es]); |
3129 if (nt == PointsToNode::JavaObject && !this->scalar_replaceable()) |
3192 if (nt == PointsToNode::JavaObject && !this->scalar_replaceable()) |
3130 tty->print("NSR"); |
3193 tty->print("NSR "); |
3131 } |
3194 } |
3132 if (is_Field()) { |
3195 if (is_Field()) { |
3133 FieldNode* f = (FieldNode*)this; |
3196 FieldNode* f = (FieldNode*)this; |
|
3197 if (f->is_oop()) |
|
3198 tty->print("oop "); |
|
3199 if (f->offset() > 0) |
|
3200 tty->print("+%d ", f->offset()); |
3134 tty->print("("); |
3201 tty->print("("); |
3135 for (BaseIterator i(f); i.has_next(); i.next()) { |
3202 for (BaseIterator i(f); i.has_next(); i.next()) { |
3136 PointsToNode* b = i.get(); |
3203 PointsToNode* b = i.get(); |
3137 tty->print(" %d%s", b->idx(),(b->is_JavaObject() ? "P" : "")); |
3204 tty->print(" %d%s", b->idx(),(b->is_JavaObject() ? "P" : "")); |
3138 } |
3205 } |