Skip to content

Commit

Permalink
Merge pull request #787 from kares/jruby-rev
Browse files Browse the repository at this point in the history
let's not (potentially) leak context on Java 7
  • Loading branch information
pitr-ch committed Jan 1, 2019
2 parents d739255 + 1782462 commit 173828a
Showing 1 changed file with 9 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
public class SynchronizationLibrary implements Library {

private static final Unsafe UNSAFE = loadUnsafe();
private static final boolean FULL_FENCE = supportsFences();

private static Unsafe loadUnsafe() {
try {
Expand Down Expand Up @@ -140,17 +141,17 @@ public static class JRubyAttrVolatile {
// volatile threadContext is used as a memory barrier per the JVM memory model happens-before semantic
// on volatile fields. any volatile field could have been used but using the thread context is an
// attempt to avoid code elimination.
private static volatile ThreadContext threadContext = null;
private static volatile int volatileField;

@JRubyMethod(name = "full_memory_barrier", visibility = Visibility.PUBLIC)
public static IRubyObject fullMemoryBarrier(ThreadContext context, IRubyObject self) {
// Prevent reordering of ivar writes with publication of this instance
if (!supportsFences()) {
if (!FULL_FENCE) {
// Assuming that following volatile read and write is not eliminated it simulates fullFence.
// If it's eliminated it'll cause problems only on non-x86 platforms.
// http://shipilev.net/blog/2014/jmm-pragmatics/#_happens_before_test_your_understanding
final ThreadContext oldContext = threadContext;
threadContext = context;
final int volatileRead = volatileField;
volatileField = context.getLine();
} else {
UNSAFE.fullFence();
}
Expand All @@ -163,9 +164,9 @@ public static IRubyObject instanceVariableGetVolatile(
IRubyObject self,
IRubyObject name) {
// Ensure we ses latest value with loadFence
if (!supportsFences()) {
if (!FULL_FENCE) {
// piggybacking on volatile read, simulating loadFence
final ThreadContext oldContext = threadContext;
final int volatileRead = volatileField;
return ((RubyBasicObject) self).instance_variable_get(context, name);
} else {
UNSAFE.loadFence();
Expand All @@ -180,10 +181,10 @@ public static IRubyObject InstanceVariableSetVolatile(
IRubyObject name,
IRubyObject value) {
// Ensure we make last update visible
if (!supportsFences()) {
if (!FULL_FENCE) {
// piggybacking on volatile write, simulating storeFence
final IRubyObject result = ((RubyBasicObject) self).instance_variable_set(name, value);
threadContext = context;
volatileField = context.getLine();
return result;
} else {
// JRuby uses StampedVariableAccessor which calls fullFence
Expand Down

0 comments on commit 173828a

Please sign in to comment.