7031614: jmap -permstat fails with java.lang.InternalError in sun.jvm.hotspot.oops.OopField.getValue
authornever
Wed, 30 Mar 2011 07:47:19 -0700
changeset 8878 a6283814032c
parent 8877 bca1a5b8df1c
child 8879 e6ae9a7aa72a
child 8880 77bf0208d131
7031614: jmap -permstat fails with java.lang.InternalError in sun.jvm.hotspot.oops.OopField.getValue Reviewed-by: kvn, dcubed
hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ClassObjectReferenceImpl.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Instance.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceMirrorKlass.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/java_lang_Class.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java
hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaFactoryImpl.java
hotspot/src/share/vm/oops/instanceMirrorKlass.hpp
hotspot/src/share/vm/runtime/vmStructs.cpp
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ClassObjectReferenceImpl.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ClassObjectReferenceImpl.java	Wed Mar 30 07:47:19 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
 import com.sun.jdi.*;
 import sun.jvm.hotspot.oops.Instance;
 import sun.jvm.hotspot.oops.Klass;
-import sun.jvm.hotspot.oops.OopUtilities;
+import sun.jvm.hotspot.oops.java_lang_Class;
 
 public class ClassObjectReferenceImpl extends ObjectReferenceImpl
                                       implements ClassObjectReference {
@@ -39,7 +39,7 @@
 
     public ReferenceType reflectedType() {
         if (reflectedType == null) {
-            Klass k = OopUtilities.classOopToKlass(ref());
+            Klass k = java_lang_Class.asKlass(ref());
             reflectedType = vm.referenceType(k);
         }
         return reflectedType;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Instance.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Instance.java	Wed Mar 30 07:47:19 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,7 +64,7 @@
 
   public void iterateFields(OopVisitor visitor, boolean doVMFields) {
     super.iterateFields(visitor, doVMFields);
-    ((InstanceKlass) getKlass()).iterateNonStaticFields(visitor);
+    ((InstanceKlass) getKlass()).iterateNonStaticFields(visitor, this);
   }
 
   public void printValueOn(PrintStream tty) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Wed Mar 30 07:47:19 2011 -0700
@@ -241,6 +241,10 @@
   // Byteside of the header
   private static long headerSize;
 
+  public long getObjectSize(Oop object) {
+    return getSizeHelper() * VM.getVM().getAddressSize();
+  }
+
   public static long getHeaderSize() { return headerSize; }
 
   // Accessors for declared fields
@@ -459,7 +463,22 @@
       visitor.doCInt(vtableLen, true);
       visitor.doCInt(itableLen, true);
     }
+  }
 
