# HG changeset patch # User Doug Simon # Date 1367015542 -7200 # Node ID d4684b468e939fb59ffa27d6b7a33a0f30e65114 # Parent 4bf3af9abdfb70d4c7a26c9119c74532f70ca4f3 made NewInstanceStub a RuntimeStub that directly calls the C runtime (GRAAL-81) diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- 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; diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- 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, diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java --- 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; diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java --- 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; + } } diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- 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; diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceSlowStubCall.java --- 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); -} diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java --- 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; diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java --- 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); } diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java --- 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); } diff -r 4bf3af9abdfb -r d4684b468e93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- 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; } diff -r 4bf3af9abdfb -r d4684b468e93 src/share/vm/graal/graalCompilerToVM.cpp --- 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); diff -r 4bf3af9abdfb -r d4684b468e93 src/share/vm/graal/graalRuntime.hpp --- 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);