changeset 5326:a53162ca8219

introduced HotSpotKlassOop type to convey a klassOop value from the compiler to the C++ code instead of relying on the C++ code automagically converting a HotSpotTypeResolvedImpl value to a klassOop
author Doug Simon <doug.simon@oracle.com>
date Mon, 30 Apr 2012 20:15:20 +0200
parents f8ea2735ec4f
children 28577a53d3a7
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotKlassOop.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypePrimitive.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolved.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeUnresolved.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiType.java src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 12 files changed, 103 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotKlassOop.java	Mon Apr 30 20:15:20 2012 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 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 com.oracle.graal.hotspot.ri;
+
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.Compiler;
+
+/**
+ * A mechanism for safely conveying a HotSpot klassOop value from the compiler to the C++ code.
+ * Such values should not be directly exposed to Java code as they are not real Java
+ * objects. For instance, invoking a method on them or using them in an <code>instanceof</code>
+ * expression will most likely crash the VM.
+ */
+public class HotSpotKlassOop extends CompilerObject {
+
+    private static final long serialVersionUID = -5445542223575839143L;
+
+    /**
+     * The Java object from which the klassOop value can be derived (by the C++ code).
+     */
+    public final Class javaMirror;
+
+    HotSpotKlassOop(Compiler compiler, Class javaMirror) {
+        super(compiler);
+        this.javaMirror = javaMirror;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotType.java	Mon Apr 30 15:41:14 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotType.java	Mon Apr 30 20:15:20 2012 +0200
@@ -41,4 +41,10 @@
     public final String name() {
         return name;
     }
+
+    /**
+     * Gets the object representing the C++ klassOop for this type.
+     * Such a value cannot be safely exposed to Java code.
+     */
+    public abstract HotSpotKlassOop klassOop();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypePrimitive.java	Mon Apr 30 15:41:14 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypePrimitive.java	Mon Apr 30 20:15:20 2012 +0200
@@ -37,12 +37,13 @@
 
     private static final long serialVersionUID = -6208552348908071473L;
     private CiKind kind;
-
+    private final HotSpotKlassOop klassOop;
 
     public HotSpotTypePrimitive(Compiler compiler, CiKind kind) {
         super(compiler);
         this.kind = kind;
         this.name = String.valueOf(Character.toUpperCase(kind.typeChar));
+        this.klassOop = new HotSpotKlassOop(compiler, kind.toJavaClass());
     }
 
     @Override
@@ -175,4 +176,9 @@
     public RiResolvedType resolve(RiResolvedType accessingClass) {
         return this;
     }
+
+    @Override
+    public HotSpotKlassOop klassOop() {
+        return klassOop;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolved.java	Mon Apr 30 15:41:14 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolved.java	Mon Apr 30 20:15:20 2012 +0200
@@ -35,4 +35,5 @@
 
     RiField createRiField(String name, RiType type, int offset, int flags);
 
+    HotSpotKlassOop klassOop();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl.java	Mon Apr 30 15:41:14 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl.java	Mon Apr 30 20:15:20 2012 +0200
@@ -118,11 +118,9 @@
             case JavaClass:
                 return CiConstant.forObject(javaMirror);
             case ObjectHub:
-                return CiConstant.forObject(this);
+                return CiConstant.forObject(klassOop());
             case StaticFields:
                 return CiConstant.forObject(javaMirror);
-            case TypeInfo:
-                return CiConstant.forObject(this);
             default:
                 return null;
         }
@@ -220,7 +218,7 @@
 
         long id = offset + ((long) flags << 32);
 
-        // (thomaswue) Must cache the fields, because the local load elimination only works if the objects from two field lookups are equal.
+        // (thomaswue) Must cache the fields, because the local load elimination only works if the objects from two field lookups are identical.
         if (fieldCache == null) {
             fieldCache = new HashMap<>(8);
         } else {
@@ -265,4 +263,15 @@
     public RiResolvedType resolve(RiResolvedType accessingClass) {
         return this;
     }
+
+    // (dnsimon) this value may require identity semantics
+    private HotSpotKlassOop klassOopCache;
+
+    @Override
+    public synchronized HotSpotKlassOop klassOop() {
+        if (klassOopCache == null) {
+            klassOopCache = new HotSpotKlassOop(compiler, javaMirror);
+        }
+        return klassOopCache;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeUnresolved.java	Mon Apr 30 15:41:14 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeUnresolved.java	Mon Apr 30 20:15:20 2012 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.Compiler;
 
 /**
@@ -119,4 +120,9 @@
     public RiResolvedType resolve(RiResolvedType accessingClass) {
         return (RiResolvedType) compiler.lookupType(name, (HotSpotTypeResolved) accessingClass, true);
     }
+
+    @Override
+    public HotSpotKlassOop klassOop() {
+        throw GraalInternalError.shouldNotReachHere("HotSpotTypeUnresolved.klassOop");
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java	Mon Apr 30 15:41:14 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java	Mon Apr 30 20:15:20 2012 +0200
@@ -288,7 +288,7 @@
         @Override
         protected XirTemplate create(CiXirAssembler asm, long flags, int size) {
             XirOperand result = asm.restart(target.wordKind);
-            XirOperand type = asm.createInputParameter("type", CiKind.Object);
+            XirOperand hub = asm.createInputParameter("hub", CiKind.Object);
 
             XirOperand temp1 = asm.createRegisterTemp("temp1", target.wordKind, AMD64.rcx);
             XirOperand temp1o = asm.createRegister("temp1o", CiKind.Object, AMD64.rcx);
@@ -299,7 +299,7 @@
             XirLabel resume = asm.createInlineLabel("resume");
 
             // check if the class is already initialized
-            asm.pload(CiKind.Int, temp2i, type, asm.i(config.klassStateOffset), false);
+            asm.pload(CiKind.Int, temp2i, hub, asm.i(config.klassStateOffset), false);
             asm.jneq(tlabFull, temp2i, asm.i(config.klassStateFullyInitialized));
 
             XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
@@ -312,9 +312,9 @@
 
             asm.bindInline(resume);
 
-            asm.pload(target.wordKind, temp1, type, asm.i(config.instanceHeaderPrototypeOffset), false);
+            asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false);
             asm.pstore(target.wordKind, result, temp1, false);
-            asm.mov(temp1o, type); // need a temporary register since Intel cannot store 64-bit constants to memory
+            asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory
             asm.pstore(CiKind.Object, result, asm.i(config.hubOffset), temp1o, false);
 
             if (size > 2 * target.wordSize) {
@@ -327,7 +327,7 @@
             // -- out of line -------------------------------------------------------
             asm.bindOutOfLine(tlabFull);
             XirOperand arg = asm.createRegisterTemp("runtime call argument", CiKind.Object, AMD64.rdx);
-            asm.mov(arg, type);
+            asm.mov(arg, hub);
             useRegisters(asm, AMD64.rax);
             asm.callRuntime(config.newInstanceStub, result);
             asm.jmp(resume);
@@ -871,26 +871,27 @@
 
     @Override
     public XirSnippet genNewInstance(XirSite site, RiType type) {
-        int instanceSize = ((HotSpotTypeResolved) type).instanceSize();
-        return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(type));
+        HotSpotTypeResolved resolvedType = (HotSpotTypeResolved) type;
+        int instanceSize = resolvedType.instanceSize();
+        return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(resolvedType.klassOop()));
     }
 
     @Override
     public XirSnippet genNewArray(XirSite site, XirArgument length, CiKind elementKind, RiType componentType, RiType arrayType) {
         if (elementKind == CiKind.Object) {
             assert arrayType instanceof RiResolvedType;
-            return new XirSnippet(newObjectArrayTemplates.get(site), length, XirArgument.forObject(arrayType));
+            return new XirSnippet(newObjectArrayTemplates.get(site), length, XirArgument.forObject(((HotSpotType) arrayType).klassOop()));
         } else {
             assert arrayType == null;
             RiType primitiveArrayType = compiler.getCompilerToVM().getPrimitiveArrayType(elementKind);
-            return new XirSnippet(newTypeArrayTemplates.get(site, elementKind), length, XirArgument.forObject(primitiveArrayType));
+            return new XirSnippet(newTypeArrayTemplates.get(site, elementKind), length, XirArgument.forObject(((HotSpotType) primitiveArrayType).klassOop()));
         }
     }
 
     @Override
     public XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type) {
         XirArgument[] params = Arrays.copyOf(lengths, lengths.length + 1);
-        params[lengths.length] = XirArgument.forObject(type);
+        params[lengths.length] = XirArgument.forObject(((HotSpotType) type).klassOop());
         return new XirSnippet(multiNewArrayTemplate.get(site, lengths.length), params);
     }
 
@@ -906,9 +907,7 @@
                 params[i++] = hub;
             }
             for (RiResolvedType hint : hints) {
-                // The Graal C++ code auto-magically converts HotSpotTypeResolvedImpl into the corresponding klassOop.
-                // See CodeInstaller::site_DataPatch in graalCodeInstaller.cpp.
-                params[i++] = XirArgument.forObject(hint);
+                params[i++] = XirArgument.forObject(((HotSpotType) hint).klassOop());
             }
             XirTemplate template = hintsExact ? checkCastTemplates.get(site, hints.length, EXACT_HINTS) : checkCastTemplates.get(site, hints.length);
             return new XirSnippet(template, params);
@@ -927,9 +926,7 @@
                 params[i++] = hub;
             }
             for (RiResolvedType hint : hints) {
-                // The Graal C++ code auto-magically converts HotSpotTypeResolvedImpl into the corresponding klassOop.
-                // See CodeInstaller::site_DataPatch in graalCodeInstaller.cpp.
-                params[i++] = XirArgument.forObject(hint);
+                params[i++] = XirArgument.forObject(((HotSpotType) hint).klassOop());
             }
             XirTemplate template = hintsExact ? instanceOfTemplates.get(site, hints.length, EXACT_HINTS) : instanceOfTemplates.get(site, hints.length);
             return new XirSnippet(template, params);
@@ -950,9 +947,7 @@
             params[i++] = trueValue;
             params[i++] = falseValue;
             for (RiResolvedType hint : hints) {
-                // The Graal C++ code auto-magically converts HotSpotTypeResolvedImpl into the corresponding klassOop.
-                // See CodeInstaller::site_DataPatch in graalCodeInstaller.cpp.
-                params[i++] = XirArgument.forObject(hint);
+                params[i++] = XirArgument.forObject(((HotSpotType) hint).klassOop());
             }
             XirTemplate template = hintsExact ? materializeInstanceOfTemplates.get(site, hints.length, EXACT_HINTS) : materializeInstanceOfTemplates.get(site, hints.length);
             return new XirSnippet(template, params);
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiType.java	Mon Apr 30 15:41:14 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiType.java	Mon Apr 30 20:15:20 2012 +0200
@@ -50,13 +50,7 @@
          * The runtime representation of the "hub" of this type--that is, the closest part of the type
          * representation which is typically stored in the object header.
          */
-        ObjectHub,
-
-        /**
-         * The runtime representation of the type information for an object, which is typically used
-         * for subtype tests.
-         */
-        TypeInfo
+        ObjectHub
     }
 
     /**
--- a/src/share/vm/classfile/systemDictionary.hpp	Mon Apr 30 15:41:14 2012 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Apr 30 20:15:20 2012 +0200
@@ -189,6 +189,7 @@
                                                                                                                          \
   /* Support for Graal */                                                                                                \
   template(HotSpotTypeResolved_klass,             com_oracle_graal_hotspot_HotSpotTypeResolved,                 Opt) \
+  template(HotSpotKlassOop_klass,                 com_oracle_graal_hotspot_HotSpotKlassOop,                     Opt) \
   template(HotSpotType_klass,                     com_oracle_graal_hotspot_HotSpotType,                         Opt) \
   template(HotSpotField_klass,                    com_oracle_graal_hotspot_HotSpotField,                        Opt) \
   template(HotSpotCompiledMethod_klass,           com_oracle_graal_hotspot_HotSpotCompiledMethod,               Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Apr 30 15:41:14 2012 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Apr 30 20:15:20 2012 +0200
@@ -279,6 +279,7 @@
   template(com_oracle_graal_hotspot_HotSpotOptions,               "com/oracle/graal/hotspot/HotSpotOptions")                      \
   template(com_oracle_graal_hotspot_HotSpotTypeResolved,          "com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl")          \
   template(com_oracle_graal_hotspot_HotSpotType,                  "com/oracle/graal/hotspot/ri/HotSpotType")                      \
+  template(com_oracle_graal_hotspot_HotSpotKlassOop,              "com/oracle/graal/hotspot/ri/HotSpotKlassOop")                  \
   template(com_oracle_graal_hotspot_HotSpotExceptionHandler,      "com/oracle/graal/hotspot/ri/HotSpotExceptionHandler")          \
   template(com_oracle_graal_hotspot_HotSpotProxy,                 "com/oracle/graal/hotspot/HotSpotProxy")                        \
   template(com_oracle_graal_hotspot_Compiler,                     "com/oracle/graal/hotspot/Compiler")                            \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Apr 30 15:41:14 2012 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Apr 30 20:15:20 2012 +0200
@@ -743,8 +743,7 @@
     case 's':
     case 'c':
     case 'i':
-      fatal("int-sized values not expected in DataPatch")
-      ;
+      fatal("int-sized values not expected in DataPatch");
       break;
     case 'f':
     case 'j':
@@ -773,9 +772,9 @@
       address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
       Handle obj = CiConstant::object(constant);
 
-      if (obj->is_a(HotSpotTypeResolved::klass())) {
+      if (obj->is_a(HotSpotKlassOop::klass())) {
         assert(!obj.is_null(), "");
-        *((jobject*) operand) = JNIHandles::make_local(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(obj)));
+        *((jobject*) operand) = JNIHandles::make_local(java_lang_Class::as_klassOop(HotSpotKlassOop::javaMirror(obj)));
         _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
         TRACE_graal_3("relocating (HotSpotType) at %016x/%016x", instruction, operand);
       } else {
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon Apr 30 15:41:14 2012 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Apr 30 20:15:20 2012 +0200
@@ -58,6 +58,9 @@
     boolean_field(HotSpotTypeResolved, isInterface)                                     \
     int_field(HotSpotTypeResolved, instanceSize)                                        \
   end_class                                                                             \
+  start_class(HotSpotKlassOop)                                                          \
+    oop_field(HotSpotKlassOop, javaMirror, "Ljava/lang/Class;")                         \
+    end_class                                                                           \
   start_class(HotSpotMethodResolved)                                                    \
     oop_field(HotSpotMethodResolved, compiler, "Lcom/oracle/graal/hotspot/Compiler;")   \
     oop_field(HotSpotMethodResolved, name, "Ljava/lang/String;")                        \