--- old/src/cpu/x86/vm/c1_Runtime1_x86.cpp 2018-02-04 23:12:53.058913405 -0800 +++ new/src/cpu/x86/vm/c1_Runtime1_x86.cpp 2018-02-04 23:12:52.898899080 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2018, 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 @@ -1667,31 +1667,15 @@ __ jmp(done); __ bind(runtime); - __ push(rcx); -#ifdef _LP64 - __ push(r8); - __ push(r9); - __ push(r10); - __ push(r11); -# ifndef _WIN64 - __ push(rdi); - __ push(rsi); -# endif -#endif + + save_live_registers(sasm, 3); + // load the pre-value f.load_argument(0, rcx); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), rcx, thread); -#ifdef _LP64 -# ifndef _WIN64 - __ pop(rsi); - __ pop(rdi); -# endif - __ pop(r11); - __ pop(r10); - __ pop(r9); - __ pop(r8); -#endif - __ pop(rcx); + + restore_live_registers(sasm); + __ bind(done); __ pop(rdx); @@ -1773,27 +1757,13 @@ __ bind(runtime); __ push(rdx); -#ifdef _LP64 - __ push(r8); - __ push(r9); - __ push(r10); - __ push(r11); -# ifndef _WIN64 - __ push(rdi); - __ push(rsi); -# endif -#endif + + save_live_registers(sasm, 3); + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread); -#ifdef _LP64 -# ifndef _WIN64 - __ pop(rsi); - __ pop(rdi); -# endif - __ pop(r11); - __ pop(r10); - __ pop(r9); - __ pop(r8); -#endif + + restore_live_registers(sasm); + __ pop(rdx); __ bind(done); --- /dev/null 2018-02-03 01:35:01.401000000 -0800 +++ new/test/compiler/gcbarriers/PreserveFPRegistersTest.java 2018-02-04 23:12:53.337938334 -0800 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2018, 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 + * @bug 8148175 + * @run main/othervm/timeout=300 -XX:+UseG1GC -Xbatch -Xmx128m PreserveFPRegistersTest + */ +public class PreserveFPRegistersTest { + + public static void main(String... args) throws InterruptedException { + new PreserveFPRegistersTest().go(); + } + + public final Object[][] storage; + + /** + * Number of objects per region. + */ + public final int K = 10; + + /** + * Length of object array: sizeOf(Object[N]) ~= regionSize / K . + */ + public final int N; + + /** + * How many regions involved into testing. + */ + public final int regionCount; + + PreserveFPRegistersTest() { + long regionSize = 1_000_000; //WB.g1RegionSize(); + + Runtime rt = Runtime.getRuntime(); + long used = rt.totalMemory() - rt.freeMemory(); + long totalFree = rt.maxMemory() - used; + regionCount = (int) ( (totalFree / regionSize) * 0.9); + int refSize = 4; + + N = (int) ((regionSize / K ) / refSize) - 5; + storage = new Object[regionCount * K][]; + for (int i = 0; i < storage.length; i++) { + storage[i] = new Object[N]; + } + } + + public void go() throws InterruptedException { + final float FINAL = getValue(); + + for (int to = 0; to < regionCount; to++) { + Object celebrity = storage[to * K]; + for (int from = 0; from < regionCount; from++) { + for (int rn = 0; rn != 100; rn++) { + storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity; + } + if (FINAL != getValue()) { + throw new AssertionError("Final value has changed: " + FINAL + " != " + getValue()); + } + } + } + + System.out.println("TEST PASSED"); + } + + public float getValue() { + return 6; + } + + private int getX(int to, int from, int rn) { + return (rn*regionCount + to) % N; + } + + private int getY(int to, int from, int rn) { + return ((rn*regionCount + to) / N + from * K) % (regionCount*K) ; + } +}