Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e8dce761d09a
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: af76b65532dc
Choose a head ref
  • 2 commits
  • 7 files changed
  • 1 contributor

Commits on Feb 11, 2015

  1. Copy the full SHA
    06aed17 View commit details
  2. [Truffle] Remove RubyCallStack.getCurrentMethod() in favor of using d…

    …irectly the VirtualFrame.
    eregon committed Feb 11, 2015
    Copy the full SHA
    af76b65 View commit details
Original file line number Diff line number Diff line change
@@ -1020,12 +1020,12 @@ public NestingNode(NestingNode prev) {
}

@Specialization
public RubyArray nesting() {
public RubyArray nesting(VirtualFrame frame) {
notDesignedForCompilation();

final List<RubyModule> modules = new ArrayList<>();

InternalMethod method = RubyCallStack.getCallingMethod();
InternalMethod method = RubyCallStack.getCallingMethod(frame);
LexicalScope lexicalScope = method == null ? null : method.getSharedMethodInfo().getLexicalScope();
RubyClass object = getContext().getCoreLibrary().getObjectClass();

Original file line number Diff line number Diff line change
@@ -11,8 +11,10 @@

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.runtime.DebugOperations;
import org.jruby.truffle.runtime.RubyCallStack;
import org.jruby.truffle.runtime.RubyContext;
@@ -223,10 +225,10 @@ public ParseTreeNode(ParseTreeNode prev) {
}

@Specialization
public Object parseTree() {
public Object parseTree(VirtualFrame frame) {
notDesignedForCompilation();

final org.jruby.ast.Node parseTree = RubyCallStack.getCallingMethod().getSharedMethodInfo().getParseTree();
final org.jruby.ast.Node parseTree = RubyCallStack.getCallingMethod(frame).getSharedMethodInfo().getParseTree();

if (parseTree == null) {
return getContext().getCoreLibrary().getNilObject();
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.objects;

import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;

/**
* Reads the internal metaclass of an object.
*/
@NodeChild(value="object", type=RubyNode.class)
public abstract class MetaClassNode extends RubyNode {

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

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

public abstract RubyClass executeMetaClass(VirtualFrame frame, Object value);

@Specialization(guards = "isTrue")
protected RubyClass singletonClassTrue(boolean value) {
return getContext().getCoreLibrary().getTrueClass();
}

@Specialization(guards = "!isTrue")
protected RubyClass singletonClassFalse(boolean value) {
return getContext().getCoreLibrary().getFalseClass();
}

@Specialization
protected RubyClass singletonClass(int value) {
return getContext().getCoreLibrary().getFixnumClass();
}

@Specialization
protected RubyClass singletonClass(long value) {
return getContext().getCoreLibrary().getFixnumClass();
}

@Specialization
protected RubyClass singletonClass(double value) {
return getContext().getCoreLibrary().getFloatClass();
}

@Specialization
protected RubyClass singletonClass(RubyBasicObject object) {
return object.getMetaClass();
}

}
Original file line number Diff line number Diff line change
@@ -18,6 +18,8 @@
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.objects.MetaClassNode;
import org.jruby.truffle.nodes.objects.MetaClassNodeFactory;
import org.jruby.truffle.runtime.ModuleOperations;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyCallStack;
@@ -29,6 +31,7 @@

public abstract class AbstractGeneralSuperCallNode extends RubyNode {

@Child protected MetaClassNode metaClassNode;
@Child protected DirectCallNode callNode;

@CompilerDirectives.CompilationFinal private InternalMethod currentMethod;
@@ -38,20 +41,20 @@ public abstract class AbstractGeneralSuperCallNode extends RubyNode {

public AbstractGeneralSuperCallNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
metaClassNode = MetaClassNodeFactory.create(context, sourceSection, null);
}

protected boolean guard(Object self) {
InternalMethod method = RubyCallStack.getCurrentMethod();

// This is overly restrictive, but seems the be the only reasonable check in term of performance.
// The ideal condition would be to check if both ancestor lists starting at
// the current method's module are identical, which is non-trivial
// if the current method's module is an (included) module and not a class.
boolean compatibleAncestors = getContext().getCoreLibrary().getMetaClass(self) == selfMetaClass;
protected boolean guard(VirtualFrame frame, Object self) {
InternalMethod method = RubyArguments.getMethod(frame.getArguments());

return superMethod != null &&
method == currentMethod &&
compatibleAncestors &&

// This is overly restrictive, but seems the be the only reasonable check in term of performance.
// The ideal condition would be to check if both ancestor lists starting at
// the current method's module are identical, which is non-trivial
// if the current method's module is an (included) module and not a class.
metaClassNode.executeMetaClass(frame, self) == selfMetaClass &&
unmodifiedAssumption.isValid();
}

@@ -62,7 +65,7 @@ protected void lookup(VirtualFrame frame) {
private void lookup(VirtualFrame frame, boolean checkIfDefined) {
CompilerAsserts.neverPartOfCompilation();

currentMethod = RubyCallStack.getCurrentMethod();
currentMethod = RubyArguments.getMethod(frame.getArguments());

String name = currentMethod.getName();
RubyModule declaringModule = currentMethod.getDeclaringModule();
@@ -97,7 +100,7 @@ public Object isDefined(VirtualFrame frame) {

final Object self = RubyArguments.getSelf(frame.getArguments());

if (!guard(self)) {
if (!guard(frame, self)) {
lookup(frame, true);
}

Original file line number Diff line number Diff line change
@@ -74,7 +74,7 @@ public final Object execute(VirtualFrame frame) {

// Check we have a method and the module is unmodified

if (!guard(self)) {
if (!guard(frame, self)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
lookup(frame);
}
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ public GeneralSuperReCallNode(RubyContext context, SourceSection sourceSection,
public final Object execute(VirtualFrame frame) {
final Object self = RubyArguments.getSelf(frame.getArguments());

if (!guard(self)) {
if (!guard(frame, self)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
lookup(frame);
}
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;

import org.jruby.truffle.nodes.CoreSourceSection;
@@ -25,15 +26,10 @@

public abstract class RubyCallStack {

public static InternalMethod getCurrentMethod() {
final FrameInstance currentFrame = Truffle.getRuntime().getCurrentFrame();
return getMethod(currentFrame);
}

public static InternalMethod getCallingMethod() {
public static InternalMethod getCallingMethod(VirtualFrame frame) {
CompilerAsserts.neverPartOfCompilation();

final InternalMethod currentMethod = getCurrentMethod();
final InternalMethod currentMethod = RubyArguments.getMethod(frame.getArguments());

return Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<InternalMethod>() {