< prev index next >

src/hotspot/share/opto/compile.cpp

Print this page
rev 52415 : 8213371: GC/C2 abstraction and cleanup to handle custom offset for GC memory accesses


1448     }
1449   } else if( ta && _AliasLevel >= 2 ) {
1450     // For arrays indexed by constant indices, we flatten the alias
1451     // space to include all of the array body.  Only the header, klass
1452     // and array length can be accessed un-aliased.
1453     if( offset != Type::OffsetBot ) {
1454       if( ta->const_oop() ) { // MethodData* or Method*
1455         offset = Type::OffsetBot;   // Flatten constant access into array body
1456         tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset);
1457       } else if( offset == arrayOopDesc::length_offset_in_bytes() ) {
1458         // range is OK as-is.
1459         tj = ta = TypeAryPtr::RANGE;
1460       } else if( offset == oopDesc::klass_offset_in_bytes() ) {
1461         tj = TypeInstPtr::KLASS; // all klass loads look alike
1462         ta = TypeAryPtr::RANGE; // generic ignored junk
1463         ptr = TypePtr::BotPTR;
1464       } else if( offset == oopDesc::mark_offset_in_bytes() ) {
1465         tj = TypeInstPtr::MARK;
1466         ta = TypeAryPtr::RANGE; // generic ignored junk
1467         ptr = TypePtr::BotPTR;


1468       } else {                  // Random constant offset into array body
1469         offset = Type::OffsetBot;   // Flatten constant access into array body
1470         tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset);
1471       }
1472     }
1473     // Arrays of fixed size alias with arrays of unknown size.
1474     if (ta->size() != TypeInt::POS) {
1475       const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS);
1476       tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset);
1477     }
1478     // Arrays of known objects become arrays of unknown objects.
1479     if (ta->elem()->isa_narrowoop() && ta->elem() != TypeNarrowOop::BOTTOM) {
1480       const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size());
1481       tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset);
1482     }
1483     if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) {
1484       const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size());
1485       tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset);
1486     }
1487     // Arrays of bytes and of booleans both use 'bastore' and 'baload' so


1512         tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
1513       }
1514     } else if( is_known_inst ) {
1515       tj = to; // Keep NotNull and klass_is_exact for instance type
1516     } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
1517       // During the 2nd round of IterGVN, NotNull castings are removed.
1518       // Make sure the Bottom and NotNull variants alias the same.
1519       // Also, make sure exact and non-exact variants alias the same.
1520       tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
1521     }
1522     if (to->speculative() != NULL) {
1523       tj = to = TypeInstPtr::make(to->ptr(),to->klass(),to->klass_is_exact(),to->const_oop(),to->offset(), to->instance_id());
1524     }
1525     // Canonicalize the holder of this field
1526     if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
1527       // First handle header references such as a LoadKlassNode, even if the
1528       // object's klass is unloaded at compile time (4965979).
1529       if (!is_known_inst) { // Do it only for non-instance types
1530         tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset);
1531       }


1532     } else if (offset < 0 || offset >= k->size_helper() * wordSize) {
1533       // Static fields are in the space above the normal instance
1534       // fields in the java.lang.Class instance.
1535       if (to->klass() != ciEnv::current()->Class_klass()) {
1536         to = NULL;
1537         tj = TypeOopPtr::BOTTOM;
1538         offset = tj->offset();
1539       }
1540     } else {
1541       ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
1542       if (!k->equals(canonical_holder) || tj->offset() != offset) {
1543         if( is_known_inst ) {
1544           tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id());
1545         } else {
1546           tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset);
1547         }
1548       }
1549     }
1550   }
1551 


