1.1 --- a/src/share/vm/opto/subnode.cpp Thu May 24 18:39:44 2012 -0700 1.2 +++ b/src/share/vm/opto/subnode.cpp Fri May 25 07:53:11 2012 -0700 1.3 @@ -702,12 +702,84 @@ 1.4 return TypeInt::CC; 1.5 } 1.6 1.7 +static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) { 1.8 + // Return the klass node for 1.9 + // LoadP(AddP(foo:Klass, #java_mirror)) 1.10 + // or NULL if not matching. 1.11 + if (n->Opcode() != Op_LoadP) return NULL; 1.12 + 1.13 + const TypeInstPtr* tp = phase->type(n)->isa_instptr(); 1.14 + if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL; 1.15 + 1.16 + Node* adr = n->in(MemNode::Address); 1.17 + intptr_t off = 0; 1.18 + Node* k = AddPNode::Ideal_base_and_offset(adr, phase, off); 1.19 + if (k == NULL) return NULL; 1.20 + const TypeKlassPtr* tkp = phase->type(k)->isa_klassptr(); 1.21 + if (!tkp || off != in_bytes(Klass::java_mirror_offset())) return NULL; 1.22 + 1.23 + // We've found the klass node of a Java mirror load. 1.24 + return k; 1.25 +} 1.26 + 1.27 +static inline Node* isa_const_java_mirror(PhaseGVN* phase, Node* n) { 1.28 + // for ConP(Foo.class) return ConP(Foo.klass) 1.29 + // otherwise return NULL 1.30 + if (!n->is_Con()) return NULL; 1.31 + 1.32 + const TypeInstPtr* tp = phase->type(n)->isa_instptr(); 1.33 + if (!tp) return NULL; 1.34 + 1.35 + ciType* mirror_type = tp->java_mirror_type(); 1.36 + // TypeInstPtr::java_mirror_type() returns non-NULL for compile- 1.37 + // time Class constants only. 1.38 + if (!mirror_type) return NULL; 1.39 + 1.40 + // x.getClass() == int.class can never be true (for all primitive types) 1.41 + // Return a ConP(NULL) node for this case. 1.42 + if (mirror_type->is_classless()) { 1.43 + return phase->makecon(TypePtr::NULL_PTR); 1.44 + } 1.45 + 1.46 + // return the ConP(Foo.klass) 1.47 + assert(mirror_type->is_klass(), "mirror_type should represent a klassOop"); 1.48 + return phase->makecon(TypeKlassPtr::make(mirror_type->as_klass())); 1.49 +} 1.50 + 1.51 //------------------------------Ideal------------------------------------------ 1.52 -// Check for the case of comparing an unknown klass loaded from the primary 1.53 +// Normalize comparisons between Java mirror loads to compare the klass instead. 1.54 +// 1.55 +// Also check for the case of comparing an unknown klass loaded from the primary 1.56 // super-type array vs a known klass with no subtypes. This amounts to 1.57 // checking to see an unknown klass subtypes a known klass with no subtypes; 1.58 // this only happens on an exact match. We can shorten this test by 1 load. 1.59 Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { 1.60 + // Normalize comparisons between Java mirrors into comparisons of the low- 1.61 + // level klass, where a dependent load could be shortened. 1.62 + // 1.63 + // The new pattern has a nice effect of matching the same pattern used in the 1.64 + // fast path of instanceof/checkcast/Class.isInstance(), which allows 1.65 + // redundant exact type check be optimized away by GVN. 1.66 + // For example, in 1.67 + // if (x.getClass() == Foo.class) { 1.68 + // Foo foo = (Foo) x; 1.69 + // // ... use a ... 1.70 + // } 1.71 + // a CmpPNode could be shared between if_acmpne and checkcast 1.72 + { 1.73 + Node* k1 = isa_java_mirror_load(phase, in(1)); 1.74 + Node* k2 = isa_java_mirror_load(phase, in(2)); 1.75 + Node* conk2 = isa_const_java_mirror(phase, in(2)); 1.76 + 1.77 + if (k1 && (k2 || conk2)) { 1.78 + Node* lhs = k1; 1.79 + Node* rhs = (k2 != NULL) ? k2 : conk2; 1.80 + this->set_req(1, lhs); 1.81 + this->set_req(2, rhs); 1.82 + return this; 1.83 + } 1.84 + } 1.85 + 1.86 // Constant pointer on right? 1.87 const TypeKlassPtr* t2 = phase->type(in(2))->isa_klassptr(); 1.88 if (t2 == NULL || !t2->klass_is_exact())