Skip to content

Commit d461bf9

Browse files
committed
Performance improvements in the unclass builtin
1 parent 3a1e26a commit d461bf9

File tree

1 file changed

+44
-35
lines changed
  • com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base

1 file changed

+44
-35
lines changed

com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,77 +24,86 @@
2424
import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
2525
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
2626

27-
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
27+
import com.oracle.truffle.api.CompilerDirectives;
2828
import com.oracle.truffle.api.dsl.Cached;
2929
import com.oracle.truffle.api.dsl.Specialization;
3030
import com.oracle.truffle.api.profiles.BranchProfile;
3131
import com.oracle.truffle.r.nodes.attributes.RemoveFixedAttributeNode;
3232
import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetClassAttributeNode;
3333
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
34+
import com.oracle.truffle.r.nodes.builtin.base.UnClassNodeGen.RemoveClassAttrNodeGen;
3435
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
3536
import com.oracle.truffle.r.runtime.data.RAttributable;
3637
import com.oracle.truffle.r.runtime.data.RNull;
3738
import com.oracle.truffle.r.runtime.data.RShareable;
38-
import com.oracle.truffle.r.runtime.data.RVector;
3939
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
40+
import com.oracle.truffle.r.runtime.data.nodes.VectorReuse;
41+
import com.oracle.truffle.r.runtime.nodes.RBaseNode;
4042

4143
@RBuiltin(name = "unclass", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE)
4244
public abstract class UnClass extends RBuiltinNode.Arg1 {
43-
private final BranchProfile objectProfile = BranchProfile.create();
44-
private final BranchProfile shareableProfile = BranchProfile.create();
45-
4645
static {
4746
Casts casts = new Casts(UnClass.class);
4847
casts.arg("x").mustNotBeMissing().asAttributable(true, true, true);
4948
}
5049

50+
@Child private RemoveClassAttrNode removeClassAttrNode;
51+
5152
@Specialization
5253
protected RNull unClass(RNull rnull) {
5354
return rnull;
5455
}
5556

56-
@TruffleBoundary
57-
private static Object unClassVector(RAbstractVector arg) {
58-
RVector<?> resultVector = arg.materialize();
59-
if (!resultVector.isTemporary()) {
60-
resultVector = resultVector.copy();
61-
resultVector.incRefCount();
62-
}
63-
return RVector.setVectorClassAttr(resultVector, null);
64-
}
65-
66-
// TODO: this specialization could go away if connections were simple vectors (we wouldn't need
67-
// special method for setting class attributes then)
6857
@Specialization
69-
protected Object unClass(RAbstractVector arg,
58+
protected Object unClass(RAttributable arg,
7059
@Cached("create()") GetClassAttributeNode getClassNode) {
7160
if (getClassNode.isObject(arg)) {
72-
objectProfile.enter();
73-
return unClassVector(arg);
61+
if (removeClassAttrNode == null) {
62+
CompilerDirectives.transferToInterpreterAndInvalidate();
63+
removeClassAttrNode = insert(RemoveClassAttrNodeGen.create());
64+
}
65+
return removeClassAttrNode.execute(arg);
7466
}
7567
return arg;
7668
}
7769

78-
@Specialization(guards = "notAbstractVector(arg)")
79-
protected Object unClass(RAttributable arg,
80-
@Cached("createClass()") RemoveFixedAttributeNode removeClassNode,
81-
@Cached("create()") GetClassAttributeNode getClassNode) {
82-
if (getClassNode.getClassAttr(arg) != null) {
83-
objectProfile.enter();
84-
if (arg instanceof RShareable) {
70+
protected abstract static class RemoveClassAttrNode extends RBaseNode {
71+
public abstract Object execute(RAttributable attributable);
72+
73+
@Specialization(guards = "reuse.supports(x)")
74+
protected Object doVector(RAbstractVector x,
75+
@Cached("createClass()") RemoveFixedAttributeNode removeClassNode,
76+
@Cached("createTemporary(x)") VectorReuse reuse) {
77+
RAbstractVector result = reuse.getMaterializedResult(x);
78+
removeClassNode.execute(result);
79+
return result;
80+
}
81+
82+
@Specialization(replaces = "doVector")
83+
protected Object doVectorGeneric(RAbstractVector x,
84+
@Cached("createClass()") RemoveFixedAttributeNode removeClassNode,
85+
@Cached("createTemporaryGeneric()") VectorReuse reuse) {
86+
return doVector(x, removeClassNode, reuse);
87+
}
88+
89+
@Specialization(guards = "notAbstractVector(x)")
90+
protected Object unClass(RAttributable x,
91+
@Cached BranchProfile shareableProfile,
92+
@Cached("createClass()") RemoveFixedAttributeNode removeClassNode) {
93+
RAttributable result = x;
94+
if (x instanceof RShareable) {
8595
shareableProfile.enter();
86-
RShareable shareable = (RShareable) arg;
96+
RShareable shareable = (RShareable) x;
8797
if (!shareable.isTemporary()) {
88-
shareable = shareable.copy();
89-
shareable.incRefCount();
98+
result = (RAttributable) shareable.copy();
9099
}
91100
}
92-
removeClassNode.execute(arg);
101+
removeClassNode.execute(result);
102+
return result;
93103
}
94-
return arg;
95-
}
96104

97-
protected boolean notAbstractVector(Object arg) {
98-
return !(arg instanceof RAbstractVector);
105+
protected static boolean notAbstractVector(Object arg) {
106+
return !(arg instanceof RAbstractVector);
107+
}
99108
}
100109
}

0 commit comments

Comments
 (0)