8148175: C1: G1 barriers don't preserve FP registers
authorvlivanov
Mon, 28 Mar 2016 13:49:34 +0300
changeset 36832 ead44efe160f
parent 36831 6a71b98a4417
child 36833 0f6d4a480a96
8148175: C1: G1 barriers don't preserve FP registers Reviewed-by: kvn
hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
hotspot/test/TEST.groups
hotspot/test/compiler/gcbarriers/PreserveFPRegistersTest.java
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Mon Mar 28 13:49:34 2016 +0300
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Mon Mar 28 13:49:34 2016 +0300
@@ -1646,31 +1646,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);
@@ -1744,27 +1728,13 @@
         __ jmp(enqueued);
 
         __ bind(runtime);
-#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);
+
         __ bind(enqueued);
         __ pop(rdx);
 
--- a/hotspot/test/TEST.groups	Mon Mar 28 13:49:34 2016 +0300
+++ b/hotspot/test/TEST.groups	Mon Mar 28 13:49:34 2016 +0300
@@ -98,7 +98,7 @@
   serviceability/attach/AttachWithStalePidFile.java \
   serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \
   serviceability/dcmd/vm/DynLibsTest.java \
-  serviceability/tmtools		
+  serviceability/tmtools
 
 
 # JRE adds further tests to compact3
@@ -248,7 +248,7 @@
   gc/metaspace/G1AddMetaspaceDependency.java \
   gc/metaspace/TestMetaspacePerfCounters.java \
   gc/startup_warnings/TestG1.java \
-  gc/whitebox/TestConcMarkCycleWB.java 
+  gc/whitebox/TestConcMarkCycleWB.java
 
 hotspot_native_sanity = \
   native_sanity
@@ -267,7 +267,7 @@
   -compiler/c2/6792161 \
   -compiler/c2/7070134 \
   -compiler/c2/8004867
-  
+
 hotspot_compiler_2 = \
   compiler/classUnloading/ \
   compiler/codecache/ \
@@ -284,8 +284,9 @@
   compiler/interpreter/ \
   compiler/jvmci/ \
   -compiler/codegen/7184394 \
-  -compiler/codecache/stress
-  
+  -compiler/codecache/stress \
+  -compiler/gcbarriers/PreserveFPRegistersTest.java
+
 hotspot_compiler_3 = \
   compiler/intrinsics/ \
   compiler/jsr292/ \
@@ -370,4 +371,4 @@
   -:needs_nashorn
 
 hotspot_tmtools = \
-  serviceability/tmtools	
+  serviceability/tmtools
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/gcbarriers/PreserveFPRegistersTest.java	Mon Mar 28 13:49:34 2016 +0300
@@ -0,0 +1,98 @@
+/*
+ * 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
+ * @bug 8148175
+ * @run main/othervm/timeout=300 -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) ;
+    }
+}