+  /*
+   *  Visit the static fields of this InstanceKlass with the obj of
+   *  the visitor set to the oop holding the fields, which is
+   *  currently the java mirror.
+   */
+  public void iterateStaticFields(OopVisitor visitor) {
+    visitor.setObj(getJavaMirror());
+    visitor.prologue();
+    iterateStaticFieldsInternal(visitor);
+    visitor.epilogue();
+
+  }
+
+  void iterateStaticFieldsInternal(OopVisitor visitor) {
     TypeArray fields = getFields();
     int length = (int) fields.getLength();
     for (int index = 0; index < length; index += NEXT_OFFSET) {
@@ -477,9 +496,9 @@
     return getSuper();
   }
 
-  public void iterateNonStaticFields(OopVisitor visitor) {
+  public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
     if (getSuper() != null) {
-      ((InstanceKlass) getSuper()).iterateNonStaticFields(visitor);
+      ((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
     }
     TypeArray fields = getFields();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceMirrorKlass.java	Wed Mar 30 07:47:19 2011 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.memory.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+// An InstanceKlass is the VM level representation of a Java class.
+
+public class InstanceMirrorKlass extends InstanceKlass {
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+    // Just make sure it's there for now
+    Type type = db.lookupType("instanceMirrorKlass");
+  }
+
+  InstanceMirrorKlass(OopHandle handle, ObjectHeap heap) {
+    super(handle, heap);
+  }
+
+  public long getObjectSize(Oop o) {
+    return java_lang_Class.getOopSize(o) * VM.getVM().getAddressSize();
+  }
+
+  public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
+    super.iterateNonStaticFields(visitor, obj);
+    // Fetch the real klass from the mirror object
+    Klass klass = java_lang_Class.asKlass(obj);
+    if (klass instanceof InstanceKlass) {
+      ((InstanceKlass)klass).iterateStaticFields(visitor);
+    }
+  }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Wed Mar 30 07:47:19 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -362,7 +362,16 @@
         if (klass.equals(compiledICHolderKlassHandle))  return new CompiledICHolder(handle, this);
         if (klass.equals(methodDataKlassHandle))        return new MethodData(handle, this);
       }
-      if (klass.equals(instanceKlassKlassHandle))       return new InstanceKlass(handle, this);
+      if (klass.equals(instanceKlassKlassHandle)) {
+          InstanceKlass ik = new InstanceKlass(handle, this);
+          if (ik.getName().asString().equals("java/lang/Class")) {
+              // We would normally do this using the vtable style
+              // lookup but since it's not used for these currently
+              // it's simpler to just check for the name.
+              return new InstanceMirrorKlass(handle, this);
+          }
+          return ik;
+      }
       if (klass.equals(objArrayKlassKlassHandle))       return new ObjArrayKlass(handle, this);
       if (klass.equals(typeArrayKlassKlassHandle))      return new TypeArrayKlass(handle, this);
 
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java	Wed Mar 30 07:47:19 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -103,12 +103,8 @@
   // Returns the byte size of this object
   public long getObjectSize() {
     Klass k = getKlass();
-    if (k instanceof InstanceKlass) {
-        return ((InstanceKlass)k).getSizeHelper()
-            * VM.getVM().getAddressSize();
-    }
-    // If it is not an instance, this method should be replaced.
-    return getHeaderSize();
+    // All other types should be overriding getObjectSize directly
+    return ((InstanceKlass)k).getObjectSize(this);
   }
 
   // Type test operations
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Wed Mar 30 07:47:19 2011 -0700
@@ -74,9 +74,6 @@
     private static int THREAD_STATUS_TERMINATED;
   */
 
-  // java.lang.Class fields
-  private static OopField hcKlassField;
-
   // java.util.concurrent.locks.AbstractOwnableSynchronizer fields
   private static OopField absOwnSyncOwnerThreadField;
 
@@ -268,27 +265,6 @@
     return null;
   }
 
-  // initialize fields for java.lang.Class
-  private static void initClassFields() {
-    if (hcKlassField == null) {
-       // hc_klass is a HotSpot magic field and hence we can't
-       // find it from InstanceKlass for java.lang.Class.
-       TypeDataBase db = VM.getVM().getTypeDataBase();
-       int hcKlassOffset = (int) db.lookupType("java_lang_Class").getCIntegerField("klass_offset").getValue();
-       if (VM.getVM().isCompressedOopsEnabled()) {
-         hcKlassField = new NarrowOopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
-       } else {
-         hcKlassField = new OopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
-       }
-    }
-  }
-
-  /** get klassOop field at offset hc_klass_offset from a java.lang.Class object */
-  public static Klass classOopToKlass(Oop aClass) {
-    initClassFields();
-    return (Klass) hcKlassField.getValue(aClass);
-  }
-
   // initialize fields for j.u.c.l AbstractOwnableSynchornizer class
   private static void initAbsOwnSyncFields() {
     if (absOwnSyncOwnerThreadField == null) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/java_lang_Class.java	Wed Mar 30 07:47:19 2011 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.util.*;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.memory.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+import sun.jvm.hotspot.utilities.*;
+import sun.jvm.hotspot.jdi.JVMTIThreadState;
+
+/** A utility class encapsulating useful oop operations */
+
+// initialize fields for java.lang.Class
+public class java_lang_Class {
+
+  // java.lang.Class fields
+  static OopField klassField;
+  static IntField oopSizeField;
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static synchronized void initialize(TypeDataBase db) {
+    // klass and oop_size are HotSpot magic fields and hence we can't
+    // find them from InstanceKlass for java.lang.Class.
+    Type jlc = db.lookupType("java_lang_Class");
+    int klassOffset = (int) jlc.getCIntegerField("klass_offset").getValue();
+    if (VM.getVM().isCompressedOopsEnabled()) {
+      klassField = new NarrowOopField(new NamedFieldIdentifier("klass"), klassOffset, true);
+    } else {
+      klassField = new OopField(new NamedFieldIdentifier("klass"), klassOffset, true);
+    }
+    int oopSizeOffset = (int) jlc.getCIntegerField("oop_size_offset").getValue();
+    oopSizeField = new IntField(new NamedFieldIdentifier("oop_size"), oopSizeOffset, true);
+  }
+
+  /** get klassOop field at offset hc_klass_offset from a java.lang.Class object */
+  public static Klass asKlass(Oop aClass) {
+    return (Klass) java_lang_Class.klassField.getValue(aClass);
+  }
+
+  /** get oop_size field at offset oop_size_offset from a java.lang.Class object */
+  public static long getOopSize(Oop aClass) {
+    return java_lang_Class.oopSizeField.getValue(aClass);
+  }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Wed Mar 30 07:47:19 2011 -0700
@@ -839,20 +839,18 @@
   }
 
   private void readSystemProperties() {
-     final InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
-     systemKls.iterate(new DefaultOopVisitor() {
-                               ObjectReader objReader = new ObjectReader();
-                               public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) {
-                                  if (field.getID().getName().equals("props")) {
-                                     try {
-                                        sysProps = (Properties) objReader.readObject(field.getValue(systemKls.getJavaMirror()));
-                                     } catch (Exception e) {
-                                        if (Assert.ASSERTS_ENABLED) {
-                                           e.printStackTrace();
-                                        }
-                                     }
-                                  }
-                               }
-                        }, false);
+    final InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
+    systemKls.iterateStaticFields(new DefaultOopVisitor() {
+        ObjectReader objReader = new ObjectReader();
+        public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) {
+          if (field.getID().getName().equals("props")) {
+            try {
+              sysProps = (Properties) objReader.readObject(field.getValue(getObj()));
+            } catch (Exception e) {
+              e.printStackTrace();
+            }
+          }
+        }
+      });
   }
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java	Wed Mar 30 07:47:19 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,16 +64,16 @@
          */
         InstanceKlass ik =
             SystemDictionaryHelper.findInstanceKlass("java.lang.ref.Finalizer");
