diff --git a/src/main/java/org/truffleruby/cext/CExtNodes.java b/src/main/java/org/truffleruby/cext/CExtNodes.java index 9d448c6211e4..ce959f4f9d9a 100644 --- a/src/main/java/org/truffleruby/cext/CExtNodes.java +++ b/src/main/java/org/truffleruby/cext/CExtNodes.java @@ -206,7 +206,7 @@ Object callWithCExtLockAndFrame( try { return InteropNodes.execute(this, receiver, args, receivers, translateInteropExceptionNode); } finally { - runMarksNode.execute(extensionStack); + runMarksNode.execute(this, extensionStack); if (!owned) { MutexOperations.unlockInternal(lock); } @@ -215,7 +215,7 @@ Object callWithCExtLockAndFrame( try { return InteropNodes.execute(this, receiver, args, receivers, translateInteropExceptionNode); } finally { - runMarksNode.execute(extensionStack); + runMarksNode.execute(this, extensionStack); } } @@ -258,7 +258,7 @@ Object callWithCExtLockAndFrame( return unwrapNode.execute(this, InteropNodes.execute(this, receiver, args, receivers, translateInteropExceptionNode)); } finally { - runMarksNode.execute(extensionStack); + runMarksNode.execute(this, extensionStack); if (!owned) { MutexOperations.unlockInternal(lock); } @@ -268,7 +268,7 @@ Object callWithCExtLockAndFrame( return unwrapNode.execute(this, InteropNodes.execute(this, receiver, args, receivers, translateInteropExceptionNode)); } finally { - runMarksNode.execute(extensionStack); + runMarksNode.execute(this, extensionStack); } } @@ -386,7 +386,7 @@ Object sendWithoutCExtLock(VirtualFrame frame, Object receiver, RubySymbol metho Object[] args = unwrapCArrayNode.execute(argv); // Remove empty kwargs in the caller, so the callee does not need to care about this special case - final RubyHash keywords = hashCastNode.execute(ArrayUtils.getLast(args)); + final RubyHash keywords = hashCastNode.execute(this, ArrayUtils.getLast(args)); if (emptyProfile.profile(this, keywords.empty())) { args = LiteralCallNode.removeEmptyKeywordArguments(args); return sendWithoutCExtLock(frame, receiver, method, block, EmptyArgumentsDescriptor.INSTANCE, args, @@ -424,7 +424,7 @@ Object sendWithoutCExtLock(VirtualFrame frame, Object receiver, RubySymbol metho Object[] args = unwrapCArrayNode.execute(argv); // Remove empty kwargs in the caller, so the callee does not need to care about this special case - final RubyHash keywords = hashCastNode.execute(ArrayUtils.getLast(args)); + final RubyHash keywords = hashCastNode.execute(this, ArrayUtils.getLast(args)); if (emptyProfile.profile(this, keywords.empty())) { args = LiteralCallNode.removeEmptyKeywordArguments(args); return sendWithoutCExtLock(frame, receiver, method, block, EmptyArgumentsDescriptor.INSTANCE, args, @@ -944,7 +944,7 @@ public abstract static class CheckFrozenNode extends CoreMethodArrayArgumentsNod @Specialization boolean rb_check_frozen(Object object, @Cached TypeNodes.CheckFrozenNode raiseIfFrozenNode) { - raiseIfFrozenNode.execute(object); + raiseIfFrozenNode.execute(this, object); return true; } @@ -1473,7 +1473,7 @@ Object captureException(RubyProc block, @Cached InlinedBranchProfile noExceptionProfile, @Cached CallBlockNode yieldNode) { try { - yieldNode.yield(block); + yieldNode.yield(this, block); noExceptionProfile.enter(this); return nil; } catch (Throwable e) { @@ -1834,7 +1834,7 @@ Object addToMarkList(Object guardedObject, ValueWrapper wrappedValue = toWrapperNode.execute(this, guardedObject); if (wrappedValue != null) { noExceptionProfile.enter(this); - keepAliveNode.execute(wrappedValue); + keepAliveNode.execute(this, wrappedValue); } return nil; } diff --git a/src/main/java/org/truffleruby/cext/ValueWrapper.java b/src/main/java/org/truffleruby/cext/ValueWrapper.java index 64aed4692897..7d2f3bb65457 100644 --- a/src/main/java/org/truffleruby/cext/ValueWrapper.java +++ b/src/main/java/org/truffleruby/cext/ValueWrapper.java @@ -108,7 +108,7 @@ static void toNative(ValueWrapper wrapper, @Bind("$node") Node node) { if (!wrapper.isPointer()) { createHandleProfile.enter(node); - createNativeHandleNode.execute(wrapper); + createNativeHandleNode.execute(node, wrapper); } } @@ -123,7 +123,7 @@ static long asPointer(ValueWrapper wrapper, if (ValueWrapperManager.isTaggedObject(handle)) { taggedObjectProfile.enter(node); - keepAliveNode.execute(wrapper); + keepAliveNode.execute(node, wrapper); } return handle; diff --git a/src/main/java/org/truffleruby/cext/ValueWrapperManager.java b/src/main/java/org/truffleruby/cext/ValueWrapperManager.java index a4001292127d..fdc441d7d7b9 100644 --- a/src/main/java/org/truffleruby/cext/ValueWrapperManager.java +++ b/src/main/java/org/truffleruby/cext/ValueWrapperManager.java @@ -16,6 +16,8 @@ import java.util.concurrent.atomic.AtomicLong; import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.nodes.Node; import org.truffleruby.RubyContext; import org.truffleruby.RubyLanguage; @@ -283,35 +285,39 @@ public static final class HandleBlockHolder { } @GenerateUncached + @GenerateInline + @GenerateCached(false) public abstract static class AllocateHandleNode extends RubyBaseNode { private static final Set keepAlive = ConcurrentHashMap.newKeySet(); - public abstract long execute(ValueWrapper wrapper); + public abstract long execute(Node node, ValueWrapper wrapper); @Specialization(guards = "!isSharedObject(wrapper)") - long allocateHandleOnKnownThread(ValueWrapper wrapper) { - if (getContext().getOptions().CEXTS_KEEP_HANDLES_ALIVE) { + static long allocateHandleOnKnownThread(Node node, ValueWrapper wrapper) { + if (getContext(node).getOptions().CEXTS_KEEP_HANDLES_ALIVE) { keepAlive(wrapper); } return allocateHandle( + node, wrapper, - getContext(), - getLanguage(), - getBlockHolder(getContext(), getLanguage()), + getContext(node), + getLanguage(node), + getBlockHolder(getContext(node), getLanguage(node)), false); } @Specialization(guards = "isSharedObject(wrapper)") - long allocateSharedHandleOnKnownThread(ValueWrapper wrapper) { - if (getContext().getOptions().CEXTS_KEEP_HANDLES_ALIVE) { + static long allocateSharedHandleOnKnownThread(Node node, ValueWrapper wrapper) { + if (getContext(node).getOptions().CEXTS_KEEP_HANDLES_ALIVE) { keepAlive(wrapper); } return allocateHandle( + node, wrapper, - getContext(), - getLanguage(), - getBlockHolder(getContext(), getLanguage()), + getContext(node), + getLanguage(node), + getBlockHolder(getContext(node), getLanguage(node)), true); } @@ -320,8 +326,8 @@ protected static void keepAlive(ValueWrapper wrapper) { keepAlive.add(wrapper); } - protected long allocateHandle(ValueWrapper wrapper, RubyContext context, RubyLanguage language, - HandleBlockHolder holder, boolean shared) { + protected static long allocateHandle(Node node, ValueWrapper wrapper, RubyContext context, + RubyLanguage language, HandleBlockHolder holder, boolean shared) { HandleBlock block; if (shared) { block = holder.sharedHandleBlock; @@ -334,7 +340,7 @@ protected long allocateHandle(ValueWrapper wrapper, RubyContext context, RubyLan } if (context.getOptions().BACKTRACE_ON_TO_NATIVE) { - context.getDefaultBacktraceFormatter().printBacktraceOnEnvStderr("ValueWrapper#toNative: ", this); + context.getDefaultBacktraceFormatter().printBacktraceOnEnvStderr("ValueWrapper#toNative: ", node); } if (block == null || block.isFull()) { diff --git a/src/main/java/org/truffleruby/core/MarkingService.java b/src/main/java/org/truffleruby/core/MarkingService.java index 7a39594d9d62..7bb2c5c8e789 100644 --- a/src/main/java/org/truffleruby/core/MarkingService.java +++ b/src/main/java/org/truffleruby/core/MarkingService.java @@ -11,6 +11,7 @@ import java.util.ArrayList; +import org.truffleruby.annotations.SuppressFBWarnings; import org.truffleruby.cext.CapturedException; import org.truffleruby.cext.ValueWrapper; import org.truffleruby.core.array.ArrayUtils; @@ -43,7 +44,7 @@ protected static final class ExtensionCallStackEntry { private final ExtensionCallStackEntry previous; ValueWrapper preservedObject; - ArrayList preservedObjects; + @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") ArrayList preservedObjectList; private final boolean keywordsGiven; private Object specialVariables; private final Object block; @@ -79,7 +80,11 @@ public boolean hasKeptObjects() { } public boolean hasSingleKeptObject() { - return current.preservedObject != null && current.preservedObjects == null; + return current.preservedObject != null && current.preservedObjectList == null; + } + + public boolean isPreservedObjectListInitialized() { + return current.preservedObjectList != null; } public void markOnExitObject(ValueWrapper value) { diff --git a/src/main/java/org/truffleruby/core/MarkingServiceNodes.java b/src/main/java/org/truffleruby/core/MarkingServiceNodes.java index 363389aab1fb..15f396cc67a8 100644 --- a/src/main/java/org/truffleruby/core/MarkingServiceNodes.java +++ b/src/main/java/org/truffleruby/core/MarkingServiceNodes.java @@ -9,7 +9,11 @@ */ package org.truffleruby.core; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.NonIdempotent; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import org.truffleruby.cext.ValueWrapper; import org.truffleruby.core.MarkingService.ExtensionCallStack; @@ -28,42 +32,47 @@ public abstract class MarkingServiceNodes { @GenerateUncached + @GenerateCached(false) + @GenerateInline public abstract static class KeepAliveNode extends RubyBaseNode { - public abstract void execute(ValueWrapper object); + public abstract void execute(Node node, ValueWrapper object); @Specialization(guards = "!stack.hasKeptObjects()") - void keepFirstObject(ValueWrapper object, - @Bind("getStack(object)") ExtensionCallStack stack) { + static void keepFirstObject(Node node, ValueWrapper object, + @Bind("getStack(node)") ExtensionCallStack stack) { stack.current.preservedObject = object; } @Specialization(guards = "stack.hasSingleKeptObject()") - void keepCreatingList(ValueWrapper object, - @Bind("getStack(object)") ExtensionCallStack stack, + static void keepCreatingList(Node node, ValueWrapper object, + @Bind("getStack(node)") ExtensionCallStack stack, @Cached InlinedConditionProfile sameObjectProfile) { - if (sameObjectProfile.profile(this, object != stack.current.preservedObject)) { + if (sameObjectProfile.profile(node, object != stack.current.preservedObject)) { createKeptList(object, stack); } } - @Specialization(guards = { "stack.hasKeptObjects()", "!stack.hasSingleKeptObject()" }) + @Specialization(guards = { + "stack.isPreservedObjectListInitialized()", + "stack.hasKeptObjects()", + "!stack.hasSingleKeptObject()" }) @TruffleBoundary - void keepAddingToList(ValueWrapper object, - @Bind("getStack(object)") ExtensionCallStack stack) { - stack.current.preservedObjects.add(object); + static void keepAddingToList(Node node, ValueWrapper object, + @Bind("getStack(node)") ExtensionCallStack stack) { + stack.current.preservedObjectList.add(object); } @TruffleBoundary - private void createKeptList(ValueWrapper object, ExtensionCallStack stack) { - stack.current.preservedObjects = new ArrayList<>(); - stack.current.preservedObjects.add(stack.current.preservedObject); - stack.current.preservedObjects.add(object); + private static void createKeptList(ValueWrapper object, ExtensionCallStack stack) { + stack.current.preservedObjectList = new ArrayList<>(); + stack.current.preservedObjectList.add(stack.current.preservedObject); + stack.current.preservedObjectList.add(object); } - // We take a parameter so that the bind isn't considered cacheable. - protected ExtensionCallStack getStack(ValueWrapper object) { - return getLanguage().getCurrentThread().getCurrentFiber().extensionCallStack; + @NonIdempotent + protected static ExtensionCallStack getStack(Node node) { + return getLanguage(node).getCurrentThread().getCurrentFiber().extensionCallStack; } } @@ -83,26 +92,28 @@ protected void addToList(ExtensionCallStack stack, ValueWrapper object) { } } + @GenerateInline + @GenerateCached(false) public abstract static class RunMarkOnExitNode extends RubyBaseNode { - public abstract void execute(ExtensionCallStack stack); + public abstract void execute(Node node, ExtensionCallStack stack); @Specialization(guards = "!stack.hasMarkObjects()") - void nothingToMark(ExtensionCallStack stack) { + static void nothingToMark(ExtensionCallStack stack) { // Do nothing. } @Specialization(guards = "stack.hasSingleMarkObject()") - void markSingleObject(ExtensionCallStack stack, - @Cached @Shared DispatchNode callNode) { + static void markSingleObject(Node node, ExtensionCallStack stack, + @Cached(inline = false) @Shared DispatchNode callNode) { ValueWrapper value = stack.getSingleMarkObject(); - callNode.call(getContext().getCoreLibrary().truffleCExtModule, "run_marker", value.getObject()); + callNode.call(getContext(node).getCoreLibrary().truffleCExtModule, "run_marker", value.getObject()); } @TruffleBoundary @Specialization(guards = { "stack.hasMarkObjects()", "!stack.hasSingleMarkObject()" }) - void marksToRun(ExtensionCallStack stack, - @Cached @Shared DispatchNode callNode) { + static void marksToRun(Node node, ExtensionCallStack stack, + @Cached(inline = false) @Shared DispatchNode callNode) { // Run the markers... var valuesForMarking = stack.getMarkOnExitObjects(); // Push a new stack frame because we should @@ -111,17 +122,11 @@ void marksToRun(ExtensionCallStack stack, stack.push(false, nil, nil); try { for (var value : valuesForMarking) { - callNode.call(getContext().getCoreLibrary().truffleCExtModule, "run_marker", value.getObject()); + callNode.call(getContext(node).getCoreLibrary().truffleCExtModule, "run_marker", value.getObject()); } } finally { stack.pop(); } } - - - @NeverDefault - public static RunMarkOnExitNode create() { - return MarkingServiceNodesFactory.RunMarkOnExitNodeGen.create(); - } } } diff --git a/src/main/java/org/truffleruby/core/VMPrimitiveNodes.java b/src/main/java/org/truffleruby/core/VMPrimitiveNodes.java index fe57af9668c0..2e8cf56dcefc 100644 --- a/src/main/java/org/truffleruby/core/VMPrimitiveNodes.java +++ b/src/main/java/org/truffleruby/core/VMPrimitiveNodes.java @@ -118,7 +118,7 @@ Object doCatch(Object tag, RubyProc block, @Cached ReferenceEqualNode referenceEqualNode, @Cached CallBlockNode yieldNode) { try { - return yieldNode.yield(block, tag); + return yieldNode.yield(this, block, tag); } catch (ThrowException e) { catchProfile.enter(this); if (matchProfile.profile(this, referenceEqualNode.execute(this, e.getTag(), tag))) { @@ -154,7 +154,7 @@ Object vmExtendedModules(Object object, RubyProc block, if (isSingletonProfile.profile(this, metaClass.isSingleton)) { for (RubyModule included : metaClass.fields.prependedAndIncludedModules()) { - yieldNode.yield(block, included); + yieldNode.yield(this, block, included); } } @@ -420,7 +420,7 @@ Object getSection(Object section, RubyProc block, .getNativeConfiguration() .getSection(RubyGuards.getJavaString(section))) { final RubyString key = createString(fromJavaStringNode, entry.getKey(), Encodings.UTF_8); // CR_7BIT - yieldNode.yield(block, key, entry.getValue()); + yieldNode.yield(this, block, key, entry.getValue()); } return nil; diff --git a/src/main/java/org/truffleruby/core/array/ArrayNodes.java b/src/main/java/org/truffleruby/core/array/ArrayNodes.java index 942a07e6aef0..8d446d63e8f2 100644 --- a/src/main/java/org/truffleruby/core/array/ArrayNodes.java +++ b/src/main/java/org/truffleruby/core/array/ArrayNodes.java @@ -71,7 +71,7 @@ import org.truffleruby.core.range.RangeNodes.NormalizedStartLengthNode; import org.truffleruby.core.string.RubyString; import org.truffleruby.core.string.StringHelperNodes; -import org.truffleruby.core.support.TypeNodes; +import org.truffleruby.core.support.TypeNodes.CheckFrozenNode; import org.truffleruby.core.symbol.RubySymbol; import org.truffleruby.extra.ffi.Pointer; import org.truffleruby.interop.ToJavaStringNode; @@ -661,38 +661,38 @@ RubyArray concatManyGeneral(RubyArray array, Object first, Object[] rest, @ImportStatic(ArrayGuards.class) public abstract static class DeleteNode extends CoreMethodArrayArgumentsNode { - @Child private TypeNodes.CheckFrozenNode raiseIfFrozenNode; - @Specialization( guards = "stores.isMutable(store)", limit = "storageStrategyLimit()") - Object delete(RubyArray array, Object value, Object maybeBlock, + Object deleteMutable(RubyArray array, Object value, Object maybeBlock, @Bind("array.getStore()") Object store, @CachedLibrary("store") ArrayStoreLibrary stores, @Cached @Shared SameOrEqualNode sameOrEqualNode, @Cached @Shared InlinedIntValueProfile arraySizeProfile, @Cached @Shared InlinedLoopConditionProfile loopProfile, - @Cached @Shared CallBlockNode yieldNode) { + @Cached @Shared CallBlockNode yieldNode, + @Cached @Shared CheckFrozenNode raiseIfFrozenNode) { return delete(array, value, maybeBlock, true, store, store, stores, stores, arraySizeProfile, loopProfile, - yieldNode, sameOrEqualNode); + yieldNode, sameOrEqualNode, raiseIfFrozenNode); } @Specialization( guards = "!stores.isMutable(store)", limit = "storageStrategyLimit()") - Object delete(RubyArray array, Object value, Object maybeBlock, + Object deleteNotMutable(RubyArray array, Object value, Object maybeBlock, @Bind("array.getStore()") Object store, @CachedLibrary("store") ArrayStoreLibrary stores, @CachedLibrary(limit = "1") ArrayStoreLibrary newStores, @Cached @Shared SameOrEqualNode sameOrEqualNode, @Cached @Shared InlinedIntValueProfile arraySizeProfile, @Cached @Shared InlinedLoopConditionProfile loopProfile, - @Cached @Shared CallBlockNode yieldNode) { + @Cached @Shared CallBlockNode yieldNode, + @Cached @Shared CheckFrozenNode raiseIfFrozenNode) { final Object newStore = stores.allocator(store).allocate(arraySizeProfile.profile(this, array.size)); return delete(array, value, maybeBlock, false, store, newStore, stores, newStores, arraySizeProfile, - loopProfile, yieldNode, sameOrEqualNode); + loopProfile, yieldNode, sameOrEqualNode, raiseIfFrozenNode); } private Object delete(RubyArray array, Object value, Object maybeBlock, @@ -704,7 +704,8 @@ private Object delete(RubyArray array, Object value, Object maybeBlock, InlinedIntValueProfile arraySizeProfile, InlinedLoopConditionProfile loopProfile, CallBlockNode yieldNode, - SameOrEqualNode sameOrEqualNode) { + SameOrEqualNode sameOrEqualNode, + CheckFrozenNode raiseIfFrozenNode) { assert !sameStores || (oldStore == newStore && oldStores == newStores); @@ -718,7 +719,7 @@ private Object delete(RubyArray array, Object value, Object maybeBlock, final Object stored = oldStores.read(oldStore, n); if (sameOrEqualNode.execute(this, stored, value)) { - checkFrozen(array); + raiseIfFrozenNode.execute(this, array); found = stored; n++; } else { @@ -743,18 +744,10 @@ private Object delete(RubyArray array, Object value, Object maybeBlock, if (maybeBlock == nil) { return nil; } else { - return yieldNode.yield((RubyProc) maybeBlock, value); + return yieldNode.yield(this, (RubyProc) maybeBlock, value); } } } - - public void checkFrozen(Object object) { - if (raiseIfFrozenNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - raiseIfFrozenNode = insert(TypeNodes.CheckFrozenNode.create()); - } - raiseIfFrozenNode.execute(object); - } } @CoreMethod(names = "delete_at", required = 1, raiseIfFrozenSelf = true, lowerFixnum = 1) @@ -814,7 +807,7 @@ Object each(RubyArray array, RubyProc block, public void accept(Node node, CallBlockNode yieldNode, RubyArray array, Object state, Object element, int index, BooleanCastNode booleanCastNode) { RubyProc block = (RubyProc) state; - yieldNode.yield(block, element); + yieldNode.yield(node, block, element); } } @@ -834,7 +827,7 @@ Object eachOther(RubyArray array, RubyProc block, public void accept(Node node, CallBlockNode yieldNode, RubyArray array, Object state, Object element, int index, BooleanCastNode booleanCastNode) { RubyProc block = (RubyProc) state; - yieldNode.yield(block, element, index); + yieldNode.yield(node, block, element, index); } } @@ -1107,7 +1100,6 @@ static boolean include(RubyArray array, Object value, @ImportStatic({ ArrayGuards.class, ArrayStoreLibrary.class }) public abstract static class InitializeNode extends CoreMethodArrayArgumentsNode { - @Child private ToIntNode toIntNode; @Child private DispatchNode toAryNode; @Child private KernelNodes.RespondToNode respondToToAryNode; @@ -1213,25 +1205,26 @@ RubyArray initializeSizeOther(RubyArray array, Object size, Object fillingValue, // With block @Specialization(guards = "size >= 0") - Object initializeBlock(RubyArray array, int size, Object unusedFillingValue, RubyProc block, + static Object initializeBlock(RubyArray array, int size, Object unusedFillingValue, RubyProc block, @Cached ArrayBuilderNode arrayBuilder, @CachedLibrary(limit = "2") @Exclusive ArrayStoreLibrary stores, @Cached @Shared IsSharedNode isSharedNode, @Cached @Shared ConditionProfile sharedProfile, @Cached @Exclusive LoopConditionProfile loopProfile, - @Cached CallBlockNode yieldNode) { + @Cached CallBlockNode yieldNode, + @Bind("this") Node node) { BuilderState state = arrayBuilder.start(size); int n = 0; try { for (; loopProfile.inject(n < size); n++) { - final Object value = yieldNode.yield(block, n); + final Object value = yieldNode.yield(node, block, n); arrayBuilder.appendValue(state, n, value); } } finally { - profileAndReportLoopCount(loopProfile, n); + profileAndReportLoopCount(node, loopProfile, n); Object store = arrayBuilder.finish(state, n); - if (sharedProfile.profile(isSharedNode.executeIsShared(this, array))) { + if (sharedProfile.profile(isSharedNode.executeIsShared(node, array))) { store = stores.makeShared(store, n); } setStoreAndSize(array, store, n); @@ -1362,7 +1355,7 @@ private Object injectBlockHelper(RubyArray array, public void accept(Node node, CallBlockNode yieldNode, RubyArray array, Object stateObject, Object element, int index, BooleanCastNode booleanCastNode) { final State state = (State) stateObject; - state.accumulator = yieldNode.yield(state.block, state.accumulator, element); + state.accumulator = yieldNode.yield(node, state.block, state.accumulator, element); } // Uses Symbol and no block @@ -1479,7 +1472,7 @@ public void accept(Node node, CallBlockNode yieldNode, RubyArray array, Object s int index, BooleanCastNode booleanCastNode) { final State state = (State) stateObject; - Object value = yieldNode.yield(state.block, element); + Object value = yieldNode.yield(node, state.block, element); arrayBuilder.appendValue(state.builderState, index, value); } @@ -1502,7 +1495,7 @@ Object map(RubyArray array, RubyProc block, public void accept(Node node, CallBlockNode yieldNode, RubyArray array, Object state, Object element, int index, BooleanCastNode booleanCastNode) { RubyProc block = (RubyProc) state; - writeNode.executeWrite(array, index, yieldNode.yield(block, element)); + writeNode.executeWrite(array, index, yieldNode.yield(node, block, element)); } } @@ -1775,7 +1768,7 @@ public void accept(Node node, CallBlockNode yieldNode, RubyArray array, Object s int index, BooleanCastNode booleanCastNode) { final State state = (State) stateObject; - if (!booleanCastNode.execute(node, yieldNode.yield(state.block, element))) { + if (!booleanCastNode.execute(node, yieldNode.yield(node, state.block, element))) { arrayBuilder.appendValue(state.builderState, state.newArraySize, element); state.newArraySize++; } @@ -1985,7 +1978,7 @@ public void accept(Node node, CallBlockNode yieldNode, RubyArray array, Object s int index, BooleanCastNode booleanCastNode) { final State state = (State) stateObject; - if (booleanCastNode.execute(node, yieldNode.yield(state.block, element))) { + if (booleanCastNode.execute(node, yieldNode.yield(node, state.block, element))) { arrayBuilder.appendValue(state.builderState, state.selectedSize, element); state.selectedSize++; } @@ -2080,21 +2073,22 @@ RubyArray sortEmpty(RubyArray array, Object unusedBlock) { @Specialization( guards = { "!isEmptyArray(array)", "isSmall(array)" }, limit = "storageStrategyLimit()") - RubyArray sortVeryShort(VirtualFrame frame, RubyArray array, Nil block, + static RubyArray sortVeryShort(VirtualFrame frame, RubyArray array, Nil block, @Bind("array.getStore()") Object store, @CachedLibrary("store") ArrayStoreLibrary stores, @CachedLibrary(limit = "1") @Exclusive ArrayStoreLibrary newStores, @Cached @Shared IntValueProfile arraySizeProfile, @Cached @Exclusive DispatchNode compareDispatchNode, - @Cached CmpIntNode cmpIntNode) { + @Cached CmpIntNode cmpIntNode, + @Bind("this") Node node) { final Object newStore = stores .unsharedAllocator(store) - .allocate(getContext().getOptions().ARRAY_SMALL); + .allocate(getContext(node).getOptions().ARRAY_SMALL); final int size = arraySizeProfile.profile(array.size); // Copy with a exploded loop for PE - for (int i = 0; i < getContext().getOptions().ARRAY_SMALL; i++) { + for (int i = 0; i < getContext(node).getOptions().ARRAY_SMALL; i++) { if (i < size) { newStores.write(newStore, i, stores.read(store, i)); } @@ -2102,14 +2096,14 @@ RubyArray sortVeryShort(VirtualFrame frame, RubyArray array, Nil block, // Selection sort - written very carefully to allow PE - for (int i = 0; i < getContext().getOptions().ARRAY_SMALL; i++) { + for (int i = 0; i < getContext(node).getOptions().ARRAY_SMALL; i++) { if (i < size) { - for (int j = i + 1; j < getContext().getOptions().ARRAY_SMALL; j++) { + for (int j = i + 1; j < getContext(node).getOptions().ARRAY_SMALL; j++) { if (j < size) { final Object a = newStores.read(newStore, i); final Object b = newStores.read(newStore, j); final Object comparisonResult = compareDispatchNode.call(b, "<=>", a); - if (cmpIntNode.executeCmpInt(comparisonResult, b, a) < 0) { + if (cmpIntNode.executeCmpInt(node, comparisonResult, b, a) < 0) { newStores.write(newStore, j, a); newStores.write(newStore, i, b); } @@ -2118,7 +2112,7 @@ RubyArray sortVeryShort(VirtualFrame frame, RubyArray array, Nil block, } } - return createArray(newStore, size); + return createArray(node, newStore, size); } @Specialization( diff --git a/src/main/java/org/truffleruby/core/basicobject/BasicObjectNodes.java b/src/main/java/org/truffleruby/core/basicobject/BasicObjectNodes.java index 3a24751e6418..041f3f47a4fd 100644 --- a/src/main/java/org/truffleruby/core/basicobject/BasicObjectNodes.java +++ b/src/main/java/org/truffleruby/core/basicobject/BasicObjectNodes.java @@ -11,6 +11,8 @@ import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.object.Shape; @@ -280,7 +282,7 @@ Object evalWithBlock(Frame callerFrame, Object self, Object[] rubyArgs, RootCall } final Object block = RubyArguments.getBlock(rubyArgs); - return instanceExecNode.execute(EmptyArgumentsDescriptor.INSTANCE, self, new Object[]{ self }, + return instanceExecNode.execute(this, EmptyArgumentsDescriptor.INSTANCE, self, new Object[]{ self }, (RubyProc) block); } @@ -365,7 +367,7 @@ private static LexicalScope prependReceiverClassToScope(LexicalScope callerLexic // For BasicObject#instance_eval, the new scopes SHOULD affect constant lookup but SHOULD NOT affect class variables lookup LexicalScope lexicalScope = new LexicalScope(callerLexicalScope, logicalClass, true); - if (CanHaveSingletonClassNode.getUncached().execute(receiver)) { + if (CanHaveSingletonClassNode.executeUncached(receiver)) { final RubyClass singletonClass = SingletonClassNode.getUncached().execute(receiver); // For true/false/nil Ruby objects #singleton_class (and SingletonClassNode as well) returns @@ -398,7 +400,8 @@ Object instanceExec(VirtualFrame frame, Object receiver, Object[] arguments, Rub new SingletonClassOfSelfDefaultDefinee(receiver), block.declarationContext.getRefinements()); var descriptor = RubyArguments.getDescriptor(frame); - return callBlockNode.executeCallBlock(declarationContext, block, receiver, nil, descriptor, arguments); + return callBlockNode.executeCallBlock(this, declarationContext, block, receiver, nil, descriptor, + arguments); } @Specialization @@ -409,19 +412,23 @@ Object instanceExec(Object receiver, Object[] arguments, Nil block) { } @GenerateUncached + @GenerateCached(false) + @GenerateInline public abstract static class InstanceExecBlockNode extends RubyBaseNode { - public abstract Object execute(ArgumentsDescriptor descriptor, Object self, Object[] args, RubyProc block); + public abstract Object execute(Node node, ArgumentsDescriptor descriptor, Object self, Object[] args, + RubyProc block); @Specialization - Object instanceExec(ArgumentsDescriptor descriptor, Object self, Object[] arguments, RubyProc block, + static Object instanceExec( + Node node, ArgumentsDescriptor descriptor, Object self, Object[] arguments, RubyProc block, @Cached CallBlockNode callBlockNode) { final DeclarationContext declarationContext = new DeclarationContext( Visibility.PUBLIC, new SingletonClassOfSelfDefaultDefinee(self), block.declarationContext.getRefinements()); - return callBlockNode.executeCallBlock(declarationContext, block, self, nil, descriptor, arguments); + return callBlockNode.executeCallBlock(node, declarationContext, block, self, nil, descriptor, arguments); } } diff --git a/src/main/java/org/truffleruby/core/binding/BindingNodes.java b/src/main/java/org/truffleruby/core/binding/BindingNodes.java index 04ec10b83aec..1eff01136fc3 100644 --- a/src/main/java/org/truffleruby/core/binding/BindingNodes.java +++ b/src/main/java/org/truffleruby/core/binding/BindingNodes.java @@ -19,7 +19,6 @@ import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Idempotent; -import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.frame.FrameSlotKind; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -175,21 +174,18 @@ RubyBinding dup(RubyBinding binding) { * variables. */ @ImportStatic({ BindingNodes.class, FindDeclarationVariableNodes.class }) @GenerateUncached + @GenerateInline + @GenerateCached(false) public abstract static class HasLocalVariableNode extends RubyBaseNode { - @NeverDefault - public static HasLocalVariableNode create() { - return BindingNodesFactory.HasLocalVariableNodeGen.create(); - } - - public abstract boolean execute(RubyBinding binding, String name); + public abstract boolean execute(Node node, RubyBinding binding, String name); @Specialization( guards = { "name == cachedName", "getFrameDescriptor(binding) == descriptor" }, limit = "getCacheLimit()") - boolean localVariableDefinedCached(RubyBinding binding, String name, + static boolean localVariableDefinedCached(RubyBinding binding, String name, @Cached("name") String cachedName, @Cached("getFrameDescriptor(binding)") FrameDescriptor descriptor, @Cached("findFrameSlotOrNull(name, binding.getFrame())") FrameSlotAndDepth cachedFrameSlot) { @@ -198,7 +194,7 @@ boolean localVariableDefinedCached(RubyBinding binding, String name, @TruffleBoundary @Specialization(replaces = "localVariableDefinedCached") - boolean localVariableDefinedUncached(RubyBinding binding, String name) { + static boolean localVariableDefinedUncached(RubyBinding binding, String name) { return FindDeclarationVariableNodes.findFrameSlotOrNull(name, binding.getFrame()) != null; } diff --git a/src/main/java/org/truffleruby/core/cast/BigIntegerCastNode.java b/src/main/java/org/truffleruby/core/cast/BigIntegerCastNode.java index 560f8845e7e9..290b6c88727c 100644 --- a/src/main/java/org/truffleruby/core/cast/BigIntegerCastNode.java +++ b/src/main/java/org/truffleruby/core/cast/BigIntegerCastNode.java @@ -10,7 +10,10 @@ package org.truffleruby.core.cast; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; import org.truffleruby.core.exception.RubyException; import org.truffleruby.core.numeric.BigIntegerOps; import org.truffleruby.core.numeric.RubyBignum; @@ -20,9 +23,11 @@ import java.math.BigInteger; /** Casts a value into a BigInteger. */ +@GenerateCached(false) +@GenerateInline public abstract class BigIntegerCastNode extends RubyBaseNode { - public abstract BigInteger execute(Object value); + public abstract BigInteger execute(Node node, Object value); @Specialization BigInteger doInt(int value) { diff --git a/src/main/java/org/truffleruby/core/cast/CmpIntNode.java b/src/main/java/org/truffleruby/core/cast/CmpIntNode.java index 83092c1ac647..260642b86725 100644 --- a/src/main/java/org/truffleruby/core/cast/CmpIntNode.java +++ b/src/main/java/org/truffleruby/core/cast/CmpIntNode.java @@ -20,7 +20,8 @@ package org.truffleruby.core.cast; -import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.nodes.Node; import org.truffleruby.core.numeric.RubyBignum; import org.truffleruby.core.string.StringUtils; @@ -35,21 +36,19 @@ import org.truffleruby.language.objects.LogicalClassNode; /** This is a port of MRI's rb_cmpint, as taken from RubyComparable and broken out into specialized nodes. */ +@GenerateInline +@GenerateCached(false) public abstract class CmpIntNode extends RubyBaseNode { - public static CmpIntNode create() { - return CmpIntNodeGen.create(); - } - - public abstract int executeCmpInt(Object cmpResult, Object a, Object b); + public abstract int executeCmpInt(Node node, Object cmpResult, Object a, Object b); @Specialization - int cmpInt(int value, Object receiver, Object other) { + static int cmpInt(int value, Object receiver, Object other) { return value; } @Specialization - int cmpLong(long value, Object receiver, Object other) { + static int cmpLong(long value, Object receiver, Object other) { if (value > 0) { return 1; } @@ -62,17 +61,18 @@ int cmpLong(long value, Object receiver, Object other) { } @Specialization - int cmpBignum(RubyBignum value, Object receiver, Object other) { + static int cmpBignum(RubyBignum value, Object receiver, Object other) { return value.value.signum(); } @Specialization - int cmpNil(Nil nil, Object receiver, Object other) { - throw new RaiseException(getContext(), coreExceptions().argumentError(formatMessage(receiver, other), this)); + static int cmpNil(Node node, Nil nil, Object receiver, Object other) { + throw new RaiseException(getContext(node), + coreExceptions(node).argumentError(formatMessage(receiver, other), node)); } @TruffleBoundary - private String formatMessage(Object receiver, Object other) { + private static String formatMessage(Object receiver, Object other) { return StringUtils.format( "comparison of %s with %s failed", LogicalClassNode.getUncached().execute(receiver).fields.getName(), @@ -80,12 +80,11 @@ private String formatMessage(Object receiver, Object other) { } @Specialization(guards = { "!isRubyInteger(value)", "!isNil(value)" }) - static int cmpObject(Object value, Object receiver, Object other, - @Cached DispatchNode gtNode, - @Cached DispatchNode ltNode, + static int cmpObject(Node node, Object value, Object receiver, Object other, + @Cached(inline = false) DispatchNode gtNode, + @Cached(inline = false) DispatchNode ltNode, @Cached BooleanCastNode gtCastNode, - @Cached BooleanCastNode ltCastNode, - @Bind("this") Node node) { + @Cached BooleanCastNode ltCastNode) { if (gtCastNode.execute(node, gtNode.call(value, ">", 0))) { return 1; diff --git a/src/main/java/org/truffleruby/core/cast/DurationToNanoSecondsNode.java b/src/main/java/org/truffleruby/core/cast/DurationToNanoSecondsNode.java index 6749adf79b90..5421903d2e13 100644 --- a/src/main/java/org/truffleruby/core/cast/DurationToNanoSecondsNode.java +++ b/src/main/java/org/truffleruby/core/cast/DurationToNanoSecondsNode.java @@ -9,10 +9,11 @@ */ package org.truffleruby.core.cast; -import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import org.truffleruby.language.RubyBaseNode; @@ -24,33 +25,34 @@ import java.util.concurrent.TimeUnit; +@GenerateInline +@GenerateCached(false) public abstract class DurationToNanoSecondsNode extends RubyBaseNode { - public abstract long execute(Object duration); + public abstract long execute(Node node, Object duration); @Specialization - long noDuration(NotProvided duration) { + static long noDuration(NotProvided duration) { return Long.MAX_VALUE; } @Specialization - long duration(long duration, + static long duration(Node node, long duration, @Cached @Shared InlinedConditionProfile durationLessThanZeroProfile) { - return validate(this, TimeUnit.SECONDS.toNanos(duration), durationLessThanZeroProfile); + return validate(node, TimeUnit.SECONDS.toNanos(duration), durationLessThanZeroProfile); } @Specialization - long duration(double duration, + static long duration(Node node, double duration, @Cached @Shared InlinedConditionProfile durationLessThanZeroProfile) { - return validate(this, (long) (duration * 1e9), durationLessThanZeroProfile); + return validate(node, (long) (duration * 1e9), durationLessThanZeroProfile); } @Fallback - static long duration(Object duration, - @Cached DispatchNode durationToNanoSeconds, + static long duration(Node node, Object duration, + @Cached(inline = false) DispatchNode durationToNanoSeconds, @Cached @Shared InlinedConditionProfile durationLessThanZeroProfile, - @Cached ToLongNode toLongNode, - @Bind("this") Node node) { + @Cached ToLongNode toLongNode) { final Object nanoseconds = durationToNanoSeconds.call( coreLibrary(node).truffleKernelOperationsModule, "convert_duration_to_nanoseconds", diff --git a/src/main/java/org/truffleruby/core/cast/HashCastNode.java b/src/main/java/org/truffleruby/core/cast/HashCastNode.java index c35ab7a2f628..ed8f886b351a 100644 --- a/src/main/java/org/truffleruby/core/cast/HashCastNode.java +++ b/src/main/java/org/truffleruby/core/cast/HashCastNode.java @@ -9,6 +9,9 @@ */ package org.truffleruby.core.cast; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import org.truffleruby.core.hash.RubyHash; import org.truffleruby.language.RubyBaseNode; @@ -25,33 +28,35 @@ import static org.truffleruby.language.dispatch.DispatchConfiguration.PRIVATE_RETURN_MISSING; +@GenerateCached(false) +@GenerateInline public abstract class HashCastNode extends RubyBaseNode { - public abstract RubyHash execute(Object value); + public abstract RubyHash execute(Node node, Object value); @Specialization - RubyHash castHash(RubyHash hash) { + static RubyHash castHash(RubyHash hash) { return hash; } @Specialization(guards = "!isRubyHash(object)") - RubyHash cast(Object object, + static RubyHash cast(Node node, Object object, @Cached InlinedBranchProfile errorProfile, - @Cached DispatchNode toHashNode) { + @Cached(inline = false) DispatchNode toHashNode) { final Object result = toHashNode.call(PRIVATE_RETURN_MISSING, object, "to_hash"); if (result == DispatchNode.MISSING) { - errorProfile.enter(this); + errorProfile.enter(node); throw new RaiseException( - getContext(), - coreExceptions().typeErrorNoImplicitConversion(object, "Hash", this)); + getContext(node), + coreExceptions(node).typeErrorNoImplicitConversion(object, "Hash", node)); } if (!RubyGuards.isRubyHash(result)) { - errorProfile.enter(this); + errorProfile.enter(node); throw new RaiseException( - getContext(), - coreExceptions().typeErrorCantConvertTo(object, "Hash", "to_hash", result, this)); + getContext(node), + coreExceptions(node).typeErrorCantConvertTo(object, "Hash", "to_hash", result, node)); } return (RubyHash) result; @@ -66,7 +71,7 @@ public abstract static class HashCastASTNode extends RubyContextSourceNode { @Specialization RubyHash cast(Object object, @Cached HashCastNode hashCastNode) { - return hashCastNode.execute(object); + return hashCastNode.execute(this, object); } diff --git a/src/main/java/org/truffleruby/core/cast/LongCastNode.java b/src/main/java/org/truffleruby/core/cast/LongCastNode.java index 746a18810bb4..bba39d9f94a5 100644 --- a/src/main/java/org/truffleruby/core/cast/LongCastNode.java +++ b/src/main/java/org/truffleruby/core/cast/LongCastNode.java @@ -9,6 +9,9 @@ */ package org.truffleruby.core.cast; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.nodes.Node; import org.truffleruby.language.RubyBaseNode; import org.truffleruby.language.control.RaiseException; @@ -18,25 +21,27 @@ /** See {@link ToIntNode} for a comparison of different integer conversion nodes. */ @GenerateUncached +@GenerateInline +@GenerateCached(false) public abstract class LongCastNode extends RubyBaseNode { - public abstract long executeCastLong(Object value); + public abstract long executeCastLong(Node node, Object value); @Specialization - long doInt(int value) { + static long doInt(int value) { return value; } @Specialization - long doLong(long value) { + static long doLong(long value) { return value; } @TruffleBoundary @Specialization(guards = "!isImplicitLong(value)") - long doBasicObject(Object value) { + static long doBasicObject(Node node, Object value) { throw new RaiseException( - getContext(), - coreExceptions().typeErrorIsNotA(value.toString(), "Integer (fitting in long)", this)); + getContext(node), + coreExceptions(node).typeErrorIsNotA(value.toString(), "Integer (fitting in long)", node)); } } diff --git a/src/main/java/org/truffleruby/core/encoding/EncodingNodes.java b/src/main/java/org/truffleruby/core/encoding/EncodingNodes.java index 1786821bb276..4c90e1513a50 100644 --- a/src/main/java/org/truffleruby/core/encoding/EncodingNodes.java +++ b/src/main/java/org/truffleruby/core/encoding/EncodingNodes.java @@ -485,12 +485,12 @@ Object allocate(RubyClass rubyClass) { @Primitive(name = "encoding_each_alias") public abstract static class EachAliasNode extends PrimitiveArrayArgumentsNode { - @Child private CallBlockNode yieldNode = CallBlockNode.create(); @Child private TruffleString.FromByteArrayNode fromByteArrayNode = TruffleString.FromByteArrayNode.create(); @TruffleBoundary @Specialization - Object eachAlias(RubyProc block) { + Object eachAlias(RubyProc block, + @Cached CallBlockNode yieldNode) { var iterator = EncodingDB.getAliases().entryIterator(); while (iterator.hasNext()) { var entry = iterator.next(); @@ -499,6 +499,7 @@ Object eachAlias(RubyProc block) { ArrayUtils.extractRange(entry.bytes, entry.p, entry.end), Encodings.US_ASCII); // CR_7BIT yieldNode.yield( + this, block, aliasName, Encodings.getBuiltInEncoding(entry.value.getEncoding())); diff --git a/src/main/java/org/truffleruby/core/hash/HashNodes.java b/src/main/java/org/truffleruby/core/hash/HashNodes.java index fa1e6e6a8c03..dc961cd68bd3 100644 --- a/src/main/java/org/truffleruby/core/hash/HashNodes.java +++ b/src/main/java/org/truffleruby/core/hash/HashNodes.java @@ -9,9 +9,11 @@ */ package org.truffleruby.core.hash; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import org.truffleruby.RubyLanguage; @@ -180,7 +182,7 @@ RubyHash copyAndSetRuby2Keywords(RubyHash self, boolean ruby2_keywords, @Cached DispatchNode initializeDupNode) { final RubyHash newObject = new RubyHash(self.getLogicalClass(), getLanguage().hashShape, getContext(), EmptyHashStore.NULL_HASH_STORE, 0, ruby2_keywords); - copyInstanceVariablesNode.execute(newObject, self); + copyInstanceVariablesNode.execute(this, newObject, self); initializeDupNode.call(newObject, "initialize_dup", self); return newObject; } @@ -322,16 +324,17 @@ Object defaultValue(RubyHash hash) { public abstract static class DeleteNode extends CoreMethodArrayArgumentsNode { @Specialization(limit = "hashStrategyLimit()") - Object delete(RubyHash hash, Object key, Object maybeBlock, + static Object delete(RubyHash hash, Object key, Object maybeBlock, @CachedLibrary("hash.store") HashStoreLibrary hashes, @Cached CallBlockNode yieldNode, @Cached @Shared InlinedConditionProfile hasValue, - @Cached @Shared InlinedConditionProfile hasBlock) { + @Cached @Shared InlinedConditionProfile hasBlock, + @Bind("this") Node node) { final Object value = hashes.delete(hash.store, hash, key); - if (hasValue.profile(this, value != null)) { + if (hasValue.profile(node, value != null)) { return value; - } else if (hasBlock.profile(this, maybeBlock != nil)) { - return yieldNode.yield((RubyProc) maybeBlock, key); + } else if (hasBlock.profile(node, maybeBlock != nil)) { + return yieldNode.yield(node, (RubyProc) maybeBlock, key); } else { return nil; } @@ -353,7 +356,7 @@ RubyHash each(RubyHash hash, RubyProc block, @Override public void accept(int index, Object key, Object value, Object state) { - callBlockNode.yield((RubyProc) state, createArray(new Object[]{ key, value })); + callBlockNode.yieldCached((RubyProc) state, createArray(new Object[]{ key, value })); } } diff --git a/src/main/java/org/truffleruby/core/hash/library/HashStoreLibrary.java b/src/main/java/org/truffleruby/core/hash/library/HashStoreLibrary.java index 48c00845b1d6..0a232084336e 100644 --- a/src/main/java/org/truffleruby/core/hash/library/HashStoreLibrary.java +++ b/src/main/java/org/truffleruby/core/hash/library/HashStoreLibrary.java @@ -133,9 +133,9 @@ Object yieldPair(RubyProc block, Object key, Object value, // MRI behavior, see rb_hash_each_pair() // We use getMethodArityNumber() here since for non-lambda the semantics are the same for both branches if (arityMoreThanOne.profile(this, block.arity.getMethodArityNumber() > 1)) { - return yieldNode.yield(block, key, value); + return yieldNode.yield(this, block, key, value); } else { - return yieldNode.yield(block, createArray(new Object[]{ key, value })); + return yieldNode.yield(this, block, createArray(new Object[]{ key, value })); } } } diff --git a/src/main/java/org/truffleruby/core/kernel/KernelNodes.java b/src/main/java/org/truffleruby/core/kernel/KernelNodes.java index 72dd1bccfbca..a5a020c7a6ad 100644 --- a/src/main/java/org/truffleruby/core/kernel/KernelNodes.java +++ b/src/main/java/org/truffleruby/core/kernel/KernelNodes.java @@ -433,17 +433,22 @@ RubyClass getClass(Object self) { @ImportStatic(ShapeCachingGuards.class) @GenerateUncached + @GenerateInline(inlineByDefault = true) public abstract static class CopyInstanceVariablesNode extends RubyBaseNode { public static final PropertyGetter[] EMPTY_PROPERTY_GETTER_ARRAY = new PropertyGetter[0]; - public abstract RubyDynamicObject execute(RubyDynamicObject newObject, RubyDynamicObject from); + public abstract RubyDynamicObject execute(Node node, RubyDynamicObject newObject, RubyDynamicObject from); + + public final RubyDynamicObject executeCached(RubyDynamicObject newObject, RubyDynamicObject from) { + return execute(this, newObject, from); + } @ExplodeLoop @Specialization( guards = { "from.getShape() == cachedShape", "propertyGetters.length <= MAX_EXPLODE_SIZE" }, limit = "getDynamicObjectCacheLimit()") - RubyDynamicObject copyCached(RubyDynamicObject newObject, RubyDynamicObject from, + static RubyDynamicObject copyCached(RubyDynamicObject newObject, RubyDynamicObject from, @Cached("from.getShape()") Shape cachedShape, @Cached(value = "getCopiedProperties(cachedShape)", dimensions = 1) PropertyGetter[] propertyGetters, @Cached("createWriteFieldNodes(propertyGetters)") DynamicObjectLibrary[] writeFieldNodes) { @@ -457,17 +462,18 @@ RubyDynamicObject copyCached(RubyDynamicObject newObject, RubyDynamicObject from } @Specialization(guards = "updateShape(from)") - RubyDynamicObject updateShapeAndCopy(RubyDynamicObject newObject, RubyDynamicObject from) { - return execute(newObject, from); + static RubyDynamicObject updateShapeAndCopy(RubyDynamicObject newObject, RubyDynamicObject from, + @Cached(inline = false) CopyInstanceVariablesNode copyInstanceVariablesNode) { + return copyInstanceVariablesNode.executeCached(newObject, from); } @Specialization(replaces = { "copyCached", "updateShapeAndCopy" }) - RubyDynamicObject copyUncached(RubyDynamicObject newObject, RubyDynamicObject from) { + static RubyDynamicObject copyUncached(RubyDynamicObject newObject, RubyDynamicObject from) { copyInstanceVariables(from, newObject); return newObject; } - protected PropertyGetter[] getCopiedProperties(Shape shape) { + protected static PropertyGetter[] getCopiedProperties(Shape shape) { final List copiedProperties = new ArrayList<>(); for (Property property : shape.getProperties()) { @@ -488,7 +494,7 @@ protected DynamicObjectLibrary[] createWriteFieldNodes(PropertyGetter[] property } @TruffleBoundary - private void copyInstanceVariables(RubyDynamicObject from, RubyDynamicObject to) { + private static void copyInstanceVariables(RubyDynamicObject from, RubyDynamicObject to) { // Concurrency: OK if callers create the object and publish it after copy // Only copy user-level instance variables, hidden ones are initialized later with #initialize_copy. Shape shape = from.getShape(); @@ -512,7 +518,7 @@ RubyDynamicObject copyRubyDynamicObject(RubyDynamicObject self, @Cached DispatchNode allocateNode, @Cached @Exclusive CopyInstanceVariablesNode copyInstanceVariablesNode) { var newObject = (RubyDynamicObject) allocateNode.call(self.getLogicalClass(), "__allocate__"); - copyInstanceVariablesNode.execute(newObject, self); + copyInstanceVariablesNode.execute(this, newObject, self); return newObject; } @@ -526,7 +532,7 @@ RubyDynamicObject copyRubyClass(RubyClass self, } var newClass = new RubyClass(coreLibrary().classClass, getLanguage(), getEncapsulatingSourceSection(), null, null, false, null, self.superclass); - copyInstanceVariablesNode.execute(newClass, self); + copyInstanceVariablesNode.execute(this, newClass, self); return newClass; } @@ -943,7 +949,7 @@ Object initializeCopy(Frame callerFrame, Object self, Object[] rubyArgs, RootCal @Cached LogicalClassNode lhsClassNode, @Cached LogicalClassNode rhsClassNode, @Cached InlinedBranchProfile errorProfile) { - checkFrozenNode.execute(self); + checkFrozenNode.execute(this, self); if (lhsClassNode.execute(self) != rhsClassNode.execute(from)) { errorProfile.enter(this); @@ -1032,7 +1038,7 @@ Object instanceVariableSet(RubyDynamicObject object, Object name, Object value, @Cached TypeNodes.CheckFrozenNode raiseIfFrozenNode) { final String nameString = nameToJavaStringNode.execute(this, name); checkIVarNameNode.execute(object, nameString, name); - raiseIfFrozenNode.execute(object); + raiseIfFrozenNode.execute(this, object); writeNode.execute(this, object, nameString, value); return value; } @@ -1057,7 +1063,7 @@ Object removeInstanceVariable(RubyDynamicObject object, Object name, @Cached TypeNodes.CheckFrozenNode raiseIfFrozenNode) { final String nameString = nameToJavaStringNode.execute(this, name); checkIVarNameNode.execute(object, nameString, name); - raiseIfFrozenNode.execute(object); + raiseIfFrozenNode.execute(this, object); return removeIVar(object, nameString); } @@ -1591,7 +1597,7 @@ public abstract static class SleepNode extends CoreMethodArrayArgumentsNode { @Specialization long sleep(Object maybeDuration, @Cached DurationToNanoSecondsNode durationToNanoSecondsNode) { - long durationInNanos = durationToNanoSecondsNode.execute(maybeDuration); + long durationInNanos = durationToNanoSecondsNode.execute(this, maybeDuration); assert durationInNanos >= 0; final RubyThread thread = getLanguage().getCurrentThread(); @@ -1745,35 +1751,38 @@ public abstract static class KernelToHexStringNode extends PrimitiveArrayArgumen @Specialization String toHexString(Object value, @Cached ToHexStringNode toHexStringNode) { - return toHexStringNode.execute(value); + return toHexStringNode.execute(this, value); } } @GenerateUncached + @GenerateInline + @GenerateCached(false) public abstract static class ToHexStringNode extends RubyBaseNode { - public static ToHexStringNode getUncached() { - return KernelNodesFactory.ToHexStringNodeGen.getUncached(); - } + public abstract String execute(Node node, Object value); - public abstract String execute(Object value); + public static String executeUncached(Object value) { + return KernelNodesFactory.ToHexStringNodeGen.getUncached().execute(null, value); + } @Specialization - String toHexString(int value) { + static String toHexString(int value) { return toHexString((long) value); } @TruffleBoundary @Specialization - String toHexString(long value) { + static String toHexString(long value) { return Long.toHexString(value); } @Specialization - String toHexString(RubyBignum value) { + static String toHexString(RubyBignum value) { return BigIntegerOps.toString(value.value, 16); } + } @CoreMethod(names = { "to_s", "inspect" }) // Basic #inspect, refined later in core @@ -1806,7 +1815,7 @@ RubyString toS(Object self, @Cached ToHexStringNode toHexStringNode) { String className = classNode.execute(self).fields.getName(); Object id = objectIDNode.execute(self); - String hexID = toHexStringNode.execute(id); + String hexID = toHexStringNode.execute(this, id); String javaString = Utils.concat("#<", className, ":0x", hexID, ">"); @@ -1820,7 +1829,7 @@ RubyString toS(Object self, public static String uncachedBasicToS(Object self) { String className = LogicalClassNode.getUncached().execute(self).fields.getName(); Object id = ObjectIDNode.getUncached().execute(self); - String hexID = ToHexStringNode.getUncached().execute(id); + String hexID = ToHexStringNode.executeUncached(id); return "#<" + className + ":0x" + hexID + ">"; } diff --git a/src/main/java/org/truffleruby/core/module/ModuleNodes.java b/src/main/java/org/truffleruby/core/module/ModuleNodes.java index c3a3b221f434..73857588b9d5 100644 --- a/src/main/java/org/truffleruby/core/module/ModuleNodes.java +++ b/src/main/java/org/truffleruby/core/module/ModuleNodes.java @@ -808,7 +808,7 @@ Object classExec(ArgumentsDescriptor descriptor, RubyModule self, Object[] args, new FixedDefaultDefinee(self), block.declarationContext.getRefinements()); - return callBlockNode.executeCallBlock(declarationContext, block, self, nil, descriptor, args); + return callBlockNode.executeCallBlock(this, declarationContext, block, self, nil, descriptor, args); } } @@ -2032,20 +2032,20 @@ public abstract static class RemoveMethodNode extends CoreMethodArrayArgumentsNo private final BranchProfile errorProfile = BranchProfile.create(); - @Child private TypeNodes.CheckFrozenNode raiseIfFrozenNode = TypeNodes.CheckFrozenNode.create(); @Child private DispatchNode methodRemovedNode = DispatchNode.create(); @Specialization RubyModule removeMethods(RubyModule module, Object[] names, + @Cached TypeNodes.CheckFrozenNode raiseIfFrozenNode, @Cached NameToJavaStringNode nameToJavaStringNode) { for (Object name : names) { - removeMethod(module, nameToJavaStringNode.execute(this, name)); + removeMethod(module, nameToJavaStringNode.execute(this, name), raiseIfFrozenNode); } return module; } - private void removeMethod(RubyModule module, String name) { - raiseIfFrozenNode.execute(module); + private void removeMethod(RubyModule module, String name, TypeNodes.CheckFrozenNode raiseIfFrozenNode) { + raiseIfFrozenNode.execute(this, module); if (module.fields.removeMethod(name)) { if (RubyGuards.isSingletonClass(module)) { @@ -2262,7 +2262,7 @@ RubyModule refine(RubyModule namespace, RubyModule moduleToRefine, RubyProc bloc } } - CallBlockNode.getUncached().executeCallBlock( + CallBlockNode.executeUncached( declarationContext, block, refinement, diff --git a/src/main/java/org/truffleruby/core/monitor/TruffleMonitorNodes.java b/src/main/java/org/truffleruby/core/monitor/TruffleMonitorNodes.java index 3c4d53813466..d06629b4ebe8 100644 --- a/src/main/java/org/truffleruby/core/monitor/TruffleMonitorNodes.java +++ b/src/main/java/org/truffleruby/core/monitor/TruffleMonitorNodes.java @@ -29,18 +29,17 @@ public abstract class TruffleMonitorNodes { @Primitive(name = "monitor_synchronize") public abstract static class SynchronizeNode extends PrimitiveArrayArgumentsNode { - @Child private CallBlockNode yieldNode = CallBlockNode.create(); - @Specialization Object synchronizeOnMutex(RubyMutex mutex, RubyProc block, - @Cached InlinedBranchProfile errorProfile) { + @Cached InlinedBranchProfile errorProfile, + @Cached CallBlockNode yieldNode) { /* Like Mutex#synchronize we must maintain the owned locks list here as the monitor might be exited inside * synchronize block and then re-entered again before the end, and we have to make sure the list of owned * locks remains consistent. */ final RubyThread thread = getLanguage().getCurrentThread(); MutexOperations.lock(getContext(), mutex.lock, thread, this); try { - return yieldNode.yield(block); + return yieldNode.yield(this, block); } finally { MutexOperations.checkOwnedMutex(getContext(), mutex.lock, this, errorProfile); MutexOperations.unlock(mutex.lock, thread); diff --git a/src/main/java/org/truffleruby/core/mutex/MutexNodes.java b/src/main/java/org/truffleruby/core/mutex/MutexNodes.java index 2db5371cfbfb..c97d9ee6c33a 100644 --- a/src/main/java/org/truffleruby/core/mutex/MutexNodes.java +++ b/src/main/java/org/truffleruby/core/mutex/MutexNodes.java @@ -135,7 +135,7 @@ Object synchronize(RubyMutex mutex, RubyProc block, * locks list to be in consistent state at the end. */ MutexOperations.lock(getContext(), lock, thread, this); try { - return yieldNode.yield(block); + return yieldNode.yield(this, block); } finally { MutexOperations.checkOwnedMutex(getContext(), lock, this, errorProfile); MutexOperations.unlock(lock, thread); @@ -156,7 +156,7 @@ long sleep(RubyMutex mutex, Object maybeDuration, maybeDuration = NotProvided.INSTANCE; } - long durationInNanos = durationToNanoSecondsNode.execute(maybeDuration); + long durationInNanos = durationToNanoSecondsNode.execute(this, maybeDuration); final ReentrantLock lock = mutex.lock; final RubyThread thread = getLanguage().getCurrentThread(); diff --git a/src/main/java/org/truffleruby/core/numeric/IntegerNodes.java b/src/main/java/org/truffleruby/core/numeric/IntegerNodes.java index f7390ab4f779..9b31f7470643 100644 --- a/src/main/java/org/truffleruby/core/numeric/IntegerNodes.java +++ b/src/main/java/org/truffleruby/core/numeric/IntegerNodes.java @@ -1941,9 +1941,9 @@ Object doModPow(Object baseObject, Object exponentObject, Object moduloObject, @Cached BigIntegerCastNode exponentCastNode, @Cached BigIntegerCastNode moduloCastNode, @Cached ModPowNode modPowNode) { - final var base = baseCastNode.execute(baseObject); - final var exponent = exponentCastNode.execute(exponentObject); - final var modulo = moduloCastNode.execute(moduloObject); + final var base = baseCastNode.execute(this, baseObject); + final var exponent = exponentCastNode.execute(this, exponentObject); + final var modulo = moduloCastNode.execute(this, moduloObject); return modPowNode.execute(this, base, exponent, modulo); } } @@ -1987,7 +1987,7 @@ Object downto(int from, int to, RubyProc block, int i = from; try { for (; loopProfile.inject(this, i >= to); i--) { - yieldNode.yield(block, i); + yieldNode.yield(this, block, i); } } finally { profileAndReportLoopCount(this, loopProfile, from - i + 1); @@ -2010,7 +2010,7 @@ Object downto(long from, long to, RubyProc block, long i = from; try { for (; i >= to; i--) { - yieldNode.yield(block, i); + yieldNode.yield(this, block, i); } } finally { profileAndReportLoopCount(this, loopProfile, from - i + 1); @@ -2070,7 +2070,7 @@ Object upto(int from, int to, RubyProc block, int i = from; try { for (; loopProfile.inject(i <= to); i++) { - yieldNode.yield(block, i); + yieldNode.yield(this, block, i); } } finally { profileAndReportLoopCount(loopProfile, i - from + 1); @@ -2091,7 +2091,7 @@ Object upto(long from, long to, RubyProc block, long i = from; try { for (; i <= to; i++) { - yieldNode.yield(block, i); + yieldNode.yield(this, block, i); } } finally { profileAndReportLoopCount(loopProfile, i - from + 1); diff --git a/src/main/java/org/truffleruby/core/objectspace/ObjectSpaceNodes.java b/src/main/java/org/truffleruby/core/objectspace/ObjectSpaceNodes.java index 187add6b2f19..84e0c52eca52 100644 --- a/src/main/java/org/truffleruby/core/objectspace/ObjectSpaceNodes.java +++ b/src/main/java/org/truffleruby/core/objectspace/ObjectSpaceNodes.java @@ -137,7 +137,7 @@ int eachObject(NotProvided ofClass, RubyProc block, for (Object object : ObjectGraph.stopAndGetAllObjects("ObjectSpace.each_object", getContext(), this)) { if (include(object)) { - yieldNode.yield(block, object); + yieldNode.yield(this, block, object); count++; } } @@ -155,7 +155,7 @@ int eachObject(RubyModule ofClass, RubyProc block, final String reason = "ObjectSpace.each_object(" + ofClass + ")"; for (Object object : ObjectGraph.stopAndGetAllObjects(reason, getContext(), this)) { if (include(object) && isANode.executeIsA(object, ofClass)) { - yieldNode.yield(block, object); + yieldNode.yield(this, block, object); count++; } } diff --git a/src/main/java/org/truffleruby/core/objectspace/WeakMapNodes.java b/src/main/java/org/truffleruby/core/objectspace/WeakMapNodes.java index ba80d0c12dad..065f1a7334f9 100644 --- a/src/main/java/org/truffleruby/core/objectspace/WeakMapNodes.java +++ b/src/main/java/org/truffleruby/core/objectspace/WeakMapNodes.java @@ -117,7 +117,7 @@ RubyWeakMap eachKey(RubyWeakMap map, Nil block) { RubyWeakMap eachKey(RubyWeakMap map, RubyProc block, @Cached CallBlockNode yieldNode) { for (Object key : keys(map.storage)) { - yieldNode.yield(block, key); + yieldNode.yield(this, block, key); } return map; } @@ -135,7 +135,7 @@ RubyWeakMap eachValue(RubyWeakMap map, Nil block) { RubyWeakMap eachValue(RubyWeakMap map, RubyProc block, @Cached CallBlockNode yieldNode) { for (Object value : values(map.storage)) { - yieldNode.yield(block, value); + yieldNode.yield(this, block, value); } return map; } @@ -154,7 +154,7 @@ RubyWeakMap each(RubyWeakMap map, RubyProc block, @Cached CallBlockNode yieldNode) { for (SimpleEntry entry : entries(map.storage)) { - yieldNode.yield(block, entry.getKey(), entry.getValue()); + yieldNode.yield(this, block, entry.getKey(), entry.getValue()); } return map; diff --git a/src/main/java/org/truffleruby/core/proc/ProcNodes.java b/src/main/java/org/truffleruby/core/proc/ProcNodes.java index 1c54eca54aae..9b91751fdaf9 100644 --- a/src/main/java/org/truffleruby/core/proc/ProcNodes.java +++ b/src/main/java/org/truffleruby/core/proc/ProcNodes.java @@ -161,6 +161,7 @@ public abstract static class CallNode extends AlwaysInlinedMethodNode { Object call(Frame callerFrame, RubyProc proc, Object[] rubyArgs, RootCallTarget target, @Cached CallBlockNode callBlockNode) { return callBlockNode.executeCallBlock( + this, proc.declarationContext, proc, ProcOperations.getSelf(proc), diff --git a/src/main/java/org/truffleruby/core/proc/RubyProc.java b/src/main/java/org/truffleruby/core/proc/RubyProc.java index d5619a52cbe5..a7fbc1db1d60 100644 --- a/src/main/java/org/truffleruby/core/proc/RubyProc.java +++ b/src/main/java/org/truffleruby/core/proc/RubyProc.java @@ -11,6 +11,8 @@ import java.util.Set; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.nodes.Node; import org.truffleruby.core.klass.RubyClass; import org.truffleruby.interop.ForeignToRubyArgumentsNode; import org.truffleruby.language.RubyDynamicObject; @@ -145,8 +147,9 @@ public boolean isExecutable() { @ExportMessage public Object execute(Object[] arguments, @Cached CallBlockNode yieldNode, - @Cached ForeignToRubyArgumentsNode foreignToRubyArgumentsNode) { - return yieldNode.yield(this, foreignToRubyArgumentsNode.executeConvert(arguments)); + @Cached ForeignToRubyArgumentsNode foreignToRubyArgumentsNode, + @Bind("$node") Node node) { + return yieldNode.yield(node, this, foreignToRubyArgumentsNode.executeConvert(arguments)); } // endregion } diff --git a/src/main/java/org/truffleruby/core/range/RangeNodes.java b/src/main/java/org/truffleruby/core/range/RangeNodes.java index 1c8dae8f4c5d..677ac6596c69 100644 --- a/src/main/java/org/truffleruby/core/range/RangeNodes.java +++ b/src/main/java/org/truffleruby/core/range/RangeNodes.java @@ -14,6 +14,8 @@ import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.NodeChild; +import com.oracle.truffle.api.dsl.NodeField; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile; @@ -78,7 +80,7 @@ RubyArray map(RubyIntRange range, RubyProc block, int n = 0; try { for (; loopProfile.inject(this, n < length); n++) { - arrayBuilder.appendValue(state, n, yieldNode.yield(block, begin + n)); + arrayBuilder.appendValue(state, n, yieldNode.yield(this, block, begin + n)); } } finally { profileAndReportLoopCount(this, loopProfile, n); @@ -113,7 +115,7 @@ RubyIntRange eachInt(RubyIntRange range, RubyProc block, int n = range.begin; try { for (; loopProfile.inject(this, n < exclusiveEnd); n++) { - yieldNode.yield(block, n); + yieldNode.yield(this, block, n); } } finally { profileAndReportLoopCount(this, loopProfile, n - range.begin); @@ -137,7 +139,7 @@ RubyLongRange eachLong(RubyLongRange range, RubyProc block, long n = range.begin; try { for (; loopProfile.inject(this, n < exclusiveEnd); n++) { - yieldNode.yield(block, n); + yieldNode.yield(this, block, n); } } finally { profileAndReportLoopCount(this, loopProfile, n - range.begin); @@ -230,7 +232,7 @@ Object stepInt(RubyIntRange range, int step, RubyProc block, int n = range.begin; try { for (; loopProfile.inject(n < result); n += step) { - yieldNode.yield(block, n); + yieldNode.yield(this, block, n); } } finally { profileAndReportLoopCount(loopProfile, n - range.begin); @@ -252,7 +254,7 @@ Object stepLong(RubyLongRange range, int step, RubyProc block, long n = range.begin; try { for (; n < result; n += step) { - yieldNode.yield(block, n); + yieldNode.yield(this, block, n); } } finally { reportLongLoopCount(n - range.begin); @@ -387,68 +389,69 @@ Object newRange(RubyClass rubyClass, Object begin, Object end, Object maybeExclu @Cached BooleanCastWithDefaultNode booleanCastWithDefaultNode, @Cached NewRangeNode newRangeNode) { final boolean excludeEnd = booleanCastWithDefaultNode.execute(this, maybeExcludeEnd, false); - return newRangeNode.execute(rubyClass, begin, end, excludeEnd); + return newRangeNode.execute(this, rubyClass, begin, end, excludeEnd); } } - public static final class RangeLiteralNode extends RubyContextSourceNode { + @NodeChild(value = "beginNode", type = RubyNode.class) + @NodeChild(value = "endNode", type = RubyNode.class) + @NodeField(name = "excludeEnd", type = Boolean.class) + public abstract static class RangeLiteralNode extends RubyContextSourceNode { - @Child RubyNode beginNode; - @Child RubyNode endNode; - @Child NewRangeNode newRangeNode = RangeNodesFactory.NewRangeNodeGen.create(); - private final boolean excludeEnd; + abstract RubyNode getBeginNode(); - public RangeLiteralNode(RubyNode beginNode, RubyNode endNode, boolean excludeEnd) { - this.beginNode = beginNode; - this.endNode = endNode; - this.excludeEnd = excludeEnd; - } + abstract RubyNode getEndNode(); - @Override - public Object execute(VirtualFrame frame) { - Object begin = beginNode.execute(frame); - Object end = endNode.execute(frame); - return newRangeNode.execute(coreLibrary().rangeClass, begin, end, excludeEnd); + abstract boolean getExcludeEnd(); + + @Specialization + Object doRange(Object begin, Object end, + @Cached NewRangeNode newRangeNode) { + return newRangeNode.execute(this, coreLibrary().rangeClass, begin, end, getExcludeEnd()); } @Override public RubyNode cloneUninitialized() { - return new RangeLiteralNode(beginNode.cloneUninitialized(), endNode.cloneUninitialized(), excludeEnd) + return RangeNodesFactory.RangeLiteralNodeGen + .create(getBeginNode().cloneUninitialized(), getEndNode().cloneUninitialized(), getExcludeEnd()) .copyFlags(this); } } + @GenerateCached(false) + @GenerateInline public abstract static class NewRangeNode extends RubyBaseNode { - public abstract Object execute(RubyClass rubyClass, Object begin, Object end, boolean excludeEnd); + public abstract Object execute(Node node, RubyClass rubyClass, Object begin, Object end, boolean excludeEnd); @Specialization(guards = "rubyClass == getRangeClass()") - RubyIntRange intRange(RubyClass rubyClass, int begin, int end, boolean excludeEnd) { + static RubyIntRange intRange(RubyClass rubyClass, int begin, int end, boolean excludeEnd) { return new RubyIntRange(excludeEnd, begin, end); } @Specialization(guards = { "rubyClass == getRangeClass()", "fitsInInteger(begin)", "fitsInInteger(end)" }) - RubyIntRange longFittingIntRange(RubyClass rubyClass, long begin, long end, boolean excludeEnd) { + static RubyIntRange longFittingIntRange(RubyClass rubyClass, long begin, long end, boolean excludeEnd) { return new RubyIntRange(excludeEnd, (int) begin, (int) end); } @Specialization(guards = { "rubyClass == getRangeClass()", "!fitsInInteger(begin) || !fitsInInteger(end)" }) - RubyLongRange longRange(RubyClass rubyClass, long begin, long end, boolean excludeEnd) { + static RubyLongRange longRange(RubyClass rubyClass, long begin, long end, boolean excludeEnd) { return new RubyLongRange(excludeEnd, begin, end); } @Specialization(guards = { "!standardClass || (!isImplicitLong(begin) || !isImplicitLong(end))" }) - RubyObjectRange objectRange(RubyClass rubyClass, Object begin, Object end, boolean excludeEnd, - @Cached DispatchNode compare, + static RubyObjectRange objectRange(Node node, RubyClass rubyClass, Object begin, Object end, boolean excludeEnd, + @Cached(inline = false) DispatchNode compare, @Bind("rubyClass == getRangeClass()") boolean standardClass) { if (compare.call(begin, "<=>", end) == nil && end != nil && begin != nil) { - throw new RaiseException(getContext(), coreExceptions().argumentError("bad value for range", this)); + throw new RaiseException(getContext(node), + coreExceptions(node).argumentError("bad value for range", node)); } - final Shape shape = getLanguage().objectRangeShape; + final Shape shape = getLanguage(node).objectRangeShape; final RubyObjectRange range = new RubyObjectRange(rubyClass, shape, excludeEnd, begin, end, standardClass); - AllocationTracing.trace(range, this); + AllocationTracing.trace(range, node); return range; } diff --git a/src/main/java/org/truffleruby/core/string/StringHelperNodes.java b/src/main/java/org/truffleruby/core/string/StringHelperNodes.java index adbd6803567c..30e9e8436a48 100644 --- a/src/main/java/org/truffleruby/core/string/StringHelperNodes.java +++ b/src/main/java/org/truffleruby/core/string/StringHelperNodes.java @@ -392,23 +392,20 @@ static long hash(Node node, Object string, } } + @GenerateInline + @GenerateCached(false) public abstract static class StringGetAssociatedNode extends RubyBaseNode { - @NeverDefault - public static StringGetAssociatedNode create() { - return StringHelperNodesFactory.StringGetAssociatedNodeGen.create(); - } - - public abstract Object execute(Object string); + public abstract Object execute(Node node, Object string); @Specialization(limit = "getDynamicObjectCacheLimit()") - Object getAssociated(RubyString string, + static Object getAssociated(RubyString string, @CachedLibrary("string") DynamicObjectLibrary objectLibrary) { return objectLibrary.getOrDefault(string, Layouts.ASSOCIATED_IDENTIFIER, null); } @Specialization - Object getAssociatedImmutable(ImmutableRubyString string) { + static Object getAssociatedImmutable(ImmutableRubyString string) { return null; } diff --git a/src/main/java/org/truffleruby/core/string/StringNodes.java b/src/main/java/org/truffleruby/core/string/StringNodes.java index 9c64b411c28e..b5c840d76b2c 100644 --- a/src/main/java/org/truffleruby/core/string/StringNodes.java +++ b/src/main/java/org/truffleruby/core/string/StringNodes.java @@ -1101,11 +1101,12 @@ public static EachByteNode create() { // use separate specialization instances for getTString() in the loop @Specialization(guards = "strings.seen(string)", limit = "2") - Object eachByte(Object string, RubyProc block, + static Object eachByte(Object string, RubyProc block, @Cached RubyStringLibrary strings, @Cached TruffleString.MaterializeNode materializeNode, @Cached TruffleString.ReadByteNode readByteNode, - @Cached CallBlockNode yieldNode) { + @Cached CallBlockNode yieldNode, + @Bind("this") Node node) { var tstring = strings.getTString(string); var encoding = strings.getEncoding(string).tencoding; @@ -1113,7 +1114,7 @@ Object eachByte(Object string, RubyProc block, materializeNode.execute(tstring, encoding); for (int i = 0; i < tstring.byteLength(encoding); i++) { int singleByte = readByteNode.execute(tstring, i, encoding); - yieldNode.yield(block, singleByte); + yieldNode.yield(node, block, singleByte); tstring = strings.getTString(string); encoding = strings.getEncoding(string).tencoding; @@ -1179,7 +1180,7 @@ Object eachChar(Object string, RubyProc block, int clen; for (int i = 0; i < byteLength; i += clen) { clen = byteLengthOfCodePointNode.execute(tstring, i, tencoding); - yieldNode.yield(block, createSubString(substringNode, tstring, encoding, i, clen)); + yieldNode.yield(this, block, createSubString(substringNode, tstring, encoding, i, clen)); } return string; @@ -1256,7 +1257,7 @@ Object eachCodePoint(Object string, RubyProc block, coreExceptions().argumentErrorInvalidByteSequence(encoding, this)); } - yieldNode.yield(block, codePoint); + yieldNode.yield(this, block, codePoint); } return string; @@ -1525,7 +1526,7 @@ Object initializeCopyImmutable(RubyString self, Object from, @Bind("stringsFrom.getTString(from)") AbstractTruffleString tstring) { self.setTString(tstring, stringsFrom.getEncoding(from)); - final Object associated = stringGetAssociatedNode.execute(from); + final Object associated = stringGetAssociatedNode.execute(this, from); copyAssociated(self, associated, writeAssociatedNode); return self; } @@ -1548,7 +1549,7 @@ Object initializeCopyMutable(RubyString self, Object from, MutableTruffleString copy = copyMutableTruffleStringNode.execute(tstring, 0, byteLength, tencoding); self.setTString(copy, encoding); - final Object associated = stringGetAssociatedNode.execute(from); + final Object associated = stringGetAssociatedNode.execute(this, from); copyAssociated(self, associated, writeAssociatedNode); return self; } @@ -1573,7 +1574,7 @@ Object initializeCopyNative(RubyString self, RubyString from, var copy = fromNativePointerNode.execute(newPointer, 0, tstring.byteLength(tencoding), tencoding, false); self.setTString(copy, encoding); - final Object associated = stringGetAssociatedNode.execute(from); + final Object associated = stringGetAssociatedNode.execute(this, from); copyAssociated(self, associated, writeAssociatedNode); return self; } @@ -1809,7 +1810,6 @@ private static AbstractTruffleString makeSubstring(TruffleString.SubstringByteIn @ImportStatic(StringGuards.class) public abstract static class ScrubNode extends PrimitiveArrayArgumentsNode { - @Child private CallBlockNode yieldNode = CallBlockNode.create(); @Child GetByteCodeRangeNode codeRangeNode = GetByteCodeRangeNode.create(); @Child private TruffleString.ConcatNode concatNode = TruffleString.ConcatNode.create(); @Child private TruffleString.GetInternalByteArrayNode byteArrayNode = TruffleString.GetInternalByteArrayNode @@ -1822,7 +1822,8 @@ RubyString scrubAsciiCompat(Object string, RubyProc block, @Cached @Shared RubyStringLibrary strings, @Cached @Exclusive TruffleString.ByteLengthOfCodePointNode byteLengthOfCodePointNode, @Bind("strings.getTString(string)") AbstractTruffleString tstring, - @Bind("strings.getEncoding(string)") RubyEncoding encoding) { + @Bind("strings.getEncoding(string)") RubyEncoding encoding, + @Cached @Shared CallBlockNode yieldNode) { final Encoding enc = encoding.jcoding; var tencoding = encoding.tencoding; TruffleString buf = EMPTY_BINARY; @@ -1870,7 +1871,7 @@ RubyString scrubAsciiCompat(Object string, RubyProc block, } } } - Object repl = yieldNode.yield(block, + Object repl = yieldNode.yield(this, block, createSubString(substringNode, tstring, encoding, p, clen)); buf = concatNode.execute(buf, strings.getTString(repl), tencoding, true); p += clen; @@ -1890,7 +1891,7 @@ RubyString scrubAsciiCompat(Object string, RubyProc block, } if (p < e) { - Object repl = yieldNode.yield(block, + Object repl = yieldNode.yield(this, block, createSubString(substringNode, tstring, encoding, p, e - p)); buf = concatNode.execute(buf, strings.getTString(repl), tencoding, true); } @@ -1906,7 +1907,8 @@ RubyString scrubAsciiIncompatible(Object string, RubyProc block, @Cached @Shared RubyStringLibrary strings, @Cached @Exclusive TruffleString.ByteLengthOfCodePointNode byteLengthOfCodePointNode, @Bind("strings.getTString(string)") AbstractTruffleString tstring, - @Bind("strings.getEncoding(string)") RubyEncoding encoding) { + @Bind("strings.getEncoding(string)") RubyEncoding encoding, + @Cached @Shared CallBlockNode yieldNode) { final Encoding enc = encoding.jcoding; var tencoding = encoding.tencoding; TruffleString buf = EMPTY_BINARY; @@ -1949,7 +1951,7 @@ RubyString scrubAsciiIncompatible(Object string, RubyProc block, } } - RubyString repl = (RubyString) yieldNode.yield(block, + RubyString repl = (RubyString) yieldNode.yield(this, block, createSubString(substringNode, tstring, encoding, p, clen)); buf = concatNode.execute(buf, repl.tstring, tencoding, true); p += clen; @@ -1964,7 +1966,7 @@ RubyString scrubAsciiIncompatible(Object string, RubyProc block, } if (p < e) { - RubyString repl = (RubyString) yieldNode.yield(block, + RubyString repl = (RubyString) yieldNode.yield(this, block, createSubString(substringNode, tstring, encoding, p, e - p)); buf = concatNode.execute(buf, repl.tstring, tencoding, true); } @@ -2800,7 +2802,7 @@ RubyArray unpackCached(Object string, Object format, Object offsetObject, byteArray.getArray(), byteArray.getEnd(), byteArray.getOffset() + offset, - stringGetAssociatedNode.execute(string) }); // TODO impl associated for ImmutableRubyString + stringGetAssociatedNode.execute(this, string) }); // TODO impl associated for ImmutableRubyString } catch (FormatException e) { exceptionProfile.enter(this); throw FormatExceptionTranslator.translate(getContext(), this, e); @@ -2849,7 +2851,7 @@ static RubyArray unpackUncached(Object string, Object format, Object offsetObjec byteArray.getArray(), byteArray.getEnd(), byteArray.getOffset() + offset, - stringGetAssociatedNode.execute(string) }); + stringGetAssociatedNode.execute(node, string) }); } catch (FormatException e) { exceptionProfile.enter(node); throw FormatExceptionTranslator.translate(getContext(node), node, e); @@ -3309,7 +3311,7 @@ private static Object[] addSubstring(Node node, CallBlockNode yieldNode, Object[ RubyString substring, Object block, InlinedConditionProfile executeBlockProfile, InlinedConditionProfile growArrayProfile) { if (executeBlockProfile.profile(node, block != nil)) { - yieldNode.yield((RubyProc) block, substring); + yieldNode.yield(node, (RubyProc) block, substring); } else { if (growArrayProfile.profile(node, index < store.length)) { store[index] = substring; diff --git a/src/main/java/org/truffleruby/core/support/TypeNodes.java b/src/main/java/org/truffleruby/core/support/TypeNodes.java index 966662f1b078..93109003b0c2 100644 --- a/src/main/java/org/truffleruby/core/support/TypeNodes.java +++ b/src/main/java/org/truffleruby/core/support/TypeNodes.java @@ -13,6 +13,8 @@ import java.util.List; import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.nodes.Node; @@ -452,30 +454,28 @@ public static TypeCheckFrozenNode create(RubyNode rubyNode) { @Specialization Object check(Object value, @Cached CheckFrozenNode checkFrozenNode) { - checkFrozenNode.execute(value); + checkFrozenNode.execute(this, value); return value; } } @GenerateUncached + @GenerateInline + @GenerateCached(false) public abstract static class CheckFrozenNode extends RubyBaseNode { - @NeverDefault - public static CheckFrozenNode create() { - return TypeNodesFactory.CheckFrozenNodeGen.create(); - } - - public abstract void execute(Object object); + public abstract void execute(Node node, Object object); @Specialization - void check(Object value, - @Cached IsFrozenNode isFrozenNode, + static void check(Node node, Object value, + // IsFrozenNode can't be inlined since known bug (GR-45912) + @Cached(inline = false) IsFrozenNode isFrozenNode, @Cached InlinedBranchProfile errorProfile) { if (isFrozenNode.execute(value)) { - errorProfile.enter(this); - throw new RaiseException(getContext(), coreExceptions().frozenError(value, this)); + errorProfile.enter(node); + throw new RaiseException(getContext(node), coreExceptions(node).frozenError(value, node)); } } } diff --git a/src/main/java/org/truffleruby/core/thread/ThreadNodes.java b/src/main/java/org/truffleruby/core/thread/ThreadNodes.java index 81b623a84457..02e1454910b0 100644 --- a/src/main/java/org/truffleruby/core/thread/ThreadNodes.java +++ b/src/main/java/org/truffleruby/core/thread/ThreadNodes.java @@ -350,7 +350,7 @@ Object handleInterrupt(RubyThread self, RubySymbol timing, RubyProc block, runPendingSafepointActions("before"); } - return yieldNode.yield(block); + return yieldNode.yield(this, block); } finally { self.interruptMode = oldInterruptMode; safepoint.setAllowSideEffects(prevSideEffects); @@ -783,7 +783,6 @@ RubyHash recursiveObjects() { @Primitive(name = "thread_detect_recursion_single") public abstract static class ThreadDetectRecursionSingleNode extends PrimitiveArrayArgumentsNode { - @Child private CallBlockNode yieldNode = CallBlockNode.create(); @Child private HashStoreLibrary hashes = HashStoreLibrary.createDispatched(); protected boolean add(RubyHash hash, Object key, Object value) { @@ -796,11 +795,12 @@ protected Object removeLast(RubyHash hash, Object key) { @Specialization boolean detectRecursionSingle(Object obj, RubyProc block, - @Cached InlinedConditionProfile insertedProfile) { + @Cached InlinedConditionProfile insertedProfile, + @Cached CallBlockNode yieldNode) { RubyHash objects = getLanguage().getCurrentThread().recursiveObjectsSingle; if (insertedProfile.profile(this, add(objects, obj, true))) { try { - yieldNode.yield(block); + yieldNode.yield(this, block); } finally { removeLast(objects, obj); } @@ -1049,10 +1049,9 @@ public abstract static class EachCallerLocationNode extends CoreMethodArrayArgum // Skip the block of `Thread#each_caller_location` + its internal iteration. private static final int SKIP = 2; - @Child private CallBlockNode yieldNode = CallBlockNode.create(); - @Specialization - Object eachCallerLocation(VirtualFrame frame, RubyProc block) { + Object eachCallerLocation(VirtualFrame frame, RubyProc block, + @Cached CallBlockNode yieldNode) { final List elements = new ArrayList<>(); getContext().getCallStack().iterateFrameBindings(SKIP, frameInstance -> { @@ -1075,7 +1074,7 @@ Object eachCallerLocation(VirtualFrame frame, RubyProc block) { backtrace, i); - yieldNode.yield(block, rubyBacktraceLocation); + yieldNode.yield(this, block, rubyBacktraceLocation); } elements.clear(); } diff --git a/src/main/java/org/truffleruby/core/tracepoint/TraceBaseEventNode.java b/src/main/java/org/truffleruby/core/tracepoint/TraceBaseEventNode.java index 584f4a8ca277..fea9c48ff0af 100644 --- a/src/main/java/org/truffleruby/core/tracepoint/TraceBaseEventNode.java +++ b/src/main/java/org/truffleruby/core/tracepoint/TraceBaseEventNode.java @@ -64,7 +64,7 @@ protected Object callBlock(RubyProc block, Object... arguments) { yieldNode = insert(CallBlockNode.create()); } - return yieldNode.yield(block, arguments); + return yieldNode.yieldCached(block, arguments); } } diff --git a/src/main/java/org/truffleruby/core/tracepoint/TracePointNodes.java b/src/main/java/org/truffleruby/core/tracepoint/TracePointNodes.java index ada0c0801745..fb0a4a6deda1 100644 --- a/src/main/java/org/truffleruby/core/tracepoint/TracePointNodes.java +++ b/src/main/java/org/truffleruby/core/tracepoint/TracePointNodes.java @@ -125,7 +125,7 @@ Object enable(RubyTracePoint tracePoint, RubyProc block, @Cached CallBlockNode yieldNode) { final boolean setupDone = createEventBindings(getContext(), getLanguage(), tracePoint); try { - return yieldNode.yield(block); + return yieldNode.yield(this, block); } finally { if (setupDone) { disposeEventBindings(tracePoint); @@ -147,7 +147,7 @@ Object disable(RubyTracePoint tracePoint, RubyProc block, @Cached CallBlockNode yieldNode) { final boolean wasEnabled = disposeEventBindings(tracePoint); try { - return yieldNode.yield(block); + return yieldNode.yield(this, block); } finally { if (wasEnabled) { createEventBindings(getContext(), getLanguage(), tracePoint); diff --git a/src/main/java/org/truffleruby/debug/BindingLocalVariablesObject.java b/src/main/java/org/truffleruby/debug/BindingLocalVariablesObject.java index 84d1d41a1a5a..1b6edd421b29 100644 --- a/src/main/java/org/truffleruby/debug/BindingLocalVariablesObject.java +++ b/src/main/java/org/truffleruby/debug/BindingLocalVariablesObject.java @@ -81,8 +81,9 @@ protected void writeMember(String member, Object value, @ExportMessage(name = "isMemberReadable") @ExportMessage(name = "isMemberModifiable") protected boolean memberExists(String member, - @Cached @Exclusive BindingNodes.HasLocalVariableNode hasLocalVariableNode) { - return hasLocalVariableNode.execute(binding, member); + @Cached @Exclusive BindingNodes.HasLocalVariableNode hasLocalVariableNode, + @Bind("$node") Node node) { + return hasLocalVariableNode.execute(node, binding, member); } @ExportMessage diff --git a/src/main/java/org/truffleruby/debug/RubyScope.java b/src/main/java/org/truffleruby/debug/RubyScope.java index 75fd318ace70..a494079317ae 100644 --- a/src/main/java/org/truffleruby/debug/RubyScope.java +++ b/src/main/java/org/truffleruby/debug/RubyScope.java @@ -154,8 +154,9 @@ static boolean readSelf(RubyScope scope, String member) { @Specialization(guards = "!RECEIVER_MEMBER.equals(member)") static boolean isMemberReadable(RubyScope scope, String member, - @Cached @Exclusive BindingNodes.HasLocalVariableNode hasLocalVariableNode) { - return hasLocalVariableNode.execute(scope.binding, member); + @Cached @Exclusive BindingNodes.HasLocalVariableNode hasLocalVariableNode, + @Bind("this") Node node) { + return hasLocalVariableNode.execute(node, scope.binding, member); } } @@ -168,8 +169,9 @@ static boolean readSelf(RubyScope scope, String member) { @Specialization(guards = "!RECEIVER_MEMBER.equals(member)") static boolean isMemberModifiable(RubyScope scope, String member, - @Cached @Exclusive BindingNodes.HasLocalVariableNode hasLocalVariableNode) { - return hasLocalVariableNode.execute(scope.binding, member); + @Cached @Exclusive BindingNodes.HasLocalVariableNode hasLocalVariableNode, + @Bind("this") Node node) { + return hasLocalVariableNode.execute(node, scope.binding, member); } } diff --git a/src/main/java/org/truffleruby/debug/TruffleDebugNodes.java b/src/main/java/org/truffleruby/debug/TruffleDebugNodes.java index 81454d231d82..cbadde04d6ee 100644 --- a/src/main/java/org/truffleruby/debug/TruffleDebugNodes.java +++ b/src/main/java/org/truffleruby/debug/TruffleDebugNodes.java @@ -195,7 +195,7 @@ RubyHandle setBreak(Object file, int line, RubyProc block, @Override protected void onEnter(VirtualFrame frame) { - yieldNode.yield( + yieldNode.yieldCached( block, BindingNodes.createBinding( getContext(), diff --git a/src/main/java/org/truffleruby/extra/ConcurrentMapNodes.java b/src/main/java/org/truffleruby/extra/ConcurrentMapNodes.java index f672f7651fb7..ed5add967ef6 100644 --- a/src/main/java/org/truffleruby/extra/ConcurrentMapNodes.java +++ b/src/main/java/org/truffleruby/extra/ConcurrentMapNodes.java @@ -119,7 +119,7 @@ Object computeIfAbsent(RubyConcurrentMap self, Object key, RubyProc block, @Cached CallBlockNode yieldNode) { final int hashCode = hashNode.execute(this, key); final Object returnValue = ConcurrentOperations - .getOrCompute(self.getMap(), new Key(key, hashCode), (k) -> yieldNode.yield(block)); + .getOrCompute(self.getMap(), new Key(key, hashCode), (k) -> yieldNode.yield(this, block)); assert returnValue != null; return returnValue; } @@ -136,7 +136,7 @@ Object computeIfPresent(RubyConcurrentMap self, Object key, RubyProc block, return nullToNil( computeIfPresent(self.getMap(), new Key(key, hashCode), (k, v) -> // TODO (Chris, 6 May 2021): It's unfortunate we're calling this behind a boundary! Can we do better? - nilToNull(yieldNode.yield(block, v)))); + nilToNull(yieldNode.yield(this, block, v)))); } @TruffleBoundary @@ -156,7 +156,7 @@ Object compute(RubyConcurrentMap self, Object key, RubyProc block, return nullToNil(compute( self.getMap(), new Key(key, hashCode), - (k, v) -> nilToNull(yieldNode.yield(block, nullToNil(v))))); + (k, v) -> nilToNull(yieldNode.yield(this, block, nullToNil(v))))); } @TruffleBoundary @@ -177,7 +177,7 @@ Object mergePair(RubyConcurrentMap self, Object key, Object value, RubyProc bloc self.getMap(), new Key(key, hashCode), value, - (existingValue, newValue) -> nilToNull(yieldNode.yield(block, existingValue)))); + (existingValue, newValue) -> nilToNull(yieldNode.yield(this, block, existingValue)))); } @TruffleBoundary @@ -379,7 +379,7 @@ Object eachPair(RubyConcurrentMap self, RubyProc block, break; } - yieldNode.yield(block, pair.getKey().key, pair.getValue()); + yieldNode.yield(this, block, pair.getKey().key, pair.getValue()); } return self; diff --git a/src/main/java/org/truffleruby/extra/TruffleRubyNodes.java b/src/main/java/org/truffleruby/extra/TruffleRubyNodes.java index 851b8b4c676f..28d7cc8c0f0d 100644 --- a/src/main/java/org/truffleruby/extra/TruffleRubyNodes.java +++ b/src/main/java/org/truffleruby/extra/TruffleRubyNodes.java @@ -122,7 +122,7 @@ static Object synchronize(RubyDynamicObject object, RubyProc block, MutexOperations.lockInternal(getContext(node), lock, node); try { - return yieldNode.yield(block); + return yieldNode.yield(node, block); } finally { MutexOperations.unlockInternal(lock); } diff --git a/src/main/java/org/truffleruby/interop/PolyglotNodes.java b/src/main/java/org/truffleruby/interop/PolyglotNodes.java index 353d45685466..9a9fdbbe01d3 100644 --- a/src/main/java/org/truffleruby/interop/PolyglotNodes.java +++ b/src/main/java/org/truffleruby/interop/PolyglotNodes.java @@ -206,7 +206,7 @@ RubyInnerContext newInnerContext( .initializeCreatorContext(false) .inheritAllAccess(inheritAllAccess) .forceSharing(codeSharingBoolean) - .onCancelled(() -> CallBlockNode.getUncached().yield(onCancelledCallback)) + .onCancelled(() -> CallBlockNode.yieldUncached(onCancelledCallback)) .build(); return new RubyInnerContext( diff --git a/src/main/java/org/truffleruby/language/RubyCoreMethodRootNode.java b/src/main/java/org/truffleruby/language/RubyCoreMethodRootNode.java index d5050faf6751..bd45e9d0b3e5 100644 --- a/src/main/java/org/truffleruby/language/RubyCoreMethodRootNode.java +++ b/src/main/java/org/truffleruby/language/RubyCoreMethodRootNode.java @@ -61,7 +61,7 @@ public Object execute(VirtualFrame frame) { CompilerDirectives.transferToInterpreterAndInvalidate(); translateExceptionNode = insert(TranslateExceptionNode.create()); } - throw translateExceptionNode.executeTranslation(t); + throw translateExceptionNode.executeCached(t); } } diff --git a/src/main/java/org/truffleruby/language/RubyDynamicObject.java b/src/main/java/org/truffleruby/language/RubyDynamicObject.java index a1dfc17ca9ae..f8881fe50427 100644 --- a/src/main/java/org/truffleruby/language/RubyDynamicObject.java +++ b/src/main/java/org/truffleruby/language/RubyDynamicObject.java @@ -516,7 +516,8 @@ public long asPointer( @Cached @Shared BranchProfile errorProfile, @Cached @Exclusive DispatchNode dispatchNode, @Cached @Shared TranslateInteropRubyExceptionNode translateRubyException, - @Cached LongCastNode longCastNode) throws UnsupportedMessageException { + @Cached LongCastNode longCastNode, + @Bind("$node") Node node) throws UnsupportedMessageException { Object value; try { @@ -528,7 +529,7 @@ public long asPointer( errorProfile.enter(); throw UnsupportedMessageException.create(); } - return longCastNode.executeCastLong(value); + return longCastNode.executeCastLong(node, value); } @ExportMessage diff --git a/src/main/java/org/truffleruby/language/RubyEvalRootNode.java b/src/main/java/org/truffleruby/language/RubyEvalRootNode.java index a5f5aedf8c43..0cc3edfb1b96 100644 --- a/src/main/java/org/truffleruby/language/RubyEvalRootNode.java +++ b/src/main/java/org/truffleruby/language/RubyEvalRootNode.java @@ -78,7 +78,7 @@ public Object execute(VirtualFrame frame) { CompilerDirectives.transferToInterpreterAndInvalidate(); translateExceptionNode = insert(TranslateExceptionNode.create()); } - throw translateExceptionNode.executeTranslation(t); + throw translateExceptionNode.executeCached(t); } } diff --git a/src/main/java/org/truffleruby/language/RubyLambdaRootNode.java b/src/main/java/org/truffleruby/language/RubyLambdaRootNode.java index fd2113b2d376..995a9831ce47 100644 --- a/src/main/java/org/truffleruby/language/RubyLambdaRootNode.java +++ b/src/main/java/org/truffleruby/language/RubyLambdaRootNode.java @@ -146,7 +146,7 @@ public Object execute(VirtualFrame frame) { CompilerDirectives.transferToInterpreterAndInvalidate(); translateExceptionNode = insert(TranslateExceptionNode.create()); } - throw translateExceptionNode.executeTranslation(t); + throw translateExceptionNode.executeCached(t); } } diff --git a/src/main/java/org/truffleruby/language/RubyMethodRootNode.java b/src/main/java/org/truffleruby/language/RubyMethodRootNode.java index a8807be7ac68..8e186e2351f0 100644 --- a/src/main/java/org/truffleruby/language/RubyMethodRootNode.java +++ b/src/main/java/org/truffleruby/language/RubyMethodRootNode.java @@ -96,7 +96,7 @@ public Object execute(VirtualFrame frame) { CompilerDirectives.transferToInterpreterAndInvalidate(); translateExceptionNode = insert(TranslateExceptionNode.create()); } - throw translateExceptionNode.executeTranslation(t); + throw translateExceptionNode.executeCached(t); } } diff --git a/src/main/java/org/truffleruby/language/RubyProcRootNode.java b/src/main/java/org/truffleruby/language/RubyProcRootNode.java index a920ec4a9cc7..cb7408c14a97 100644 --- a/src/main/java/org/truffleruby/language/RubyProcRootNode.java +++ b/src/main/java/org/truffleruby/language/RubyProcRootNode.java @@ -104,7 +104,7 @@ public Object execute(VirtualFrame frame) { CompilerDirectives.transferToInterpreterAndInvalidate(); translateExceptionNode = insert(TranslateExceptionNode.create()); } - throw translateExceptionNode.executeTranslation(t); + throw translateExceptionNode.executeCached(t); } } diff --git a/src/main/java/org/truffleruby/language/exceptions/TryNode.java b/src/main/java/org/truffleruby/language/exceptions/TryNode.java index 06ec10b58d66..8af605f1b977 100644 --- a/src/main/java/org/truffleruby/language/exceptions/TryNode.java +++ b/src/main/java/org/truffleruby/language/exceptions/TryNode.java @@ -84,7 +84,7 @@ Object doTry(VirtualFrame frame, CompilerDirectives.transferToInterpreterAndInvalidate(); translateExceptionNode = insert(TranslateExceptionNode.create()); } - throw translateExceptionNode.executeTranslation(t); + throw translateExceptionNode.executeCached(t); } if (elsePart != null) { diff --git a/src/main/java/org/truffleruby/language/globals/IsDefinedGlobalVariableNode.java b/src/main/java/org/truffleruby/language/globals/IsDefinedGlobalVariableNode.java index 8e5a85799746..871e62fa4dbf 100644 --- a/src/main/java/org/truffleruby/language/globals/IsDefinedGlobalVariableNode.java +++ b/src/main/java/org/truffleruby/language/globals/IsDefinedGlobalVariableNode.java @@ -46,13 +46,13 @@ Object simple(VirtualFrame frame, } @Specialization(guards = { "storage.hasHooks()", "arity == 0" }) - Object hooks(VirtualFrame frame, - @Cached(value = "getLanguage().getGlobalVariableIndex(lookupGlobalVariableStorageNode.name)", - neverDefault = false) int index, + static Object hooks(VirtualFrame frame, + @Cached(value = "getLanguage().getGlobalVariableIndex(lookupGlobalVariableStorageNode.name)") int index, @Bind("getStorage(frame)") GlobalVariableStorage storage, - @Cached(value = "isDefinedArity(storage)", neverDefault = false) int arity, - @Cached @Exclusive CallBlockNode yieldNode) { - return yieldNode.yield(storage.getIsDefined()); + @Cached(value = "isDefinedArity(storage)") int arity, + @Cached @Exclusive CallBlockNode yieldNode, + @Bind("this") Node node) { + return yieldNode.yield(node, storage.getIsDefined()); } @Specialization(guards = { "storage.hasHooks()", "arity == 1" }) @@ -62,7 +62,7 @@ static Object hooksWithBinding(VirtualFrame frame, @Cached @Exclusive CallBlockNode yieldNode, @Cached GetSpecialVariableStorage readStorage, @Bind("this") Node node) { - return yieldNode.yield(storage.getIsDefined(), readStorage.execute(frame, node)); + return yieldNode.yield(node, storage.getIsDefined(), readStorage.execute(frame, node)); } protected int isDefinedArity(GlobalVariableStorage storage) { diff --git a/src/main/java/org/truffleruby/language/globals/ReadGlobalVariableNode.java b/src/main/java/org/truffleruby/language/globals/ReadGlobalVariableNode.java index 8f94d499c799..d3e2ffc2b102 100644 --- a/src/main/java/org/truffleruby/language/globals/ReadGlobalVariableNode.java +++ b/src/main/java/org/truffleruby/language/globals/ReadGlobalVariableNode.java @@ -11,6 +11,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.nodes.Node; import org.truffleruby.RubyContext; import org.truffleruby.RubyLanguage; import org.truffleruby.core.kernel.TruffleKernelNodes.GetSpecialVariableStorage; @@ -46,16 +47,17 @@ Object readHooks(VirtualFrame frame, @Bind("getStorage(frame)") GlobalVariableStorage storage, @Bind("getterArity(storage)") int arity, @Cached @Exclusive CallBlockNode yieldNode) { - return yieldNode.yield(storage.getGetter()); + return yieldNode.yield(this, storage.getGetter()); } @Specialization(guards = { "storage.hasHooks()", "arity == 1" }) - Object readHooksWithStorage(VirtualFrame frame, + static Object readHooksWithStorage(VirtualFrame frame, @Bind("getStorage(frame)") GlobalVariableStorage storage, @Bind("getterArity(storage)") int arity, @Cached @Exclusive CallBlockNode yieldNode, - @Cached GetSpecialVariableStorage storageNode) { - return yieldNode.yield(storage.getGetter(), storageNode.execute(frame, this)); + @Cached GetSpecialVariableStorage storageNode, + @Bind("this") Node node) { + return yieldNode.yield(node, storage.getGetter(), storageNode.execute(frame, node)); } protected int getterArity(GlobalVariableStorage storage) { diff --git a/src/main/java/org/truffleruby/language/globals/WriteGlobalVariableNode.java b/src/main/java/org/truffleruby/language/globals/WriteGlobalVariableNode.java index 1a0096f19f07..3ce55afa61f9 100644 --- a/src/main/java/org/truffleruby/language/globals/WriteGlobalVariableNode.java +++ b/src/main/java/org/truffleruby/language/globals/WriteGlobalVariableNode.java @@ -11,6 +11,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.nodes.Node; import org.truffleruby.RubyContext; import org.truffleruby.RubyLanguage; import org.truffleruby.core.array.AssignableNode; @@ -56,20 +57,21 @@ Object writeHooks(VirtualFrame frame, Object value, @Bind("getStorage(frame)") GlobalVariableStorage storage, @Bind("setterArity(storage)") int arity, @Cached @Exclusive CallBlockNode yieldNode) { - yieldNode.yield(storage.getSetter(), value); + yieldNode.yield(this, storage.getSetter(), value); return value; } @Specialization(guards = { "storage.hasHooks()", "arity == 2" }) - Object writeHooksWithStorage(VirtualFrame frame, Object value, + static Object writeHooksWithStorage(VirtualFrame frame, Object value, @Bind("getStorage(frame)") GlobalVariableStorage storage, @Bind("setterArity(storage)") int arity, @Cached @Exclusive CallBlockNode yieldNode, - @Cached GetSpecialVariableStorage storageNode) { - yieldNode.yield( + @Cached GetSpecialVariableStorage storageNode, + @Bind("this") Node node) { + yieldNode.yield(node, storage.getSetter(), value, - storageNode.execute(frame, this)); + storageNode.execute(frame, node)); return value; } diff --git a/src/main/java/org/truffleruby/language/methods/CallForeignMethodNode.java b/src/main/java/org/truffleruby/language/methods/CallForeignMethodNode.java index 031178b60d20..6ea9c973c0bd 100644 --- a/src/main/java/org/truffleruby/language/methods/CallForeignMethodNode.java +++ b/src/main/java/org/truffleruby/language/methods/CallForeignMethodNode.java @@ -69,7 +69,7 @@ Object call(Object receiver, String methodName, Object block, Object[] arguments return foreignInvokeNode.execute(this, receiver, methodName, newArguments); } catch (Throwable t) { errorProfile.enter(this); - throw translateException.executeTranslation(t); + throw translateException.execute(this, t); } } diff --git a/src/main/java/org/truffleruby/language/methods/TranslateExceptionNode.java b/src/main/java/org/truffleruby/language/methods/TranslateExceptionNode.java index b19c76ea6079..cc7e58288a75 100644 --- a/src/main/java/org/truffleruby/language/methods/TranslateExceptionNode.java +++ b/src/main/java/org/truffleruby/language/methods/TranslateExceptionNode.java @@ -10,6 +10,7 @@ package org.truffleruby.language.methods; import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.strings.TruffleString; @@ -35,6 +36,7 @@ import org.truffleruby.language.control.TerminationException; @GenerateUncached +@GenerateInline(inlineByDefault = true) public abstract class TranslateExceptionNode extends RubyBaseNode { @NeverDefault @@ -42,7 +44,11 @@ public static TranslateExceptionNode create() { return TranslateExceptionNodeGen.create(); } - public abstract RuntimeException executeTranslation(Throwable throwable); + public abstract RuntimeException execute(Node node, Throwable throwable); + + public final RuntimeException executeCached(Throwable throwable) { + return execute(this, throwable); + } public static void logJavaException(RubyContext context, Node currentNode, Throwable exception) { if (context.getOptions().EXCEPTIONS_PRINT_JAVA) { @@ -65,35 +71,35 @@ public static void logUncaughtJavaException(RubyContext context, Node currentNod } @Specialization - RuntimeException translate(ControlFlowException e) { + static RuntimeException translate(ControlFlowException e) { throw e; } @Specialization - RuntimeException translate(AbstractTruffleException e) { + static RuntimeException translate(AbstractTruffleException e) { throw e; } @Specialization - RuntimeException translate(TerminationException e) { + static RuntimeException translate(TerminationException e) { throw e; } @Specialization - RuntimeException translate(ThreadDeath e) { + static RuntimeException translate(ThreadDeath e) { throw e; } @Specialization(guards = "needsSpecialTranslation(e)") - RuntimeException translateSpecial(Throwable e) { - throw doTranslateSpecial(e); + static RuntimeException translateSpecial(Node node, Throwable e) { + throw doTranslateSpecial(node, e); } @Fallback - RuntimeException translate(Throwable e) { + static RuntimeException translate(Node node, Throwable e) { // An internal exception CompilerDirectives.transferToInterpreterAndInvalidate(); - logUncaughtJavaException(getContext(), this, e); + logUncaughtJavaException(getContext(node), node, e); throw ExceptionOperations.rethrow(e); } @@ -105,21 +111,23 @@ protected boolean needsSpecialTranslation(Throwable e) { } @TruffleBoundary - private RaiseException doTranslateSpecial(Throwable e) { + private static RaiseException doTranslateSpecial(Node node, Throwable e) { if (e instanceof TruffleString.IllegalByteArrayLengthException) { - return new RaiseException(getContext(), coreExceptions().argumentError(e.getMessage(), this)); + return new RaiseException(getContext(node), coreExceptions(node).argumentError(e.getMessage(), node)); } else if (e instanceof UnsupportedSpecializationException) { - return new RaiseException(getContext(), - translateUnsupportedSpecialization(getContext(), (UnsupportedSpecializationException) e)); + return new RaiseException(getContext(node), + translateUnsupportedSpecialization(node, getContext(node), (UnsupportedSpecializationException) e)); } else if (e instanceof StackOverflowError) { - return new RaiseException(getContext(), translateStackOverflow(getContext(), (StackOverflowError) e)); + return new RaiseException(getContext(node), + translateStackOverflow(node, getContext(node), (StackOverflowError) e)); } else { - return new RaiseException(getContext(), translateOutOfMemory(getContext(), (OutOfMemoryError) e)); + return new RaiseException(getContext(node), + translateOutOfMemory(node, getContext(node), (OutOfMemoryError) e)); } } @TruffleBoundary - private RubyException translateStackOverflow(RubyContext context, StackOverflowError error) { + private static RubyException translateStackOverflow(Node node, RubyContext context, StackOverflowError error) { boolean ignore = InitStackOverflowClassesEagerlyNode.ignore(error); if (!ignore) { if (context.getOptions().EXCEPTIONS_WARN_STACKOVERFLOW) { @@ -127,28 +135,28 @@ private RubyException translateStackOverflow(RubyContext context, StackOverflowE System.err.print("[ruby] WARNING StackOverflowError\n"); } - logJavaException(context, this, error); + logJavaException(context, node, error); } - return context.getCoreExceptions().systemStackErrorStackLevelTooDeep(this, error, !ignore); + return context.getCoreExceptions().systemStackErrorStackLevelTooDeep(node, error, !ignore); } @TruffleBoundary - private RubyException translateOutOfMemory(RubyContext context, OutOfMemoryError error) { + private static RubyException translateOutOfMemory(Node node, RubyContext context, OutOfMemoryError error) { if (context.getOptions().EXCEPTIONS_WARN_OUT_OF_MEMORY) { // We cannot afford to initialize the Log class System.err.print("[ruby] WARNING OutOfMemoryError\n"); } - logJavaException(context, this, error); - return context.getCoreExceptions().noMemoryError(this, error); + logJavaException(context, node, error); + return context.getCoreExceptions().noMemoryError(node, error); } @TruffleBoundary - private RubyException translateUnsupportedSpecialization(RubyContext context, + private static RubyException translateUnsupportedSpecialization(Node node, RubyContext context, UnsupportedSpecializationException exception) { - logJavaException(context, this, exception); + logJavaException(context, node, exception); final StringBuilder builder = new StringBuilder(); builder.append("TruffleRuby doesn't have a case for the "); @@ -158,7 +166,7 @@ private RubyException translateUnsupportedSpecialization(RubyContext context, builder.append('\n'); BacktraceFormatter.appendJavaStackTrace(exception, builder); String message = builder.toString().strip(); - return context.getCoreExceptions().typeError(message, this, exception); + return context.getCoreExceptions().typeError(message, node, exception); } public static StringBuilder argumentsToString(StringBuilder builder, Object[] arguments) { diff --git a/src/main/java/org/truffleruby/language/objects/CanHaveSingletonClassNode.java b/src/main/java/org/truffleruby/language/objects/CanHaveSingletonClassNode.java index a559e3a4a6cf..54ae5fe286f6 100644 --- a/src/main/java/org/truffleruby/language/objects/CanHaveSingletonClassNode.java +++ b/src/main/java/org/truffleruby/language/objects/CanHaveSingletonClassNode.java @@ -10,42 +10,47 @@ package org.truffleruby.language.objects; import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.nodes.Node; import org.truffleruby.language.ImmutableRubyObject; import org.truffleruby.language.RubyBaseNode; import com.oracle.truffle.api.dsl.Specialization; @GenerateUncached +@GenerateCached(false) +@GenerateInline public abstract class CanHaveSingletonClassNode extends RubyBaseNode { - public static CanHaveSingletonClassNode getUncached() { - return CanHaveSingletonClassNodeGen.getUncached(); + public static boolean executeUncached(Object value) { + return CanHaveSingletonClassNodeGen.getUncached().execute(null, value); } - public abstract boolean execute(Object value); + public abstract boolean execute(Node node, Object value); @Specialization - boolean canHaveSingletonClass(int value) { + static boolean canHaveSingletonClass(int value) { return false; } @Specialization - boolean canHaveSingletonClass(long value) { + static boolean canHaveSingletonClass(long value) { return false; } @Specialization - boolean canHaveSingletonClass(double value) { + static boolean canHaveSingletonClass(double value) { return false; } @Specialization(guards = "!isNil(value)") - boolean canHaveSingletonClass(ImmutableRubyObject value) { + static boolean canHaveSingletonClass(ImmutableRubyObject value) { return false; } @Fallback - boolean fallback(Object value) { + static boolean fallback(Object value) { return true; } diff --git a/src/main/java/org/truffleruby/language/yield/CallBlockNode.java b/src/main/java/org/truffleruby/language/yield/CallBlockNode.java index 15280305d073..a23c6d2fd9d2 100644 --- a/src/main/java/org/truffleruby/language/yield/CallBlockNode.java +++ b/src/main/java/org/truffleruby/language/yield/CallBlockNode.java @@ -9,7 +9,9 @@ */ package org.truffleruby.language.yield; +import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.nodes.Node; import org.truffleruby.core.proc.ProcOperations; import org.truffleruby.core.proc.RubyProc; import org.truffleruby.language.RubyBaseNode; @@ -30,6 +32,7 @@ @ReportPolymorphism @GenerateUncached +@GenerateInline(inlineByDefault = true) public abstract class CallBlockNode extends RubyBaseNode { @NeverDefault @@ -37,24 +40,39 @@ public static CallBlockNode create() { return CallBlockNodeGen.create(); } - public static CallBlockNode getUncached() { - return CallBlockNodeGen.getUncached(); + public static Object executeUncached(DeclarationContext declarationContext, RubyProc block, Object self, + Object blockArgument, ArgumentsDescriptor descriptor, Object[] arguments) { + return CallBlockNodeGen.getUncached().executeCallBlock(null, declarationContext, block, self, blockArgument, + descriptor, arguments); + } + + public static Object yieldUncached(RubyProc block, Object... args) { + return CallBlockNodeGen.getUncached().executeCallBlock(null, block.declarationContext, block, + ProcOperations.getSelf(block), nil, EmptyArgumentsDescriptor.INSTANCE, args); } - public final Object yield(RubyProc block, ArgumentsDescriptor descriptor, Object... args) { - return executeCallBlock(block.declarationContext, block, ProcOperations.getSelf(block), nil, descriptor, args); + public final Object yieldCached(RubyProc block, ArgumentsDescriptor descriptor, Object... args) { + return executeCallBlock(this, block.declarationContext, block, ProcOperations.getSelf(block), nil, descriptor, + args); } - public final Object yield(RubyProc block, Object... args) { - return executeCallBlock(block.declarationContext, block, ProcOperations.getSelf(block), nil, + public final Object yield(Node node, RubyProc block, Object... args) { + return executeCallBlock(node, block.declarationContext, block, ProcOperations.getSelf(block), nil, EmptyArgumentsDescriptor.INSTANCE, args); } - public abstract Object executeCallBlock(DeclarationContext declarationContext, RubyProc block, Object self, + public final Object yieldCached(RubyProc block, Object... args) { + return executeCallBlock(this, block.declarationContext, block, ProcOperations.getSelf(block), nil, + EmptyArgumentsDescriptor.INSTANCE, args); + } + + public abstract Object executeCallBlock(Node node, DeclarationContext declarationContext, RubyProc block, + Object self, Object blockArgument, ArgumentsDescriptor descriptor, Object[] arguments); @Specialization(guards = "block.callTarget == cachedCallTarget", limit = "getCacheLimit()") - Object callBlockCached( + static Object callBlockCached( + Node node, DeclarationContext declarationContext, RubyProc block, Object self, @@ -62,27 +80,27 @@ Object callBlockCached( ArgumentsDescriptor descriptor, Object[] arguments, @Cached("block.callTarget") RootCallTarget cachedCallTarget, - @Cached("createBlockCallNode(cachedCallTarget)") DirectCallNode callNode) { + @Cached("createBlockCallNode(node, cachedCallTarget)") DirectCallNode callNode) { final Object[] frameArguments = packArguments(declarationContext, block, self, blockArgument, descriptor, arguments); return callNode.call(frameArguments); } @Specialization(replaces = "callBlockCached") - Object callBlockUncached( + static Object callBlockUncached( DeclarationContext declarationContext, RubyProc block, Object self, Object blockArgument, ArgumentsDescriptor descriptor, Object[] arguments, - @Cached IndirectCallNode callNode) { + @Cached(inline = false) IndirectCallNode callNode) { final Object[] frameArguments = packArguments(declarationContext, block, self, blockArgument, descriptor, arguments); return callNode.call(block.callTarget, frameArguments); } - private Object[] packArguments(DeclarationContext declarationContext, RubyProc block, Object self, + private static Object[] packArguments(DeclarationContext declarationContext, RubyProc block, Object self, Object blockArgument, ArgumentsDescriptor descriptor, Object[] arguments) { return RubyArguments.pack( block.declarationFrame, @@ -96,14 +114,14 @@ private Object[] packArguments(DeclarationContext declarationContext, RubyProc b arguments); } - protected DirectCallNode createBlockCallNode(RootCallTarget callTarget) { + protected static DirectCallNode createBlockCallNode(Node node, RootCallTarget callTarget) { final DirectCallNode callNode = Truffle.getRuntime().createDirectCallNode(callTarget); if (callNode.isCallTargetCloningAllowed() && RubyRootNode.of(callTarget).shouldAlwaysClone()) { callNode.cloneCallTarget(); } - if (getContext().getOptions().YIELD_ALWAYS_INLINE && callNode.isInlinable()) { + if (getContext(node).getOptions().YIELD_ALWAYS_INLINE && callNode.isInlinable()) { callNode.forceInlining(); } diff --git a/src/main/java/org/truffleruby/language/yield/YieldExpressionNode.java b/src/main/java/org/truffleruby/language/yield/YieldExpressionNode.java index 3e96deac036c..b4fd6263d387 100644 --- a/src/main/java/org/truffleruby/language/yield/YieldExpressionNode.java +++ b/src/main/java/org/truffleruby/language/yield/YieldExpressionNode.java @@ -71,7 +71,7 @@ public final Object execute(VirtualFrame frame) { descriptor = EmptyArgumentsDescriptor.INSTANCE; } - return getYieldNode().yield(block, descriptor, argumentsObjects); + return getYieldNode().yieldCached(block, descriptor, argumentsObjects); } private Object[] unsplat(Object[] argumentsObjects) { diff --git a/src/main/java/org/truffleruby/parser/BodyTranslator.java b/src/main/java/org/truffleruby/parser/BodyTranslator.java index b8a504939b7e..d7631844778f 100644 --- a/src/main/java/org/truffleruby/parser/BodyTranslator.java +++ b/src/main/java/org/truffleruby/parser/BodyTranslator.java @@ -40,7 +40,7 @@ import org.truffleruby.core.kernel.KernelNodesFactory; import org.truffleruby.core.module.ModuleNodes; import org.truffleruby.core.numeric.BignumOperations; -import org.truffleruby.core.range.RangeNodes; +import org.truffleruby.core.range.RangeNodesFactory; import org.truffleruby.core.range.RubyIntRange; import org.truffleruby.core.range.RubyLongRange; import org.truffleruby.core.regexp.ClassicRegexp; @@ -1417,7 +1417,7 @@ public RubyNode visitDotNode(DotParseNode node) { } else { final RubyNode begin = node.getBeginNode().accept(this); final RubyNode end = node.getEndNode().accept(this); - ret = new RangeNodes.RangeLiteralNode(begin, end, node.isExclusive()); + ret = RangeNodesFactory.RangeLiteralNodeGen.create(begin, end, node.isExclusive()); } ret.unsafeSetSourceSection(sourceSection); return addNewlineIfNeeded(node, ret); diff --git a/src/main/java/org/truffleruby/stdlib/readline/ReadlineHistoryNodes.java b/src/main/java/org/truffleruby/stdlib/readline/ReadlineHistoryNodes.java index bce143d95356..404f55902b51 100644 --- a/src/main/java/org/truffleruby/stdlib/readline/ReadlineHistoryNodes.java +++ b/src/main/java/org/truffleruby/stdlib/readline/ReadlineHistoryNodes.java @@ -172,7 +172,7 @@ RubyBasicObject each(RubyBasicObject history, RubyProc block, fromJavaStringNode, historyEntryToString(e), getLocaleEncoding()); - yieldNode.yield(block, line); + yieldNode.yield(this, block, line); } return history;