changeset 9363:545a023c2ca3

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 27 Apr 2013 11:12:44 +0200
parents e6d3af0a42ab (current diff) 44e05c9afb54 (diff)
children f14413a91e12
files
diffstat 13 files changed, 158 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Sat Apr 27 01:34:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Sat Apr 27 11:12:44 2013 +0200
@@ -43,6 +43,7 @@
 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 static com.oracle.graal.hotspot.stubs.NewMultiArrayStub.*;
 
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
@@ -127,13 +128,20 @@
                 /* arg0: thread */ nativeCallingConvention(word,
                 /* arg1:    hub */                         word));
 
-        addRuntimeCall(NEW_MULTI_ARRAY, config.newMultiArrayStub,
-                /*        temps */ null,
+        addStubCall(NEW_MULTI_ARRAY,
                 /*          ret */ rax.asValue(Kind.Object),
                 /* arg0:    hub */ rax.asValue(word),
                 /* arg1:   rank */ rbx.asValue(Kind.Int),
                 /* arg2:   dims */ rcx.asValue(word));
 
+        addRuntimeCall(NEW_MULTI_ARRAY_C, config.newMultiArrayAddress,
+                /*        temps */ null,
+                /*          ret */ ret(Kind.Void),
+                /* arg0: thread */ nativeCallingConvention(word,
+                /* arg1:    hub */                         word,
+                /* arg2:   rank */                         Kind.Int,
+                /* arg3:   dims */                         word));
+
         addRuntimeCall(VERIFY_OOP, config.verifyOopStub,
                 /*        temps */ null,
                 /*          ret */ ret(Kind.Void),
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Sat Apr 27 01:34:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Sat Apr 27 11:12:44 2013 +0200
@@ -119,6 +119,6 @@
      */
     public boolean isCRuntimeCall() {
         HotSpotVMConfig config = HotSpotGraalRuntime.graalRuntime().getConfig();
-        return address == config.newArrayAddress || address == config.newInstanceAddress;
+        return address == config.newArrayAddress || address == config.newInstanceAddress || address == config.newMultiArrayAddress;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sat Apr 27 01:34:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sat Apr 27 11:12:44 2013 +0200
@@ -343,7 +343,6 @@
     public int typeProfileWidth;
 
     // runtime stubs
-    public long newMultiArrayStub;
     public long inlineCacheMissStub;
     public long handleExceptionStub;
     public long handleDeoptStub;
@@ -381,6 +380,7 @@
 
     public long newInstanceAddress;
     public long newArrayAddress;
+    public long newMultiArrayAddress;
 
     public int deoptReasonNullCheck;
     public int deoptReasonRangeCheck;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Sat Apr 27 01:34:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Sat Apr 27 11:12:44 2013 +0200
@@ -32,6 +32,7 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
+import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*;
 import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*;
 import static com.oracle.graal.hotspot.stubs.Stub.*;
 import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
@@ -359,6 +360,7 @@
 
         registerStub(new NewInstanceStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_INSTANCE)));
         registerStub(new NewArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_ARRAY)));
+        registerStub(new NewMultiArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_MULTI_ARRAY)));
     }
 
     private void registerStub(Stub stub) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Sat Apr 27 01:34:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Sat Apr 27 11:12:44 2013 +0200
@@ -28,13 +28,14 @@
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.stubs.*;
 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_multi_array} stub.
