diff --git a/src/cpu/sparc/vm/methodHandles_sparc.cpp b/src/cpu/sparc/vm/methodHandles_sparc.cpp index 50bbbafa4050568c73633b463304ffd35d2b75a4..699f9151b8cc88cd1ab9b0a3495373145a09a09e 100644 --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp @@ -689,8 +689,8 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan { // Perform an in-place conversion to int or an int subword. __ ldsw(G3_amh_vmargslot, O0_argslot); - Address vmarg = __ argument_address(O0_argslot); Address value; + Address vmarg = __ argument_address(O0_argslot); bool value_left_justified = false; switch (ek) { @@ -700,9 +700,21 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan case _adapter_opt_l2i: { // just delete the extra slot +#ifdef _LP64 + // In V9, longs are given 2 64-bit slots in the interpreter, but the + // data is passed in only 1 slot. + // Keep the second slot. + __ add(Gargs, __ argument_offset(O0_argslot, -1), O0_argslot); + remove_arg_slots(_masm, -stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch); + value = Address(O0_argslot, 4); // Get least-significant 32-bit of 64-bit value. + vmarg = Address(O0_argslot, Interpreter::stackElementSize); +#else + // Keep the first slot. __ add(Gargs, __ argument_offset(O0_argslot), O0_argslot); remove_arg_slots(_masm, -stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch); - value = vmarg = Address(O0_argslot, 0); + value = Address(O0_argslot, 0); + vmarg = value; +#endif } break; case _adapter_opt_unboxi: diff --git a/test/compiler/6991596/Test6991596.java b/test/compiler/6991596/Test6991596.java index 3809be35c0f82354ea6c45ec23f93f42fb6f7e0a..aff08c886415a0396d0c19c0239d360a774951df 100644 --- a/test/compiler/6991596/Test6991596.java +++ b/test/compiler/6991596/Test6991596.java @@ -35,7 +35,7 @@ import java.dyn.*; public class Test6991596 { private static final Class CLASS = Test6991596.class; private static final String NAME = "foo"; - private static final boolean DEBUG = false; + private static final boolean DEBUG = System.getProperty("DEBUG", "false").equals("true"); public static void main(String[] args) throws Throwable { testboolean(); @@ -47,7 +47,7 @@ public class Test6991596 { } // Helpers to get various methods. - static MethodHandle getmh1(Class ret, Class arg) { + static MethodHandle getmh1(Class ret, Class arg) throws NoAccessException { return MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(ret, arg)); } static MethodHandle getmh2(MethodHandle mh1, Class ret, Class arg) { @@ -76,38 +76,38 @@ public class Test6991596 { MethodHandle mh2 = getmh2(mh1, boolean.class, boolean.class); // TODO add this for all cases when the bugs are fixed. //MethodHandle mh3 = getmh3(mh1, boolean.class, boolean.class); - boolean a = mh1.invokeExact((boolean) x); - boolean b = mh2.invokeExact(x); + boolean a = (boolean) mh1.invokeExact((boolean) x); + boolean b = (boolean) mh2.invokeExact(x); //boolean c = mh3.invokeExact((boolean) x); - assert a == b : a + " != " + b; - //assert c == x : c + " != " + x; + check(x, a, b); + //check(x, c, x); } // byte { MethodHandle mh1 = getmh1( byte.class, byte.class ); MethodHandle mh2 = getmh2(mh1, byte.class, boolean.class); - byte a = mh1.invokeExact((byte) (x ? 1 : 0)); - byte b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + byte a = (byte) mh1.invokeExact((byte) (x ? 1 : 0)); + byte b = (byte) mh2.invokeExact(x); + check(x, a, b); } // char { MethodHandle mh1 = getmh1( char.class, char.class); MethodHandle mh2 = getmh2(mh1, char.class, boolean.class); - char a = mh1.invokeExact((char) (x ? 1 : 0)); - char b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + char a = (char) mh1.invokeExact((char) (x ? 1 : 0)); + char b = (char) mh2.invokeExact(x); + check(x, a, b); } // short { MethodHandle mh1 = getmh1( short.class, short.class); MethodHandle mh2 = getmh2(mh1, short.class, boolean.class); - short a = mh1.invokeExact((short) (x ? 1 : 0)); - short b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + short a = (short) mh1.invokeExact((short) (x ? 1 : 0)); + short b = (short) mh2.invokeExact(x); + check(x, a, b); } } @@ -134,36 +134,36 @@ public class Test6991596 { { MethodHandle mh1 = getmh1( boolean.class, boolean.class); MethodHandle mh2 = getmh2(mh1, boolean.class, byte.class); - boolean a = mh1.invokeExact((x & 1) == 1); - boolean b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + boolean a = (boolean) mh1.invokeExact((x & 1) == 1); + boolean b = (boolean) mh2.invokeExact(x); + check(x, a, b); } // byte { MethodHandle mh1 = getmh1( byte.class, byte.class); MethodHandle mh2 = getmh2(mh1, byte.class, byte.class); - byte a = mh1.invokeExact((byte) x); - byte b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + byte a = (byte) mh1.invokeExact((byte) x); + byte b = (byte) mh2.invokeExact(x); + check(x, a, b); } // char { MethodHandle mh1 = getmh1( char.class, char.class); MethodHandle mh2 = getmh2(mh1, char.class, byte.class); - char a = mh1.invokeExact((char) x); - char b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + char a = (char) mh1.invokeExact((char) x); + char b = (char) mh2.invokeExact(x); + check(x, a, b); } // short { MethodHandle mh1 = getmh1( short.class, short.class); MethodHandle mh2 = getmh2(mh1, short.class, byte.class); - short a = mh1.invokeExact((short) x); - short b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + short a = (short) mh1.invokeExact((short) x); + short b = (short) mh2.invokeExact(x); + check(x, a, b); } } @@ -188,36 +188,36 @@ public class Test6991596 { { MethodHandle mh1 = getmh1( boolean.class, boolean.class); MethodHandle mh2 = getmh2(mh1, boolean.class, char.class); - boolean a = mh1.invokeExact((x & 1) == 1); - boolean b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + boolean a = (boolean) mh1.invokeExact((x & 1) == 1); + boolean b = (boolean) mh2.invokeExact(x); + check(x, a, b); } // byte { MethodHandle mh1 = getmh1( byte.class, byte.class); MethodHandle mh2 = getmh2(mh1, byte.class, char.class); - byte a = mh1.invokeExact((byte) x); - byte b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + byte a = (byte) mh1.invokeExact((byte) x); + byte b = (byte) mh2.invokeExact(x); + check(x, a, b); } // char { MethodHandle mh1 = getmh1( char.class, char.class); MethodHandle mh2 = getmh2(mh1, char.class, char.class); - char a = mh1.invokeExact((char) x); - char b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + char a = (char) mh1.invokeExact((char) x); + char b = (char) mh2.invokeExact(x); + check(x, a, b); } // short { MethodHandle mh1 = getmh1( short.class, short.class); MethodHandle mh2 = getmh2(mh1, short.class, char.class); - short a = mh1.invokeExact((short) x); - short b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + short a = (short) mh1.invokeExact((short) x); + short b = (short) mh2.invokeExact(x); + check(x, a, b); } } @@ -248,36 +248,36 @@ public class Test6991596 { { MethodHandle mh1 = getmh1( boolean.class, boolean.class); MethodHandle mh2 = getmh2(mh1, boolean.class, short.class); - boolean a = mh1.invokeExact((x & 1) == 1); - boolean b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + boolean a = (boolean) mh1.invokeExact((x & 1) == 1); + boolean b = (boolean) mh2.invokeExact(x); + check(x, a, b); } // byte { MethodHandle mh1 = getmh1( byte.class, byte.class); MethodHandle mh2 = getmh2(mh1, byte.class, short.class); - byte a = mh1.invokeExact((byte) x); - byte b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + byte a = (byte) mh1.invokeExact((byte) x); + byte b = (byte) mh2.invokeExact(x); + check(x, a, b); } // char { MethodHandle mh1 = getmh1( char.class, char.class); MethodHandle mh2 = getmh2(mh1, char.class, short.class); - char a = mh1.invokeExact((char) x); - char b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + char a = (char) mh1.invokeExact((char) x); + char b = (char) mh2.invokeExact(x); + check(x, a, b); } // short { MethodHandle mh1 = getmh1( short.class, short.class); MethodHandle mh2 = getmh2(mh1, short.class, short.class); - short a = mh1.invokeExact((short) x); - short b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + short a = (short) mh1.invokeExact((short) x); + short b = (short) mh2.invokeExact(x); + check(x, a, b); } } @@ -316,45 +316,46 @@ public class Test6991596 { { MethodHandle mh1 = getmh1( boolean.class, boolean.class); MethodHandle mh2 = getmh2(mh1, boolean.class, int.class); - boolean a = mh1.invokeExact((x & 1) == 1); - boolean b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + boolean a = (boolean) mh1.invokeExact((x & 1) == 1); + boolean b = (boolean) mh2.invokeExact(x); + check(x, a, b); } // byte { MethodHandle mh1 = getmh1( byte.class, byte.class); MethodHandle mh2 = getmh2(mh1, byte.class, int.class); - byte a = mh1.invokeExact((byte) x); - byte b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + byte a = (byte) mh1.invokeExact((byte) x); + byte b = (byte) mh2.invokeExact(x); + check(x, a, b); } // char { MethodHandle mh1 = getmh1( char.class, char.class); MethodHandle mh2 = getmh2(mh1, char.class, int.class); - char a = mh1.invokeExact((char) x); - char b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + char a = (char) mh1.invokeExact((char) x); + char b = (char) mh2.invokeExact(x); + check(x, a, b); } // short { MethodHandle mh1 = getmh1( short.class, short.class); MethodHandle mh2 = getmh2(mh1, short.class, int.class); - short a = mh1.invokeExact((short) x); - short b = mh2.invokeExact(x); + short a = (short) mh1.invokeExact((short) x); + short b = (short) mh2.invokeExact(x); assert a == b : a + " != " + b; + check(x, a, b); } // int { MethodHandle mh1 = getmh1( int.class, int.class); MethodHandle mh2 = getmh2(mh1, int.class, int.class); - int a = mh1.invokeExact((int) x); - int b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + int a = (int) mh1.invokeExact((int) x); + int b = (int) mh2.invokeExact(x); + check(x, a, b); } } @@ -395,49 +396,66 @@ public class Test6991596 { { MethodHandle mh1 = getmh1( boolean.class, boolean.class); MethodHandle mh2 = getmh2(mh1, boolean.class, long.class); - boolean a = mh1.invokeExact((x & 1L) == 1L); - boolean b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + boolean a = (boolean) mh1.invokeExact((x & 1L) == 1L); + boolean b = (boolean) mh2.invokeExact(x); + check(x, a, b); } // byte { MethodHandle mh1 = getmh1( byte.class, byte.class); MethodHandle mh2 = getmh2(mh1, byte.class, long.class); - byte a = mh1.invokeExact((byte) x); - byte b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + byte a = (byte) mh1.invokeExact((byte) x); + byte b = (byte) mh2.invokeExact(x); + check(x, a, b); } // char { MethodHandle mh1 = getmh1( char.class, char.class); MethodHandle mh2 = getmh2(mh1, char.class, long.class); - char a = mh1.invokeExact((char) x); - char b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + char a = (char) mh1.invokeExact((char) x); + char b = (char) mh2.invokeExact(x); + check(x, a, b); } // short { MethodHandle mh1 = getmh1( short.class, short.class); MethodHandle mh2 = getmh2(mh1, short.class, long.class); - short a = mh1.invokeExact((short) x); - short b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + short a = (short) mh1.invokeExact((short) x); + short b = (short) mh2.invokeExact(x); + check(x, a, b); } // int { MethodHandle mh1 = getmh1( int.class, int.class); MethodHandle mh2 = getmh2(mh1, int.class, long.class); - int a = mh1.invokeExact((int) x); - int b = mh2.invokeExact(x); - assert a == b : a + " != " + b; + int a = (int) mh1.invokeExact((int) x); + int b = (int) mh2.invokeExact(x); + check(x, a, b); } - } + static void check(boolean x, boolean e, boolean a) { p(z2h(x), z2h(e), z2h(a)); assert e == a : z2h(x) + ": " + z2h(e) + " != " + z2h(a); } + static void check(boolean x, byte e, byte a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); } + static void check(boolean x, int e, int a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); } + + static void check(int x, boolean e, boolean a) { p(i2h(x), z2h(e), z2h(a)); assert e == a : i2h(x) + ": " + z2h(e) + " != " + z2h(a); } + static void check(int x, byte e, byte a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); } + static void check(int x, int e, int a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); } + + static void check(long x, boolean e, boolean a) { p(l2h(x), z2h(e), z2h(a)); assert e == a : l2h(x) + ": " + z2h(e) + " != " + z2h(a); } + static void check(long x, byte e, byte a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); } + static void check(long x, int e, int a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); } + + static void p(String x, String e, String a) { if (DEBUG) System.out.println(x + ": expected: " + e + ", actual: " + a); } + + static String z2h(boolean x) { return x ? "1" : "0"; } + static String i2h(int x) { return Integer.toHexString(x); } + static String l2h(long x) { return Long.toHexString(x); } + // to int public static boolean foo(boolean i) { return i; } public static byte foo(byte i) { return i; }