# HG changeset patch # User Stefan Anzinger # Date 1410290129 25200 # Node ID 26f5733fb645b01a07500c85e6d00fad7358393b # Parent 2b7c005ae93a003a3069cd76f33ea2626cd23f24 Fix the endianess issue, when using JSR/RET instruction and deoptimization happens in this subroutine diff -r 2b7c005ae93a -r 26f5733fb645 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- 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 actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors) { double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities); diff -r 2b7c005ae93a -r 26f5733fb645 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java --- 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 c = (Class) 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, "", "()V", null, new String[] { }); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()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}; + } diff -r 2b7c005ae93a -r 26f5733fb645 src/share/vm/classfile/systemDictionary.hpp --- 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)) \ diff -r 2b7c005ae93a -r 26f5733fb645 src/share/vm/classfile/vmSymbols.hpp --- 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")) \ diff -r 2b7c005ae93a -r 26f5733fb645 src/share/vm/graal/graalCodeInstaller.cpp --- 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 { diff -r 2b7c005ae93a -r 26f5733fb645 src/share/vm/graal/graalJavaAccess.hpp --- 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) \