Skip to content
Permalink
Browse files
[Truffle] Use a ThreadPassNode directly rather than resolving constan…
…t and such.

* Notably did not work if inside BasicObject.
  • Loading branch information
eregon committed Jan 27, 2015
1 parent 0919714 commit 0f550c55745979de9ef70a41c46530156c4011ea
Showing 3 changed files with 55 additions and 25 deletions.
@@ -175,25 +175,21 @@ public RubyThread join(RubyThread self) {
@CoreMethod(names = "pass", onSingleton = true)
public abstract static class PassNode extends CoreMethodNode {

@Child ThreadPassNode threadPassNode;

public PassNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
threadPassNode = new ThreadPassNode(context, sourceSection);
}

public PassNode(PassNode prev) {
super(prev);
threadPassNode = prev.threadPassNode;
}

@Specialization
public RubyNilClass pass() {
final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();

try {
Thread.yield();
} finally {
getContext().getThreadManager().enterGlobalLock(runningThread);
}

return getContext().getCoreLibrary().getNilObject();
public RubyNilClass pass(VirtualFrame frame) {
return threadPassNode.executeRubyNilClass(frame);
}

}
@@ -0,0 +1,48 @@
/*
* Copyright (c) 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.core;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyNilClass;
import org.jruby.truffle.runtime.core.RubyThread;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

public class ThreadPassNode extends RubyNode {

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

public ThreadPassNode(ThreadPassNode prev) {
super(prev);
}

@Override
public RubyNilClass executeRubyNilClass(VirtualFrame frame) {

This comment has been minimized.

Copy link
@chrisseaton

chrisseaton Jan 27, 2015

Contributor

This could be executeVoid as it's only ever used in a sequence and not at the end, so that's the method that will be called. You can then return nil in execute (which I don't imagine will ever actually be called).

This comment has been minimized.

Copy link
@eregon

eregon Jan 27, 2015

Author Member

Right, I should indeed do that.

final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();

try {
Thread.yield();
} finally {
getContext().getThreadManager().enterGlobalLock(runningThread);
}

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

@Override
public Object execute(VirtualFrame frame) {
return executeRubyNilClass(frame);
}

}
@@ -1964,25 +1964,11 @@ public RubyNode visitNewlineNode(org.jruby.ast.NewlineNode node) {

if (Options.TRUFFLE_PASSALOT.load() > 0) {
if (Options.TRUFFLE_PASSALOT.load() > Math.random() * 100) {
final LexicalScope lexicalScope = environment.getLexicalScope();
final RubyNode moduleNode = new LexicalScopeNode(context, translated.getSourceSection(), lexicalScope);

translated = SequenceNode.sequence(
translated.getContext(),
translated.getSourceSection(),
new RubyCallNode(
translated.getContext(),
translated.getSourceSection(),
"pass",
new ReadConstantNode(
translated.getContext(),
translated.getSourceSection(),
"Thread",
moduleNode,
lexicalScope
),
null,
false),
new ThreadPassNode(translated.getContext(), translated.getSourceSection()),
translated);
}
}

0 comments on commit 0f550c5

Please sign in to comment.