hotspot/src/share/vm/opto/memnode.cpp
changeset 590 2954744d7bba
parent 589 a44a1e70a3e4
child 594 9f4474e5dbaf
--- a/hotspot/src/share/vm/opto/memnode.cpp	Wed May 21 10:45:07 2008 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Wed May 21 13:46:23 2008 -0700
@@ -671,11 +671,13 @@
       case Op_LoadP:            // Loading from within a klass
       case Op_LoadN:            // Loading from within a klass
       case Op_LoadKlass:        // Loading from within a klass
+      case Op_LoadNKlass:       // Loading from within a klass
       case Op_ConP:             // Loading from a klass
       case Op_ConN:             // Loading from a klass
       case Op_CreateEx:         // Sucking up the guts of an exception oop
       case Op_Con:              // Reading from TLS
       case Op_CMoveP:           // CMoveP is pinned
+      case Op_CMoveN:           // CMoveN is pinned
         break;                  // No progress
 
       case Op_Proj:             // Direct call to an allocation routine
@@ -1610,8 +1612,35 @@
 }
 
 //=============================================================================
+//----------------------------LoadKlassNode::make------------------------------
+// Polymorphic factory method:
+Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) {
+  Compile* C = gvn.C;
+  Node *ctl = NULL;
+  // sanity check the alias category against the created node type
+  const TypeOopPtr *adr_type = adr->bottom_type()->isa_oopptr();
+  assert(adr_type != NULL, "expecting TypeOopPtr");
+#ifdef _LP64
+  if (adr_type->is_ptr_to_narrowoop()) {
+    const TypeNarrowOop* narrowtype = tk->is_oopptr()->make_narrowoop();
+    Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, narrowtype));
+    return DecodeNNode::decode(&gvn, load_klass);
+  } else
+#endif
+  {
+    assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
+    return new (C, 3) LoadKlassNode(ctl, mem, adr, at, tk);
+  }
+  ShouldNotReachHere();
+  return (LoadKlassNode*)NULL;
+}
+
 //------------------------------Value------------------------------------------
 const Type *LoadKlassNode::Value( PhaseTransform *phase ) const {
+  return klass_value_common(phase);
+}
+
+const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const {
   // Either input is TOP ==> the result is TOP
   const Type *t1 = phase->type( in(MemNode::Memory) );
   if (t1 == Type::TOP)  return Type::TOP;
@@ -1743,6 +1772,10 @@
 // To clean up reflective code, simplify k.java_mirror.as_klass to plain k.
 // Also feed through the klass in Allocate(...klass...)._klass.
 Node* LoadKlassNode::Identity( PhaseTransform *phase ) {
+  return klass_identity_common(phase);
+}
+
+Node* LoadNode::klass_identity_common(PhaseTransform *phase ) {
   Node* x = LoadNode::Identity(phase);
   if (x != this)  return x;
 
@@ -1801,6 +1834,34 @@
   return this;
 }
 
+
+//------------------------------Value------------------------------------------
+const Type *LoadNKlassNode::Value( PhaseTransform *phase ) const {
+  const Type *t = klass_value_common(phase);
+
+  if (t == TypePtr::NULL_PTR) {
+    return TypeNarrowOop::NULL_PTR;
+  }
+  if (t != Type::TOP && !t->isa_narrowoop()) {
+    assert(t->is_oopptr(), "sanity");
+    t = t->is_oopptr()->make_narrowoop();
+  }
+  return t;
+}
+
+//------------------------------Identity---------------------------------------
+// To clean up reflective code, simplify k.java_mirror.as_klass to narrow k.
+// Also feed through the klass in Allocate(...klass...)._klass.
+Node* LoadNKlassNode::Identity( PhaseTransform *phase ) {
+  Node *x = klass_identity_common(phase);
+
+  const Type *t = phase->type( x );
+  if( t == Type::TOP ) return x;
+  if( t->isa_narrowoop()) return x;
+
+  return EncodePNode::encode(phase, x);
+}
+
 //------------------------------Value-----------------------------------------
 const Type *LoadRangeNode::Value( PhaseTransform *phase ) const {
   // Either input is TOP ==> the result is TOP