File tree Expand file tree Collapse file tree 2 files changed +11
-13
lines changed
src/main/java/org/truffleruby/language/methods Expand file tree Collapse file tree 2 files changed +11
-13
lines changed Original file line number Diff line number Diff line change 9
9
*/
10
10
package org .truffleruby .language .methods ;
11
11
12
- import com .oracle .truffle .api .CompilerDirectives ;
13
12
import com .oracle .truffle .api .RootCallTarget ;
14
13
15
14
import java .util .function .Supplier ;
16
15
17
16
public class CachedLazyCallTargetSupplier {
18
17
19
- private volatile RootCallTarget value = null ;
18
+ // Volatile, so that writes from another thread will finish publishing the RootCallTarget first
19
+ private volatile RootCallTarget callTarget = null ;
20
20
private Supplier <RootCallTarget > supplier ;
21
21
22
22
public CachedLazyCallTargetSupplier (Supplier <RootCallTarget > supplier ) {
23
23
this .supplier = supplier ;
24
24
}
25
25
26
26
public RootCallTarget get () {
27
- if (isAvailable ()) {
28
- return value ;
29
- }
30
- CompilerDirectives .transferToInterpreterAndInvalidate ();
31
27
synchronized (this ) {
32
- if (value == null ) {
33
- value = supplier .get ();
28
+ if (callTarget == null ) {
29
+ callTarget = supplier .get ();
34
30
supplier = null ;
35
31
}
36
- return value ;
32
+ return callTarget ;
37
33
}
38
34
}
39
35
40
- public boolean isAvailable () {
41
- return value != null ;
36
+ public RootCallTarget getWhenAvailable () {
37
+ return callTarget ;
42
38
}
43
39
44
40
}
Original file line number Diff line number Diff line change 11
11
12
12
import java .util .Set ;
13
13
14
+ import com .oracle .truffle .api .CompilerDirectives ;
14
15
import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
15
16
import com .oracle .truffle .api .dsl .NodeFactory ;
16
17
import org .truffleruby .RubyContext ;
@@ -172,8 +173,8 @@ private InternalMethod(
172
173
173
174
/* If the call target supplier has already been run, then don't wait until the first time the InternalMethod is
174
175
* asked for the call target, because this would be a deoptimization in getCallTarget(). */
175
- if (callTarget == null && callTargetSupplier != null && callTargetSupplier . isAvailable () ) {
176
- this .callTarget = callTargetSupplier .get ();
176
+ if (callTarget == null && callTargetSupplier != null ) {
177
+ this .callTarget = callTargetSupplier .getWhenAvailable ();
177
178
}
178
179
}
179
180
@@ -231,6 +232,7 @@ public RubyProc getProc() {
231
232
232
233
public RootCallTarget getCallTarget () {
233
234
if (callTarget == null ) {
235
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
234
236
callTarget = callTargetSupplier .get ();
235
237
assert RubyRootNode .of (callTarget ).getSharedMethodInfo () == sharedMethodInfo ;
236
238
}
You can’t perform that action at this time.
0 commit comments