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 }