src/share/vm/opto/memnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7118863 Cdiff src/share/vm/opto/memnode.cpp

src/share/vm/opto/memnode.cpp

Print this page

        

*** 1471,1493 **** // Helper to recognize certain Klass fields which are invariant across // some group of array types (e.g., int[] or all T[] where T < Object). const Type* LoadNode::load_array_final_field(const TypeKlassPtr *tkls, ciKlass* klass) const { ! if (tkls->offset() == Klass::modifier_flags_offset_in_bytes() + (int)sizeof(oopDesc)) { // The field is Klass::_modifier_flags. Return its (constant) value. // (Folds up the 2nd indirection in aClassConstant.getModifiers().) assert(this->Opcode() == Op_LoadI, "must load an int from _modifier_flags"); return TypeInt::make(klass->modifier_flags()); } ! if (tkls->offset() == Klass::access_flags_offset_in_bytes() + (int)sizeof(oopDesc)) { // The field is Klass::_access_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags"); return TypeInt::make(klass->access_flags()); } ! if (tkls->offset() == Klass::layout_helper_offset_in_bytes() + (int)sizeof(oopDesc)) { // The field is Klass::_layout_helper. Return its constant value if known. assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper"); return TypeInt::make(klass->layout_helper()); } --- 1471,1493 ---- // Helper to recognize certain Klass fields which are invariant across // some group of array types (e.g., int[] or all T[] where T < Object). const Type* LoadNode::load_array_final_field(const TypeKlassPtr *tkls, ciKlass* klass) const { ! if (tkls->offset() == Klass::modifier_flags_offset_in_bytes()) { // The field is Klass::_modifier_flags. Return its (constant) value. // (Folds up the 2nd indirection in aClassConstant.getModifiers().) assert(this->Opcode() == Op_LoadI, "must load an int from _modifier_flags"); return TypeInt::make(klass->modifier_flags()); } ! if (tkls->offset() == Klass::access_flags_offset_in_bytes()) { // The field is Klass::_access_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags"); return TypeInt::make(klass->access_flags()); } ! if (tkls->offset() == Klass::layout_helper_offset_in_bytes()) { // The field is Klass::_layout_helper. Return its constant value if known. assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper"); return TypeInt::make(klass->layout_helper()); }
*** 1634,1669 **** ciKlass* klass = tkls->klass(); if (klass->is_loaded() && tkls->klass_is_exact()) { // We are loading a field from a Klass metaobject whose identity // is known at compile time (the type is "exact" or "precise"). // Check for fields we know are maintained as constants by the VM. ! if (tkls->offset() == Klass::super_check_offset_offset_in_bytes() + (int)sizeof(oopDesc)) { // The field is Klass::_super_check_offset. Return its (constant) value. // (Folds up type checking code.) assert(Opcode() == Op_LoadI, "must load an int from _super_check_offset"); return TypeInt::make(klass->super_check_offset()); } // Compute index into primary_supers array ! juint depth = (tkls->offset() - (Klass::primary_supers_offset_in_bytes() + (int)sizeof(oopDesc))) / sizeof(klassOop); // Check for overflowing; use unsigned compare to handle the negative case. if( depth < ciKlass::primary_super_limit() ) { // The field is an element of Klass::_primary_supers. Return its (constant) value. // (Folds up type checking code.) assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers"); ciKlass *ss = klass->super_of_depth(depth); return ss ? TypeKlassPtr::make(ss) : TypePtr::NULL_PTR; } const Type* aift = load_array_final_field(tkls, klass); if (aift != NULL) return aift; ! if (tkls->offset() == in_bytes(arrayKlass::component_mirror_offset()) + (int)sizeof(oopDesc) && klass->is_array_klass()) { // The field is arrayKlass::_component_mirror. Return its (constant) value. // (Folds up aClassConstant.getComponentType, common in Arrays.copyOf.) assert(Opcode() == Op_LoadP, "must load an oop from _component_mirror"); return TypeInstPtr::make(klass->as_array_klass()->component_mirror()); } ! if (tkls->offset() == Klass::java_mirror_offset_in_bytes() + (int)sizeof(oopDesc)) { // The field is Klass::_java_mirror. Return its (constant) value. // (Folds up the 2nd indirection in anObjConstant.getClass().) assert(Opcode() == Op_LoadP, "must load an oop from _java_mirror"); return TypeInstPtr::make(klass->java_mirror()); } --- 1634,1669 ---- ciKlass* klass = tkls->klass(); if (klass->is_loaded() && tkls->klass_is_exact()) { // We are loading a field from a Klass metaobject whose identity // is known at compile time (the type is "exact" or "precise"). // Check for fields we know are maintained as constants by the VM. ! if (tkls->offset() == Klass::super_check_offset_offset_in_bytes()) { // The field is Klass::_super_check_offset. Return its (constant) value. // (Folds up type checking code.) assert(Opcode() == Op_LoadI, "must load an int from _super_check_offset"); return TypeInt::make(klass->super_check_offset()); } // Compute index into primary_supers array ! juint depth = (tkls->offset() - Klass::primary_supers_offset_in_bytes()) / sizeof(klassOop); // Check for overflowing; use unsigned compare to handle the negative case. if( depth < ciKlass::primary_super_limit() ) { // The field is an element of Klass::_primary_supers. Return its (constant) value. // (Folds up type checking code.) assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers"); ciKlass *ss = klass->super_of_depth(depth); return ss ? TypeKlassPtr::make(ss) : TypePtr::NULL_PTR; } const Type* aift = load_array_final_field(tkls, klass); if (aift != NULL) return aift; ! if (tkls->offset() == in_bytes(arrayKlass::component_mirror_offset()) && klass->is_array_klass()) { // The field is arrayKlass::_component_mirror. Return its (constant) value. // (Folds up aClassConstant.getComponentType, common in Arrays.copyOf.) assert(Opcode() == Op_LoadP, "must load an oop from _component_mirror"); return TypeInstPtr::make(klass->as_array_klass()->component_mirror()); } ! if (tkls->offset() == Klass::java_mirror_offset_in_bytes()) { // The field is Klass::_java_mirror. Return its (constant) value. // (Folds up the 2nd indirection in anObjConstant.getClass().) assert(Opcode() == Op_LoadP, "must load an oop from _java_mirror"); return TypeInstPtr::make(klass->java_mirror()); }
*** 1677,1687 **** while( inner->is_obj_array_klass() ) inner = inner->as_obj_array_klass()->base_element_type(); if( inner->is_instance_klass() && !inner->as_instance_klass()->flags().is_interface() ) { // Compute index into primary_supers array ! juint depth = (tkls->offset() - (Klass::primary_supers_offset_in_bytes() + (int)sizeof(oopDesc))) / sizeof(klassOop); // Check for overflowing; use unsigned compare to handle the negative case. if( depth < ciKlass::primary_super_limit() && depth <= klass->super_depth() ) { // allow self-depth checks to handle self-check case // The field is an element of Klass::_primary_supers. Return its (constant) value. // (Folds up type checking code.) --- 1677,1687 ---- while( inner->is_obj_array_klass() ) inner = inner->as_obj_array_klass()->base_element_type(); if( inner->is_instance_klass() && !inner->as_instance_klass()->flags().is_interface() ) { // Compute index into primary_supers array ! juint depth = (tkls->offset() - Klass::primary_supers_offset_in_bytes()) / sizeof(klassOop); // Check for overflowing; use unsigned compare to handle the negative case. if( depth < ciKlass::primary_super_limit() && depth <= klass->super_depth() ) { // allow self-depth checks to handle self-check case // The field is an element of Klass::_primary_supers. Return its (constant) value. // (Folds up type checking code.)
*** 1693,1703 **** } // If the type is enough to determine that the thing is not an array, // we can give the layout_helper a positive interval type. // This will help short-circuit some reflective code. ! if (tkls->offset() == Klass::layout_helper_offset_in_bytes() + (int)sizeof(oopDesc) && !klass->is_array_klass() // not directly typed as an array && !klass->is_interface() // specifically not Serializable & Cloneable && !klass->is_java_lang_Object() // not the supertype of all T[] ) { // Note: When interfaces are reliable, we can narrow the interface --- 1693,1703 ---- } // If the type is enough to determine that the thing is not an array, // we can give the layout_helper a positive interval type. // This will help short-circuit some reflective code. ! if (tkls->offset() == Klass::layout_helper_offset_in_bytes() && !klass->is_array_klass() // not directly typed as an array && !klass->is_interface() // specifically not Serializable & Cloneable && !klass->is_java_lang_Object() // not the supertype of all T[] ) { // Note: When interfaces are reliable, we can narrow the interface
*** 1936,1957 **** if (tkls != NULL && !StressReflectiveCode) { ciKlass* klass = tkls->klass(); if( !klass->is_loaded() ) return _type; // Bail out if not loaded if( klass->is_obj_array_klass() && ! (uint)tkls->offset() == objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)) { ciKlass* elem = klass->as_obj_array_klass()->element_klass(); // // Always returning precise element type is incorrect, // // e.g., element type could be object and array may contain strings // return TypeKlassPtr::make(TypePtr::Constant, elem, 0); // The array's TypeKlassPtr was declared 'precise' or 'not precise' // according to the element type's subclassing. return TypeKlassPtr::make(tkls->ptr(), elem, 0/*offset*/); } if( klass->is_instance_klass() && tkls->klass_is_exact() && ! (uint)tkls->offset() == Klass::super_offset_in_bytes() + sizeof(oopDesc)) { ciKlass* sup = klass->as_instance_klass()->super(); // The field is Klass::_super. Return its (constant) value. // (Folds up the 2nd indirection in aClassConstant.getSuperClass().) return sup ? TypeKlassPtr::make(sup) : TypePtr::NULL_PTR; } --- 1936,1957 ---- if (tkls != NULL && !StressReflectiveCode) { ciKlass* klass = tkls->klass(); if( !klass->is_loaded() ) return _type; // Bail out if not loaded if( klass->is_obj_array_klass() && ! tkls->offset() == objArrayKlass::element_klass_offset_in_bytes()) { ciKlass* elem = klass->as_obj_array_klass()->element_klass(); // // Always returning precise element type is incorrect, // // e.g., element type could be object and array may contain strings // return TypeKlassPtr::make(TypePtr::Constant, elem, 0); // The array's TypeKlassPtr was declared 'precise' or 'not precise' // according to the element type's subclassing. return TypeKlassPtr::make(tkls->ptr(), elem, 0/*offset*/); } if( klass->is_instance_klass() && tkls->klass_is_exact() && ! tkls->offset() == Klass::super_offset_in_bytes()) { ciKlass* sup = klass->as_instance_klass()->super(); // The field is Klass::_super. Return its (constant) value. // (Folds up the 2nd indirection in aClassConstant.getSuperClass().) return sup ? TypeKlassPtr::make(sup) : TypePtr::NULL_PTR; }
*** 2015,2025 **** ) { int mirror_field = Klass::java_mirror_offset_in_bytes(); if (offset == java_lang_Class::array_klass_offset_in_bytes()) { mirror_field = in_bytes(arrayKlass::component_mirror_offset()); } ! if (tkls->offset() == mirror_field + (int)sizeof(oopDesc)) { return adr2->in(AddPNode::Base); } } } } --- 2015,2025 ---- ) { int mirror_field = Klass::java_mirror_offset_in_bytes(); if (offset == java_lang_Class::array_klass_offset_in_bytes()) { mirror_field = in_bytes(arrayKlass::component_mirror_offset()); } ! if (tkls->offset() == mirror_field) { return adr2->in(AddPNode::Base); } } } }
src/share/vm/opto/memnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File