< prev index next >
src/hotspot/share/opto/compile.cpp
Print this page
*** 1578,1606 ****
if (to->klass() != ciEnv::current()->Class_klass() ||
offset < k->size_helper() * wordSize) {
// No constant oop pointers (such as Strings); they alias with
// unknown strings.
assert(!is_known_inst, "not scalarizable allocation");
! tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,Type::Offset(offset));
}
} else if( is_known_inst ) {
tj = to; // Keep NotNull and klass_is_exact for instance type
} else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
// During the 2nd round of IterGVN, NotNull castings are removed.
// Make sure the Bottom and NotNull variants alias the same.
// Also, make sure exact and non-exact variants alias the same.
! tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,Type::Offset(offset));
}
if (to->speculative() != NULL) {
! tj = to = TypeInstPtr::make(to->ptr(),to->klass(),to->klass_is_exact(),to->const_oop(),Type::Offset(to->offset()), to->instance_id());
}
// Canonicalize the holder of this field
if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
// First handle header references such as a LoadKlassNode, even if the
// object's klass is unloaded at compile time (4965979).
if (!is_known_inst) { // Do it only for non-instance types
! tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, Type::Offset(offset));
}
} else if (BarrierSet::barrier_set()->barrier_set_c2()->flatten_gc_alias_type(tj)) {
to = tj->is_instptr();
} else if (offset < 0 || offset >= k->size_helper() * wordSize) {
// Static fields are in the space above the normal instance
--- 1578,1606 ----
if (to->klass() != ciEnv::current()->Class_klass() ||
offset < k->size_helper() * wordSize) {
// No constant oop pointers (such as Strings); they alias with
// unknown strings.
assert(!is_known_inst, "not scalarizable allocation");
! tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,Type::Offset(offset), to->klass()->flatten_array());
}
} else if( is_known_inst ) {
tj = to; // Keep NotNull and klass_is_exact for instance type
} else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
// During the 2nd round of IterGVN, NotNull castings are removed.
// Make sure the Bottom and NotNull variants alias the same.
// Also, make sure exact and non-exact variants alias the same.
! tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,Type::Offset(offset), to->klass()->flatten_array());
}
if (to->speculative() != NULL) {
! tj = to = TypeInstPtr::make(to->ptr(),to->klass(),to->klass_is_exact(),to->const_oop(),Type::Offset(to->offset()), to->klass()->flatten_array(), to->instance_id());
}
// Canonicalize the holder of this field
if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
// First handle header references such as a LoadKlassNode, even if the
// object's klass is unloaded at compile time (4965979).
if (!is_known_inst) { // Do it only for non-instance types
! tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, Type::Offset(offset), false);
}
} else if (BarrierSet::barrier_set()->barrier_set_c2()->flatten_gc_alias_type(tj)) {
to = tj->is_instptr();
} else if (offset < 0 || offset >= k->size_helper() * wordSize) {
// Static fields are in the space above the normal instance
*** 1612,1624 ****
}
} else {
ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
if (!k->equals(canonical_holder) || tj->offset() != offset) {
if( is_known_inst ) {
! tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, Type::Offset(offset), to->instance_id());
} else {
! tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, Type::Offset(offset));
}
}
}
}
--- 1612,1624 ----
}
} else {
ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
if (!k->equals(canonical_holder) || tj->offset() != offset) {
if( is_known_inst ) {
! tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, Type::Offset(offset), canonical_holder->flatten_array(), to->instance_id());
} else {
! tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, Type::Offset(offset), canonical_holder->flatten_array());
}
}
}
}
*** 1631,1649 ****
// use NotNull as the PTR.
if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) {
tj = tk = TypeKlassPtr::make(TypePtr::NotNull,
TypeKlassPtr::OBJECT->klass(),
! Type::Offset(offset));
}
ciKlass* klass = tk->klass();
if (klass != NULL && klass->is_obj_array_klass()) {
ciKlass* k = TypeAryPtr::OOPS->klass();
if( !k || !k->is_loaded() ) // Only fails for some -Xcomp runs
k = TypeInstPtr::BOTTOM->klass();
! tj = tk = TypeKlassPtr::make(TypePtr::NotNull, k, Type::Offset(offset));
}
// Check for precise loads from the primary supertype array and force them
// to the supertype cache alias index. Check for generic array loads from
// the primary supertype array and also force them to the supertype cache
--- 1631,1650 ----
// use NotNull as the PTR.
if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) {
tj = tk = TypeKlassPtr::make(TypePtr::NotNull,
TypeKlassPtr::OBJECT->klass(),
! Type::Offset(offset),
! false);
}
ciKlass* klass = tk->klass();
if (klass != NULL && klass->is_obj_array_klass()) {
ciKlass* k = TypeAryPtr::OOPS->klass();
if( !k || !k->is_loaded() ) // Only fails for some -Xcomp runs
k = TypeInstPtr::BOTTOM->klass();
! tj = tk = TypeKlassPtr::make(TypePtr::NotNull, k, Type::Offset(offset), false);
}
// Check for precise loads from the primary supertype array and force them
// to the supertype cache alias index. Check for generic array loads from
// the primary supertype array and also force them to the supertype cache
*** 1655,1665 ****
if (offset == Type::OffsetBot ||
(offset >= primary_supers_offset &&
offset < (int)(primary_supers_offset + Klass::primary_super_limit() * wordSize)) ||
offset == (int)in_bytes(Klass::secondary_super_cache_offset())) {
offset = in_bytes(Klass::secondary_super_cache_offset());
! tj = tk = TypeKlassPtr::make(TypePtr::NotNull, tk->klass(), Type::Offset(offset));
}
}
// Flatten all Raw pointers together.
if (tj->base() == Type::RawPtr)
--- 1656,1666 ----
if (offset == Type::OffsetBot ||
(offset >= primary_supers_offset &&
offset < (int)(primary_supers_offset + Klass::primary_super_limit() * wordSize)) ||
offset == (int)in_bytes(Klass::secondary_super_cache_offset())) {
offset = in_bytes(Klass::secondary_super_cache_offset());
! tj = tk = TypeKlassPtr::make(TypePtr::NotNull, tk->klass(), Type::Offset(offset), tk->flatten_array());
}
}
// Flatten all Raw pointers together.
if (tj->base() == Type::RawPtr)
*** 3435,3447 ****
}
#endif
if (EnableValhalla && (nop == Op_LoadKlass || nop == Op_LoadNKlass)) {
const TypeKlassPtr* tk = n->bottom_type()->make_ptr()->is_klassptr();
assert(!tk->klass_is_exact(), "should have been folded");
! if (tk->klass()->can_be_value_array_klass()) {
// Array load klass needs to filter out property bits (but not
! // GetNullFreePropertyNode which needs to extract the null free bits)
uint last = unique();
Node* pointer = NULL;
if (nop == Op_LoadKlass) {
Node* cast = new CastP2XNode(NULL, n);
Node* masked = new LShiftXNode(cast, new ConINode(TypeInt::make(oopDesc::storage_props_nof_bits)));
--- 3436,3449 ----
}
#endif
if (EnableValhalla && (nop == Op_LoadKlass || nop == Op_LoadNKlass)) {
const TypeKlassPtr* tk = n->bottom_type()->make_ptr()->is_klassptr();
assert(!tk->klass_is_exact(), "should have been folded");
! if (tk->klass()->can_be_value_array_klass() && n->as_Mem()->adr_type()->offset() == oopDesc::klass_offset_in_bytes()) {
// Array load klass needs to filter out property bits (but not
! // GetNullFreePropertyNode or GetFlattenedPropertyNode which
! // needs to extract the storage property bits)
uint last = unique();
Node* pointer = NULL;
if (nop == Op_LoadKlass) {
Node* cast = new CastP2XNode(NULL, n);
Node* masked = new LShiftXNode(cast, new ConINode(TypeInt::make(oopDesc::storage_props_nof_bits)));
*** 3453,3463 ****
Node* masked = new AndINode(cast, new ConINode(TypeInt::make(oopDesc::compressed_klass_mask())));
pointer = new CastI2NNode(masked, n->bottom_type());
}
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
Node* u = n->fast_out(i);
! if (u->_idx < last && u->Opcode() != Op_GetNullFreeProperty) {
// If user is a comparison with a klass that can't be a value type
// array klass, we don't need to clear the storage property bits.
Node* cmp = (u->is_DecodeNKlass() && u->outcnt() == 1) ? u->unique_out() : u;
if (cmp->is_Cmp()) {
const TypeKlassPtr* kp1 = cmp->in(1)->bottom_type()->make_ptr()->isa_klassptr();
--- 3455,3465 ----
Node* masked = new AndINode(cast, new ConINode(TypeInt::make(oopDesc::compressed_klass_mask())));
pointer = new CastI2NNode(masked, n->bottom_type());
}
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
Node* u = n->fast_out(i);
! if (u->_idx < last && u->Opcode() != Op_GetNullFreeProperty && u->Opcode() != Op_GetFlattenedProperty) {
// If user is a comparison with a klass that can't be a value type
// array klass, we don't need to clear the storage property bits.
Node* cmp = (u->is_DecodeNKlass() && u->outcnt() == 1) ? u->unique_out() : u;
if (cmp->is_Cmp()) {
const TypeKlassPtr* kp1 = cmp->in(1)->bottom_type()->make_ptr()->isa_klassptr();
*** 3993,4015 ****
n->dump(-1);
assert(false, "value type node was not removed");
break;
}
#endif
! case Op_GetNullFreeProperty: {
// Extract the null free bits
uint last = unique();
Node* null_free = NULL;
if (n->in(1)->Opcode() == Op_LoadKlass) {
Node* cast = new CastP2XNode(NULL, n->in(1));
! null_free = new AndLNode(cast, new ConLNode(TypeLong::make(((jlong)1)<<(oopDesc::wide_storage_props_shift + ArrayStorageProperties::null_free_bit))));
} else {
assert(n->in(1)->Opcode() == Op_LoadNKlass, "not a compressed klass?");
Node* cast = new CastN2INode(n->in(1));
! null_free = new AndINode(cast, new ConINode(TypeInt::make(1<<(oopDesc::narrow_storage_props_shift + ArrayStorageProperties::null_free_bit))));
}
! n->replace_by(null_free);
break;
}
default:
assert(!n->is_Call(), "");
assert(!n->is_Mem(), "");
--- 3995,4019 ----
n->dump(-1);
assert(false, "value type node was not removed");
break;
}
#endif
! case Op_GetNullFreeProperty:
! case Op_GetFlattenedProperty: {
// Extract the null free bits
uint last = unique();
Node* null_free = NULL;
+ int bit = nop == Op_GetNullFreeProperty ? ArrayStorageProperties::null_free_bit : ArrayStorageProperties::flattened_bit;
if (n->in(1)->Opcode() == Op_LoadKlass) {
Node* cast = new CastP2XNode(NULL, n->in(1));
! null_free = new AndLNode(cast, new ConLNode(TypeLong::make(((jlong)1)<<(oopDesc::wide_storage_props_shift + bit))));
} else {
assert(n->in(1)->Opcode() == Op_LoadNKlass, "not a compressed klass?");
Node* cast = new CastN2INode(n->in(1));
! null_free = new AndINode(cast, new ConINode(TypeInt::make(1<<(oopDesc::narrow_storage_props_shift + bit))));
}
! n->subsume_by(null_free, this);
break;
}
default:
assert(!n->is_Call(), "");
assert(!n->is_Mem(), "");
< prev index next >