--- /dev/null 2016-04-25 11:46:41.725730096 -0400 +++ new/test/runtime/locallong/LocalLongTest.java 2016-09-06 17:16:27.762481967 -0400 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, 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. + */ + + +/* + * @test LocalLongTest + * @bug 8163014 + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @compile LocalLongHelper.java + * @run driver LocalLongTest + */ + +import jdk.test.lib.Platform; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class LocalLongTest { + public static void main(String... args) throws Exception { + if (Platform.is64bit()) { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xcomp", + "-Xlog:monitormismatch=info", + "LocalLongHelper"); + OutputAnalyzer o = new OutputAnalyzer(pb.start()); + o.shouldHaveExitValue(0); + } + }; +} --- /dev/null 2016-04-25 11:46:41.725730096 -0400 +++ new/test/runtime/locallong/LocalLongHelper.java 2016-09-06 17:16:27.862080535 -0400 @@ -0,0 +1,84 @@ +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.lang.StackWalker.StackFrame; + +public class LocalLongHelper { + static StackWalker sw; + static Method intValue; + static Method getLocals; + static Class primitiveValueClass; + static Method primitiveType; + static Method getMethodType; + static Field memberName; + static Field offset; + + public static void main(String[] args) throws Throwable { + setupReflectionStatics(); + new LocalLongHelper().longArg(0xC0FFEE, 0x1234567890ABCDEFL); + } + + /* + * The first 4 local slots should be: + * 0: this + * 1: int "i" + * 2: long "l", first slot + * 3: long "l", second slot + */ + public long longArg(int i, long l) throws Throwable { + List frames = sw.walk(s -> s.collect(Collectors.toList())); + Object[] locals = (Object[]) getLocals.invoke(frames.get(0)); + + int locals_1 = (int) intValue.invoke(locals[1]); // java.lang.LiveStackFrame$PrimitiveValue.intValue() + int locals_2 = (int) intValue.invoke(locals[2]); + int locals_3 = (int) intValue.invoke(locals[3]); + if (locals_2 != 0){ + throw new RuntimeException("Expected locals_2 == 0"); + } + return l; // Don't want l to become a dead var + } + + private static void setupReflectionStatics() throws Throwable { + Class liveStackFrameClass = Class.forName("java.lang.LiveStackFrame"); + primitiveValueClass = Class.forName("java.lang.LiveStackFrame$PrimitiveValue"); + + getLocals = liveStackFrameClass.getDeclaredMethod("getLocals"); + getLocals.setAccessible(true); + + intValue = primitiveValueClass.getDeclaredMethod("intValue"); + intValue.setAccessible(true); + + Class stackFrameInfoClass = Class.forName("java.lang.StackFrameInfo"); + memberName = stackFrameInfoClass.getDeclaredField("memberName"); + memberName.setAccessible(true); + offset = stackFrameInfoClass.getDeclaredField("bci"); + offset.setAccessible(true); + getMethodType = Class.forName("java.lang.invoke.MemberName").getDeclaredMethod("getMethodType"); + getMethodType.setAccessible(true); + + Class extendedOptionClass = Class.forName("java.lang.StackWalker$ExtendedOption"); + Method ewsNI = StackWalker.class.getDeclaredMethod("newInstance", Set.class, extendedOptionClass); + ewsNI.setAccessible(true); + Field f = extendedOptionClass.getDeclaredField("LOCALS_AND_OPERANDS"); + f.setAccessible(true); + Object localsAndOperandsOption = f.get(null); + + primitiveType = primitiveValueClass.getDeclaredMethod("type"); + primitiveType.setAccessible(true); + + sw = (StackWalker) ewsNI.invoke(null, java.util.Collections.emptySet(), localsAndOperandsOption); + } + + private static String type(Object o) throws Throwable { + if (primitiveValueClass.isInstance(o)) { + final char c = (char) primitiveType.invoke(o); + return String.valueOf(c); + } else if (o != null) { + return o.getClass().getName(); + } else { + return "null"; + } + } +} --- old/src/cpu/sparc/vm/interp_masm_sparc.cpp 2016-09-06 17:16:29.733137699 -0400 +++ new/src/cpu/sparc/vm/interp_masm_sparc.cpp 2016-09-06 17:16:28.404395531 -0400 @@ -359,7 +359,7 @@ #ifdef _LP64 stx(l, r1, offset); // store something more useful here - debug_only(stx(G0, r1, offset+Interpreter::stackElementSize);) + stx(G0, r1, offset+Interpreter::stackElementSize); #else st(l, r1, offset); st(l->successor(), r1, offset + Interpreter::stackElementSize); --- old/src/cpu/aarch64/vm/interp_masm_aarch64.cpp 2016-09-06 17:16:29.771818983 -0400 +++ new/src/cpu/aarch64/vm/interp_masm_aarch64.cpp 2016-09-06 17:16:28.602524679 -0400 @@ -326,7 +326,8 @@ } void InterpreterMacroAssembler::push_l(Register r) { - str(r, pre(esp, 2 * -wordSize)); + str(zr, pre(esp, -wordSize)); + str(r, pre(esp, -wordsize)); } void InterpreterMacroAssembler::pop_f(FloatRegister r) { --- old/src/cpu/x86/vm/interp_masm_x86.cpp 2016-09-06 17:16:29.890007721 -0400 +++ new/src/cpu/x86/vm/interp_masm_x86.cpp 2016-09-06 17:16:28.858942053 -0400 @@ -612,6 +612,7 @@ void InterpreterMacroAssembler::push_l(Register r) { subptr(rsp, 2 * wordSize); movq(Address(rsp, 0), r); + movptr(Address(rsp, Interpreter::expr_offset_in_bytes(1)), NULL_WORD ); } void InterpreterMacroAssembler::pop(TosState state) {