7012965: Fix failed on sparc for 7009756: volatile variables could be broken throw reflection API
Summary: Use LDX/STX on v9 and LDD/STD on v8 sparc for volatile long moves.
Reviewed-by: never
--- a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Thu Oct 07 13:49:40 2010 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Tue Jan 18 17:10:03 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -35,14 +35,12 @@
inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; }
inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; }
inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; }
-inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; }
inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; }
inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; }
inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; }
inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; }
-inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
@@ -54,8 +52,49 @@
inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); }
inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); }
+
+#ifdef _LP64
+
+inline void Atomic::store(jlong store_value, jlong* dest) { *dest = store_value; }
+inline void Atomic::store(jlong store_value, volatile jlong* dest) { *dest = store_value; }
inline jlong Atomic::load(volatile jlong* src) { return *src; }
+#else
+
+extern "C" void _Atomic_move_long_v8(volatile jlong* src, volatile jlong* dst);
+extern "C" void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst);
+
+inline void Atomic_move_long(volatile jlong* src, volatile jlong* dst) {
+#ifdef COMPILER2
+ // Compiler2 does not support v8, it is used only for v9.
+ assert (VM_Version::v9_instructions_work(), "only supported on v9");
+ _Atomic_move_long_v9(src, dst);
+#else
+ // The branch is cheaper then emulated LDD.
+ if (VM_Version::v9_instructions_work()) {
+ _Atomic_move_long_v9(src, dst);
+ } else {
+ _Atomic_move_long_v8(src, dst);
+ }
+#endif
+}
+
+inline jlong Atomic::load(volatile jlong* src) {
+ volatile jlong dest;
+ Atomic_move_long(src, &dest);
+ return dest;
+}
+
+inline void Atomic::store(jlong store_value, jlong* dest) {
+ Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest);
+}
+
+inline void Atomic::store(jlong store_value, volatile jlong* dest) {
+ Atomic_move_long((volatile jlong*)&store_value, dest);
+}
+
+#endif
+
#ifdef _GNU_SOURCE
inline jint Atomic::add (jint add_value, volatile jint* dest) {
--- a/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Thu Oct 07 13:49:40 2010 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Tue Jan 18 17:10:03 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -77,11 +77,11 @@
inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { return *p; }
inline jshort OrderAccess::load_acquire(volatile jshort* p) { return *p; }
inline jint OrderAccess::load_acquire(volatile jint* p) { return *p; }
-inline jlong OrderAccess::load_acquire(volatile jlong* p) { return *p; }
+inline jlong OrderAccess::load_acquire(volatile jlong* p) { return Atomic::load(p); }
inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { return *p; }
inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; }
inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; }
-inline julong OrderAccess::load_acquire(volatile julong* p) { return *p; }
+inline julong OrderAccess::load_acquire(volatile julong* p) { return Atomic::load((volatile jlong*)p); }
inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; }
inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return *p; }
@@ -92,11 +92,11 @@
inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { *p = v; }
inline void OrderAccess::release_store(volatile jshort* p, jshort v) { *p = v; }
inline void OrderAccess::release_store(volatile jint* p, jint v) { *p = v; }
-inline void OrderAccess::release_store(volatile jlong* p, jlong v) { *p = v; }
+inline void OrderAccess::release_store(volatile jlong* p, jlong v) { Atomic::store(v, p); }
inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { *p = v; }
inline void OrderAccess::release_store(volatile jushort* p, jushort v) { *p = v; }
inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; }
-inline void OrderAccess::release_store(volatile julong* p, julong v) { *p = v; }
+inline void OrderAccess::release_store(volatile julong* p, julong v) { Atomic::store((jlong)v, (volatile jlong*)p); }
inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; }
inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { *p = v; }
@@ -120,11 +120,11 @@
inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { *p = v; fence(); }
inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { *p = v; fence(); }
inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { *p = v; fence(); }
-inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { *p = v; fence(); }
+inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { release_store(p, v); fence(); }
inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { *p = v; fence(); }
inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { *p = v; fence(); }
inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { *p = v; fence(); }
-inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { *p = v; fence(); }
+inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store(p, v); fence(); }
inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); }
inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { *p = v; fence(); }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.il Thu Oct 07 13:49:40 2010 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.il Tue Jan 18 17:10:03 2011 -0800
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2002, 2011, 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
@@ -152,6 +152,39 @@
.nonvolatile
.end
+ // Support for jlong Atomic::load and Atomic::store on v8.
+ //
+ // void _Atomic_move_long_v8(volatile jlong* src, volatile jlong* dst)
+ //
+ // Arguments:
+ // src: O0
+ // dest: O1
+ //
+ // Overwrites O2 and O3
+
+ .inline _Atomic_move_long_v8,2
+ .volatile
+ ldd [%o0], %o2
+ std %o2, [%o1]
+ .nonvolatile
+ .end
+
+ // Support for jlong Atomic::load and Atomic::store on v9.
+ //
+ // void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst)
+ //
+ // Arguments:
+ // src: O0
+ // dest: O1
+ //
+ // Overwrites O2
+
+ .inline _Atomic_move_long_v9,2
+ .volatile
+ ldx [%o0], %o2
+ stx %o2, [%o1]
+ .nonvolatile
+ .end
// Support for jint Atomic::add(jint add_value, volatile jint* dest).
//