11
11
12
12
import com .oracle .truffle .api .dsl .Bind ;
13
13
import com .oracle .truffle .api .dsl .Cached ;
14
+ import com .oracle .truffle .api .dsl .GenerateCached ;
15
+ import com .oracle .truffle .api .dsl .GenerateInline ;
14
16
import com .oracle .truffle .api .library .CachedLibrary ;
15
17
import com .oracle .truffle .api .nodes .Node ;
16
18
import com .oracle .truffle .api .object .DynamicObjectLibrary ;
20
22
import org .truffleruby .RubyContext ;
21
23
import org .truffleruby .RubyLanguage ;
22
24
import org .truffleruby .annotations .CoreMethod ;
25
+ import org .truffleruby .annotations .Split ;
23
26
import org .truffleruby .builtins .CoreMethodArrayArgumentsNode ;
24
27
import org .truffleruby .builtins .CoreMethodNode ;
25
28
import org .truffleruby .annotations .CoreModule ;
31
34
import com .oracle .truffle .api .Truffle ;
32
35
import com .oracle .truffle .api .TruffleOptions ;
33
36
import com .oracle .truffle .api .dsl .Specialization ;
37
+ import org .truffleruby .language .RubyBaseNode ;
34
38
import org .truffleruby .language .RubyDynamicObject ;
35
39
import org .truffleruby .language .yield .CallBlockNode ;
36
40
@@ -106,19 +110,18 @@ Object fullMemoryBarrier() {
106
110
}
107
111
}
108
112
109
- @ CoreMethod (names = "synchronized" , onSingleton = true , required = 1 , needsBlock = true )
113
+ @ CoreMethod (names = "synchronized" , onSingleton = true , required = 1 , needsBlock = true , split = Split . ALWAYS )
110
114
public abstract static class SynchronizedNode extends CoreMethodArrayArgumentsNode {
111
115
112
116
/** We must not allow to synchronize on boxed primitives as that would be misleading. We use a ReentrantLock and
113
117
* not simply Java's {@code synchronized} here as we need to be able to interrupt for guest safepoints and it is
114
118
* not possible to interrupt Java's {@code synchronized (object) {}}. */
115
- @ Specialization ( limit = "getDynamicObjectCacheLimit()" )
119
+ @ Specialization
116
120
static Object synchronize (RubyDynamicObject object , RubyProc block ,
117
- @ CachedLibrary ( "object" ) DynamicObjectLibrary objectLibrary ,
121
+ @ Cached GetLockNode getLockNode ,
118
122
@ Cached CallBlockNode yieldNode ,
119
- @ Cached InlinedBranchProfile initializeLockProfile ,
120
123
@ Bind ("this" ) Node node ) {
121
- final ReentrantLock lock = getLock (node , object , objectLibrary , initializeLockProfile );
124
+ final ReentrantLock lock = getLockNode . execute (node , object );
122
125
123
126
MutexOperations .lockInternal (getContext (node ), lock , node );
124
127
try {
@@ -128,8 +131,18 @@ static Object synchronize(RubyDynamicObject object, RubyProc block,
128
131
}
129
132
}
130
133
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 ) {
133
146
ReentrantLock lock = (ReentrantLock ) objectLibrary .getOrDefault (object , Layouts .OBJECT_LOCK , null );
134
147
if (lock != null ) {
135
148
return lock ;
@@ -147,7 +160,6 @@ private static ReentrantLock getLock(Node node, RubyDynamicObject object, Dynami
147
160
}
148
161
}
149
162
}
150
-
151
163
}
152
164
153
165
}
0 commit comments