Skip to content

Commit

Permalink
[Truffle] Use new LoopNode for while (gives us OSR for the first time).
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Oct 23, 2014
1 parent 7e37a41 commit e6fc529
Showing 1 changed file with 32 additions and 37 deletions.
69 changes: 32 additions & 37 deletions core/src/main/java/org/jruby/truffle/nodes/control/WhileNode.java
Expand Up @@ -19,58 +19,53 @@
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.*;

/**
* Represents a Ruby {@code while} statement.
*/
public class WhileNode extends RubyNode {



@Child protected BooleanCastNode condition;
@Child protected RubyNode body;

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();
@Child protected LoopNode loopNode;

public WhileNode(RubyContext context, SourceSection sourceSection, BooleanCastNode condition, RubyNode body) {
super(context, sourceSection);
this.condition = condition;
this.body = body;
loopNode = Truffle.getRuntime().createLoopNode(new WhileRepeatingNode(condition, body));
}

@Override
public Object execute(VirtualFrame frame) {
int count = 0;

try {
outer: while (condition.executeBoolean(frame)) {
while (true) {
if (CompilerDirectives.inInterpreter()) {
count++;
}
loopNode.executeLoop(frame);
} catch (BreakException e) {
return e.getResult();
}

try {
body.execute(frame);
continue outer;
} catch (BreakException e) {
breakProfile.enter();
return e.getResult();
} catch (NextException e) {
nextProfile.enter();
continue outer;
} catch (RedoException e) {
redoProfile.enter();
}
}
return getContext().getCoreLibrary().getNilObject();
}

public class WhileRepeatingNode extends Node implements RepeatingNode {

@Child protected BooleanCastNode condition;
@Child protected RubyNode body;

public WhileRepeatingNode(BooleanCastNode condition, RubyNode body) {
this.condition = condition;
this.body = body;
}

@Override
public boolean executeRepeating(VirtualFrame frame) {
if (!condition.executeBoolean(frame)) {
return false;
}
} finally {
if (CompilerDirectives.inInterpreter()) {
((RubyRootNode) getRootNode()).reportLoopCountThroughBlocks(count);

while (true) {
try {
body.execute(frame);
return true;
} catch (NextException e) {
return true;
} catch (RedoException e) {
}
}
}

return getContext().getCoreLibrary().getNilObject();
}

}

0 comments on commit e6fc529

Please sign in to comment.