escape.cpp (3771:006174cfe979) | escape.cpp (3820:f3da5ff1514c) |
---|---|
1/* 2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * --- 1372 unchanged lines hidden (view full) --- 1381 if (alloc->as_CallStaticJava()->method() == NULL) { 1382 const char* name = alloc->as_CallStaticJava()->_name; 1383 assert(strncmp(name, "_multianewarray", 15) == 0, "sanity"); 1384 } 1385#endif 1386 // Non-escaped allocation returned from Java or runtime call have 1387 // unknown values in fields. 1388 for (EdgeIterator i(pta); i.has_next(); i.next()) { | 1/* 2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * --- 1372 unchanged lines hidden (view full) --- 1381 if (alloc->as_CallStaticJava()->method() == NULL) { 1382 const char* name = alloc->as_CallStaticJava()->_name; 1383 assert(strncmp(name, "_multianewarray", 15) == 0, "sanity"); 1384 } 1385#endif 1386 // Non-escaped allocation returned from Java or runtime call have 1387 // unknown values in fields. 1388 for (EdgeIterator i(pta); i.has_next(); i.next()) { |
1389 PointsToNode* ptn = i.get(); 1390 if (ptn->is_Field() && ptn->as_Field()->is_oop()) { 1391 if (add_edge(ptn, phantom_obj)) { | 1389 PointsToNode* field = i.get(); 1390 if (field->is_Field() && field->as_Field()->is_oop()) { 1391 if (add_edge(field, phantom_obj)) { |
1392 // New edge was added 1393 new_edges++; | 1392 // New edge was added 1393 new_edges++; |
1394 add_field_uses_to_worklist(ptn->as_Field()); | 1394 add_field_uses_to_worklist(field->as_Field()); |
1395 } 1396 } 1397 } 1398 return new_edges; 1399 } 1400 assert(init_val == null_obj, "sanity"); 1401 // Do nothing for Call nodes since its fields values are unknown. 1402 if (!alloc->is_Allocate()) --- 5 unchanged lines hidden (view full) --- 1408 GrowableArray<int> offsets_worklist; 1409 1410 // Check if an oop field's initializing value is recorded and add 1411 // a corresponding NULL if field's value if it is not recorded. 1412 // Connection Graph does not record a default initialization by NULL 1413 // captured by Initialize node. 1414 // 1415 for (EdgeIterator i(pta); i.has_next(); i.next()) { | 1395 } 1396 } 1397 } 1398 return new_edges; 1399 } 1400 assert(init_val == null_obj, "sanity"); 1401 // Do nothing for Call nodes since its fields values are unknown. 1402 if (!alloc->is_Allocate()) --- 5 unchanged lines hidden (view full) --- 1408 GrowableArray<int> offsets_worklist; 1409 1410 // Check if an oop field's initializing value is recorded and add 1411 // a corresponding NULL if field's value if it is not recorded. 1412 // Connection Graph does not record a default initialization by NULL 1413 // captured by Initialize node. 1414 // 1415 for (EdgeIterator i(pta); i.has_next(); i.next()) { |
1416 PointsToNode* ptn = i.get(); // Field (AddP) 1417 if (!ptn->is_Field() || !ptn->as_Field()->is_oop()) | 1416 PointsToNode* field = i.get(); // Field (AddP) 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) { 1421 if (!visited_bottom_offset) { 1422 // OffsetBot is used to reference array's element, 1423 // always add reference to NULL to all Field nodes since we don't 1424 // known which element is referenced. | 1420 if (offset == Type::OffsetBot) { 1421 if (!visited_bottom_offset) { 1422 // OffsetBot is used to reference array's element, 1423 // always add reference to NULL to all Field nodes since we don't 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 1427 new_edges++; | 1426 // New edge was added 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; 1430 } 1431 } 1432 } else { 1433 // Check only oop fields. | 1429 visited_bottom_offset = true; 1430 } 1431 } 1432 } else { 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()) { 1436#ifdef ASSERT 1437 // Raw pointers are used for initializing stores so skip it 1438 // since it should be recorded already | 1435 if (adr_type->isa_rawptr()) { 1436#ifdef ASSERT 1437 // Raw pointers are used for initializing stores so skip it 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() && 1441 (base->in(0) == alloc),"unexpected pointer type"); 1442#endif 1443 continue; 1444 } 1445 if (!offsets_worklist.contains(offset)) { 1446 offsets_worklist.append(offset); 1447 Node* value = NULL; 1448 if (ini != NULL) { | 1440 assert(adr_type->isa_rawptr() && base->is_Proj() && 1441 (base->in(0) == alloc),"unexpected pointer type"); 1442#endif 1443 continue; 1444 } 1445 if (!offsets_worklist.contains(offset)) { 1446 offsets_worklist.append(offset); 1447 Node* value = NULL; 1448 if (ini != NULL) { |
1449 BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT; 1450 Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase); 1451 if (store != NULL && store->is_Store()) { | 1449 // StoreP::memory_type() == T_ADDRESS 1450 BasicType ft = UseCompressedOops ? T_NARROWOOP : T_ADDRESS; 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 { 1454 // There could be initializing stores which follow allocation. 1455 // For example, a volatile field store is not collected 1456 // by Initialize node. 1457 // 1458 // Need to check for dependent loads to separate such stores from 1459 // stores which follow loads. For now, add initial value NULL so 1460 // that compare pointers optimization works correctly. 1461 } 1462 } 1463 if (value == NULL) { 1464 // A field's initializing value was not recorded. Add NULL. | 1497 } else { 1498 // There could be initializing stores which follow allocation. 1499 // For example, a volatile field store is not collected 1500 // by Initialize node. 1501 // 1502 // Need to check for dependent loads to separate such stores from 1503 // stores which follow loads. For now, add initial value NULL so 1504 // that compare pointers optimization works correctly. 1505 } 1506 } 1507 if (value == 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 1467 new_edges++; | 1510 // New edge was added 1511 new_edges++; |
1468 add_field_uses_to_worklist(ptn->as_Field()); | 1512 add_field_uses_to_worklist(field->as_Field()); |
1469 } 1470 } 1471 } 1472 } 1473 } 1474 return new_edges; 1475} 1476 --- 125 unchanged lines hidden (view full) --- 1602 PointsToNode* e = i.get(); 1603 if (e->is_JavaObject()) { 1604 assert(field->has_base(e->as_JavaObject()), "sanity"); 1605 } 1606 } 1607 } 1608 // Verify that all fields have initializing values. 1609 if (field->edge_count() == 0) { | 1513 } 1514 } 1515 } 1516 } 1517 } 1518 return new_edges; 1519} 1520 --- 125 unchanged lines hidden (view full) --- 1646 PointsToNode* e = i.get(); 1647 if (e->is_JavaObject()) { 1648 assert(field->has_base(e->as_JavaObject()), "sanity"); 1649 } 1650 } 1651 } 1652 // Verify that all fields have initializing values. 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"); 1612 } 1613 } 1614 } 1615} 1616#endif 1617 1618// Optimize ideal graph. --- 343 unchanged lines hidden (view full) --- 1962 1963// Helper functions 1964 1965// Return true if this node points to specified node or nodes it points to. 1966bool PointsToNode::points_to(JavaObjectNode* ptn) const { 1967 if (is_JavaObject()) { 1968 return (this == ptn); 1969 } | 1674 assert(field->edge_count() > 0, "sanity"); 1675 } 1676 } 1677 } 1678} 1679#endif 1680 1681// Optimize ideal graph. --- 343 unchanged lines hidden (view full) --- 2025 2026// Helper functions 2027 2028// Return true if this node points to specified node or nodes it points to. 2029bool PointsToNode::points_to(JavaObjectNode* ptn) const { 2030 if (is_JavaObject()) { 2031 return (this == ptn); 2032 } |
1970 assert(is_LocalVar(), "sanity"); | 2033 assert(is_LocalVar() || is_Field(), "sanity"); |
1971 for (EdgeIterator i(this); i.has_next(); i.next()) { 1972 if (i.get() == ptn) 1973 return true; 1974 } 1975 return false; 1976} 1977 1978// Return true if one node points to an other. --- 1143 unchanged lines hidden (view full) --- 3122void PointsToNode::dump(bool print_state) const { 3123 NodeType nt = node_type(); 3124 tty->print("%s ", node_type_names[(int) nt]); 3125 if (print_state) { 3126 EscapeState es = escape_state(); 3127 EscapeState fields_es = fields_escape_state(); 3128 tty->print("%s(%s) ", esc_names[(int)es], esc_names[(int)fields_es]); 3129 if (nt == PointsToNode::JavaObject && !this->scalar_replaceable()) | 2034 for (EdgeIterator i(this); i.has_next(); i.next()) { 2035 if (i.get() == ptn) 2036 return true; 2037 } 2038 return false; 2039} 2040 2041// Return true if one node points to an other. --- 1143 unchanged lines hidden (view full) --- 3185void PointsToNode::dump(bool print_state) const { 3186 NodeType nt = node_type(); 3187 tty->print("%s ", node_type_names[(int) nt]); 3188 if (print_state) { 3189 EscapeState es = escape_state(); 3190 EscapeState fields_es = fields_escape_state(); 3191 tty->print("%s(%s) ", esc_names[(int)es], esc_names[(int)fields_es]); 3192 if (nt == PointsToNode::JavaObject && !this->scalar_replaceable()) |
3130 tty->print("NSR"); | 3193 tty->print("NSR "); |
3131 } 3132 if (is_Field()) { 3133 FieldNode* f = (FieldNode*)this; | 3194 } 3195 if (is_Field()) { 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("("); 3135 for (BaseIterator i(f); i.has_next(); i.next()) { 3136 PointsToNode* b = i.get(); 3137 tty->print(" %d%s", b->idx(),(b->is_JavaObject() ? "P" : "")); 3138 } 3139 tty->print(" )"); 3140 } 3141 tty->print("["); --- 52 unchanged lines hidden --- | 3201 tty->print("("); 3202 for (BaseIterator i(f); i.has_next(); i.next()) { 3203 PointsToNode* b = i.get(); 3204 tty->print(" %d%s", b->idx(),(b->is_JavaObject() ? "P" : "")); 3205 } 3206 tty->print(" )"); 3207 } 3208 tty->print("["); --- 52 unchanged lines hidden --- |