src/share/vm/opto/subnode.cpp

changeset 3834
8f6ce6f1049b
parent 3787
6759698e3140
child 3910
ae9241bbce4a
     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())

mercurial