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 ---