Mercurial > hg > truffle
comparison src/share/vm/opto/escape.cpp @ 6944:f3da5ff1514c
8002069: Assert failed in C2: assert(field->edge_count() > 0) failed: sanity
Summary: Added missed type check of initializing store in ConnectionGraph::find_init_values().
Reviewed-by: roland, twisti, vlivanov
author | kvn |
---|---|
date | Tue, 06 Nov 2012 15:16:32 -0800 |
parents | 006174cfe979 |
children | 2aff40cb4703 |
comparison
equal
deleted
inserted
replaced
6943:dbeaeee28bc2 | 6944:f3da5ff1514c |
---|---|
1384 } | 1384 } |
1385 #endif | 1385 #endif |
1386 // Non-escaped allocation returned from Java or runtime call have | 1386 // Non-escaped allocation returned from Java or runtime call have |
1387 // unknown values in fields. | 1387 // unknown values in fields. |
1388 for (EdgeIterator i(pta); i.has_next(); i.next()) { | 1388 for (EdgeIterator i(pta); i.has_next(); i.next()) { |
1389 PointsToNode* ptn = i.get(); | 1389 PointsToNode* field = i.get(); |
1390 if (ptn->is_Field() && ptn->as_Field()->is_oop()) { | 1390 if (field->is_Field() && field->as_Field()->is_oop()) { |
1391 if (add_edge(ptn, phantom_obj)) { | 1391 if (add_edge(field, phantom_obj)) { |
1392 // New edge was added | 1392 // New edge was added |
1393 new_edges++; | 1393 new_edges++; |
1394 add_field_uses_to_worklist(ptn->as_Field()); | 1394 add_field_uses_to_worklist(field->as_Field()); |
1395 } | 1395 } |
1396 } | 1396 } |
1397 } | 1397 } |
1398 return new_edges; | 1398 return new_edges; |
1399 } | 1399 } |
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 // |
1460 // that compare pointers optimization works correctly. | 1504 // that compare pointers optimization works correctly. |
1461 } | 1505 } |
1462 } | 1506 } |
1463 if (value == NULL) { | 1507 if (value == NULL) { |
1464 // A field's initializing value was not recorded. Add NULL. | 1508 // A field's initializing value was not recorded. Add NULL. |
1465 if (add_edge(ptn, null_obj)) { | 1509 if (add_edge(field, null_obj)) { |
1466 // New edge was added | 1510 // New edge was added |
1467 new_edges++; | 1511 new_edges++; |
1468 add_field_uses_to_worklist(ptn->as_Field()); | 1512 add_field_uses_to_worklist(field->as_Field()); |
1469 } | 1513 } |
1470 } | 1514 } |
1471 } | 1515 } |
1472 } | 1516 } |
1473 } | 1517 } |
1605 } | 1649 } |
1606 } | 1650 } |
1607 } | 1651 } |
1608 // Verify that all fields have initializing values. | 1652 // Verify that all fields have initializing values. |
1609 if (field->edge_count() == 0) { | 1653 if (field->edge_count() == 0) { |
1654 tty->print_cr("----------field does not have references----------"); | |
1610 field->dump(); | 1655 field->dump(); |
1656 for (BaseIterator i(field); i.has_next(); i.next()) { | |
1657 PointsToNode* base = i.get(); | |
1658 tty->print_cr("----------field has next base---------------------"); | |
1659 base->dump(); | |
1660 if (base->is_JavaObject() && (base != phantom_obj) && (base != null_obj)) { | |
1661 tty->print_cr("----------base has fields-------------------------"); | |
1662 for (EdgeIterator j(base); j.has_next(); j.next()) { | |
1663 j.get()->dump(); | |
1664 } | |
1665 tty->print_cr("----------base has references---------------------"); | |
1666 for (UseIterator j(base); j.has_next(); j.next()) { | |
1667 j.get()->dump(); | |
1668 } | |
1669 } | |
1670 } | |
1671 for (UseIterator i(field); i.has_next(); i.next()) { | |
1672 i.get()->dump(); | |
1673 } | |
1611 assert(field->edge_count() > 0, "sanity"); | 1674 assert(field->edge_count() > 0, "sanity"); |
1612 } | 1675 } |
1613 } | 1676 } |
1614 } | 1677 } |
1615 } | 1678 } |
1965 // Return true if this node points to specified node or nodes it points to. | 2028 // Return true if this node points to specified node or nodes it points to. |
1966 bool PointsToNode::points_to(JavaObjectNode* ptn) const { | 2029 bool PointsToNode::points_to(JavaObjectNode* ptn) const { |
1967 if (is_JavaObject()) { | 2030 if (is_JavaObject()) { |
1968 return (this == ptn); | 2031 return (this == ptn); |
1969 } | 2032 } |
1970 assert(is_LocalVar(), "sanity"); | 2033 assert(is_LocalVar() || is_Field(), "sanity"); |
1971 for (EdgeIterator i(this); i.has_next(); i.next()) { | 2034 for (EdgeIterator i(this); i.has_next(); i.next()) { |
1972 if (i.get() == ptn) | 2035 if (i.get() == ptn) |
1973 return true; | 2036 return true; |
1974 } | 2037 } |
1975 return false; | 2038 return false; |
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 } |