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