Skip to content

Commit ed1f69c

Browse files
committed
ShareObjectNode supports DSL inlining
1 parent e4e30a0 commit ed1f69c

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

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

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
import java.util.List;
1414
import java.util.Objects;
1515

16+
import com.oracle.truffle.api.CompilerAsserts;
17+
import com.oracle.truffle.api.dsl.GenerateInline;
18+
import com.oracle.truffle.api.nodes.Node;
1619
import com.oracle.truffle.api.object.PropertyGetter;
1720
import org.truffleruby.core.kernel.KernelNodes;
1821
import org.truffleruby.language.RubyBaseNode;
@@ -32,24 +35,28 @@
3235

3336
/** Share the object and all that is reachable from it (see {@link ObjectGraph#getAdjacentObjects}) */
3437
@ImportStatic(ShapeCachingGuards.class)
38+
@GenerateInline(inlineByDefault = true)
3539
public abstract class ShareObjectNode extends RubyBaseNode {
3640

3741
protected static final int CACHE_LIMIT = 8;
3842

39-
protected final int depth;
43+
public final void execute(Node node, RubyDynamicObject object, int depth) {
44+
CompilerAsserts.partialEvaluationConstant(depth);
45+
executeInternal(node, object, depth);
46+
}
4047

41-
public ShareObjectNode(int depth) {
42-
this.depth = depth;
48+
public final void executeCached(RubyDynamicObject object, int depth) {
49+
execute(this, object, depth);
4350
}
4451

45-
public abstract void executeShare(RubyDynamicObject object);
52+
protected abstract void executeInternal(Node node, RubyDynamicObject object, int depth);
4653

4754
@ExplodeLoop
4855
@Specialization(
4956
guards = { "object.getShape() == cachedShape", "propertyGetters.length <= MAX_EXPLODE_SIZE" },
5057
assumptions = { "cachedShape.getValidAssumption()", "sharedShape.getValidAssumption()" },
5158
limit = "CACHE_LIMIT")
52-
protected void shareCached(RubyDynamicObject object,
59+
protected static void shareCached(Node node, RubyDynamicObject object, int depth,
5360
@Cached("object.getShape()") Shape cachedShape,
5461
@Cached("createSharedShape(cachedShape)") Shape sharedShape,
5562
@CachedLibrary(limit = "1") DynamicObjectLibrary objectLibrary,
@@ -66,12 +73,12 @@ protected void shareCached(RubyDynamicObject object,
6673
// Note that the metaclass might refer to `object` via `attached`, so it is important to share the object first.
6774
if (!object.getMetaClass().getShape().isShared()) {
6875
shareMetaClassProfile.enter();
69-
SharedObjects.writeBarrier(getLanguage(), object.getMetaClass());
76+
SharedObjects.writeBarrier(getLanguage(node), object.getMetaClass());
7077
}
7178
assert SharedObjects
7279
.isShared(object.getLogicalClass()) : "the logical class should have been shared by the metaclass";
7380

74-
shareInternalFieldsNode.execute(this, object, depth);
81+
shareInternalFieldsNode.execute(node, object, depth);
7582

7683
for (int i = 0; i < propertyGetters.length; i++) {
7784
final PropertyGetter propertyGetter = propertyGetters[i];
@@ -82,7 +89,7 @@ protected void shareCached(RubyDynamicObject object,
8289
assert allFieldsAreShared(object);
8390
}
8491

85-
private boolean allFieldsAreShared(RubyDynamicObject object) {
92+
private static boolean allFieldsAreShared(RubyDynamicObject object) {
8693
for (Object value : ObjectGraph.getAdjacentObjects(object)) {
8794
assert SharedObjects.isShared(value) : "unshared field in shared object: " + value;
8895
}
@@ -91,13 +98,14 @@ private boolean allFieldsAreShared(RubyDynamicObject object) {
9198
}
9299

93100
@Specialization(guards = "updateShape(object)")
94-
protected void updateShapeAndShare(RubyDynamicObject object) {
95-
executeShare(object);
101+
protected static void updateShapeAndShare(RubyDynamicObject object, int depth,
102+
@Cached(inline = false) ShareObjectNode shareObjectNode) {
103+
shareObjectNode.executeCached(object, depth);
96104
}
97105

98106
@Specialization(replaces = { "shareCached", "updateShapeAndShare" })
99-
protected void shareUncached(RubyDynamicObject object) {
100-
SharedObjects.writeBarrier(getLanguage(), object);
107+
protected static void shareUncached(Node node, RubyDynamicObject object, int depth) {
108+
SharedObjects.writeBarrier(getLanguage(node), object);
101109
}
102110

103111
protected static PropertyGetter[] getObjectProperties(Shape shape) {
@@ -110,7 +118,7 @@ protected static PropertyGetter[] getObjectProperties(Shape shape) {
110118
return objectProperties.toArray(KernelNodes.CopyInstanceVariablesNode.EMPTY_PROPERTY_GETTER_ARRAY);
111119
}
112120

113-
protected WriteBarrierNode[] createWriteBarrierNodes(PropertyGetter[] propertyGetters) {
121+
protected static WriteBarrierNode[] createWriteBarrierNodes(PropertyGetter[] propertyGetters) {
114122
WriteBarrierNode[] nodes = propertyGetters.length == 0
115123
? WriteBarrierNode.EMPTY_ARRAY
116124
: new WriteBarrierNode[propertyGetters.length];
@@ -120,7 +128,7 @@ protected WriteBarrierNode[] createWriteBarrierNodes(PropertyGetter[] propertyGe
120128
return nodes;
121129
}
122130

123-
protected Shape createSharedShape(Shape cachedShape) {
131+
protected static Shape createSharedShape(Shape cachedShape) {
124132
if (cachedShape.isShared()) {
125133
throw new UnsupportedOperationException(
126134
"Thread-safety bug: the object is already shared. This means another thread marked the object as shared concurrently.");

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,17 @@ protected static void alreadySharedUncached(RubyDynamicObject value, int depth)
7171
assumptions = "cachedShape.getValidAssumption()",
7272
// limit of 1 to avoid creating many nodes if the value's Shape is polymorphic.
7373
limit = "1")
74-
protected static void writeBarrierCached(RubyDynamicObject value, int depth,
74+
protected static void writeBarrierCached(Node node, RubyDynamicObject value, int depth,
7575
@Cached("value.getShape()") Shape cachedShape,
76-
@Cached("createShareObjectNode(depth)") ShareObjectNode shareObjectNode) {
77-
shareObjectNode.executeShare(value);
76+
// Recursive inlining is not supported. ShareObjectNode contains cached parameter ShareInternalFieldsNode
77+
// which contains again WriteBarrierNode
78+
@Cached(inline = false) ShareObjectNode shareObjectNode) {
79+
shareObjectNode.executeCached(value, depth + 1);
7880
}
7981

8082
@Specialization(guards = "updateShape(value)")
8183
protected static void updateShapeAndWriteBarrier(RubyDynamicObject value, int depth,
84+
// Recursive inlining is not supported.
8285
@Cached(inline = false) WriteBarrierNode writeBarrierNode) {
8386
writeBarrierNode.executeCached(value, depth);
8487
}
@@ -110,8 +113,4 @@ protected static boolean isFinalizer(Object object) {
110113
return object instanceof FinalizerReference || object instanceof DataObjectFinalizerReference;
111114
}
112115

113-
protected static ShareObjectNode createShareObjectNode(int depth) {
114-
return ShareObjectNodeGen.create(depth + 1);
115-
}
116-
117116
}

0 commit comments

Comments
 (0)