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: 8c790a3fbab4
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ba4a334cd4f7
Choose a head ref
  • 2 commits
  • 4 files changed
  • 2 contributors

Commits on Jun 15, 2015

  1. Copy the full SHA
    d43c419 View commit details

Commits on Jun 18, 2015

  1. Merge pull request #3047 from pitr-ch/is_a

    [Truffle] is_a?: add cached fast path and TypeError
    chrisseaton committed Jun 18, 2015
    Copy the full SHA
    ba4a334 View commit details
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@
@NodeChildren({ @NodeChild("module"), @NodeChild("name") })
public abstract class LookupConstantNode extends RubyNode {

public static int getCacheLimit() {
protected static int getCacheLimit() {
return DispatchNode.DISPATCH_POLYMORPHIC_MAX;
}

Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@
import org.jruby.truffle.nodes.cast.NumericToFloatNode;
import org.jruby.truffle.nodes.cast.NumericToFloatNodeGen;
import org.jruby.truffle.nodes.coerce.ToStrNodeGen;
import org.jruby.truffle.nodes.constants.LookupConstantNode;
import org.jruby.truffle.nodes.core.KernelNodesFactory.CopyNodeFactory;
import org.jruby.truffle.nodes.core.KernelNodesFactory.SameOrEqualNodeFactory;
import org.jruby.truffle.nodes.core.KernelNodesFactory.SingletonMethodsNodeFactory;
@@ -936,8 +937,11 @@ public RubyBasicObject instanceVariables(RubyBasicObject self) {
@CoreMethod(names = {"is_a?", "kind_of?"}, required = 1)
public abstract static class IsANode extends CoreMethodArrayArgumentsNode {

@Child MetaClassNode metaClassNode;

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

public abstract boolean executeIsA(VirtualFrame frame, Object self, RubyModule rubyClass);
@@ -947,14 +951,42 @@ public boolean isANil(RubyBasicObject self, Object nil) {
return false;
}

@TruffleBoundary
@Specialization(
limit = "getCacheLimit()",
guards = {"getMetaClass(frame, self) == cachedMetaClass", "module == cachedModule"},
assumptions = "cachedModule.getUnmodifiedAssumption()")
public boolean isACached(VirtualFrame frame,
Object self,
RubyModule module,
@Cached("getMetaClass(frame, self)") RubyClass cachedMetaClass,
@Cached("module") RubyModule cachedModule,
@Cached("isA(cachedMetaClass, cachedModule)") boolean result) {
return result;
}

@Specialization
public boolean isA(Object self, RubyModule rubyClass) {
public boolean isAUncached(VirtualFrame frame, Object self, RubyModule module) {
return isA(getMetaClass(frame, self), module);
}

@Specialization(guards = "!isRubyModule(module)")
public boolean isATypeError(VirtualFrame frame, Object self, Object module) {
CompilerDirectives.transferToInterpreter();
// TODO(CS): fast path
return ModuleOperations.assignableTo(getContext().getCoreLibrary().getMetaClass(self), rubyClass);
throw new RaiseException(getContext().getCoreLibrary().typeError("class or module required", this));
}

@TruffleBoundary
protected boolean isA(RubyClass metaClass, RubyModule module) {
return ModuleOperations.assignableTo(metaClass, module);
}

protected RubyClass getMetaClass(VirtualFrame frame, Object object) {
return metaClassNode.executeMetaClass(frame, object);
}

protected int getCacheLimit() {
return DispatchNode.DISPATCH_POLYMORPHIC_MAX;
}
}

@CoreMethod(names = "lambda", isModuleFunction = true, needsBlock = true)
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@
})
public abstract class CallMethodNode extends RubyNode {

public static int getCacheLimit() {
protected static int getCacheLimit() {
return DispatchNode.DISPATCH_POLYMORPHIC_MAX;
}

Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@
@NodeChild("self")
public abstract class LookupSuperMethodNode extends RubyNode {

public static int getCacheLimit() {
protected static int getCacheLimit() {
return DispatchNode.DISPATCH_POLYMORPHIC_MAX;
}