< prev index next >
src/hotspot/share/opto/memnode.cpp
Print this page
*** 1769,1778 ****
--- 1769,1795 ----
// also allow array-loading from the primary supertype
// array during subtype checks
Opcode() == Op_LoadKlass,
"Field accesses must be precise" );
// For klass/static loads, we expect the _type to be precise
+ } else if (tp->base() == Type::RawPtr && adr->is_Load() && off == 0) {
+ /* With mirrors being an indirect in the Klass*
+ * the VM is now using two load. LoadKlass(LoadP(LoadP(Klass, mirror_offset), zero_offset))
+ * The LoadP from the Klass has a RawPtr type (see LibraryCallKit::load_mirror_from_klass).
+ *
+ * So check the type and klass of the node before the LoadP
+ */
+ Node* adr2 = adr->in(MemNode::Address);
+ const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
+ if (tkls != NULL && !StressReflectiveCode) {
+ ciKlass* klass = tkls->klass();
+ if (klass->is_loaded() && tkls->klass_is_exact() && tkls->offset() == in_bytes(Klass::java_mirror_offset())) {
+ assert(adr->Opcode() == Op_LoadP, "must load an oop from _java_mirror");
+ assert(Opcode() == Op_LoadP, "must load an oop from _java_mirror");
+ return TypeInstPtr::make(klass->java_mirror());
+ }
+ }
}
const TypeKlassPtr *tkls = tp->isa_klassptr();
if (tkls != NULL && !StressReflectiveCode) {
ciKlass* klass = tkls->klass();
*** 1796,1811 ****
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(Klass::java_mirror_offset())) {
- // 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());
- }
}
// We can still check if we are loading from the primary_supers array at a
// shallow enough depth. Even though the klass is not exact, entries less
// than or equal to its super depth are correct.
--- 1813,1822 ----
*** 2201,2217 ****
// Java Example: x.getClass().isAssignableFrom(y)
//
// This improves reflective code, often making the Class
// mirror go completely dead. (Current exception: Class
// mirrors may appear in debug info, but we could clean them out by
! // introducing a new debug info operator for Klass*.java_mirror).
if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
&& offset == java_lang_Class::klass_offset_in_bytes()) {
- // We are loading a special hidden field from a Class mirror,
- // the field which points to its Klass or ArrayKlass metaobject.
if (base->is_Load()) {
! Node* adr2 = base->in(MemNode::Address);
const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
if (tkls != NULL && !tkls->empty()
&& (tkls->klass()->is_instance_klass() ||
tkls->klass()->is_array_klass())
&& adr2->is_AddP()
--- 2212,2229 ----
// Java Example: x.getClass().isAssignableFrom(y)
//
// This improves reflective code, often making the Class
// mirror go completely dead. (Current exception: Class
// mirrors may appear in debug info, but we could clean them out by
! // introducing a new debug info operator for Klass.java_mirror).
!
if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
&& offset == java_lang_Class::klass_offset_in_bytes()) {
if (base->is_Load()) {
! Node* base2 = base->in(MemNode::Address);
! if (base2->is_Load()) { /* direct load of a load which is the oophandle */
! Node* adr2 = base2->in(MemNode::Address);
const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
if (tkls != NULL && !tkls->empty()
&& (tkls->klass()->is_instance_klass() ||
tkls->klass()->is_array_klass())
&& adr2->is_AddP()
*** 2221,2230 ****
--- 2233,2243 ----
return adr2->in(AddPNode::Base);
}
}
}
}
+ }
return this;
}
< prev index next >