changeset 9352:d4684b468e93

made NewInstanceStub a RuntimeStub that directly calls the C runtime (GRAAL-81)
author Doug Simon <doug.simon@oracle.com>
date Sat, 27 Apr 2013 00:32:22 +0200
parents 4bf3af9abdfb
children 6bb12a72d26b
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceSlowStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalRuntime.hpp
diffstat 12 files changed, 61 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Apr 26 22:57:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sat Apr 27 00:32:22 2013 +0200
@@ -182,7 +182,7 @@
 
     @Override
     protected void emitCall(RuntimeCallTarget callTarget, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
-        boolean needsCalleeSave = callTarget.getDescriptor() == NewArrayStub.NEW_ARRAY_C;
+        boolean needsCalleeSave = ((HotSpotRuntimeCallTarget) callTarget).isCRuntimeCall();
         if (needsCalleeSave) {
             currentRuntimeCallInfo = info;
         }
@@ -191,7 +191,7 @@
 
     @Override
     public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention cc, DeoptimizingNode info, Value... args) {
-        boolean needsCalleeSave = callTarget.getDescriptor() == NewArrayStub.NEW_ARRAY_C;
+        boolean needsCalleeSave = ((HotSpotRuntimeCallTarget) callTarget).isCRuntimeCall();
 
         RegisterValue[] savedRegisters = null;
         StackSlot[] savedRegisterLocations = null;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Fri Apr 26 22:57:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Sat Apr 27 00:32:22 2013 +0200
@@ -30,7 +30,6 @@
 import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*;
 import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*;
-import static com.oracle.graal.hotspot.nodes.NewInstanceSlowStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*;
 import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*;
@@ -43,6 +42,7 @@
 import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*;
 import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.EncryptAESCryptStubCall.*;
 import static com.oracle.graal.hotspot.stubs.NewArrayStub.*;
+import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
 
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
@@ -112,7 +112,7 @@
 
         addRuntimeCall(NEW_ARRAY_C, config.newArrayAddress,
                 /*        temps */ null,
-                /*          ret */ rax.asValue(Kind.Object),
+                /*          ret */ ret(Kind.Void),
                 /* arg0: thread */ nativeCallingConvention(word,
                 /* arg1:    hub */                         word,
                 /* arg2: length */                         Kind.Int));
@@ -121,10 +121,11 @@
                 /*          ret */ rax.asValue(Kind.Object),
                 /* arg0:    hub */ rdx.asValue(word));
 
