Skip to content

Commit 0d41eaf

Browse files
committed
[GR-14095] Fixes
PullRequest: truffleruby/646
2 parents 726b4fe + b73b5b2 commit 0d41eaf

File tree

8 files changed

+43
-16
lines changed

8 files changed

+43
-16
lines changed

src/launcher/java/org/truffleruby/launcher/RubyLauncher.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ private int runRubyMain(Context.Builder contextBuilder, CommandLineOptions confi
222222

223223
private static void debugPreInitialization() {
224224
if (!isAOT() && TruffleRuby.PRE_INITIALIZE_CONTEXTS) {
225+
// This is only run when saying that you are pre-initialising a context but actually you're not running in the image generator
226+
225227
try {
226228
final Class<?> holderClz = Class.forName("org.graalvm.polyglot.Engine$ImplHolder");
227229
final Method preInitMethod = holderClz.getDeclaredMethod("preInitializeEngine");

src/main/java/org/truffleruby/cext/WrapNode.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.jcodings.specific.UTF8Encoding;
2020
import org.truffleruby.Layouts;
2121
import org.truffleruby.core.rope.RopeOperations;
22+
import org.truffleruby.extra.ffi.Pointer;
2223
import org.truffleruby.language.NotProvided;
2324
import org.truffleruby.language.RubyBaseNode;
2425
import org.truffleruby.language.control.RaiseException;
@@ -85,7 +86,12 @@ public ValueWrapper wrapValue(DynamicObject value,
8586
synchronized (value) {
8687
wrapper = (ValueWrapper) readWrapperNode.execute(value);
8788
if (wrapper == null) {
89+
/*
90+
* This is double-checked locking, but it's safe because the object that we create,
91+
* the ValueWrapper, is not published until after a memory store fence.
92+
*/
8893
wrapper = new ValueWrapper(value, UNSET_HANDLE);
94+
Pointer.UNSAFE.storeFence();
8995
writeWrapperNode.write(value, wrapper);
9096
}
9197
}

src/main/java/org/truffleruby/core/module/ModuleOperations.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,13 @@ public static void setClassVariable(final RubyContext context, DynamicObject mod
543543
if (!trySetClassVariable(module, name, value)) {
544544
synchronized (context.getClassVariableDefinitionLock()) {
545545
if (!trySetClassVariable(module, name, value)) {
546+
/*
547+
* This is double-checked locking, but it is safe because when writing to a ConcurrentHashMap "an
548+
* update operation for a given key bears a happens-before relation with any (non-null) retrieval
549+
* for that key reporting the updated value" (JavaDoc) so the value is guaranteed to be fully
550+
* published before it can be found in the map.
551+
*/
552+
546553
moduleFields.getClassVariables().put(name, value);
547554
}
548555
}

src/main/java/org/truffleruby/core/rope/PathToRopeCache.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.truffleruby.core.string.StringOperations;
1616

1717
import java.util.WeakHashMap;
18+
import java.util.concurrent.locks.Lock;
1819
import java.util.concurrent.locks.ReadWriteLock;
1920
import java.util.concurrent.locks.ReentrantReadWriteLock;
2021

@@ -40,23 +41,27 @@ public PathToRopeCache(RubyContext context) {
4041
*/
4142
@TruffleBoundary
4243
public Rope getCachedPath(String string) {
43-
lock.readLock().lock();
44+
final Lock readLock = lock.readLock();
45+
46+
readLock.lock();
4447
try {
4548
final Rope rope = javaStringToRope.get(string);
4649
if (rope != null) {
4750
return rope;
4851
}
4952
} finally {
50-
lock.readLock().unlock();
53+
readLock.unlock();
5154
}
5255

5356
final Rope cachedRope = context.getRopeCache().getRope(StringOperations.encodeRope(string, UTF8Encoding.INSTANCE));
5457

55-
lock.writeLock().lock();
58+
final Lock writeLock = lock.writeLock();
59+
60+
writeLock.lock();
5661
try {
5762
javaStringToRope.putIfAbsent(string, cachedRope);
5863
} finally {
59-
lock.writeLock().unlock();
64+
writeLock.unlock();
6065
}
6166

6267
return cachedRope;

src/main/java/org/truffleruby/core/symbol/SymbolTable.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.Collection;
3636
import java.util.Map;
3737
import java.util.WeakHashMap;
38+
import java.util.concurrent.locks.Lock;
3839
import java.util.concurrent.locks.ReadWriteLock;
3940
import java.util.concurrent.locks.ReentrantReadWriteLock;
4041

@@ -65,14 +66,16 @@ public DynamicObject getSymbol(String string) {
6566
final StringKey stringKey = new StringKey(string, hashing);
6667
DynamicObject symbol;
6768

68-
lock.readLock().lock();
69+
final Lock readLock = lock.readLock();
70+
71+
readLock.lock();
6972
try {
7073
symbol = lookupCache(stringToSymbolCache, stringKey);
7174
if (symbol != null) {
7275
return symbol;
7376
}
7477
} finally {
75-
lock.readLock().unlock();
78+
readLock.unlock();
7679
}
7780

7881
final Rope rope;
@@ -84,13 +87,16 @@ public DynamicObject getSymbol(String string) {
8487
symbol = getSymbol(rope);
8588

8689
// Add it to the direct j.l.String to Symbol cache
87-
lock.writeLock().lock();
90+
91+
final Lock writeLock = lock.writeLock();
92+
93+
writeLock.lock();
8894
try {
8995
if (lookupCache(stringToSymbolCache, stringKey) == null) {
9096
stringToSymbolCache.put(stringKey, new SoftReference<>(symbol));
9197
}
9298
} finally {
93-
lock.writeLock().unlock();
99+
writeLock.unlock();
94100
}
95101

96102
return symbol;

src/main/java/org/truffleruby/language/loader/ReentrantLockFreeingMap.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
* GNU General Public License version 2, or
88
* GNU Lesser General Public License version 2.1.
99
*/
10-
1110
package org.truffleruby.language.loader;
1211

1312
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;

src/main/java/org/truffleruby/language/loader/ResourceLoader.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ public RubySource loadResource(String path, boolean internal) throws IOException
4646
throw new FileNotFoundException(path);
4747
}
4848

49-
// We guarantee that we only put UTF-8 source files into resources
50-
final InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8);
49+
final Source source;
5150

52-
final Source source = Source
53-
.newBuilder(TruffleRuby.LANGUAGE_ID, reader, path)
54-
.internal(internal)
55-
.build();
51+
// We guarantee that we only put UTF-8 source files into resources
52+
try (final InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
53+
source = Source
54+
.newBuilder(TruffleRuby.LANGUAGE_ID, reader, path)
55+
.internal(internal)
56+
.build();
57+
}
5658

5759
return new RubySource(source);
5860
}

src/shared/java/org/truffleruby/shared/BasicPlatform.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public static String getOSName() {
6262
public static OS_TYPE determineOS() {
6363
final String osName = System.getProperty("os.name");
6464

65-
final String lowerOSName = osName.toLowerCase();
65+
final String lowerOSName = osName.toLowerCase(Locale.ENGLISH);
6666
if (lowerOSName.contains("windows")) {
6767
return OS_TYPE.WINDOWS;
6868
}

0 commit comments

Comments
 (0)