Skip to content

Commit

Permalink
[GR-17457] Convert nodes to DSL inlinable
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/4020
  • Loading branch information
horakivo committed Oct 9, 2023
2 parents 6c4c2df + 86227ca commit dce0412
Show file tree
Hide file tree
Showing 56 changed files with 476 additions and 391 deletions.
18 changes: 9 additions & 9 deletions src/main/java/org/truffleruby/cext/CExtNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -215,7 +215,7 @@ Object callWithCExtLockAndFrame(
try {
return InteropNodes.execute(this, receiver, args, receivers, translateInteropExceptionNode);
} finally {
runMarksNode.execute(extensionStack);
runMarksNode.execute(this, extensionStack);
}
}

Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/truffleruby/cext/ValueWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -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;
Expand Down
34 changes: 20 additions & 14 deletions src/main/java/org/truffleruby/cext/ValueWrapperManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -283,35 +285,39 @@ public static final class HandleBlockHolder {
}

@GenerateUncached
@GenerateInline
@GenerateCached(false)
public abstract static class AllocateHandleNode extends RubyBaseNode {

private static final Set<ValueWrapper> 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);
}

Expand All @@ -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;
Expand All @@ -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()) {
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/org/truffleruby/core/MarkingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -43,7 +44,7 @@ protected static final class ExtensionCallStackEntry {

private final ExtensionCallStackEntry previous;
ValueWrapper preservedObject;
ArrayList<ValueWrapper> preservedObjects;
@SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") ArrayList<ValueWrapper> preservedObjectList;
private final boolean keywordsGiven;
private Object specialVariables;
private final Object block;
Expand Down Expand Up @@ -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) {
Expand Down
67 changes: 36 additions & 31 deletions src/main/java/org/truffleruby/core/MarkingServiceNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}

Expand All @@ -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
Expand All @@ -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();
}
}
}
6 changes: 3 additions & 3 deletions src/main/java/org/truffleruby/core/VMPrimitiveNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -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))) {
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit dce0412

Please sign in to comment.