1610     case Type::AnyPtr:   tj = TypePtr::BOTTOM;      break;  // caller checks it
1611     default: ShouldNotReachHere();
1612     }
1613     break;
1614   case 2:                       // No collapsing at level 2; keep all splits
1615   case 3:                       // No collapsing at level 3; keep all splits
1616     break;
1617   default:
1618     Unimplemented();
1619   }
1620 
1621   offset = tj->offset();
1622   assert( offset != Type::OffsetTop, "Offset has fallen from constant" );
1623 
1624   assert( (offset != Type::OffsetBot && tj->base() != Type::AryPtr) ||
1625           (offset == Type::OffsetBot && tj->base() == Type::AryPtr) ||
1626           (offset == Type::OffsetBot && tj == TypeOopPtr::BOTTOM) ||
1627           (offset == Type::OffsetBot && tj == TypePtr::BOTTOM) ||
1628           (offset == oopDesc::mark_offset_in_bytes() && tj->base() == Type::AryPtr) ||
1629           (offset == oopDesc::klass_offset_in_bytes() && tj->base() == Type::AryPtr) ||
1630           (offset == arrayOopDesc::length_offset_in_bytes() && tj->base() == Type::AryPtr)  ,

1631           "For oops, klasses, raw offset must be constant; for arrays the offset is never known" );
1632   assert( tj->ptr() != TypePtr::TopPTR &&
1633           tj->ptr() != TypePtr::AnyNull &&
1634           tj->ptr() != TypePtr::Null, "No imprecise addresses" );
1635 //    assert( tj->ptr() != TypePtr::Constant ||
1636 //            tj->base() == Type::RawPtr ||
1637 //            tj->base() == Type::KlassPtr, "No constant oop addresses" );
1638 
1639   return tj;
1640 }
1641 
1642 void Compile::AliasType::Init(int i, const TypePtr* at) {
1643   _index = i;
1644   _adr_type = at;
1645   _field = NULL;
1646   _element = NULL;
1647   _is_rewritable = true; // default
1648   const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL;
1649   if (atoop != NULL && atoop->is_known_instance()) {
1650     const TypeOopPtr *gt = atoop->cast_to_instance_id(TypeOopPtr::InstanceBot);




1448     }
1449   } else if( ta && _AliasLevel >= 2 ) {
1450     // For arrays indexed by constant indices, we flatten the alias
1451     // space to include all of the array body.  Only the header, klass
1452     // and array length can be accessed un-aliased.
1453     if( offset != Type::OffsetBot ) {
1454       if( ta->const_oop() ) { // MethodData* or Method*
1455         offset = Type::OffsetBot;   // Flatten constant access into array body
1456         tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset);
1457       } else if( offset == arrayOopDesc::length_offset_in_bytes() ) {
1458         // range is OK as-is.
1459         tj = ta = TypeAryPtr::RANGE;
1460       } else if( offset == oopDesc::klass_offset_in_bytes() ) {
1461         tj = TypeInstPtr::KLASS; // all klass loads look alike
1462         ta = TypeAryPtr::RANGE; // generic ignored junk
1463         ptr = TypePtr::BotPTR;
1464       } else if( offset == oopDesc::mark_offset_in_bytes() ) {
1465         tj = TypeInstPtr::MARK;
1466         ta = TypeAryPtr::RANGE; // generic ignored junk
1467         ptr = TypePtr::BotPTR;
1468       } else if (BarrierSet::barrier_set()->barrier_set_c2()->flatten_gc_alias_type(tj)) {
1469         ta = tj->isa_aryptr();
1470       } else {                  // Random constant offset into array body
1471         offset = Type::OffsetBot;   // Flatten constant access into array body
1472         tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset);
1473       }
1474     }
1475     // Arrays of fixed size alias with arrays of unknown size.
1476     if (ta->size() != TypeInt::POS) {
1477       const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS);
1478       tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset);
1479     }
1480     // Arrays of known objects become arrays of unknown objects.
1481     if (ta->elem()->isa_narrowoop() && ta->elem() != TypeNarrowOop::BOTTOM) {
1482       const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size());
1483       tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset);
1484     }
1485     if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) {
1486       const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size());
1487       tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset);
1488     }
1489     // Arrays of bytes and of booleans both use 'bastore' and 'baload' so


