JDK-7010665 : Misplaced membar in C1 implementation of Unsafe.get/putXXX
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: hs20
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2011-01-06
  • Updated: 2011-04-23
  • Resolved: 2011-04-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u25Fixed 7Fixed hs20Fixed
Description
The C1 shared code for generating the intrinsics for the Unsafe.getXXX and Unsafe.putXXX is:

void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
  ...
  if (x->is_volatile() && os::is_MP()) __ membar_acquire();
  get_Object_unsafe(reg, src.result(), off.result(), type, x->is_volatile());
  if (x->is_volatile() && os::is_MP()) __ membar();
}

void LIRGenerator::do_UnsafePutObject(UnsafePutObject* x) {
  ...
  if (x->is_volatile() && os::is_MP()) __ membar_release();
  put_Object_unsafe(src.result(), off.result(), data.result(), type, x->is_volatile());
} 

Note that "get" has a final membar(), but it is the "put" that needs it.

Also "get" should be "load; acquire" not "acquire; load"

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/df307487d610
14-01-2011

EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/rev/df307487d610
10-01-2011

PUBLIC COMMENTS Test comment for public access
10-01-2011

EVALUATION Correct formulation should be: void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) { ... get_Object_unsafe(reg, src.result(), off.result(), type, x->is_volatile()); if (x->is_volatile() && os::is_MP()) __ membar_acquire(); } void LIRGenerator::do_UnsafePutObject(UnsafePutObject* x) { ... if (x->is_volatile() && os::is_MP()) __ membar_release(); put_Object_unsafe(src.result(), off.result(), data.result(), type, x->is_volatile()); if (x->is_volatile() && os::is_MP()) __ membar(); }
06-01-2011