Skip to content

Commit

Permalink
Showing 1 changed file with 48 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -9,13 +9,12 @@
*/
package org.jruby.truffle.language.objects;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.Shape;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
@@ -86,8 +85,8 @@ protected DynamicObject singletonClassSymbol(DynamicObject value) {
protected DynamicObject singletonClassClassCached(
DynamicObject rubyClass,
@Cached("rubyClass.getShape()") Shape cachedShape,
@Cached("getSingletonClassForClass(rubyClass)") DynamicObject singletonClass) {
return singletonClass;
@Cached("getSingletonClassForClass(rubyClass)") DynamicObject cachedSingletonClass) {
return cachedSingletonClass;
}

@Specialization(
@@ -98,19 +97,48 @@ protected DynamicObject singletonClassClassUncached(DynamicObject rubyClass) {
return getSingletonClassForClass(rubyClass);
}

@Specialization(guards = {
"!isNil(object)",
"!isRubyBignum(object)",
"!isRubySymbol(object)",
"!isRubyClass(object)"
})
protected DynamicObject singletonClass(
@Specialization(
guards = {
"!isNil(object)",
"!isRubyBignum(object)",
"!isRubySymbol(object)",
"!isRubyClass(object)",
"object == cachedObject",
"object.getShape() == cachedShape"

This comment has been minimized.

Copy link
@eregon

eregon Feb 24, 2016

Member

We should have guards on Shapes like isRubySymbol(Shape) or as in ShapeCachingGuards.
Then, a Shape check is enough and all other guards can be on the slow path.

This comment has been minimized.

Copy link
@eregon

eregon Feb 24, 2016

Member

The cache seems incorrect here, it should be either on identity or Shape (a Shape with a singleton class, so that means a singleton Shape so identity seems more useful).
If it's on identity, guards can be on cachedObject.

},
limit = "getCacheLimit()")
protected DynamicObject singletonClassInstanceCached(
DynamicObject object,
@Cached("create()") BranchProfile needsToFreeze) {
if (RubyGuards.isRubyClass(object)) {
return ClassNodes.getSingletonClass(getContext(), object);
}
@Cached("object") DynamicObject cachedObject,
@Cached("object.getShape()") Shape cachedShape,
@Cached("getSingletonClassForInstance(object)") DynamicObject cachedSingletonClass) {
return cachedSingletonClass;
}

@Specialization(
guards = {
"!isNil(object)",
"!isRubyBignum(object)",
"!isRubySymbol(object)",
"!isRubyClass(object)"
},
contains = "singletonClassInstanceCached"
)
protected DynamicObject singletonClassInstanceUncached(DynamicObject object) {
return getSingletonClassForInstance(object);
}

private DynamicObject noSingletonClass() {
throw new RaiseException(coreLibrary().typeErrorCantDefineSingleton(this));
}

@TruffleBoundary
protected DynamicObject getSingletonClassForClass(DynamicObject rubyClass) {
return ClassNodes.getSingletonClass(getContext(), rubyClass);
}

@TruffleBoundary
protected DynamicObject getSingletonClassForInstance(DynamicObject object) {
if (Layouts.CLASS.getIsSingleton(Layouts.BASIC_OBJECT.getMetaClass(object))) {
return Layouts.BASIC_OBJECT.getMetaClass(object);
}
@@ -123,19 +151,18 @@ protected DynamicObject singletonClass(
attached = object;
}

final String name = String.format("#<Class:#<%s:0x%x>>", Layouts.MODULE.getFields(logicalClass).getName(), ObjectIDOperations.verySlowGetObjectID(getContext(), object));
final DynamicObject singletonClass = ClassNodes.createSingletonClassOfObject(getContext(), logicalClass, attached, name);
final String name = String.format("#<Class:#<%s:0x%x>>", Layouts.MODULE.getFields(logicalClass).getName(),
ObjectIDOperations.verySlowGetObjectID(getContext(), object));

final DynamicObject singletonClass = ClassNodes.createSingletonClassOfObject(
getContext(), logicalClass, attached, name);

if (isFrozenNode == null) {
CompilerDirectives.transferToInterpreter();
isFrozenNode = insert(IsFrozenNodeGen.create(getContext(), getSourceSection(), null));
}

if (isFrozenNode.executeIsFrozen(object)) {
needsToFreeze.enter();

if (freezeNode == null) {
CompilerDirectives.transferToInterpreter();
freezeNode = insert(FreezeNodeGen.create(getContext(), getSourceSection(), null));
}

@@ -147,14 +174,6 @@ protected DynamicObject singletonClass(
return singletonClass;
}

private DynamicObject noSingletonClass() {
throw new RaiseException(coreLibrary().typeErrorCantDefineSingleton(this));
}

protected DynamicObject getSingletonClassForClass(DynamicObject rubyClass) {
return ClassNodes.getSingletonClass(getContext(), rubyClass);
}

protected int getCacheLimit() {
return getContext().getOptions().CLASS_CACHE;
}

0 comments on commit 1db32d2

Please sign in to comment.