-        addRuntimeCall(NEW_INSTANCE_SLOW, config.newInstanceStub,
+        addRuntimeCall(NEW_INSTANCE_C, config.newInstanceAddress,
                 /*        temps */ null,
-                /*          ret */ rax.asValue(Kind.Object),
-                /* arg0:    hub */ rdx.asValue(word));
+                /*          ret */ ret(Kind.Void),
+                /* arg0: thread */ nativeCallingConvention(word,
+                /* arg1:    hub */                         word));
 
         addRuntimeCall(NEW_MULTI_ARRAY, config.newMultiArrayStub,
                 /*        temps */ null,
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java	Fri Apr 26 22:57:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java	Sat Apr 27 00:32:22 2013 +0200
@@ -58,9 +58,7 @@
         this.comp = comp;
         this.entryBCI = entryBCI;
 
-        // Class stubClass = Stub.class;
-        Class stubClass = NewArrayStub.class;
-        if (graalRuntime().getRuntime().lookupJavaType(stubClass).isAssignableFrom(method.getDeclaringClass()) && method.getAnnotation(Snippet.class) != null) {
+        if (graalRuntime().getRuntime().lookupJavaType(Stub.class).isAssignableFrom(method.getDeclaringClass()) && method.getAnnotation(Snippet.class) != null) {
             this.stubName = MetaUtil.format("%h.%n", method);
         } else {
             this.stubName = null;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Fri Apr 26 22:57:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Sat Apr 27 00:32:22 2013 +0200
@@ -46,7 +46,7 @@
     private long address;
 
     /**
-     * Non-null (eventually) iff this is a call to a snippet-based {@linkplain Stub stub}.
+     * Non-null (eventually) iff this is a call to a compiled {@linkplain Stub stub}.
      */
     private Stub stub;
 
@@ -113,4 +113,12 @@
         assert address != 0;
         return true;
     }
+
+    /**
+     * Determines if this is a link to a C/C++ function in the HotSpot runtime.
+     */
+    public boolean isCRuntimeCall() {
+        HotSpotVMConfig config = HotSpotGraalRuntime.graalRuntime().getConfig();
+        return address == config.newArrayAddress || address == config.newInstanceAddress;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Fri Apr 26 22:57:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sat Apr 27 00:32:22 2013 +0200
@@ -343,8 +343,6 @@
     public int typeProfileWidth;
 
     // runtime stubs
-    public long newInstanceStub;
-    public long newArrayStub;
     public long newMultiArrayStub;
     public long inlineCacheMissStub;
     public long handleExceptionStub;
@@ -381,6 +379,7 @@
     public long cipherBlockChainingEncryptAESCryptStub;
     public long cipherBlockChainingDecryptAESCryptStub;
 
+    public long newInstanceAddress;
     public long newArrayAddress;
 
     public int deoptReasonNullCheck;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceSlowStubCall.java	Fri Apr 26 22:57:22 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * 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.nodes;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.word.*;
-
-/**
- * Node implementing a call to HotSpot's {@code new_instance} stub.
- */
-public class NewInstanceSlowStubCall extends DeoptimizingStubCall implements LIRGenLowerable {
-
-    private static final Stamp defaultStamp = StampFactory.objectNonNull();
-
-    @Input private final ValueNode hub;
-
-    public static final Descriptor NEW_INSTANCE_SLOW = new Descriptor("new_instance_slow", false, Object.class, Word.class);
-
-    public NewInstanceSlowStubCall(ValueNode hub) {
-        super(defaultStamp);
-        this.hub = hub;
-    }
-
-    @Override
-    public boolean inferStamp() {
-        if (stamp() == defaultStamp && hub.isConstant()) {
-            updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectType.fromMetaspaceKlass(hub.asConstant())));
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void generate(LIRGenerator gen) {
-        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NEW_INSTANCE_SLOW);
-        Variable result = gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(hub));
-        gen.setResult(this, result);
-    }
-
-    @NodeIntrinsic
-    public static native Object call(Word hub);
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java	Fri Apr 26 22:57:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java	Sat Apr 27 00:32:22 2013 +0200
@@ -161,7 +161,7 @@
      * 
      * @return the object that was in the thread local
      */
-    public static Object clearObjectResult(Word thread) {
+    public static Object getAndClearObjectResult(Word thread) {
         Object result = thread.readObject(objectResultOffset(), OBJECT_RESULT_LOCATION);
         thread.writeObject(objectResultOffset(), null);
         return result;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Fri Apr 26 22:57:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Sat Apr 27 00:32:22 2013 +0200
@@ -104,21 +104,20 @@
                 return verifyOop(memory.toObject());
             }
         }
-        log(log, "newArray: calling new_array_runtime\n", 0L);
+        log(log, "newArray: calling new_array_c\n", 0L);
 
-        callNewArrayC(NEW_ARRAY_C, thread(), hub, length);
+        newArrayC(NEW_ARRAY_C, thread(), hub, length);
 
         if (clearPendingException(thread())) {
             log(log, "newArray: deoptimizing to caller\n", 0L);
-            clearObjectResult(thread());
+            getAndClearObjectResult(thread());
             DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
         }
-        return verifyOop(clearObjectResult(thread()));
+        return verifyOop(getAndClearObjectResult(thread()));
     }
 
-    public static final Descriptor NEW_ARRAY_C = new Descriptor("new_array_c", false, Object.class, Word.class, Word.class, int.class);
+    public static final Descriptor NEW_ARRAY_C = new Descriptor("new_array_c", false, void.class, Word.class, Word.class, int.class);
 
     @NodeIntrinsic(CRuntimeCall.class)
-    public static native Object callNewArrayC(@ConstantNodeParameter Descriptor newArrayC, Word thread, Word hub, int length);
-
+    public static native void newArrayC(@ConstantNodeParameter Descriptor newArrayC, Word thread, Word hub, int length);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Fri Apr 26 22:57:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Sat Apr 27 00:32:22 2013 +0200
@@ -22,12 +22,18 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
+import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationReason.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
 import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*;
 
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
@@ -56,9 +62,15 @@
     protected Arguments makeArguments(SnippetInfo stub) {
         HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) runtime.lookupJavaType(int[].class);
 
+        // RuntimeStub cannot (currently) support oops or metadata embedded in the code so we
+        // convert the hub (i.e., Klass*) for int[] to be a naked word. This should be safe since
+        // the int[] class will never be unloaded.
+        Constant intArrayHub = intArrayType.klass();
+        intArrayHub = Constant.forIntegerKind(graalRuntime().getTarget().wordKind, intArrayHub.asLong(), null);
+
         Arguments args = new Arguments(stub);
         args.add("hub", null);
-        args.addConst("intArrayHub", intArrayType.klass());
+        args.addConst("intArrayHub", intArrayHub);
         args.addConst("log", Boolean.getBoolean("graal.logNewInstanceStub"));
         return args;
     }