1514         tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
1515       }
1516     } else if( is_known_inst ) {
1517       tj = to; // Keep NotNull and klass_is_exact for instance type
1518     } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
1519       // During the 2nd round of IterGVN, NotNull castings are removed.
1520       // Make sure the Bottom and NotNull variants alias the same.
1521       // Also, make sure exact and non-exact variants alias the same.
1522       tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
1523     }
1524     if (to->speculative() != NULL) {
1525       tj = to = TypeInstPtr::make(to->ptr(),to->klass(),to->klass_is_exact(),to->const_oop(),to->offset(), to->instance_id());
1526     }
1527     // Canonicalize the holder of this field
1528     if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
1529       // First handle header references such as a LoadKlassNode, even if the
1530       // object's klass is unloaded at compile time (4965979).
1531       if (!is_known_inst) { // Do it only for non-instance types
1532         tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset);
1533       }
1534     } else if (BarrierSet::barrier_set()->barrier_set_c2()->flatten_gc_alias_type(tj)) {
1535       to = tj->is_instptr();
1536     } else if (offset < 0 || offset >= k->size_helper() * wordSize) {
1537       // Static fields are in the space above the normal instance
1538       // fields in the java.lang.Class instance.
1539       if (to->klass() != ciEnv::current()->Class_klass()) {
1540         to = NULL;
1541         tj = TypeOopPtr::BOTTOM;
1542         offset = tj->offset();
1543       }
1544     } else {
1545       ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
1546       if (!k->equals(canonical_holder) || tj->offset() != offset) {
1547         if( is_known_inst ) {
1548           tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id());
1549         } else {
1550           tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset);
1551         }
1552       }
1553     }
1554   }
1555 


1614     case Type::AnyPtr:   tj = TypePtr::BOTTOM;      break;  // caller checks it
1615     default: ShouldNotReachHere();
1616     }
1617     break;
1618   case 2:                       // No collapsing at level 2; keep all splits
1619   case 3:                       // No collapsing at level 3; keep all splits
1620     break;
1621   default:
1622     Unimplemented();
1623   }
1624 
1625   offset = tj->offset();
1626   assert( offset != Type::OffsetTop, "Offset has fallen from constant" );
1627 
1628   assert( (offset != Type::OffsetBot && tj->base() != Type::AryPtr) ||
1629           (offset == Type::OffsetBot && tj->base() == Type::AryPtr) ||
1630           (offset == Type::OffsetBot && tj == TypeOopPtr::BOTTOM) ||
1631           (offset == Type::OffsetBot && tj == TypePtr::BOTTOM) ||
1632           (offset == oopDesc::mark_offset_in_bytes() && tj->base() == Type::AryPtr) ||
1633           (offset == oopDesc::klass_offset_in_bytes() && tj->base() == Type::AryPtr) ||
1634           (offset == arrayOopDesc::length_offset_in_bytes() && tj->base() == Type::AryPtr) ||
1635           (BarrierSet::barrier_set()->barrier_set_c2()->verify_gc_alias_type(tj, offset)),
1636           "For oops, klasses, raw offset must be constant; for arrays the offset is never known" );
1637   assert( tj->ptr() != TypePtr::TopPTR &&
1638           tj->ptr() != TypePtr::AnyNull &&
1639           tj->ptr() != TypePtr::Null, "No imprecise addresses" );
1640 //    assert( tj->ptr() != TypePtr::Constant ||
1641 //            tj->base() == Type::RawPtr ||
1642 //            tj->base() == Type::KlassPtr, "No constant oop addresses" );
1643 
1644   return tj;
1645 }
1646 
1647 void Compile::AliasType::Init(int i, const TypePtr* at) {
1648   _index = i;
1649   _adr_type = at;
1650   _field = NULL;
1651   _element = NULL;
1652   _is_rewritable = true; // default
1653   const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL;
1654   if (atoop != NULL && atoop->is_known_instance()) {
1655     const TypeOopPtr *gt = atoop->cast_to_instance_id(TypeOopPtr::InstanceBot);


< prev index next >