Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-17457] Convert nodes to DSL inlinable #3289

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading