Skip to content

Commit 95c8d7f

Browse files
committed
[GR-18163] Cache Method#to_proc result's call target in global cache
PullRequest: truffleruby/4238
2 parents 92b4cdd + 61f1f76 commit 95c8d7f

File tree

5 files changed

+14
-54
lines changed

5 files changed

+14
-54
lines changed

src/main/java/org/truffleruby/core/method/MethodNodes.java

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -285,30 +285,18 @@ RubyUnboundMethod unbind(RubyMethod method,
285285
@CoreMethod(names = "to_proc")
286286
public abstract static class ToProcNode extends CoreMethodArrayArgumentsNode {
287287

288-
@Specialization(guards = { "isSingleContext()", "methodObject == cachedMethodObject" },
289-
limit = "getCacheLimit()")
290-
RubyProc toProcCachedSingleContext(RubyMethod methodObject,
291-
@Cached("methodObject") RubyMethod cachedMethodObject,
292-
@Cached("toProcUncached(cachedMethodObject)") RubyProc proc) {
293-
return proc;
294-
}
295-
296-
@Specialization(
297-
guards = "methodObject.method.getCallTarget() == methodCallTarget",
298-
limit = "getCacheLimit()",
299-
replaces = "toProcCachedSingleContext")
300-
RubyProc toProcCachedTarget(RubyMethod methodObject,
301-
@Cached("methodObject.method.getCallTarget()") RootCallTarget methodCallTarget,
302-
@Cached("procCallTargetToCallRubyMethod(methodCallTarget)") RootCallTarget procCallTarget) {
303-
return createProc(procCallTarget, methodObject.method, methodObject.receiver);
304-
}
305-
306-
@Specialization(replaces = { "toProcCachedSingleContext", "toProcCachedTarget" })
307-
RubyProc toProcUncached(RubyMethod methodObject) {
288+
@Specialization
289+
RubyProc toProc(RubyMethod methodObject) {
308290
final InternalMethod method = methodObject.method;
309291
final Object receiver = methodObject.receiver;
310-
final RootCallTarget callTarget = procCallTargetToCallRubyMethod(method.getCallTarget());
311-
return createProc(callTarget, method, receiver);
292+
RootCallTarget toProcCallTarget = method.toProcCallTarget;
293+
294+
if (toProcCallTarget == null) {
295+
toProcCallTarget = createToProcCallTarget(method.getCallTarget());
296+
method.toProcCallTarget = toProcCallTarget;
297+
}
298+
299+
return createProc(toProcCallTarget, method, receiver);
312300
}
313301

314302
private RubyProc createProc(RootCallTarget callTarget, InternalMethod method, Object receiver) {
@@ -331,7 +319,7 @@ private RubyProc createProc(RootCallTarget callTarget, InternalMethod method, Ob
331319
}
332320

333321
@TruffleBoundary
334-
protected RootCallTarget procCallTargetToCallRubyMethod(RootCallTarget callTarget) {
322+
protected RootCallTarget createToProcCallTarget(RootCallTarget callTarget) {
335323
// translate to something like:
336324
// lambda { |same args list| method.call(args) }
337325
// We need to preserve the method receiver and we want to have the same argument list.
@@ -354,10 +342,6 @@ protected RootCallTarget procCallTargetToCallRubyMethod(RootCallTarget callTarge
354342
return wrapRootNode.getCallTarget();
355343
}
356344

357-
protected int getCacheLimit() {
358-
return getLanguage().options.METHOD_TO_PROC_CACHE;
359-
}
360-
361345
private static final class CallWithRubyMethodReceiverNode extends RubyContextSourceNode {
362346
@Child private CallInternalMethodNode callInternalMethodNode = CallInternalMethodNode.create();
363347

src/main/java/org/truffleruby/language/methods/InternalMethod.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ public final class InternalMethod implements ObjectGraphNode {
5757
private final CachedLazyCallTargetSupplier callTargetSupplier;
5858
@CompilationFinal private RootCallTarget callTarget;
5959

60+
/** call target of a Proc created from a method and cached for consequent Method#to_proc calls */
61+
public RootCallTarget toProcCallTarget;
62+
6063
public static InternalMethod fromProc(
6164
RubyContext context,
6265
SharedMethodInfo sharedMethodInfo,

src/main/java/org/truffleruby/options/LanguageOptions.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ public final class LanguageOptions {
6969
public final int DISPATCH_CACHE;
7070
/** --yield-cache=DEFAULT_CACHE */
7171
public final int YIELD_CACHE;
72-
/** --to-proc-cache=DEFAULT_CACHE */
73-
public final int METHOD_TO_PROC_CACHE;
7472
/** --is-a-cache=DEFAULT_CACHE */
7573
public final int IS_A_CACHE;
7674
/** --bind-cache=DEFAULT_CACHE */
@@ -156,7 +154,6 @@ public LanguageOptions(Env env, OptionValues options, boolean singleContext) {
156154
METHOD_LOOKUP_CACHE = options.hasBeenSet(OptionsCatalog.METHOD_LOOKUP_CACHE_KEY) ? options.get(OptionsCatalog.METHOD_LOOKUP_CACHE_KEY) : DEFAULT_CACHE;
157155
DISPATCH_CACHE = options.hasBeenSet(OptionsCatalog.DISPATCH_CACHE_KEY) ? options.get(OptionsCatalog.DISPATCH_CACHE_KEY) : DEFAULT_CACHE;
158156
YIELD_CACHE = options.hasBeenSet(OptionsCatalog.YIELD_CACHE_KEY) ? options.get(OptionsCatalog.YIELD_CACHE_KEY) : DEFAULT_CACHE;
159-
METHOD_TO_PROC_CACHE = options.hasBeenSet(OptionsCatalog.METHOD_TO_PROC_CACHE_KEY) ? options.get(OptionsCatalog.METHOD_TO_PROC_CACHE_KEY) : DEFAULT_CACHE;
160157
IS_A_CACHE = options.hasBeenSet(OptionsCatalog.IS_A_CACHE_KEY) ? options.get(OptionsCatalog.IS_A_CACHE_KEY) : DEFAULT_CACHE;
161158
BIND_CACHE = options.hasBeenSet(OptionsCatalog.BIND_CACHE_KEY) ? options.get(OptionsCatalog.BIND_CACHE_KEY) : DEFAULT_CACHE;
162159
CONSTANT_CACHE = options.hasBeenSet(OptionsCatalog.CONSTANT_CACHE_KEY) ? options.get(OptionsCatalog.CONSTANT_CACHE_KEY) : DEFAULT_CACHE;
@@ -237,8 +234,6 @@ public Object fromDescriptor(OptionDescriptor descriptor) {
237234
return DISPATCH_CACHE;
238235
case "ruby.yield-cache":
239236
return YIELD_CACHE;
240-
case "ruby.to-proc-cache":
241-
return METHOD_TO_PROC_CACHE;
242237
case "ruby.is-a-cache":
243238
return IS_A_CACHE;
244239
case "ruby.bind-cache":
@@ -328,7 +323,6 @@ public static boolean areOptionsCompatible(OptionValues one, OptionValues two) {
328323
one.get(OptionsCatalog.METHOD_LOOKUP_CACHE_KEY).equals(two.get(OptionsCatalog.METHOD_LOOKUP_CACHE_KEY)) &&
329324
one.get(OptionsCatalog.DISPATCH_CACHE_KEY).equals(two.get(OptionsCatalog.DISPATCH_CACHE_KEY)) &&
330325
one.get(OptionsCatalog.YIELD_CACHE_KEY).equals(two.get(OptionsCatalog.YIELD_CACHE_KEY)) &&
331-
one.get(OptionsCatalog.METHOD_TO_PROC_CACHE_KEY).equals(two.get(OptionsCatalog.METHOD_TO_PROC_CACHE_KEY)) &&
332326
one.get(OptionsCatalog.IS_A_CACHE_KEY).equals(two.get(OptionsCatalog.IS_A_CACHE_KEY)) &&
333327
one.get(OptionsCatalog.BIND_CACHE_KEY).equals(two.get(OptionsCatalog.BIND_CACHE_KEY)) &&
334328
one.get(OptionsCatalog.CONSTANT_CACHE_KEY).equals(two.get(OptionsCatalog.CONSTANT_CACHE_KEY)) &&
@@ -526,13 +520,6 @@ public static boolean areOptionsCompatibleOrLog(TruffleLogger logger, LanguageOp
526520
return false;
527521
}
528522

529-
oldValue = oldOptions.METHOD_TO_PROC_CACHE;
530-
newValue = newOptions.METHOD_TO_PROC_CACHE;
531-
if (!newValue.equals(oldValue)) {
532-
logger.fine("not reusing pre-initialized context: --to-proc-cache differs, was: " + oldValue + " and is now: " + newValue);
533-
return false;
534-
}
535-
536523
oldValue = oldOptions.IS_A_CACHE;
537524
newValue = newOptions.IS_A_CACHE;
538525
if (!newValue.equals(oldValue)) {

src/options.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ LANGUAGE_OPTIONS:
2828
- METHOD_LOOKUP_CACHE
2929
- DISPATCH_CACHE
3030
- YIELD_CACHE
31-
- METHOD_TO_PROC_CACHE
3231
- IS_A_CACHE
3332
- BIND_CACHE
3433
- CONSTANT_CACHE
@@ -201,7 +200,6 @@ INTERNAL: # Options for debugging the TruffleRuby implementation
201200
METHOD_LOOKUP_CACHE: [method-lookup-cache, integer, DEFAULT_CACHE, Method lookup cache size]
202201
DISPATCH_CACHE: [dispatch-cache, integer, DEFAULT_CACHE, Dispatch (various forms of method call) cache size]
203202
YIELD_CACHE: [yield-cache, integer, DEFAULT_CACHE, Yield cache size]
204-
METHOD_TO_PROC_CACHE: [to-proc-cache, integer, DEFAULT_CACHE, Method#to_proc cache size]
205203
IS_A_CACHE: [is-a-cache, integer, DEFAULT_CACHE, 'Kernel#is_a? and #kind_of? cache size']
206204
BIND_CACHE: [bind-cache, integer, DEFAULT_CACHE, Cache size of test for being able to bind a method to a module]
207205
CONSTANT_CACHE: [constant-cache, integer, DEFAULT_CACHE, Constant cache size]

src/shared/java/org/truffleruby/shared/options/OptionsCatalog.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ public final class OptionsCatalog {
115115
public static final OptionKey<Integer> METHOD_LOOKUP_CACHE_KEY = new OptionKey<>(DEFAULT_CACHE_KEY.getDefaultValue());
116116
public static final OptionKey<Integer> DISPATCH_CACHE_KEY = new OptionKey<>(DEFAULT_CACHE_KEY.getDefaultValue());
117117
public static final OptionKey<Integer> YIELD_CACHE_KEY = new OptionKey<>(DEFAULT_CACHE_KEY.getDefaultValue());
118-
public static final OptionKey<Integer> METHOD_TO_PROC_CACHE_KEY = new OptionKey<>(DEFAULT_CACHE_KEY.getDefaultValue());
119118
public static final OptionKey<Integer> IS_A_CACHE_KEY = new OptionKey<>(DEFAULT_CACHE_KEY.getDefaultValue());
120119
public static final OptionKey<Integer> BIND_CACHE_KEY = new OptionKey<>(DEFAULT_CACHE_KEY.getDefaultValue());
121120
public static final OptionKey<Integer> CONSTANT_CACHE_KEY = new OptionKey<>(DEFAULT_CACHE_KEY.getDefaultValue());
@@ -925,14 +924,6 @@ public final class OptionsCatalog {
925924
.usageSyntax("8")
926925
.build();
927926

928-
public static final OptionDescriptor METHOD_TO_PROC_CACHE = OptionDescriptor
929-
.newBuilder(METHOD_TO_PROC_CACHE_KEY, "ruby.to-proc-cache")
930-
.help("Method#to_proc cache size")
931-
.category(OptionCategory.INTERNAL)
932-
.stability(OptionStability.EXPERIMENTAL)
933-
.usageSyntax("8")
934-
.build();
935-
936927
public static final OptionDescriptor IS_A_CACHE = OptionDescriptor
937928
.newBuilder(IS_A_CACHE_KEY, "ruby.is-a-cache")
938929
.help("Kernel#is_a? and #kind_of? cache size")
@@ -1509,8 +1500,6 @@ public static OptionDescriptor fromName(String name) {
15091500
return DISPATCH_CACHE;
15101501
case "ruby.yield-cache":
15111502
return YIELD_CACHE;
1512-
case "ruby.to-proc-cache":
1513-
return METHOD_TO_PROC_CACHE;
15141503
case "ruby.is-a-cache":
15151504
return IS_A_CACHE;
15161505
case "ruby.bind-cache":
@@ -1709,7 +1698,6 @@ public static OptionDescriptor[] allDescriptors() {
17091698
METHOD_LOOKUP_CACHE,
17101699
DISPATCH_CACHE,
17111700
YIELD_CACHE,
1712-
METHOD_TO_PROC_CACHE,
17131701
IS_A_CACHE,
17141702
BIND_CACHE,
17151703
CONSTANT_CACHE,

0 commit comments

Comments
 (0)