Skip to content

Commit 39bb0e3

Browse files
committed
Sharing the metaClass also shares the logical class for ShareObjectNode
* And use a RunTwiceBranchProfile to avoid repeated deopts if we see many different singleton classes. The same Shape no longer implies the same metaClass.
1 parent 29ad4ce commit 39bb0e3

File tree

1 file changed

+7
-12
lines changed

1 file changed

+7
-12
lines changed

src/main/java/org/truffleruby/language/objects/shared/ShareObjectNode.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.truffleruby.language.objects.ObjectGraph;
1818
import org.truffleruby.language.objects.ShapeCachingGuards;
1919

20-
import com.oracle.truffle.api.CompilerDirectives;
2120
import com.oracle.truffle.api.dsl.Cached;
2221
import com.oracle.truffle.api.dsl.ImportStatic;
2322
import com.oracle.truffle.api.dsl.Specialization;
@@ -27,6 +26,7 @@
2726
import com.oracle.truffle.api.object.ObjectLocation;
2827
import com.oracle.truffle.api.object.Property;
2928
import com.oracle.truffle.api.object.Shape;
29+
import org.truffleruby.utils.RunTwiceBranchProfile;
3030

3131
/** Share the object and all that is reachable from it (see {@link ObjectGraph#getAdjacentObjects}) */
3232
@ImportStatic(ShapeCachingGuards.class)
@@ -50,6 +50,7 @@ public ShareObjectNode(int depth) {
5050
protected void shareCached(RubyDynamicObject object,
5151
@Cached("object.getShape()") Shape cachedShape,
5252
@CachedLibrary(limit = "1") DynamicObjectLibrary objectLibrary,
53+
@Cached("new()") RunTwiceBranchProfile shareMetaClassProfile,
5354
@Cached("createShareInternalFieldsNode()") ShareInternalFieldsNode shareInternalFieldsNode,
5455
@Cached("getObjectProperties(cachedShape)") List<Property> properties,
5556
@Cached("createReadAndShareFieldNodes(properties)") ReadAndShareFieldNode[] readAndShareFieldNodes,
@@ -59,20 +60,14 @@ protected void shareCached(RubyDynamicObject object,
5960
objectLibrary.markShared(object);
6061
assert object.getShape() == sharedShape;
6162

62-
// Share the logical class
63-
if (!object.getLogicalClass().getShape().isShared()) {
64-
// The logical class is fixed for a given Shape and only needs to be shared once
65-
CompilerDirectives.transferToInterpreterAndInvalidate();
66-
SharedObjects.writeBarrier(getLanguage(), object.getLogicalClass());
67-
}
68-
69-
// Share the metaclass. Note that the metaclass might refer to `object` via `attached`,
70-
// so it is important to share the object first.
63+
// Share the metaclass. This will also the share the logical class, which is the same or its superclass.
64+
// Note that the metaclass might refer to `object` via `attached`, so it is important to share the object first.
7165
if (!object.getMetaClass().getShape().isShared()) {
72-
// The metaclass is fixed for a given Shape and only needs to be shared once
73-
CompilerDirectives.transferToInterpreterAndInvalidate();
66+
shareMetaClassProfile.enter();
7467
SharedObjects.writeBarrier(getLanguage(), object.getMetaClass());
7568
}
69+
assert SharedObjects
70+
.isShared(object.getLogicalClass()) : "the logical class should have been shared by the metaclass";
7671

7772
shareInternalFieldsNode.executeShare(object);
7873

0 commit comments

Comments
 (0)