changeset 17084:26f5733fb645

Fix the endianess issue, when using JSR/RET instruction and deoptimization happens in this subroutine
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Tue, 09 Sep 2014 12:15:29 -0700
parents 2b7c005ae93a
children 841a9f98b97c
files graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.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 6 files changed, 138 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Sep 09 12:11:57 2014 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Sep 09 12:15:29 2014 -0700
@@ -882,13 +882,15 @@
                 BciBlock successor = currentBlock.jsrSuccessor;
                 assert successor.startBci == dest : successor.startBci + " != " + dest + " @" + bci();
                 JsrScope scope = currentBlock.jsrScope;
+                int nextBci = getStream().nextBCI();
                 if (!successor.jsrScope.pop().equals(scope)) {
                     throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
                 }
-                if (successor.jsrScope.nextReturnAddress() != getStream().nextBCI()) {
+                if (successor.jsrScope.nextReturnAddress() != nextBci) {
                     throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
                 }
-                frameState.push(Kind.Int, ConstantNode.forInt(getStream().nextBCI(), currentGraph));
+                ConstantNode nextBciNode = getJsrConstant(nextBci);
+                frameState.push(Kind.Int, nextBciNode);
                 appendGoto(createTarget(successor, frameState));
             }
 
@@ -898,13 +900,23 @@
                 ValueNode local = frameState.loadLocal(localIndex);
                 JsrScope scope = currentBlock.jsrScope;
                 int retAddress = scope.nextReturnAddress();
-                append(FixedGuardNode.create(currentGraph.unique(IntegerEqualsNode.create(local, ConstantNode.forInt(retAddress, currentGraph))), JavaSubroutineMismatch, InvalidateReprofile));
+                ConstantNode returnBciNode = getJsrConstant(retAddress);
+                LogicNode guard = IntegerEqualsNode.create(local, returnBciNode);
+                guard = currentGraph.unique(guard);
+                append(FixedGuardNode.create(guard, JavaSubroutineMismatch, InvalidateReprofile));
                 if (!successor.jsrScope.equals(scope.pop())) {
                     throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
                 }
                 appendGoto(createTarget(successor, frameState));
             }
 
+            private ConstantNode getJsrConstant(long bci) {
+                Constant nextBciConstant = new RawConstant(bci);
+                Stamp nextBciStamp = StampFactory.forConstant(nextBciConstant);
+                ConstantNode nextBciNode = ConstantNode.create(nextBciConstant, nextBciStamp);
+                return currentGraph.unique(nextBciNode);
+            }
+
             @Override
             protected void genIntegerSwitch(ValueNode value, ArrayList<BciBlock> actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
                 double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java	Tue Sep 09 12:11:57 2014 -0700
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java	Tue Sep 09 12:15:29 2014 -0700
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.replacements.test;
 
+import java.util.*;
+
 import org.junit.*;
 
 import com.oracle.graal.compiler.test.*;
@@ -52,4 +54,116 @@
         }
         return m1 + m2 + m3 + m4 + m5;
     }