+ * Node implementing a call to {@link NewMultiArrayStub}.
  */
 public class NewMultiArrayStubCall extends DeoptimizingStubCall implements LIRGenLowerable {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java	Sat Apr 27 11:12:44 2013 +0200
@@ -0,0 +1,72 @@
+/*
+ * 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.stubs;
+
+import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationReason.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.api.code.*;
+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.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.SnippetTemplate.Arguments;
+import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
+import com.oracle.graal.word.*;
+
+public class NewMultiArrayStub extends Stub {
+
+    public NewMultiArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
+        super(runtime, replacements, target, linkage, "newMultiArray");
+    }
+
+    @Override
+    protected Arguments makeArguments(SnippetInfo stub) {
+        Arguments args = new Arguments(stub);
+        args.add("hub", null);
+        args.add("rank", null);
+        args.add("dims", null);
+        return args;
+    }
+
+    @Snippet
+    private static Object newMultiArray(Word hub, int rank, Word dims) {
+        newMultiArrayC(NEW_MULTI_ARRAY_C, thread(), hub, rank, dims);
+
+        if (clearPendingException(thread())) {
+            getAndClearObjectResult(thread());
+            DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
+        }
+        return verifyOop(getAndClearObjectResult(thread()));
+    }
+
+    public static final Descriptor NEW_MULTI_ARRAY_C = new Descriptor("new_multi_array_c", false, void.class, Word.class, Word.class, int.class, Word.class);
+
+    @NodeIntrinsic(CRuntimeCall.class)
+    public static native void newMultiArrayC(@ConstantNodeParameter Descriptor newArrayC, Word thread, Word hub, int rank, Word dims);
+}
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java	Sat Apr 27 01:34:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java	Sat Apr 27 11:12:44 2013 +0200
@@ -45,23 +45,19 @@
         assertEquals(Integer.MAX_VALUE, executeWith(root, Integer.MAX_VALUE - 1, 1));
         assertEquals(1, InvocationGuard.specializedInvocations);
         assertEquals(0, InvocationGuard.genericInvocations);
-        assertEquals(1, InvocationGuard.guardInvocations);
 
         assertEquals(42, executeWith(root, Integer.MAX_VALUE, 1));
         assertEquals(1, InvocationGuard.specializedInvocations);
         assertEquals(1, InvocationGuard.genericInvocations);
-        assertEquals(2, InvocationGuard.guardInvocations);
     }
 
     @NodeChildren({@NodeChild("value0"), @NodeChild("value1")})
     public abstract static class InvocationGuard extends ValueNode {
 
-        static int guardInvocations = 0;
         static int specializedInvocations = 0;
         static int genericInvocations = 0;
 
         boolean guard(int value0, int value1) {
-            guardInvocations++;
             return value0 != Integer.MAX_VALUE;
         }
 
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java	Sat Apr 27 01:34:35 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java	Sat Apr 27 11:12:44 2013 +0200
@@ -475,6 +475,19 @@
         currentElement.registerAtEnd(callback);
     }
 
+    public CodeTreeBuilder defaultDeclaration(TypeMirror type, String name) {
+        if (!Utils.isVoid(type)) {
+            startStatement();
+            type(type);
+            string(" ");
+            string(name);
+            string(" = ");
+            defaultValue(type);
+            end(); // statement
+        }
+        return this;
+    }
+
     public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTree init) {
         if (Utils.isVoid(type)) {
             startStatement();
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Sat Apr 27 01:34:35 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Sat Apr 27 11:12:44 2013 +0200
@@ -760,8 +760,12 @@
                 builder.end();
 
                 emitSpecializationListeners(builder, node);
+                builder.defaultDeclaration(node.getGenericSpecialization().getReturnSignature().getPrimitiveType(), "result");
+                if (node.getGenericSpecialization().isUseSpecializationsForGeneric()) {
+                    builder.defaultDeclaration(getContext().getType(boolean.class), "resultIsSet");
+                }
                 builder.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end();
-                prefix = "allowed";
+                prefix = null;
             }
 
             addInternalValueParameters(method, node.getGenericSpecialization(), true);
@@ -801,9 +805,10 @@
 
                 execute.tree(createGenericInvoke(builder, current, specialize));
 
-                if (specialize) {
+                if (specialize && !current.isGeneric()) {
                     builder.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(current)).string(".class)").end();
                 }
+
                 builder.tree(createGuardAndCast(builder, prefix, current.getNode().getGenericSpecialization(), current, true, execute.getRoot(), null, true));
             }
 
@@ -811,10 +816,6 @@
                 builder.string("// unreachable ").string(specializationData.getId()).newLine();
             }
 
-            if (specialize) {
-                builder.startThrow().startNew(getContext().getType(AssertionError.class)).end().end();
-            }
-
             return method;
         }
 
@@ -825,21 +826,57 @@
                 builder.startTryBlock();
             }
 
-            if (current.getMethod() == null) {
+            CodeTree executeCall = null;
+            if (current.getMethod() != null) {
+                executeCall = createTemplateMethodCall(builder, null, current.getNode().getGenericSpecialization(), current, null);
+            }
+
+            if (specialize && executeCall == null && !current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) {
                 emitEncounteredSynthetic(builder);
-            } else {
-                CodeTree executeCall = createTemplateMethodCall(builder, null, current.getNode().getGenericSpecialization(), current, null);
+            } else if (specialize) {
+
+                if (current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) {
+                    builder.startIf().string("!resultIsSet").end().startBlock();
+                    if (executeCall != null) {
+                        if (current.getReturnSignature().isVoid()) {
+                            builder.statement(executeCall);
+                        } else {
+                            builder.startStatement().string("result = ").tree(executeCall).end();
+                        }
+                        builder.statement("resultIsSet = true");
+                    } else {
+                        emitEncounteredSynthetic(builder);
+                    }
+                    builder.end();
+                }
 
-                if (specialize) {
-                    builder.declaration(current.getReturnSignature().getPrimitiveType(), "result", executeCall);
-                    builder.startStatement().startCall("super", "replace");
-                    builder.startGroup().startNew(nodeSpecializationClassName(current)).string("this").end().end();
-                    builder.end().end();
+                if (!current.isGeneric()) {
+                    builder.startIf().string("allowed").end().startBlock();
+                }
+
+                if (!current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) {
                     if (current.getReturnSignature().isVoid()) {
-                        builder.returnStatement();
+                        builder.statement(executeCall);
                     } else {
-                        builder.startReturn().string("result").end();
+                        builder.startStatement().string("result = ").tree(executeCall).end();
                     }
+                }
+
+                builder.startStatement().startCall("super", "replace");
+                builder.startGroup().startNew(nodeSpecializationClassName(current)).string("this").end().end();
+                builder.end().end();
+
+                if (current.getReturnSignature().isVoid()) {
+                    builder.returnStatement();
+                } else {
+                    builder.startReturn().string("result").end();
+                }
+                if (!current.isGeneric()) {
+                    builder.end();
+                }
+            } else {
+                if (executeCall == null) {
+                    emitEncounteredSynthetic(builder);
                 } else {
                     builder.startReturn().tree(executeCall).end();
                 }
--- a/src/cpu/x86/vm/graalRuntime_x86.cpp	Sat Apr 27 01:34:35 2013 +0200
+++ b/src/cpu/x86/vm/graalRuntime_x86.cpp	Sat Apr 27 11:12:44 2013 +0200
@@ -811,23 +811,6 @@
   OopMapSet* oop_maps = NULL;
   switch (id) {
 
-    case new_multi_array_id:
-      { GraalStubFrame f(sasm, "new_multi_array", dont_gc_arguments);
-        // rax,: klass
-        // rbx,: rank
-        // rcx: address of 1st dimension
-        OopMap* map = save_live_registers(sasm, 4);
-        int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
-
-        oop_maps = new OopMapSet();
-        oop_maps->add_gc_map(call_offset, map);
-        restore_live_registers_except_rax(sasm);
-
-        // rax,: new multi array
-        __ verify_oop(rax);
-      }
-      break;
-
     case register_finalizer_id:
       {
         __ set_info("register_finalizer", dont_gc_arguments);
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Sat Apr 27 01:34:35 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Sat Apr 27 11:12:44 2013 +0200
@@ -81,12 +81,6 @@
   return arr->length() * MapWordBits;
 }
 
-#ifdef _LP64
-  #define SLOTS_PER_WORD 2
-#else
-  #define SLOTS_PER_WORD 1
-#endif // _LP64
-
 // creates a HotSpot oop map out of the byte arrays provided by DebugInfo
 static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) {
   OopMap* map = new OopMap(total_frame_size, parameter_count);
@@ -109,7 +103,7 @@
   for (jint i = 0; i < bitset_size(frame_map); i++) {
     bool is_oop = is_bit_set(frame_map, i);
     // HotSpot stack slots are 4 bytes
-    VMReg reg = VMRegImpl::stack2reg(i * SLOTS_PER_WORD);
+    VMReg reg = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word);
     if (is_oop) {
       map->set_oop(reg);
     } else {
@@ -126,7 +120,7 @@
       VMReg hotspot_reg = get_hotspot_reg(graal_reg_number);
       // HotSpot stack slots are 4 bytes
       jint graal_slot = ((jint*) slots->base(T_INT))[i];
-      jint hotspot_slot = graal_slot * SLOTS_PER_WORD;
+      jint hotspot_slot = graal_slot * VMRegImpl::slots_per_word;
       VMReg hotspot_slot_as_reg = VMRegImpl::stack2reg(hotspot_slot);
       map->set_callee_saved(hotspot_slot_as_reg, hotspot_reg);
 #ifdef _LP64
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Sat Apr 27 01:34:35 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Sat Apr 27 11:12:44 2013 +0200
@@ -750,7 +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("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));
   set_address("inlineCacheMissStub", SharedRuntime::get_ic_miss_stub());
@@ -784,6 +783,7 @@
 
   set_address("newInstanceAddress", GraalRuntime::new_instance);
   set_address("newArrayAddress", GraalRuntime::new_array);
+  set_address("newMultiArrayAddress", GraalRuntime::new_multi_array);
 
   set_int("deoptReasonNone", Deoptimization::Reason_none);
   set_int("deoptReasonNullCheck", Deoptimization::Reason_null_check);
--- a/src/share/vm/graal/graalRuntime.hpp	Sat Apr 27 01:34:35 2013 +0200
+++ b/src/share/vm/graal/graalRuntime.hpp	Sat Apr 27 11:12:44 2013 +0200
@@ -82,7 +82,6 @@
 // by Graal.
 #define GRAAL_STUBS(stub, last_entry) \
   stub(register_finalizer)      \
-  stub(new_multi_array)         \
   stub(handle_exception_nofpu) /* optimized version that does not preserve fpu registers */ \
   stub(unwind_exception_call)   \
   stub(OSR_migration_end)       \
@@ -131,8 +130,6 @@
                                        Register arg1 = noreg, Register arg2 = noreg, Register arg3 = noreg);
 
   // runtime entry points
-  static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
-
   static void unimplemented_entry(JavaThread* thread, StubID id);
 
   static address exception_handler_for_pc(JavaThread* thread);
@@ -162,6 +159,7 @@
  public:
   static void new_instance(JavaThread* thread, Klass* klass);
   static void new_array(JavaThread* thread, Klass* klass, jint length);
+  static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
   // initialization
   static void initialize(BufferBlob* blob);