@@ -86,7 +98,17 @@
                 }
             }
         }
-        return verifyOop(NewInstanceSlowStubCall.call(hub));
+
+        log(log, "newInstance: calling new_instance_c\n", 0L);
+
+        newInstanceC(NEW_INSTANCE_C, thread(), hub);
+
+        if (clearPendingException(thread())) {
+            log(log, "newInstance: deoptimizing to caller\n", 0L);
+            getAndClearObjectResult(thread());
+            DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
+        }
+        return verifyOop(getAndClearObjectResult(thread()));
     }
 
     /**
@@ -208,4 +230,9 @@
     private static boolean forceSlowPath() {
         return Boolean.getBoolean("graal.newInstanceStub.forceSlowPath");
     }
+
+    public static final Descriptor NEW_INSTANCE_C = new Descriptor("new_instance_c", false, void.class, Word.class, Word.class);
+
+    @NodeIntrinsic(CRuntimeCall.class)
+    public static native void newInstanceC(@ConstantNodeParameter Descriptor newInstanceC, Word thread, Word hub);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Fri Apr 26 22:57:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Sat Apr 27 00:32:22 2013 +0200
@@ -103,7 +103,6 @@
         super(runtime, replacements, target);
         this.stubInfo = snippet(getClass(), methodName);
         this.linkage = linkage;
-
     }
 
     /**
@@ -127,12 +126,10 @@
     }
 
     private boolean checkCompilationResult(CompilationResult compResult) {
-        if (this instanceof NewArrayStub) {
-            for (DataPatch data : compResult.getDataReferences()) {
-                Constant constant = data.constant;
-                assert constant.getKind() != Kind.Object : MetaUtil.format("%h.%n(%p): ", getMethod()) + "cannot have embedded oop: " + constant;
-                assert constant.getPrimitiveAnnotation() == null : MetaUtil.format("%h.%n(%p): ", getMethod()) + "cannot have embedded metadata: " + constant;
-            }
+        for (DataPatch data : compResult.getDataReferences()) {
+            Constant constant = data.constant;
+            assert constant.getKind() != Kind.Object : MetaUtil.format("%h.%n(%p): ", getMethod()) + "cannot have embedded oop: " + constant;
+            assert constant.getPrimitiveAnnotation() == null : MetaUtil.format("%h.%n(%p): ", getMethod()) + "cannot have embedded metadata: " + constant;
         }
         return true;
     }
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Fri Apr 26 22:57:22 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Sat Apr 27 00:32:22 2013 +0200
@@ -750,8 +750,6 @@
   set_address("wbPreCallStub", GraalRuntime::entry_for(GraalRuntime::wb_pre_call_id));
   set_address("wbPostCallStub", GraalRuntime::entry_for(GraalRuntime::wb_post_call_id));
 
-  set_address("newInstanceStub", GraalRuntime::entry_for(GraalRuntime::new_instance_id));
-  set_address("newArrayStub", GraalRuntime::entry_for(GraalRuntime::new_array_id));
   set_address("newMultiArrayStub", GraalRuntime::entry_for(GraalRuntime::new_multi_array_id));
   set_address("identityHashCodeStub", GraalRuntime::entry_for(GraalRuntime::identity_hash_code_id));
   set_address("threadIsInterruptedStub", GraalRuntime::entry_for(GraalRuntime::thread_is_interrupted_id));
@@ -784,6 +782,7 @@
   set_address("cipherBlockChainingEncryptAESCryptStub", StubRoutines::cipherBlockChaining_encryptAESCrypt());
   set_address("cipherBlockChainingDecryptAESCryptStub", StubRoutines::cipherBlockChaining_decryptAESCrypt());
 
+  set_address("newInstanceAddress", GraalRuntime::new_instance);
   set_address("newArrayAddress", GraalRuntime::new_array);
 
   set_int("deoptReasonNone", Deoptimization::Reason_none);
--- a/src/share/vm/graal/graalRuntime.hpp	Fri Apr 26 22:57:22 2013 +0200
+++ b/src/share/vm/graal/graalRuntime.hpp	Sat Apr 27 00:32:22 2013 +0200
@@ -133,7 +133,6 @@
                                        Register arg1 = noreg, Register arg2 = noreg, Register arg3 = noreg);
 
   // runtime entry points
-  static void new_instance(JavaThread* thread, Klass* klass);
   static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
 
   static void unimplemented_entry(JavaThread* thread, StubID id);
@@ -163,6 +162,7 @@
   static void log_object(JavaThread* thread, oop msg, jint flags);
 
  public:
+  static void new_instance(JavaThread* thread, Klass* klass);
   static void new_array(JavaThread* thread, Klass* klass, jint length);
   // initialization
   static void initialize(BufferBlob* blob);