+
+    @Test
+    public void test2() {
+        test("test2Snippet");
+    }
+
+    public String test2Snippet() throws Exception {
+        try {
+            ClassLoader testCl = new MyClassLoader();
+            @SuppressWarnings("unchecked")
+            Class<Runnable> c = (Class<Runnable>) testCl.loadClass(name);
+            Runnable r = c.newInstance();
+            ct = Long.MAX_VALUE;
+            for (int i = 0; i < 100000000; i++) {
+                r.run();
+            }
+            ct = 0;
+            r.run();
+        } catch (Throwable e) {
+            e.printStackTrace(System.out);
+            Assert.fail();
+        }
+        return "SUCCESS";
+    }
+
+    public static class MyClassLoader extends ClassLoader {
+        @Override
+        protected Class<?> findClass(String className) throws ClassNotFoundException {
+            return defineClass(name.replace('/', '.'), clazz, 0, clazz.length);
+        }
+    }
+
+    public static void methodB() {
+        Random r = new Random(System.currentTimeMillis());
+        while (r.nextFloat() > .03f) {
+        }
+
+        return;
+    }
+
+    public static void methodA() {
+        Random r = new Random(System.currentTimeMillis());
+        while (r.nextDouble() > .05) {
+        }
+        return;
+    }
+
+    private static Object m = new Object();
+    static long ct = Long.MAX_VALUE;
+
+    public static Object getM() {
+        if (ct-- > 0) {
+            return m;
+        } else {
+            return null;
+        }
+    }
+
+    private static String name = "t/TestJSR";
+    //@formatter:off
+    /*
+        // Code generated the class below using asm.
+        String clazzName = "com.oracle.graal.replacements.test.DeoptimizeOnExceptionTest".replace('.', '/');
+        final ClassWriter w = new ClassWriter(0);
+        w.visit(V1_5, ACC_PUBLIC,
+                "t/TestJSR", null, "java/lang/Object",
+                new String[] { "java/lang/Runnable" });
+        MethodVisitor mv = w.visitMethod(ACC_PUBLIC, "<init>", "()V", null, new String[] { });
+        mv.visitCode();
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(10, 10);
+        mv.visitEnd();
+
+        mv = w.visitMethod(ACC_PUBLIC, "run", "()V", null, null);
+        mv.visitCode();
+        mv.visitMethodInsn(INVOKESTATIC, clazzName, "getM", "()Ljava/lang/Object;", false);
+        Label l1 = new Label();
+        mv.visitJumpInsn(JSR, l1);
+        mv.visitInsn(RETURN);
+
+        mv.visitLabel(l1);
+        mv.visitVarInsn(ASTORE, 1);
+
+        Label lElse = new Label();
+        Label lEnd = new Label();
+        mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false);
+        mv.visitInsn(POP2);
+        mv.visitMethodInsn(INVOKESTATIC, clazzName, "getM", "()Ljava/lang/Object;", false);
+        mv.visitInsn(DUP);
+        mv.visitJumpInsn(IFNULL, lElse);
+        mv.visitMethodInsn(INVOKESTATIC, clazzName, "methodA", "()V", false);
+        mv.visitJumpInsn(GOTO, lEnd);
+        mv.visitLabel(lElse);
+        mv.visitMethodInsn(INVOKESTATIC, clazzName, "methodB", "()V", false);
+        mv.visitLabel(lEnd);
+
+        mv.visitVarInsn(RET, 1);
+        mv.visitMaxs(10, 10);
+        mv.visitEnd();
+     */
+    //@formatter:on
+    private static byte[] clazz = new byte[]{-54, -2, -70, -66, 0, 0, 0, 49, 0, 25, 1, 0, 9, 116, 47, 84, 101, 115, 116, 74, 83, 82, 7, 0, 1, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
+                    79, 98, 106, 101, 99, 116, 7, 0, 3, 1, 0, 18, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 82, 117, 110, 110, 97, 98, 108, 101, 7, 0, 5, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0,
+                    3, 40, 41, 86, 12, 0, 7, 0, 8, 10, 0, 4, 0, 9, 1, 0, 3, 114, 117, 110, 1, 0, 60, 99, 111, 109, 47, 111, 114, 97, 99, 108, 101, 47, 103, 114, 97, 97, 108, 47, 114, 101, 112, 108,
+                    97, 99, 101, 109, 101, 110, 116, 115, 47, 116, 101, 115, 116, 47, 68, 101, 111, 112, 116, 105, 109, 105, 122, 101, 79, 110, 69, 120, 99, 101, 112, 116, 105, 111, 110, 84, 101,
+                    115, 116, 7, 0, 12, 1, 0, 4, 103, 101, 116, 77, 1, 0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 12, 0, 14, 0, 15, 10, 0, 13, 0,
+                    16, 1, 0, 7, 109, 101, 116, 104, 111, 100, 65, 12, 0, 18, 0, 8, 10, 0, 13, 0, 19, 1, 0, 7, 109, 101, 116, 104, 111, 100, 66, 12, 0, 21, 0, 8, 10, 0, 13, 0, 22, 1, 0, 4, 67, 111,
+                    100, 101, 0, 1, 0, 2, 0, 4, 0, 1, 0, 6, 0, 0, 0, 2, 0, 1, 0, 7, 0, 8, 0, 1, 0, 24, 0, 0, 0, 17, 0, 10, 0, 10, 0, 0, 0, 5, 42, -73, 0, 10, -79, 0, 0, 0, 0, 0, 1, 0, 11, 0, 8, 0, 1,
+                    0, 24, 0, 0, 0, 38, 0, 10, 0, 10, 0, 0, 0, 26, -72, 0, 17, -88, 0, 4, -79, 76, -72, 0, 17, 89, -58, 0, 9, -72, 0, 20, -89, 0, 6, -72, 0, 23, -87, 1, 0, 0, 0, 0, 0, 0};
+
 }
