Skip to content

Commit 3a920de

Browse files
committed
[GR-18163] Use a separate node to get the ReentrantLock for TruffleRuby.synchronized
PullRequest: truffleruby/4199
2 parents 91f3188 + d8b9749 commit 3a920de

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

src/main/java/org/truffleruby/extra/TruffleRubyNodes.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
import com.oracle.truffle.api.dsl.Bind;
1313
import com.oracle.truffle.api.dsl.Cached;
14+
import com.oracle.truffle.api.dsl.GenerateCached;
15+
import com.oracle.truffle.api.dsl.GenerateInline;
1416
import com.oracle.truffle.api.library.CachedLibrary;
1517
import com.oracle.truffle.api.nodes.Node;
1618
import com.oracle.truffle.api.object.DynamicObjectLibrary;
@@ -20,6 +22,7 @@
2022
import org.truffleruby.RubyContext;
2123
import org.truffleruby.RubyLanguage;
2224
import org.truffleruby.annotations.CoreMethod;
25+
import org.truffleruby.annotations.Split;
2326
import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
2427
import org.truffleruby.builtins.CoreMethodNode;
2528
import org.truffleruby.annotations.CoreModule;
@@ -31,6 +34,7 @@
3134
import com.oracle.truffle.api.Truffle;
3235
import com.oracle.truffle.api.TruffleOptions;
3336
import com.oracle.truffle.api.dsl.Specialization;
37+
import org.truffleruby.language.RubyBaseNode;
3438
import org.truffleruby.language.RubyDynamicObject;
3539
import org.truffleruby.language.yield.CallBlockNode;
3640

@@ -106,19 +110,18 @@ Object fullMemoryBarrier() {
106110
}
107111
}
108112

109-
@CoreMethod(names = "synchronized", onSingleton = true, required = 1, needsBlock = true)
113+
@CoreMethod(names = "synchronized", onSingleton = true, required = 1, needsBlock = true, split = Split.ALWAYS)
110114
public abstract static class SynchronizedNode extends CoreMethodArrayArgumentsNode {
111115

112116
/** We must not allow to synchronize on boxed primitives as that would be misleading. We use a ReentrantLock and
113117
* not simply Java's {@code synchronized} here as we need to be able to interrupt for guest safepoints and it is
114118
* not possible to interrupt Java's {@code synchronized (object) {}}. */
115-
@Specialization(limit = "getDynamicObjectCacheLimit()")
119+
@Specialization
116120
static Object synchronize(RubyDynamicObject object, RubyProc block,
117-
@CachedLibrary("object") DynamicObjectLibrary objectLibrary,
121+
@Cached GetLockNode getLockNode,
118122
@Cached CallBlockNode yieldNode,
119-
@Cached InlinedBranchProfile initializeLockProfile,
120123
@Bind("this") Node node) {
121-
final ReentrantLock lock = getLock(node, object, objectLibrary, initializeLockProfile);
124+
final ReentrantLock lock = getLockNode.execute(node, object);
122125

123126
MutexOperations.lockInternal(getContext(node), lock, node);
124127
try {
@@ -128,8 +131,18 @@ static Object synchronize(RubyDynamicObject object, RubyProc block,
128131
}
129132
}
130133

131-
private static ReentrantLock getLock(Node node, RubyDynamicObject object, DynamicObjectLibrary objectLibrary,
132-
InlinedBranchProfile initializeLockProfile) {
134+
}
135+
136+
@GenerateInline
137+
@GenerateCached(false)
138+
public abstract static class GetLockNode extends RubyBaseNode {
139+
140+
public abstract ReentrantLock execute(Node node, RubyDynamicObject object);
141+
142+
@Specialization(limit = "getDynamicObjectCacheLimit()")
143+
static ReentrantLock getLock(Node node, RubyDynamicObject object,
144+
@CachedLibrary("object") DynamicObjectLibrary objectLibrary,
145+
@Cached InlinedBranchProfile initializeLockProfile) {
133146
ReentrantLock lock = (ReentrantLock) objectLibrary.getOrDefault(object, Layouts.OBJECT_LOCK, null);
134147
if (lock != null) {
135148
return lock;
@@ -147,7 +160,6 @@ private static ReentrantLock getLock(Node node, RubyDynamicObject object, Dynami
147160
}
148161
}
149162
}
150-
151163
}
152164

153165
}

0 commit comments

Comments
 (0)