Skip to content

Commit

Permalink
Showing 6 changed files with 106 additions and 252 deletions.

This file was deleted.

100 changes: 100 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/nodes/yield/CallBlockNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.nodes.yield;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.cli.Options;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

@NodeChildren({
@NodeChild("block"),
@NodeChild("self"),
@NodeChild("blockArgument"),
@NodeChild(value = "arguments", type = RubyNode[].class)
})
public abstract class CallBlockNode extends RubyNode {

private static final boolean INLINER_ALWAYS_CLONE_YIELD = Options.TRUFFLE_INLINER_ALWAYS_CLONE_YIELD.load();
private static final boolean INLINER_ALWAYS_INLINE_YIELD = Options.TRUFFLE_INLINER_ALWAYS_INLINE_YIELD.load();

// Allowing the child to be Node.replace()'d.
static class CallNodeWrapperNode extends Node {
@Child DirectCallNode child;

public CallNodeWrapperNode(DirectCallNode child) {
this.child = insert(child);
}
}

public CallBlockNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public abstract Object executeCallBlock(VirtualFrame frame, DynamicObject block, Object self, DynamicObject blockArgument, Object[] arguments);

@Specialization(
guards = "getBlockCallTarget(block) == cachedCallTarget",
limit = "getCacheLimit()")
protected Object callBlock(VirtualFrame frame, DynamicObject block, Object self, Object blockArgument, Object[] arguments,
@Cached("getBlockCallTarget(block)") CallTarget cachedCallTarget,
@Cached("createBlockCallNode(cachedCallTarget)") CallNodeWrapperNode callNode) {
final Object[] frameArguments = packArguments(block, self, blockArgument, arguments);
return callNode.child.call(frame, frameArguments);
}

@Specialization
protected Object callBlockUncached(VirtualFrame frame, DynamicObject block, Object self, Object blockArgument, Object[] arguments,
@Cached("create()") IndirectCallNode callNode) {

This comment has been minimized.

Copy link
@pitr-ch

pitr-ch Aug 25, 2015

Member

Where is the create coming from?

This comment has been minimized.

Copy link
@eregon

eregon Aug 25, 2015

Author Member

From IndirectCallNode. The lookup for subclasses of Node will look at static members of the parameter type. See the @cached JavaDoc.

This comment has been minimized.

Copy link
@pitr-ch

pitr-ch Aug 27, 2015

Member

ah thanks, I did not notice it also uses the type of the annotated argument before.

final Object[] frameArguments = packArguments(block, self, blockArgument, arguments);
return callNode.call(frame, getBlockCallTarget(block), frameArguments);
}

private Object[] packArguments(DynamicObject block, Object self, Object blockArgument, Object[] arguments) {
return RubyArguments.pack(
Layouts.PROC.getMethod(block),
Layouts.PROC.getDeclarationFrame(block),
self,
(DynamicObject) blockArgument,
arguments);
}

protected static CallTarget getBlockCallTarget(DynamicObject block) {
return Layouts.PROC.getCallTargetForType(block);
}

protected CallNodeWrapperNode createBlockCallNode(CallTarget callTarget) {
final DirectCallNode callNode = Truffle.getRuntime().createDirectCallNode(callTarget);
final CallNodeWrapperNode callNodeWrapperNode = new CallNodeWrapperNode(callNode);

if (INLINER_ALWAYS_CLONE_YIELD && callNode.isCallTargetCloningAllowed()) {
callNode.cloneCallTarget();
}
if (INLINER_ALWAYS_INLINE_YIELD && callNode.isInlinable()) {
callNode.forceInlining();
}
return callNodeWrapperNode;
}

}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -24,22 +24,21 @@

public class YieldDispatchHeadNode extends Node {

@Child private YieldDispatchNode dispatch;
@Child CallBlockNode callBlockNode;

public YieldDispatchHeadNode(RubyContext context) {
dispatch = new UninitializedYieldDispatchNode(context);

callBlockNode = CallBlockNodeGen.create(context, null, null, null, null, null);
}

public Object dispatch(VirtualFrame frame, DynamicObject block, Object... argumentsObjects) {
assert block == null || RubyGuards.isRubyProc(block);
return dispatch.dispatchWithSelfAndBlock(frame, block, Layouts.PROC.getSelf(block), Layouts.PROC.getBlock(block), argumentsObjects);
return callBlockNode.executeCallBlock(frame, block, Layouts.PROC.getSelf(block), Layouts.PROC.getBlock(block), argumentsObjects);
}

public Object dispatchWithModifiedBlock(VirtualFrame frame, DynamicObject block, DynamicObject modifiedBlock, Object... argumentsObjects) {
assert block == null || RubyGuards.isRubyProc(block);
assert modifiedBlock == null || RubyGuards.isRubyProc(modifiedBlock);
return dispatch.dispatchWithSelfAndBlock(frame, block, Layouts.PROC.getSelf(block), modifiedBlock, argumentsObjects);
return callBlockNode.executeCallBlock(frame, block, Layouts.PROC.getSelf(block), modifiedBlock, argumentsObjects);
}

public Object dispatchWithModifiedSelf(VirtualFrame currentFrame, DynamicObject block, Object self, Object... argumentsObjects) {
@@ -56,12 +55,12 @@ public Object dispatchWithModifiedSelf(VirtualFrame currentFrame, DynamicObject
try {
frame.setObject(slot, Visibility.PUBLIC);

return dispatch.dispatchWithSelfAndBlock(currentFrame, block, self, Layouts.PROC.getBlock(block), argumentsObjects);
return callBlockNode.executeCallBlock(currentFrame, block, self, Layouts.PROC.getBlock(block), argumentsObjects);
} finally {
frame.setObject(slot, oldVisibility);
}
} else {
return dispatch.dispatchWithSelfAndBlock(currentFrame, block, self, Layouts.PROC.getBlock(block), argumentsObjects);
return callBlockNode.executeCallBlock(currentFrame, block, self, Layouts.PROC.getBlock(block), argumentsObjects);
}
}

@@ -70,8 +69,4 @@ private FrameSlot getVisibilitySlot(Frame frame) {
return frame.getFrameDescriptor().findOrAddFrameSlot(ModuleNodes.VISIBILITY_FRAME_SLOT_ID, "dynamic visibility for def", FrameSlotKind.Object);
}

public YieldDispatchNode getDispatch() {
return dispatch;
}

}

This file was deleted.

0 comments on commit 6b0d84b

Please sign in to comment.