diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java index ed643cb629ef06cd93cc76696597613684206b0f..470d1ba4cf21f2e3a72db08dce47ccf36bf590a3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java @@ -24,6 +24,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -63,7 +64,8 @@ public abstract class APerm extends RBuiltinNode { @Specialization protected RAbstractVector aPerm(RAbstractVector vector, @SuppressWarnings("unused") RNull permVector, byte resize, - @Cached("create()") GetDimAttributeNode getDimsNode) { + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimNode) { checkErrorConditions(vector); int[] dim = getDimsNode.getDimensions(vector); @@ -76,9 +78,9 @@ public abstract class APerm extends RBuiltinNode { for (int i = 0; i < diml; i++) { pDim[i] = dim[diml - 1 - i]; } - result.setDimensions(pDim); + setDimNode.setDimensions(result, pDim); } else { - result.setDimensions(dim); + setDimNode.setDimensions(result, dim); } // Move along the old array using stride @@ -104,7 +106,8 @@ public abstract class APerm extends RBuiltinNode { @Specialization protected RAbstractVector aPerm(RAbstractVector vector, RAbstractIntVector permVector, byte resize, - @Cached("create()") GetDimAttributeNode getDimsNode) { + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode) { checkErrorConditions(vector); int[] dim = getDimsNode.getDimensions(vector); @@ -115,7 +118,7 @@ public abstract class APerm extends RBuiltinNode { RVector<?> result = vector.createEmptySameType(vector.getLength(), vector.isComplete()); - result.setDimensions(resize == RRuntime.LOGICAL_TRUE ? pDim : dim); + setDimsNode.setDimensions(result, resize == RRuntime.LOGICAL_TRUE ? pDim : dim); // Move along the old array using stride for (int i = 0; i < result.getLength(); i++) { @@ -130,7 +133,8 @@ public abstract class APerm extends RBuiltinNode { @Specialization protected RAbstractVector aPerm(RAbstractVector vector, RAbstractStringVector permVector, byte resize, @Cached("create()") RAttributeProfiles dimNamesProfile, - @Cached("create()") GetDimAttributeNode getDimsNode) { + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode) { RList dimNames = vector.getDimNames(dimNamesProfile); if (dimNames == null) { // TODO: this error is reported after IS_OF_WRONG_LENGTH in GnuR @@ -150,7 +154,7 @@ public abstract class APerm extends RBuiltinNode { } // Note: if this turns out to be slow, we can cache the permutation - return aPerm(vector, RDataFactory.createIntVector(perm, true), resize, getDimsNode); + return aPerm(vector, RDataFactory.createIntVector(perm, true), resize, getDimsNode, setDimsNode); } private static int[] getReverse(int[] dim) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java index 28a3e5cd648b4679148037ac0d0fae5e82059078..853a071cb5cb0218d803cb97f519d208c62ec607 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java @@ -37,6 +37,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode; @@ -171,7 +172,7 @@ public abstract class Bind extends RBaseNode { } } - private Object bindInternal(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, CastNode castNode, boolean needsVectorCast) { + private Object bindInternal(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, CastNode castNode, boolean needsVectorCast, SetDimAttributeNode setDimNode) { ArgumentsSignature signature = promiseArgs.getSignature(); String[] vecNames = nullNamesProfile.profile(signature.getNonNullCount() == 0) ? null : new String[signature.getLength()]; RAbstractVector[] vectors = new RAbstractVector[args.length]; @@ -227,46 +228,52 @@ public abstract class Bind extends RBaseNode { } } if (type == BindType.cbind) { - return genericCBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel); + return genericCBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel, setDimNode); } else { - return genericRBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel); + return genericRBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel, setDimNode); } } @Specialization(guards = {"precedence == LOGICAL_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allLogical(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastLogicalNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastLogicalNode cast, + @Cached("create()") SetDimAttributeNode setDimNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode); } @Specialization(guards = {"precedence == INT_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allInt(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastIntegerNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastIntegerNode cast, + @Cached("create()") SetDimAttributeNode setDimNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode); } @Specialization(guards = {"precedence == DOUBLE_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allDouble(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastDoubleNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastDoubleNode cast, + @Cached("create()") SetDimAttributeNode setDimNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode); } @Specialization(guards = {"precedence == STRING_PRECEDENCE", "args.length> 1", "!isDataFrame(args)"}) protected Object allString(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastStringNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastStringNode cast, + @Cached("create()") SetDimAttributeNode setDimNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode); } @Specialization(guards = {"precedence == COMPLEX_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allComplex(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastComplexNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastComplexNode cast, + @Cached("create()") SetDimAttributeNode setDimNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode); } @Specialization(guards = {"precedence == LIST_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allList(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastListNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, false); + @Cached("create()") CastListNode cast, + @Cached("create()") SetDimAttributeNode setDimNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, false, setDimNode); } /** @@ -489,7 +496,8 @@ public abstract class Bind extends RBaseNode { return res; } - public RVector<?> genericCBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) { + public RVector<?> genericCBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel, + SetDimAttributeNode setDimNode) { int[] resultDimensions = new int[2]; int[] secondDims = new int[vectors.length]; @@ -540,7 +548,7 @@ public abstract class Bind extends RBaseNode { } Object colDimResultNames = allColDimNamesNull ? RNull.instance : RDataFactory.createStringVector(colDimNamesArray, vecNamesComplete); - result.setDimensions(resultDimensions); + setDimNode.setDimensions(result, resultDimensions); result.setDimNames(RDataFactory.createList(new Object[]{rowDimResultNames, colDimResultNames})); return result; } @@ -570,7 +578,8 @@ public abstract class Bind extends RBaseNode { } } - public RVector<?> genericRBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) { + public RVector<?> genericRBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel, + SetDimAttributeNode setDimNode) { int[] resultDimensions = new int[2]; int[] firstDims = new int[vectors.length]; @@ -625,7 +634,7 @@ public abstract class Bind extends RBaseNode { } Object rowDimResultNames = allRowDimNamesNull ? RNull.instance : RDataFactory.createStringVector(rowDimNamesArray, vecNamesComplete); - result.setDimensions(resultDimensions); + setDimNode.setDimensions(result, resultDimensions); result.setDimNames(RDataFactory.createList(new Object[]{rowDimResultNames, colDimResultNames})); return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java index e5e26a5b22a1c7c348fa222a89e21828b2a2a377..9f291c1c2e8ce95c266b1a527d213a0bc696c641 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java @@ -478,10 +478,9 @@ public abstract class Combine extends RBuiltinNode { result.initAttributes(RAttributesLayout.createNames(vecNames)); result.setInternalNames(vecNames); } else { - RList dimNames = materialized.getInternalDimNames(); + RList dimNames = materialized.getDimNames(); if (hasDimNamesProfile.profile(dimNames != null)) { - result.initAttributes(RAttributesLayout.createDimNames(vecNames)); - result.setInternalDimNames(dimNames); + result.initAttributes(RAttributesLayout.createDimNames(dimNames)); } } return result; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java index e31f75656d5eb43a0ca4d37666f818a7de86e739..0ff9a4a4b01e3264fd6c35ddf61e0ea5c546deae 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java @@ -30,6 +30,7 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; @@ -49,7 +50,9 @@ public abstract class Drop extends RBuiltinNode { private final ConditionProfile noDimNamesProfile = ConditionProfile.createBinaryProfile(); @Specialization - protected RAbstractVector doDrop(RAbstractVector x, @Cached("create()") GetDimAttributeNode getDimsNode) { + protected RAbstractVector doDrop(RAbstractVector x, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode) { int[] dims = getDimsNode.getDimensions(x); if (nullDimensions.profile(dims == null)) { return x; @@ -69,7 +72,7 @@ public abstract class Drop extends RBuiltinNode { if (resultIsScalarProfile.profile(lastNonOneIndex == -1)) { @SuppressWarnings("unused") RAbstractVector r = x.copy(); - x.setDimensions(null); + setDimsNode.setDimensions(x, null); x.setDimNames(null); x.setNames(null); return x; @@ -77,7 +80,7 @@ public abstract class Drop extends RBuiltinNode { // the result is vector if (resultIsVector.profile(newDimsLength <= 1)) { - return toVector(x, lastNonOneIndex); + return toVector(x, lastNonOneIndex, setDimsNode); } // else: the result will be a matrix, copy non-1 dimensions @@ -90,7 +93,7 @@ public abstract class Drop extends RBuiltinNode { } RAbstractVector result = x.copy(); - result.setDimensions(newDims); + setDimsNode.setDimensions(result, newDims); // if necessary, copy corresponding dimnames RList oldDimNames = x.getDimNames(dimNamesAttrProfile); @@ -114,9 +117,9 @@ public abstract class Drop extends RBuiltinNode { * Handles the case when result is just a vector. The only catch is that we might have to copy * corresponding index from dimnames to names attribute of the new vector. */ - private RAbstractVector toVector(RAbstractVector x, int nonOneIndex) { + private RAbstractVector toVector(RAbstractVector x, int nonOneIndex, SetDimAttributeNode setDimsNode) { RAbstractVector result = x.copy(); // share? - result.setDimensions(null); + setDimsNode.setDimensions(result, null); // copy dimnames to names if possible RList dimNames = x.getDimNames(dimNamesAttrProfile); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java index 81003390bcf0aaede7fb48b504a4cb2146a7f844..5e0c81fa1dfb924c8bf73d2341115114e8247105 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java @@ -34,6 +34,7 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNode; @@ -259,7 +260,9 @@ public class LaFunctions { } @Specialization - protected RList doQr(RAbstractDoubleVector aIn, @Cached("create()") GetDimAttributeNode getDimsNode) { + protected RList doQr(RAbstractDoubleVector aIn, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode) { // This implementation is sufficient for B25 matcal-5. if (!(aIn instanceof RDoubleVector)) { RError.nyi(this, "non-real vectors not supported (yet)"); @@ -290,7 +293,7 @@ public class LaFunctions { // TODO check complete RDoubleVector ra = RDataFactory.createDoubleVector(a, RDataFactory.COMPLETE_VECTOR); // TODO check pivot - ra.setDimensions(dims); + setDimsNode.setDimensions(ra, dims); data[0] = ra; data[1] = m < n ? m : n; data[2] = RDataFactory.createDoubleVector(tau, RDataFactory.COMPLETE_VECTOR); @@ -554,7 +557,8 @@ public class LaFunctions { @Specialization protected RDoubleVector laSolve(RAbstractVector a, RDoubleVector bin, double tol, @Cached("create()") GetDimAttributeNode getADimsNode, - @Cached("create()") GetDimAttributeNode getBinDimsNode) { + @Cached("create()") GetDimAttributeNode getBinDimsNode, + @Cached("create()") SetDimAttributeNode setBDimsNode) { int[] aDims = getADimsNode.getDimensions(a); int n = aDims[0]; if (n == 0) { @@ -580,7 +584,7 @@ public class LaFunctions { } bData = new double[n * p]; b = RDataFactory.createDoubleVector(bData, RDataFactory.COMPLETE_VECTOR); - b.setDimensions(new int[]{n, p}); + setBDimsNode.setDimensions(b, new int[]{n, p}); RList binDn = bin.getDimNames(); // This is somewhat odd, but Matrix relies on dropping NULL dimnames if (aDn != null || binDn != null) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java index 359655123762e0281c039706e26d6481b4346e28..616b798d932dda8bf7da680e6fd6d137d0d66f3d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java @@ -35,6 +35,7 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.binary.BinaryMapArithmeticFunctionNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -78,6 +79,7 @@ public abstract class MatMult extends RBuiltinNode { @Child protected GetDimAttributeNode getADimsNode = GetDimAttributeNode.create(); @Child protected GetDimAttributeNode getBDimsNode = GetDimAttributeNode.create(); + @Child protected SetDimAttributeNode setDimsNode = SetDimAttributeNode.create(); protected abstract Object executeObject(Object a, Object b); @@ -97,7 +99,7 @@ public abstract class MatMult extends RBuiltinNode { int r = getBDimsNode.getDimensions(b)[1]; int c = getADimsNode.getDimensions(a)[0]; RDoubleVector result = RDataFactory.createDoubleVector(r * c); - result.setDimensions(new int[]{r, c}); + setDimsNode.setDimensions(result, new int[]{r, c}); return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java index bec8a180fab423d0887b7139cc7907743180d4a5..0895f7591631e6d7ef4c4630ecd35884c4923457 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java @@ -28,8 +28,10 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -75,7 +77,8 @@ public abstract class Matrix extends RBuiltinNode { } @Specialization - protected RAbstractVector matrix(RAbstractVector data, int nrow, int ncol, boolean byrow, Object dimnames, boolean missingNr, boolean missingNc) { + protected RAbstractVector matrix(RAbstractVector data, int nrow, int ncol, boolean byrow, Object dimnames, boolean missingNr, boolean missingNc, + @Cached("create()") SetDimAttributeNode setDimNode) { int[] dim; if (byrowProfile.profile(byrow)) { dim = computeDimByRow(data.getLength(), nrow, ncol, missingNr, missingNc); @@ -99,7 +102,7 @@ public abstract class Matrix extends RBuiltinNode { } } else { res = data.createEmptySameType(0, RDataFactory.COMPLETE_VECTOR); - res.setDimensions(dim); + setDimNode.setDimensions(res, dim); } } else { res = data.copyResizedWithDimensions(dim, false); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java index 2d936337b0bc60b2ab1a52ec21a3f8db25a27733..44cf8ad8d2579c37b58b8e58e41fb01f3511be54 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java @@ -103,7 +103,6 @@ public abstract class Transpose extends RBuiltinNode { hasDimNamesProfile.enter(); assert dimNames.getLength() == 2; RList newDimNames = RDataFactory.createList(new Object[]{dimNames.getDataAt(1), dimNames.getDataAt(0)}); - r.setInternalDimNames(newDimNames); putDimNames.execute(r.getAttributes(), newDimNames); } return r; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java index f1fcfd5dc4d34b48cc357681924abb28a819d7dd..5e3750bbf11b644378488edf21e0d8161e38f016 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java @@ -31,11 +31,13 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetRowNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; @@ -72,6 +74,7 @@ public abstract class UpdateAttr extends RBuiltinNode { @Child private SetClassAttributeNode setClassAttrNode; @Child private SetRowNamesAttributeNode setRowNamesAttrNode; @Child private SetAttributeNode setGenAttrNode; + @Child private SetDimAttributeNode setDimNode; @CompilationFinal private String cachedName = ""; @CompilationFinal private String cachedInternedName = ""; @@ -144,7 +147,11 @@ public abstract class UpdateAttr extends RBuiltinNode { RAbstractContainer result = (RAbstractContainer) container.getNonShared(); // the name is interned, so identity comparison is sufficient if (internedName == RRuntime.DIM_ATTR_KEY) { - result.setDimensions(null); + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + setDimNode.setDimensions(result, null); } else if (internedName == RRuntime.NAMES_ATTR_KEY) { return updateNames(result, value); } else if (internedName == RRuntime.DIMNAMES_ATTR_KEY) { @@ -186,7 +193,11 @@ public abstract class UpdateAttr extends RBuiltinNode { errorProfile.enter(); throw RError.error(this, RError.Message.LENGTH_ZERO_DIM_INVALID); } - result.setDimensions(dimsVector.materialize().getDataCopy()); + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + setDimNode.setDimensions(result, dimsVector.materialize().getDataCopy()); } else if (internedName == RRuntime.NAMES_ATTR_KEY) { return updateNames(result, value); } else if (internedName == RRuntime.DIMNAMES_ATTR_KEY) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java index 744664502bc6512cc64e74509f98b5f846dd6d30..fd24c7fe3a85441890ec618d965dc8f2e03c3c3c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java @@ -34,6 +34,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; @@ -64,6 +65,7 @@ public abstract class UpdateAttributes extends RBuiltinNode { @Child private CastIntegerNode castInteger; @Child private CastToVectorNode castVector; @Child private SetAttributeNode setAttrNode; + @Child private SetDimAttributeNode setDimNode; @Override protected void createCasts(CastBuilder casts) { @@ -165,14 +167,20 @@ public abstract class UpdateAttributes extends RBuiltinNode { Object value = sourceList.getDataAt(i); String attrName = listNames.getDataAt(i); if (attrName.equals(RRuntime.DIM_ATTR_KEY)) { + + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + if (value == RNull.instance) { - result.setDimensions(null); + setDimNode.setDimensions(result, null); } else { RAbstractIntVector dimsVector = castInteger(castVector(value)); if (dimsVector.getLength() == 0) { throw RError.error(this, RError.Message.LENGTH_ZERO_DIM_INVALID); } - result.setDimensions(dimsVector.materialize().getDataCopy()); + setDimNode.setDimensions(result, dimsVector.materialize().getDataCopy()); } } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java index 319577028597641d7bd356acd485e0de78775405..c3b2751c16f81a39f79d6ec6590064f2d2a9bdb8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java @@ -70,7 +70,6 @@ public abstract class UpdateDim extends RBuiltinNode { RVector.verifyDimensions(vector.getLength(), dimsData, this); RVector<?> result = ((RAbstractVector) reuse.execute(vector)).materialize(); result.setInternalNames(null); - result.setInternalDimNames(null); DynamicObject attrs = result.getAttributes(); if (initAttrProfile.profile(attrs == null)) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java index ace3e951b770935861cfca0502a8f5fcaeac013b..160eb65328e509c85b9380e7359ee9344d4be57f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java @@ -97,15 +97,7 @@ public abstract class UpdateDimNames extends RBuiltinNode { protected RAbstractContainer updateDimnamesNull(RAbstractContainer container, @SuppressWarnings("unused") RNull list, // @Cached("createDimNames()") RemoveFixedAttributeNode remove) { RAbstractContainer result = (RAbstractContainer) container.getNonShared(); - if (isRVectorProfile.profile(container instanceof RVector)) { - RVector<?> vector = (RVector<?>) result; - if (vector.getInternalDimNames() != null) { - vector.setInternalDimNames(null); - remove.execute(vector.getAttributes()); - } - } else { - result.setDimNames(null); - } + remove.execute(result); return result; } @@ -179,7 +171,6 @@ public abstract class UpdateDimNames extends RBuiltinNode { attrSetter.execute(vector.getAttributes(), resDimNames); } resDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; - vector.setInternalDimNames(resDimNames); } else { container.setDimNames(newDimNames); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java index 2fdba2452bbd296c15841f87e7aead60fb576a88..305c602cad205fd89e0b3520f7dad06a9aa0a6ce 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java @@ -29,9 +29,11 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.Lapply.LapplyInternalNode; @@ -90,6 +92,7 @@ public abstract class VApply extends RBuiltinNode { @Child private CastIntegerNode castInteger; @Child private CastLogicalNode castLogical; @Child private CastStringNode castString; + @Child private SetDimAttributeNode setDimNode; @Override protected void createCasts(CastBuilder casts) { @@ -186,7 +189,11 @@ public abstract class VApply extends RBuiltinNode { } if (dimsProfile.profile(funValueVecLen > 1)) { - result.setDimensions(new int[]{funValueVecLen, applyResult.length}); + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + setDimNode.setDimensions(result, new int[]{funValueVecLen, applyResult.length}); } // TODO: handle names in case of matrices diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java index 5e15b1beafcee1c2817788f538d1cbca51dd7a33..56c7b015c27af255525f77ad8961c7faea4a033c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java @@ -46,7 +46,7 @@ final class ExpressionPrinter extends AbstractValuePrinter<RExpression> { valPrintCtx.parameters().setSuppressIndexLabels(true); out.print("expression("); - RStringVector names = (RStringVector) expr.getAttr(RRuntime.NAMES_ATTR_KEY); + RStringVector names = expr.getNames(); for (int i = 0; i < expr.getLength(); i++) { if (i != 0) { out.print(", "); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java index cf6378f2f601ac71a5c613e9fb4146d3ac127e5f..62a994e753e86d30a52158f32994a1dbba4891ae 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java @@ -24,6 +24,7 @@ import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RLanguage; @@ -43,6 +44,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { static final ListPrinter INSTANCE = new ListPrinter(); + private static final RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); private ListPrinter() { // singleton @@ -168,7 +170,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { int ns = s.getLength(); RAbstractStringVector names; - names = Utils.castTo(RRuntime.asAbstractVector(s.getAttr(RRuntime.NAMES_ATTR_KEY))); + names = Utils.castTo(RRuntime.asAbstractVector(s.getNames(dummyAttrProfiles))); if (ns > 0) { int npr = (ns <= pp.getMax() + 1) ? ns : pp.getMax(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java index 3167f0062c999d7e372a005dd4461eeb15869e1e..5577dd7c283cd4f934d3edcdee26c1a71687af24 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java @@ -80,7 +80,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri if (dims.getLength() == 1) { RList t = Utils.<RList> castTo(vector.getAttr(RRuntime.DIMNAMES_ATTR_KEY)); if (t != null && t.getDataAt(0) != null) { - RAbstractStringVector nn = Utils.castTo(RRuntime.asAbstractVector(t.getAttr(RRuntime.NAMES_ATTR_KEY))); + RAbstractStringVector nn = Utils.castTo(RRuntime.asAbstractVector(t.getNames())); if (nn != null) { title = nn.getDataAt(0); @@ -685,7 +685,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri } else { rl = getDimNamesAt(0); cl = getDimNamesAt(1); - axisNames = Utils.<RAbstractStringVector> castTo(dimnames.getAttr(RRuntime.NAMES_ATTR_KEY)); + axisNames = Utils.<RAbstractStringVector> castTo(dimnames.getNames()); if (axisNames == null) { rn = null; cn = null; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java index b81069298c0f33afa77acd3a240c2e86f059c492..805339e2673281bc6819bc4d3cc10b1d08f18946 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java @@ -33,6 +33,7 @@ import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.access.vector.CachedExtractVectorNodeFactory.SetNamesNodeGen; import com.oracle.truffle.r.nodes.access.vector.PositionsCheckNode.PositionProfile; import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.profile.AlwaysOnBranchProfile; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -279,6 +280,8 @@ final class CachedExtractVectorNode extends CachedVectorNode { private final ConditionProfile originalDimNamesPRofile = ConditionProfile.createBinaryProfile(); private final ConditionProfile foundNamesProfile = ConditionProfile.createBinaryProfile(); + @Child private SetDimAttributeNode setDimNode; + @ExplodeLoop private void applyDimensions(RAbstractContainer originalTarget, RVector<?> extractedTarget, int extractedTargetLength, PositionProfile[] positionProfile, Object[] positions) { // TODO speculate on the number of counted dimensions @@ -325,7 +328,13 @@ final class CachedExtractVectorNode extends CachedVectorNode { if (resultHasDimensions.profile(dimCount > 1)) { metadataApplied.enter(); - extractedTarget.setDimensions(newDimensions); + + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + + setDimNode.setDimensions(extractedTarget, newDimensions); if (newDimNames != null) { extractedTarget.setDimNames(RDataFactory.createList(newDimNames, newDimNamesNames == null ? null : RDataFactory.createStringVector(newDimNamesNames, originalDimNames.isComplete()))); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java index 088dcd2711c487ae188cc1119e8d3236ec366253..62fb60138bb7ae74e342c352b7970c34f5b786c2 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java @@ -153,7 +153,6 @@ public abstract class CopyAttributesNode extends RBaseNode { if (hasAttributes.profile(attributes != null)) { removeDim.execute(attributes); removeDimNames.execute(attributes); - result.setInternalDimNames(null); } RStringVector vecNames = left.getNames(attrLeftProfiles); @@ -187,7 +186,6 @@ public abstract class CopyAttributesNode extends RBaseNode { putDimNames.execute(result.getAttributes(), newDimNames); newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; - result.setInternalDimNames(newDimNames); return result; } if (result != right) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java index 4fd0e9cba05925452c34a0f4fdabb55c1502ac75..cfea85e1806d90b5dc4bddd2edca27daf0d8b244 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java @@ -32,7 +32,9 @@ import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetClassAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributeStorage; @@ -52,11 +54,15 @@ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode { } public static GetFixedAttributeNode create(String name) { - return GetFixedAttributeNodeGen.create(name); + if (SpecialAttributesFunctions.IsSpecialAttributeNode.isSpecialAttribute(name)) { + return SpecialAttributesFunctions.createGetSpecialAttributeNode(name); + } else { + return GetFixedAttributeNodeGen.create(name); + } } public static GetFixedAttributeNode createNames() { - return GetFixedAttributeNode.create(RRuntime.NAMES_ATTR_KEY); + return GetNamesAttributeNode.create(); } public static GetDimAttributeNode createDim() { @@ -64,7 +70,7 @@ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode { } public static GetFixedAttributeNode createClass() { - return GetFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); + return GetClassAttributeNode.create(); } public abstract Object execute(Object attr); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java index 1b7ed881a0436f587d0587a99227c258e100467e..93561001034cd3559fefbd1e64295c5d884d9496 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java @@ -23,9 +23,18 @@ package com.oracle.truffle.r.nodes.attributes; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; -import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.RemoveClassAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.RemoveDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.RemoveDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.RemoveNamesAttributeNode; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode { @@ -34,30 +43,55 @@ public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode } public static RemoveFixedAttributeNode create(String name) { - return RemoveFixedAttributeNodeGen.create(name); + if (SpecialAttributesFunctions.IsSpecialAttributeNode.isSpecialAttribute(name)) { + return SpecialAttributesFunctions.createRemoveSpecialAttributeNode(name); + } else { + return RemoveFixedAttributeNodeGen.create(name); + } } public static RemoveFixedAttributeNode createNames() { - return RemoveFixedAttributeNode.create(RRuntime.NAMES_ATTR_KEY); + return RemoveNamesAttributeNode.create(); } public static RemoveFixedAttributeNode createDim() { - return RemoveFixedAttributeNode.create(RRuntime.DIM_ATTR_KEY); + return RemoveDimAttributeNode.create(); } public static RemoveFixedAttributeNode createDimNames() { - return RemoveFixedAttributeNode.create(RRuntime.DIMNAMES_ATTR_KEY); + return RemoveDimNamesAttributeNode.create(); } public static RemoveFixedAttributeNode createClass() { - return RemoveFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); + return RemoveClassAttributeNode.create(); } - public abstract void execute(DynamicObject attrs); + public abstract void execute(Object attrs); @Specialization @TruffleBoundary protected void removeAttrFallback(DynamicObject attrs) { attrs.delete(this.name); } + + @Specialization + protected void removeAttrFromAttributable(RAttributable x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + return; + } + + removeAttrFallback(attributes); + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java index c09d2d58bc5897e4be6d3db446a096b77f9f1fa8..aecd9e3c0fc95b1f2f6cdb3c2bb80e3c5ff862da 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java @@ -32,8 +32,11 @@ import com.oracle.truffle.api.object.IncompatibleLocationException; import com.oracle.truffle.api.object.Location; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; /** * This node is responsible for setting a value to an arbitrary attribute. It accepts both @@ -116,7 +119,7 @@ public abstract class SetAttributeNode extends AttributeAccessNode { } protected static SpecialAttributesFunctions.SetSpecialAttributeNode createSpecAttrNode(String name) { - return SpecialAttributesFunctions.createSpecialAttributeNode(name); + return SpecialAttributesFunctions.createSetSpecialAttributeNode(name); } @Specialization(limit = "3", // @@ -143,8 +146,16 @@ public abstract class SetAttributeNode extends AttributeAccessNode { @Specialization protected void setAttrInAttributable(RAttributable x, String name, Object value, - @Cached("create()") BranchProfile attrNullProfile) { - DynamicObject attributes = x.getAttributes(); + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + if (attributes == null) { attrNullProfile.enter(); attributes = x.initAttributes(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java index 95f995a5481e993130e435e63cb367d8c5df0a15..1b1477258b980a07db9bec92b44c427a04247b4f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java @@ -32,10 +32,12 @@ import com.oracle.truffle.api.object.IncompatibleLocationException; import com.oracle.truffle.api.object.Location; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetSpecialAttributeNode; import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; /** * This node is responsible for setting a value to the predefined (fixed) attribute. It accepts both @@ -52,31 +54,32 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { @Child private SetFixedAttributeNode recursive; @Child private SetSpecialAttributeNode setSpecialAttrNode; - private final boolean isSpecialAttribute; - protected SetFixedAttributeNode(String name) { super(name); - this.isSpecialAttribute = SpecialAttributesFunctions.IsSpecialAttributeNode.isSpecialAttribute(name); } public static SetFixedAttributeNode create(String name) { - return SetFixedAttributeNodeGen.create(name); + if (SpecialAttributesFunctions.IsSpecialAttributeNode.isSpecialAttribute(name)) { + return SpecialAttributesFunctions.createSetSpecialAttributeNode(name); + } else { + return SetFixedAttributeNodeGen.create(name); + } } public static SetFixedAttributeNode createNames() { - return SetFixedAttributeNode.create(RRuntime.NAMES_ATTR_KEY); + return SpecialAttributesFunctions.SetNamesAttributeNode.create(); } public static SetFixedAttributeNode createDim() { - return SetFixedAttributeNode.create(RRuntime.DIM_ATTR_KEY); + return SpecialAttributesFunctions.SetDimAttributeNode.create(); } public static SetFixedAttributeNode createDimNames() { - return SetFixedAttributeNode.create(RRuntime.DIMNAMES_ATTR_KEY); + return SpecialAttributesFunctions.SetDimNamesAttributeNode.create(); } public static SetFixedAttributeNode createClass() { - return SetFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); + return SpecialAttributesFunctions.SetClassAttributeNode.create(); } public abstract void execute(Object attr, Object value); @@ -121,27 +124,26 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { @Specialization protected void setAttrInAttributable(RAttributable x, Object value, - @Cached("create()") BranchProfile attrNullProfile) { - if (isSpecialAttribute) { - if (setSpecialAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - setSpecialAttrNode = insert(SpecialAttributesFunctions.createSpecialAttributeNode(name)); - } - setSpecialAttrNode.execute(x, value); + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); } else { - DynamicObject attributes = x.getAttributes(); - if (attributes == null) { - attrNullProfile.enter(); - attributes = x.initAttributes(); - } - - if (recursive == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - recursive = insert(create(name)); - } - recursive.execute(attributes, value); + attributes = xTypeProfile.profile(x).getAttributes(); } + if (attributes == null) { + attrNullProfile.enter(); + attributes = x.initAttributes(); + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create(name)); + } + recursive.execute(attributes, value); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java index 241be5a0e6f5b3514285efe7990f335b677a99a2..ea270ac4e7452bfedc3b214b84b19cf8b9058ec0 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java @@ -28,12 +28,14 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctionsFactory.GetDimAttributeNodeGen; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RInteger; import com.oracle.truffle.r.runtime.data.RList; @@ -164,12 +166,12 @@ public final class SpecialAttributesFunctions { } /** - * A factory method for creating a node handling the given special attribute. + * A factory method for creating a node setting the given special attribute. * * @param name the special attribute name * @return the node */ - public static SetSpecialAttributeNode createSpecialAttributeNode(String name) { + public static SetSpecialAttributeNode createSetSpecialAttributeNode(String name) { assert name.intern() == name; if (name == RRuntime.NAMES_ATTR_KEY) { return SetNamesAttributeNode.create(); @@ -186,22 +188,108 @@ public final class SpecialAttributesFunctions { } } + /** + * A factory method for creating a node removing the given special attribute. + * + * @param name the special attribute name + * @return the node + */ + public static RemoveSpecialAttributeNode createRemoveSpecialAttributeNode(String name) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + return RemoveNamesAttributeNode.create(); + } else if (name == RRuntime.DIM_ATTR_KEY) { + return RemoveDimAttributeNode.create(); + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + return RemoveDimNamesAttributeNode.create(); + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + return RemoveRowNamesAttributeNode.create(); + } else if (name == RRuntime.CLASS_ATTR_KEY) { + return RemoveClassAttributeNode.create(); + } else { + throw RInternalError.shouldNotReachHere(); + } + } + + /** + * A factory method for creating a node retrieving the given special attribute. + * + * @param name the special attribute name + * @return the node + */ + public static GetFixedAttributeNode createGetSpecialAttributeNode(String name) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + return GetNamesAttributeNode.create(); + } else if (name == RRuntime.DIM_ATTR_KEY) { + return GetDimAttributeNode.create(); + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + return GetDimNamesAttributeNode.create(); + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + return GetRowNamesAttributeNode.create(); + } else if (name == RRuntime.CLASS_ATTR_KEY) { + return GetClassAttributeNode.create(); + } else { + throw RInternalError.shouldNotReachHere(); + } + } + /** * The base class for the nodes setting values to special attributes. */ - public abstract static class SetSpecialAttributeNode extends RBaseNode { + public abstract static class SetSpecialAttributeNode extends SetFixedAttributeNode { + + protected SetSpecialAttributeNode(String name) { + super(name); + } public abstract void execute(RAttributable x, Object attrValue); } + /** + * The base class for the nodes removing values from special attributes. + */ + public abstract static class RemoveSpecialAttributeNode extends RemoveFixedAttributeNode { + + protected RemoveSpecialAttributeNode(String name) { + super(name); + } + + public abstract void execute(RAttributable x); + + @Specialization(insertBefore = "removeAttrFromAttributable") + protected void removeAttrFromVector(RVector<?> x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("create()") BranchProfile attrEmptyProfile) { + DynamicObject attributes = x.getAttributes(); + if (attributes == null) { + attrNullProfile.enter(); + return; + } + + attrNullProfile.enter(); + attributes.delete(name); + + if (attributes.isEmpty()) { + attrEmptyProfile.enter(); + x.initAttributes(null); + } + } + + } + public abstract static class SetNamesAttributeNode extends SetSpecialAttributeNode { + protected SetNamesAttributeNode() { + super(RRuntime.NAMES_ATTR_KEY); + } + public static SetNamesAttributeNode create() { return SpecialAttributesFunctionsFactory.SetNamesAttributeNodeGen.create(); } - @Specialization + @Specialization(insertBefore = "setAttrInAttributable") protected void setNamesInContainer(RAbstractContainer x, RStringVector names, @Cached("createClassProfile()") ValueProfile contClassProfile) { RAbstractContainer xProfiled = contClassProfile.profile(x); @@ -209,41 +297,162 @@ public final class SpecialAttributesFunctions { } } + public abstract static class RemoveNamesAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveNamesAttributeNode() { + super(RRuntime.NAMES_ATTR_KEY); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + + public static RemoveNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveNamesAttributeNodeGen.create(); + } + } + + public abstract static class GetNamesAttributeNode extends GetFixedAttributeNode { + + protected GetNamesAttributeNode() { + super(RRuntime.NAMES_ATTR_KEY); + } + + public static GetNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.GetNamesAttributeNodeGen.create(); + } + + @Override + @Specialization(contains = "getAttrCached") + protected Object getAttrFallback(DynamicObject attrs) { + return super.getAttrFallback(attrs); + } + + } + public abstract static class SetDimAttributeNode extends SetSpecialAttributeNode { + private final ConditionProfile nullDimProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile naDimProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile negativeDimProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile dimNotMatchLengthProfile = ConditionProfile.createBinaryProfile(); + private final ValueProfile contArgClassProfile = ValueProfile.createClassProfile(); + private final ValueProfile dimArgClassProfile = ValueProfile.createClassProfile(); + private final LoopConditionProfile verifyLoopProfile = LoopConditionProfile.createCountingProfile(); + + protected SetDimAttributeNode() { + super(RRuntime.DIM_ATTR_KEY); + } + public static SetDimAttributeNode create() { return SpecialAttributesFunctionsFactory.SetDimAttributeNodeGen.create(); } - @Specialization - protected void setOneDimInContainer(RAbstractContainer x, Integer dim, - @Cached("createClassProfile()") ValueProfile contClassProfile, - @Cached("createBinaryProfile()") ConditionProfile vectorProfile) { - int[] dims = new int[]{dim}; - if (vectorProfile.profile(x instanceof RVector)) { - ((RVector<?>) x).setDimensions(dims); + public void setDimensions(RAbstractContainer x, int[] dims) { + if (nullDimProfile.profile(dims == null)) { + execute(x, RNull.instance); } else { - RAbstractContainer xProfiled = contClassProfile.profile(x); - xProfiled.setDimensions(dims); + execute(x, RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR)); } + } + @Specialization(insertBefore = "setAttrInAttributable") + protected void resetDims(RAbstractContainer x, @SuppressWarnings("unused") RNull rnull, + @Cached("create()") RemoveDimAttributeNode removeDimAttrNode, + @Cached("createBinaryProfile()") ConditionProfile vectorClassProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + removeDimAttrNode.execute(x); + if (vectorClassProfile.profile(x instanceof RVector)) { + ((RVector<?>) x).setDimNames(null); + } else { + xTypeProfile.profile(x).setDimNames(null); + } } - @Specialization - protected void setDimsInContainer(RAbstractContainer x, RAbstractIntVector dims, - @Cached("createClassProfile()") ValueProfile contClassProfile, - @Cached("createBinaryProfile()") ConditionProfile vectorProfile) { + @Specialization(insertBefore = "setAttrInAttributable") + protected void setOneDimInVector(RVector<?> x, int dim, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + int[] dims = new int[]{dim}; + verifyOneDimensions(x.getLength(), dim); + super.setAttrInAttributable(x, RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR), attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setDimsInVector(RVector<?> x, RAbstractIntVector dims, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + RAbstractContainer xProfiled = contArgClassProfile.profile(x); + verifyDimensions(xProfiled.getLength(), dims); + super.setAttrInAttributable(x, dims, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setDimsInContainerFallback(RAbstractContainer x, RAbstractIntVector dims, + @Cached("create()") SetDimAttributeNode setDimNode) { int[] dimsArr = dims.materialize().getDataCopy(); - if (vectorProfile.profile(x instanceof RVector)) { - ((RVector<?>) x).setDimensions(dimsArr); - } else { - RAbstractContainer xProfiled = contClassProfile.profile(x); - xProfiled.setDimensions(dimsArr); + setDimNode.setDimensions(x, dimsArr); + } + + private void verifyOneDimensions(int vectorLength, int dim) { + int length = dim; + if (naDimProfile.profile(RRuntime.isNA(dim))) { + throw RError.error(this, RError.Message.DIMS_CONTAIN_NA); + } else if (negativeDimProfile.profile(dim < 0)) { + throw RError.error(this, RError.Message.DIMS_CONTAIN_NEGATIVE_VALUES); + } + if (dimNotMatchLengthProfile.profile(length != vectorLength && vectorLength > 0)) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, RError.Message.DIMS_DONT_MATCH_LENGTH, length, vectorLength); + } + } + + public void verifyDimensions(int vectorLength, RAbstractIntVector dims) { + RAbstractIntVector dimsProfiled = dimArgClassProfile.profile(dims); + int dimLen = dims.getLength(); + verifyLoopProfile.profileCounted(dimLen); + int length = 1; + for (int i = 0; i < dimLen; i++) { + int dim = dimsProfiled.getDataAt(i); + if (naDimProfile.profile(RRuntime.isNA(dim))) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, RError.Message.DIMS_CONTAIN_NA); + } else if (negativeDimProfile.profile(dim < 0)) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, RError.Message.DIMS_CONTAIN_NEGATIVE_VALUES); + } + length *= dim; + } + if (length != vectorLength && vectorLength > 0) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, RError.Message.DIMS_DONT_MATCH_LENGTH, length, vectorLength); } } } + public abstract static class RemoveDimAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveDimAttributeNode() { + super(RRuntime.DIM_ATTR_KEY); + } + + public static RemoveDimAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveDimAttributeNodeGen.create(); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + + } + public abstract static class GetDimAttributeNode extends GetFixedAttributeNode { private final ConditionProfile nullDimsProfile = ConditionProfile.createBinaryProfile(); @@ -300,11 +509,79 @@ public final class SpecialAttributesFunctions { public abstract static class SetDimNamesAttributeNode extends SetSpecialAttributeNode { + private final ConditionProfile nullDimNamesProfile = ConditionProfile.createBinaryProfile(); + + protected SetDimNamesAttributeNode() { + super(RRuntime.DIMNAMES_ATTR_KEY); + } + public static SetDimNamesAttributeNode create() { return SpecialAttributesFunctionsFactory.SetDimNamesAttributeNodeGen.create(); } - @Specialization + public void setDimNames(RAbstractContainer x, RList dimNames) { + if (nullDimNamesProfile.profile(dimNames == null)) { + execute(x, RNull.instance); + } else { + execute(x, dimNames); + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void resetDimNames(RAbstractContainer x, @SuppressWarnings("unused") RNull rnull, + @Cached("create()") RemoveDimNamesAttributeNode removeDimNamesAttrNode) { +// removeDimNamesAttrNode.execute(x); + x.setDimNames(null); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setDimNamesInVector(RVector<?> x, RList newDimNames, + @Cached("create()") GetDimAttributeNode getDimNode, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + x.setDimNames(newDimNames); +// int[] dimensions = getDimNode.getDimensions(x); +// if (dimensions == null) { +// throw RError.error(this, RError.Message.DIMNAMES_NONARRAY); +// } +// int newDimNamesLength = newDimNames.getLength(); +// if (newDimNamesLength > dimensions.length) { +// throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_DIMS, newDimNamesLength, +// dimensions.length); +// } +// for (int i = 0; i < newDimNamesLength; i++) { +// Object dimObject = newDimNames.getDataAt(i); +// if (dimObject != RNull.instance) { +// if (dimObject instanceof String) { +// if (dimensions[i] != 1) { +// throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_EXTENT, i + 1); +// } +// } else { +// RStringVector dimVector = (RStringVector) dimObject; +// if (dimVector == null) { +// newDimNames.updateDataAt(i, RNull.instance, null); +// } else if (dimVector.getLength() != dimensions[i]) { +// throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_EXTENT, i + 1); +// } +// } +// } +// } +// +// RList resDimNames = newDimNames; +// if (newDimNamesLength < dimensions.length) { +// // resize the array and fill the missing entries with NULL-s +// resDimNames = (RList) resDimNames.copyResized(dimensions.length, true); +// resDimNames.setAttributes(newDimNames); +// for (int i = newDimNamesLength; i < dimensions.length; i++) { +// resDimNames.updateDataAt(i, RNull.instance, null); +// } +// } +// resDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; +// super.setAttrInAttributable(x, newDimNames, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "setAttrInAttributable") protected void setDimNamesInContainer(RAbstractContainer x, RList dimNames, @Cached("createClassProfile()") ValueProfile contClassProfile) { RAbstractContainer xProfiled = contClassProfile.profile(x); xProfiled.setDimNames(dimNames); @@ -312,13 +589,56 @@ public final class SpecialAttributesFunctions { } + public abstract static class RemoveDimNamesAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveDimNamesAttributeNode() { + super(RRuntime.DIMNAMES_ATTR_KEY); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + + public static RemoveDimNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveDimNamesAttributeNodeGen.create(); + } + } + + public abstract static class GetDimNamesAttributeNode extends GetFixedAttributeNode { + + protected GetDimNamesAttributeNode() { + super(RRuntime.DIMNAMES_ATTR_KEY); + } + + public static GetDimNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.GetDimNamesAttributeNodeGen.create(); + } + + public final RList getDimNames(Object x) { + return (RList) execute(x); + } + + @Override + @Specialization(contains = "getAttrCached") + protected Object getAttrFallback(DynamicObject attrs) { + return super.getAttrFallback(attrs); + } + + } + public abstract static class SetRowNamesAttributeNode extends SetSpecialAttributeNode { + protected SetRowNamesAttributeNode() { + super(RRuntime.ROWNAMES_ATTR_KEY); + } + public static SetRowNamesAttributeNode create() { return SpecialAttributesFunctionsFactory.SetRowNamesAttributeNodeGen.create(); } - @Specialization + @Specialization(insertBefore = "setAttrInAttributable") protected void setRowNamesInContainer(RAbstractContainer x, RAbstractVector rowNames, @Cached("createClassProfile()") ValueProfile contClassProfile) { RAbstractContainer xProfiled = contClassProfile.profile(x); xProfiled.setRowNames(rowNames); @@ -326,8 +646,47 @@ public final class SpecialAttributesFunctions { } + public abstract static class RemoveRowNamesAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveRowNamesAttributeNode() { + super(RRuntime.DIMNAMES_ATTR_KEY); + } + + public static RemoveRowNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveRowNamesAttributeNodeGen.create(); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + } + + public abstract static class GetRowNamesAttributeNode extends GetFixedAttributeNode { + + protected GetRowNamesAttributeNode() { + super(RRuntime.ROWNAMES_ATTR_KEY); + } + + public static GetRowNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.GetRowNamesAttributeNodeGen.create(); + } + + @Override + @Specialization(contains = "getAttrCached") + protected Object getAttrFallback(DynamicObject attrs) { + return super.getAttrFallback(attrs); + } + + } + public abstract static class SetClassAttributeNode extends SetSpecialAttributeNode { + protected SetClassAttributeNode() { + super(RRuntime.CLASS_ATTR_KEY); + } + public static SetClassAttributeNode create() { return SpecialAttributesFunctionsFactory.SetClassAttributeNodeGen.create(); } @@ -336,7 +695,7 @@ public final class SpecialAttributesFunctions { execute(x, RNull.instance); } - @Specialization + @Specialization(insertBefore = "setAttrInAttributable") protected <T> void handleVectorNullClass(RVector<T> vector, @SuppressWarnings("unused") RNull classAttr, @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, @Cached("createClass()") SetFixedAttributeNode setClassAttrNode, @@ -346,7 +705,7 @@ public final class SpecialAttributesFunctions { handleVector(vector, null, removeClassAttrNode, setClassAttrNode, nullAttrProfile, nullClassProfile, notNullClassProfile); } - @Specialization + @Specialization(insertBefore = "setAttrInAttributable") protected <T> void handleVector(RVector<T> vector, RStringVector classAttr, @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, @Cached("createClass()") SetFixedAttributeNode setClassAttrNode, @@ -385,12 +744,12 @@ public final class SpecialAttributesFunctions { } } - @Specialization + @Specialization(insertBefore = "setAttrInAttributable") protected void handleAttributable(RAttributable x, @SuppressWarnings("unused") RNull classAttr) { x.setClassAttr(null); } - @Specialization + @Specialization(insertBefore = "setAttrInAttributable") protected void handleAttributable(RAttributable x, RStringVector classAttr) { x.setClassAttr(classAttr); } @@ -406,4 +765,40 @@ public final class SpecialAttributesFunctions { } + public abstract static class RemoveClassAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveClassAttributeNode() { + super(RRuntime.CLASS_ATTR_KEY); + } + + public static RemoveClassAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveClassAttributeNodeGen.create(); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + + } + + public abstract static class GetClassAttributeNode extends GetFixedAttributeNode { + + protected GetClassAttributeNode() { + super(RRuntime.CLASS_ATTR_KEY); + } + + public static GetClassAttributeNode create() { + return SpecialAttributesFunctionsFactory.GetClassAttributeNodeGen.create(); + } + + @Override + @Specialization(contains = "getAttrCached") + protected Object getAttrFallback(DynamicObject attrs) { + return super.getAttrFallback(attrs); + } + + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java index f695e4d9ee8677e1381cd9fed2a70f505e2fda3f..1a1f9a30a29ff7ee1df4990fa5326c50ddf0bf79 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java @@ -105,7 +105,6 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { if (attributes != null) { removeDim.execute(attributes); removeDimNames.execute(attributes); - result.setInternalDimNames(null); } RStringVector vecNames = source.getNames(attrSourceProfiles); @@ -123,7 +122,6 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { if (hasDimNames.profile(newDimNames != null)) { putDimNames.execute(result.getAttributes(), newDimNames); newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; - result.setInternalDimNames(newDimNames); return result; } return result; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java index df9aea109de8925484edd31bcfc2ecb3b21b9746..569cc6483a43ba832a05a8fbf4b1e84eb69d6de7 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java @@ -32,6 +32,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.HasFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.primitive.UnaryMapNodeFactory.MapUnaryVectorInternalNodeGen; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RInternalError; @@ -55,6 +56,7 @@ public final class UnaryMapNode extends RBaseNode { @Child private UnaryMapFunctionNode scalarNode; @Child private MapUnaryVectorInternalNode vectorNode; @Child private GetDimAttributeNode getDimNode; + @Child private SetDimAttributeNode setDimNode; // profiles private final Class<? extends RAbstractVector> operandClass; @@ -181,7 +183,14 @@ public final class UnaryMapNode extends RBaseNode { getDimNode = insert(GetDimAttributeNode.create()); } - copyAttributesInternal((RVector<?>) result, operand, getDimNode.getDimensions(operand)); + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + + setDimNode.setDimensions(result, getDimNode.getDimensions(operand)); + + copyAttributesInternal((RVector<?>) result, operand); } return result; } @@ -198,9 +207,8 @@ public final class UnaryMapNode extends RBaseNode { } @TruffleBoundary - private void copyAttributesInternal(RVector<?> result, RAbstractVector attributeSource, int[] dims) { + private void copyAttributesInternal(RVector<?> result, RAbstractVector attributeSource) { result.copyRegAttributesFrom(attributeSource); - result.setDimensions(dims); result.copyNamesFrom(attrProfiles, attributeSource); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java index 5d952237fb70f7e3aad9089653ce63df02ad65b3..41b4410eeefc2a5edc431dda001ad52366d97db9 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java @@ -60,13 +60,11 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement protected boolean complete; // "complete" means: does not contain NAs protected RStringVector names; - private RList dimNames; // cache rownames for data frames as they are accessed at every data frame access private Object rowNames; protected RVector(boolean complete, int length, int[] dimensions, RStringVector names) { this.complete = complete; - // this.dimensions = dimensions; assert names != this; this.names = names; this.rowNames = RNull.instance; @@ -83,7 +81,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement // one-dimensional arrays do not have names, only dimnames with one value RList newDimNames = RDataFactory.createList(new Object[]{names}); initAttributes(RAttributesLayout.createDimAndDimNames(dimensionsVector, newDimNames)); - this.dimNames = newDimNames; } } } else { @@ -102,6 +99,14 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } } + private RList getDimNamesFromAttrs() { + if (attributes == null) { + return null; + } else { + return (RList) attributes.get(RRuntime.DIMNAMES_ATTR_KEY); + } + } + /** * Intended for external calls where a mutable copy is needed. */ @@ -146,14 +151,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement names = newNames; } - public final RList getInternalDimNames() { - return dimNames; - } - - public final void setInternalDimNames(RList newDimNames) { - dimNames = newDimNames; - } - public final Object getInternalRowNames() { return rowNames; } @@ -183,6 +180,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement return null; } else { if (attrProfiles.attrNullNamesProfile(names == null)) { + RList dimNames = getDimNames(); if (dimNames != null && dimNames.getLength() == 1) { return (RStringVector) dimNames.getDataAt(0); } else { @@ -200,6 +198,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement */ public final RStringVector getNames() { if (names == null) { + RList dimNames = getDimNames(); if (dimNames != null && dimNames.getLength() == 1) { return (RStringVector) dimNames.getDataAt(0); } else { @@ -369,7 +368,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement RList newDimNames = RDataFactory.createList(new Object[]{newNames}); newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; putAttribute(RRuntime.DIMNAMES_ATTR_KEY, newDimNames); - this.dimNames = newDimNames; } else { putAttribute(RRuntime.NAMES_ATTR_KEY, newNames); assert newNames != this; @@ -384,7 +382,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final RList getDimNames() { - return dimNames; + return getDimNamesFromAttrs(); } /** @@ -398,7 +396,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } else { putAttribute(RRuntime.DIMNAMES_ATTR_KEY, newDimNames); } - this.dimNames = newDimNames; } @Override @@ -411,7 +408,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement private void setDimNames(RList newDimNames, RBaseNode invokingNode) { if (attributes != null && newDimNames == null) { removeAttributeMapping(RRuntime.DIMNAMES_ATTR_KEY); - this.dimNames = null; } else if (newDimNames != null) { int[] dimensions = getDimensionsFromAttrs(); if (dimensions == null) { @@ -450,7 +446,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } putAttribute(RRuntime.DIMNAMES_ATTR_KEY, resDimNames); resDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; - this.dimNames = resDimNames; } } @@ -481,10 +476,13 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @Override public final boolean hasDimensions() { - // Sync the shape return attributes == null ? false : attributes.containsKey(RRuntime.DIM_ATTR_KEY); } + public final boolean hasDimNames() { + return attributes == null ? false : attributes.containsKey(RRuntime.DIMNAMES_ATTR_KEY); + } + @Override public final boolean isMatrix() { int[] dimensions = getDimensionsFromAttrs(); @@ -573,7 +571,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement public final void setAttributes(RVector<?> result) { result.names = this.names; - result.dimNames = this.dimNames; result.rowNames = this.rowNames; if (this.attributes != null) { result.initAttributes(RAttributesLayout.copy(this.attributes)); @@ -671,7 +668,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement public final RAttributable copyAttributesFrom(RAttributeProfiles attrProfiles, RAbstractContainer vector) { // it's meant to be used on a "fresh" vector with only dimensions potentially set assert (this.names == null); - assert (this.dimNames == null); + assert (!hasDimNames()); assert (this.rowNames == RNull.instance); assert (!hasDimensions()); assert (this.attributes == null || this.attributes.size() == 0) : this.attributes.size(); @@ -680,7 +677,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement // one-dimensional array) this.names = vector.getNames(attrProfiles); } - this.dimNames = vector.getDimNames(attrProfiles); this.rowNames = vector.getRowNames(attrProfiles); DynamicObject vecAttributes = vector.getAttributes(); if (vecAttributes != null) { @@ -699,7 +695,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement if (vector.getDimensions() == null || vector.getDimensions().length != 1) { this.names = vector.getNames(); } - this.dimNames = vector.getDimNames(); this.rowNames = vector.getRowNames(); DynamicObject vecAttributes = vector.getAttributes(); if (vecAttributes != null) { @@ -713,7 +708,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement public final void copyNamesDimsDimNamesFrom(RAttributeProfiles attrProfiles, RAbstractVector vector, RBaseNode invokingNode) { // it's meant to be used on a "fresh" vector with only dimensions potentially set assert (this.names == null); - assert (this.dimNames == null); + assert (!hasDimNames()); assert (!hasDimensions()); assert (this.attributes == null); // for some reason, names is copied first, then dims, then dimnames @@ -801,7 +796,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement // whether we nullify dimensions or re-set them to a different value, names and dimNames // must be reset this.names = null; - this.dimNames = null; if (newDimensions != null) { putAttribute(RRuntime.DIM_ATTR_KEY, RDataFactory.createIntVector(newDimensions, true)); } else { @@ -817,7 +811,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @Override public final void resetAllAttributes(boolean nullify) { this.names = null; - this.dimNames = null; this.rowNames = RNull.instance; if (nullify) { this.attributes = null;