|
13 | 13 | import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
|
14 | 14 | import org.truffleruby.builtins.CoreModule;
|
15 | 15 | import org.truffleruby.builtins.UnaryCoreMethodNode;
|
| 16 | +import org.truffleruby.collections.ConcurrentOperations; |
16 | 17 | import org.truffleruby.core.CoreLibrary;
|
17 | 18 | import org.truffleruby.core.array.RubyArray;
|
18 | 19 | import org.truffleruby.core.klass.RubyClass;
|
@@ -105,20 +106,28 @@ public abstract static class ToProcNode extends CoreMethodArrayArgumentsNode {
|
105 | 106 | protected RubyProc toProcCached(VirtualFrame frame, RubySymbol symbol,
|
106 | 107 | @Cached("symbol") RubySymbol cachedSymbol,
|
107 | 108 | @Cached("getDeclarationContext(frame)") DeclarationContext cachedDeclarationContext,
|
108 |
| - @Cached("createProc(cachedDeclarationContext, getMethod(frame), symbol)") RubyProc cachedProc) { |
| 109 | + @Cached("getOrCreateProc(cachedDeclarationContext, symbol)") RubyProc cachedProc) { |
109 | 110 | return cachedProc;
|
110 | 111 | }
|
111 | 112 |
|
112 | 113 | @Specialization
|
113 | 114 | protected RubyProc toProcUncached(VirtualFrame frame, RubySymbol symbol) {
|
114 |
| - final InternalMethod method = getMethod(frame); |
115 | 115 | DeclarationContext declarationContext = getDeclarationContext(frame);
|
116 |
| - return createProc(declarationContext, method, symbol); |
| 116 | + return getOrCreateProc(declarationContext, symbol); |
117 | 117 | }
|
118 | 118 |
|
119 | 119 | @TruffleBoundary
|
120 |
| - protected RubyProc createProc(DeclarationContext declarationContext, InternalMethod method, |
121 |
| - RubySymbol symbol) { |
| 120 | + protected RubyProc getOrCreateProc(DeclarationContext declarationContext, RubySymbol symbol) { |
| 121 | + declarationContext = declarationContext == null ? DeclarationContext.NONE : declarationContext; |
| 122 | + return ConcurrentOperations.getOrCompute( |
| 123 | + symbol.getCachedProcs(), |
| 124 | + declarationContext, |
| 125 | + key -> createProc(key, symbol)); |
| 126 | + } |
| 127 | + |
| 128 | + @TruffleBoundary |
| 129 | + protected RubyProc createProc(DeclarationContext declarationContext, RubySymbol symbol) { |
| 130 | + final InternalMethod method = getContext().getCoreMethods().SYMBOL_TO_PROC; |
122 | 131 | final SourceSection sourceSection = CoreLibrary.UNAVAILABLE_SOURCE_SECTION;
|
123 | 132 | final SharedMethodInfo sharedMethodInfo = new SharedMethodInfo(
|
124 | 133 | sourceSection,
|
@@ -157,7 +166,7 @@ protected RubyProc createProc(DeclarationContext declarationContext, InternalMet
|
157 | 166 | method,
|
158 | 167 | null,
|
159 | 168 | null,
|
160 |
| - declarationContext == null ? DeclarationContext.NONE : declarationContext); |
| 169 | + declarationContext); |
161 | 170 | }
|
162 | 171 |
|
163 | 172 | protected InternalMethod getMethod(VirtualFrame frame) {
|
|
0 commit comments