-        final OopField queueField[] = new OopField[1];
-        ik.iterateFields(new DefaultOopVisitor() {
+        final Oop[] queueref = new Oop[1];
+        ik.iterateStaticFields(new DefaultOopVisitor() {
             public void doOop(OopField field, boolean isVMField) {
-                String name = field.getID().getName();
-                if (name.equals("queue")) {
-                    queueField[0] = field;
-                }
+              String name = field.getID().getName();
+              if (name.equals("queue")) {
+                queueref[0] = field.getValue(getObj());
+              }
             }
-        }, false);
-        Oop queue = queueField[0].getValue(ik);
+          });
+        Oop queue = queueref[0];
 
         InstanceKlass k = (InstanceKlass) queue.getKlass();
 
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java	Wed Mar 30 07:47:19 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -164,7 +164,7 @@
 
     protected void writeClass(Instance instance) throws IOException  {
         writeObjectHeader(instance);
-        Klass reflectedType = OopUtilities.classOopToKlass(instance);
+        Klass reflectedType = java_lang_Class.asKlass(instance);
         boolean isInstanceKlass = (reflectedType instanceof InstanceKlass);
         // reflectedType is null for primitive types (int.class etc).
         if (reflectedType != null) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Wed Mar 30 07:47:19 2011 -0700
@@ -455,7 +455,7 @@
     }
 
     protected void writeClass(Instance instance) throws IOException {
-        Klass reflectedKlass = OopUtilities.classOopToKlass(instance);
+        Klass reflectedKlass = java_lang_Class.asKlass(instance);
         // dump instance record only for primitive type Class objects.
         // all other Class objects are covered by writeClassDumpRecords.
         if (reflectedKlass == null) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java	Wed Mar 30 07:47:19 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -117,10 +117,10 @@
         public boolean doObj(Oop obj) {
           if (obj instanceof InstanceKlass) {
             final InstanceKlass ik = (InstanceKlass) obj;
-            ik.iterateFields(
+            ik.iterateStaticFields(
                new DefaultOopVisitor() {
                    public void doOop(OopField field, boolean isVMField) {
-                     Oop next = field.getValue(ik);
+                     Oop next = field.getValue(getObj());
                      LivenessPathElement lp = new LivenessPathElement(null,
                              new NamedFieldIdentifier("Static field \"" +
                                                 field.getID().getName() +
@@ -142,8 +142,7 @@
                        System.err.println();
                      }
                    }
-                 },
-               false);
+                 });
           }
                   return false;
         }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaFactoryImpl.java	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaFactoryImpl.java	Wed Mar 30 07:47:19 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -158,7 +158,7 @@
       } else if (className.equals(javaLangThread())) {
          res = new JSJavaThread(instance, this);
       } else if (className.equals(javaLangClass())) {
-         Klass reflectedType = OopUtilities.classOopToKlass(instance);
+         Klass reflectedType = java_lang_Class.asKlass(instance);
          if (reflectedType != null) {
              JSJavaKlass jk = newJSJavaKlass(reflectedType);
              // we don't support mirrors of VM internal Klasses
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Wed Mar 30 07:47:19 2011 -0700
@@ -36,6 +36,8 @@
 
 
 class instanceMirrorKlass: public instanceKlass {
+  friend class VMStructs;
+
  private:
   static int _offset_of_static_fields;
 
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Mar 30 03:48:38 2011 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Mar 30 07:47:19 2011 -0700
@@ -70,6 +70,7 @@
 #include "oops/cpCacheKlass.hpp"
 #include "oops/cpCacheOop.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceKlassKlass.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/klass.hpp"
@@ -1101,6 +1102,7 @@
            declare_type(instanceKlass, Klass)                             \
            declare_type(instanceKlassKlass, klassKlass)                   \
            declare_type(instanceOopDesc, oopDesc)                         \
+           declare_type(instanceMirrorKlass, instanceKlass)               \
            declare_type(instanceRefKlass, instanceKlass)                  \
            declare_type(klassKlass, Klass)                                \
            declare_type(klassOopDesc, oopDesc)                            \