--- a/src/share/vm/classfile/systemDictionary.hpp	Tue Sep 09 12:11:57 2014 -0700
+++ b/src/share/vm/classfile/systemDictionary.hpp	Tue Sep 09 12:15:29 2014 -0700
@@ -237,6 +237,7 @@
   GRAAL_ONLY(do_klass(SpeculationLog_klass,                  com_oracle_graal_api_code_SpeculationLog,                     Graal)) \
   GRAAL_ONLY(do_klass(Constant_klass,                        com_oracle_graal_api_meta_Constant,                           Graal)) \
   GRAAL_ONLY(do_klass(PrimitiveConstant_klass,               com_oracle_graal_api_meta_PrimitiveConstant,                  Graal)) \
+  GRAAL_ONLY(do_klass(RawConstant_klass,                     com_oracle_graal_api_meta_RawConstant,                        Graal)) \
   GRAAL_ONLY(do_klass(NullConstant_klass,                    com_oracle_graal_api_meta_NullConstant,                       Graal)) \
   GRAAL_ONLY(do_klass(ExceptionHandler_klass,                com_oracle_graal_api_meta_ExceptionHandler,                   Graal)) \
   GRAAL_ONLY(do_klass(Kind_klass,                            com_oracle_graal_api_meta_Kind,                               Graal)) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Tue Sep 09 12:11:57 2014 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Tue Sep 09 12:15:29 2014 -0700
@@ -318,6 +318,7 @@
   GRAAL_ONLY(template(com_oracle_graal_hotspot_CompilationTask,                 "com/oracle/graal/hotspot/CompilationTask"))                      \
   GRAAL_ONLY(template(com_oracle_graal_api_meta_Constant,                       "com/oracle/graal/api/meta/Constant"))                            \
   GRAAL_ONLY(template(com_oracle_graal_api_meta_PrimitiveConstant,              "com/oracle/graal/api/meta/PrimitiveConstant"))                   \
+  GRAAL_ONLY(template(com_oracle_graal_api_meta_RawConstant,                    "com/oracle/graal/api/meta/RawConstant"))                         \
   GRAAL_ONLY(template(com_oracle_graal_api_meta_NullConstant,                   "com/oracle/graal/api/meta/NullConstant"))                        \
   GRAAL_ONLY(template(com_oracle_graal_api_meta_ExceptionHandler,               "com/oracle/graal/api/meta/ExceptionHandler"))                    \
   GRAAL_ONLY(template(com_oracle_graal_api_meta_JavaMethod,                     "com/oracle/graal/api/meta/JavaMethod"))                          \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Tue Sep 09 12:11:57 2014 -0700
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Sep 09 12:15:29 2014 -0700
@@ -278,7 +278,10 @@
     record_metadata_in_constant(value, oop_recorder);
     if (value->is_a(PrimitiveConstant::klass())) {
       assert(!reference, "unexpected primitive constant type");
-      if (type == T_INT || type == T_FLOAT) {
+      if(value->is_a(RawConstant::klass())) {
+        jlong prim = PrimitiveConstant::primitive(value);
+        return new ConstantLongValue(prim);
+      } else if (type == T_INT || type == T_FLOAT) {
         jint prim = (jint)PrimitiveConstant::primitive(value);
         return new ConstantIntValue(prim);
       } else {
--- a/src/share/vm/graal/graalJavaAccess.hpp	Tue Sep 09 12:11:57 2014 -0700
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Tue Sep 09 12:15:29 2014 -0700
@@ -205,6 +205,9 @@
   start_class(PrimitiveConstant)                                                                                                                               \
     long_field(PrimitiveConstant, primitive)                                                                                                                   \
   end_class                                                                                                                                                    \
+  start_class(RawConstant)                                                                                                                                     \
+    long_field(RawConstant, primitive)                                                                                                                         \
+  end_class                                                                                                                                                    \
   start_class(NullConstant)                                                                                                                                    \
   end_class                                                                                                                                                    \
   start_class(HotSpotCompressedNullConstant)                                                                                                                                    \