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