diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RListMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RListMR.java index e1b29ff4d097c17b20b90f33cd768a97bfffcf2c..d694fbe0c4a3530bf847223c4379d3ee2fccdd9f 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RListMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RListMR.java @@ -32,10 +32,10 @@ import com.oracle.truffle.r.engine.TruffleRLanguage; import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext.RCloseable; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RList; @MessageResolution(receiverType = RList.class, language = TruffleRLanguage.class) @@ -106,12 +106,12 @@ public class RListMR { @Resolve(message = "KEYS") public abstract static class RListKeysNode extends Node { @Child private Node findContext = TruffleRLanguage.INSTANCE.actuallyCreateFindContextNode(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @SuppressWarnings("try") protected Object access(RList receiver) { try (RCloseable c = RContext.withinContext(TruffleRLanguage.INSTANCE.actuallyFindContext0(findContext))) { - return receiver.getNames(attrProfiles); + return getNamesNode.getNames(receiver); } } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java index 882a6fcf1d1dd0f31aaeb091c4e7c229d3b332e4..8aca802a24be27ab35c04541f29133abeaf55720 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java @@ -39,7 +39,6 @@ import com.oracle.truffle.r.runtime.RInternalError; 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.RDataFactory; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; @@ -307,10 +306,11 @@ public class MethodsListDispatch { public abstract Object executeObject(String name, REnvironment rho, String pckg); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Child private CastToVectorNode castToVector = CastToVectorNodeGen.create(false); @Child private ClassHierarchyScalarNode classHierarchyNode = ClassHierarchyScalarNodeGen.create(); @Child private PromiseHelperNode promiseHelper; + @Child private GetFixedAttributeNode getGenericAttrNode = GetFixedAttributeNode.create(RRuntime.GENERIC_ATTR_KEY); + @Child private GetFixedAttributeNode getPckgAttrNode = GetFixedAttributeNode.create(RRuntime.PCKG_ATTR_KEY); @Specialization protected Object getGeneric(String name, REnvironment env, String pckg) { @@ -327,9 +327,9 @@ public class MethodsListDispatch { if (o != null) { RAttributable vl = (RAttributable) o; boolean ok = false; - if (vl instanceof RFunction && vl.getAttr(attrProfiles, RRuntime.GENERIC_ATTR_KEY) != null) { + if (vl instanceof RFunction && getGenericAttrNode.execute(vl) != null) { if (pckg.length() > 0) { - Object gpckgObj = vl.getAttr(attrProfiles, RRuntime.PCKG_ATTR_KEY); + Object gpckgObj = getPckgAttrNode.execute(vl); if (gpckgObj != null) { String gpckg = checkSingleString(castToVector.execute(gpckgObj), false, "The \"package\" slot in generic function object", this, classHierarchyNode); ok = pckg.equals(gpckg); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java index c2a0cb887709ca2e9ac96630f520e0923c3db8c4..9094f3e34ff8d521a8ec586a20f0686e6d561c10 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java @@ -17,7 +17,10 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; 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.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -32,6 +35,8 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class Cdist extends RExternalBuiltinNode.Arg4 { private static final NACheck naCheck = NACheck.create(); + @Child private GetFixedAttributeNode getNamesAttrNode = GetFixedAttributeNode.createNames(); + @Override protected void createCasts(CastBuilder casts) { casts.arg(0).asDoubleVector(); @@ -43,21 +48,24 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { @Specialization(guards = "method == cachedMethod") protected RDoubleVector cdist(RAbstractDoubleVector x, @SuppressWarnings("unused") int method, RList list, double p, @SuppressWarnings("unused") @Cached("method") int cachedMethod, @Cached("getMethod(method)") Method methodObj, - @Cached("create()") SetAttributeNode setAttrNode) { - int nr = RRuntime.nrows(x); - int nc = RRuntime.ncols(x); + @Cached("create()") SetAttributeNode setAttrNode, + @Cached("create()") SetClassAttributeNode setClassAttrNode, + @Cached("create()") GetDimAttributeNode getDimNode) { + int nr = getDimNode.nrows(x); + int nc = getDimNode.ncols(x); int n = nr * (nr - 1) / 2; /* avoid int overflow for N ~ 50,000 */ double[] ans = new double[n]; RDoubleVector xm = x.materialize(); rdistance(xm.getDataWithoutCopying(), nr, nc, ans, false, methodObj, p); RDoubleVector result = RDataFactory.createDoubleVector(ans, naCheck.neverSeenNA()); DynamicObject resultAttrs = result.initAttributes(); - RStringVector names = (RStringVector) list.getAttr(RRuntime.NAMES_ATTR_KEY); + + RStringVector names = (RStringVector) getNamesAttrNode.execute(list); for (int i = 0; i < names.getLength(); i++) { String name = names.getDataAt(i); Object listValue = list.getDataAt(i); if (name.equals(RRuntime.CLASS_ATTR_KEY)) { - result.setClassAttr(listValue instanceof RStringVector ? (RStringVector) listValue : RDataFactory.createStringVectorFromScalar((String) listValue)); + setClassAttrNode.execute(result, listValue instanceof RStringVector ? (RStringVector) listValue : RDataFactory.createStringVectorFromScalar((String) listValue)); } else { setAttrNode.execute(resultAttrs, name, listValue); } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java index 1aff0091ef52ff496d09f462d7c2a1fd8db2e4dd..5080206bbed26ecd787667839af2adae4bfe9f3f 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java @@ -22,6 +22,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.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -76,6 +77,8 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { private final BranchProfile error = BranchProfile.create(); private final BranchProfile warning = BranchProfile.create(); + @Child private GetDimAttributeNode getDimsNode = GetDimAttributeNode.create(); + private final LoopConditionProfile loopLength = LoopConditionProfile.createCountingProfile(); public RDoubleVector corcov(RDoubleVector x, RDoubleVector y, @SuppressWarnings("unused") int method, boolean iskendall, RBaseNode invokingNode) throws RError { @@ -175,14 +178,14 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { return ans; } - private static int ncols(RDoubleVector x) { + private int ncols(RDoubleVector x) { assert x.isMatrix(); - return x.getDimensions()[1]; + return getDimsNode.getDimensions(x)[1]; } - private static int nrows(RDoubleVector x) { + private int nrows(RDoubleVector x) { assert x.isMatrix(); - return x.getDimensions()[0]; + return getDimsNode.getDimensions(x)[0]; } private void complete1(int n, int ncx, RDoubleVector x, RIntVector ind, boolean naFail) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java index 2887c8f67d5837b4fe5f76b91940f39a199ac373..8c291da19ee516d98b50441e98361f0af40b22b1 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java @@ -10,10 +10,11 @@ */ package com.oracle.truffle.r.library.stats; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -29,7 +30,7 @@ public abstract class Cutree extends RExternalBuiltinNode.Arg2 { } @Specialization - protected RIntVector cutree(RAbstractIntVector mergeIn, RAbstractIntVector whichIn) { + protected RIntVector cutree(RAbstractIntVector mergeIn, RAbstractIntVector whichIn, @Cached("create()") GetDimAttributeNode getDimNode) { RIntVector merge = mergeIn.materialize(); RIntVector which = whichIn.materialize(); int whichLen = which.getLength(); @@ -43,7 +44,7 @@ public abstract class Cutree extends RExternalBuiltinNode.Arg2 { int mm = 0; boolean foundJ; - int n = RRuntime.nrows(merge) + 1; + int n = getDimNode.nrows(merge) + 1; /* * The C code uses 1-based indices for the next three arrays and so set the int * value * behind the actual start of the array. To keep the logic equivalent, we call adj(k) on the diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java index 01a1f747831be975f900f91e34525d9d0cc6dd20..b33d733a7cb6b25fac7190bc27dcaca9a1830b73 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java @@ -10,10 +10,11 @@ */ package com.oracle.truffle.r.library.stats; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; @@ -25,9 +26,9 @@ public abstract class DoubleCentre extends RExternalBuiltinNode.Arg1 { } @Specialization - protected RDoubleVector doubleCentre(RAbstractDoubleVector aVecAbs) { + protected RDoubleVector doubleCentre(RAbstractDoubleVector aVecAbs, @Cached("create()") GetDimAttributeNode getDimNode) { RDoubleVector aVec = aVecAbs.materialize(); - int n = RRuntime.nrows(aVec); + int n = getDimNode.nrows(aVec); double[] a = aVec.getDataWithoutCopying(); // does not copy for (int i = 0; i < n; i++) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java index 0f78a1f32eeb141cbe6370b9e7c4cde94bb49a3e..80d764515eef04f25d408662217f208623651a3e 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java @@ -43,6 +43,7 @@ public class SplineFunctions { } public abstract static class SplineEval extends RExternalBuiltinNode.Arg2 { + private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Specialization @TruffleBoundary @@ -90,7 +91,7 @@ public class SplineFunctions { /* * Periodic Spline --------------- The end conditions here match spline (and its derivatives) at * x[1] and x[n]. - * + * * Note: There is an explicit check that the user has supplied data with y[1] equal to y[n]. */ private static void periodicSpline(int n, double[] x, double[] y, double[] b, double[] c, double[] d) { @@ -207,7 +208,7 @@ public class SplineFunctions { /* * Natural Splines --------------- Here the end-conditions are determined by setting the second * derivative of the spline at the end-points to equal to zero. - * + * * There are n-2 unknowns (y[i]'' at x[2], ..., x[n-1]) and n-2 equations to determine them. * Either Choleski or Gaussian elimination could be used. */ diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java index e856fd478387c79b96ea48c676b782656aa248d3..49204b765ddbc5dee540d31c69888ec6a8c857f2 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.TreeSet; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -37,6 +38,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; public abstract class TypeConvert extends RExternalBuiltinNode.Arg5 { + @Child private SetFixedAttributeNode setLevelsAttrNode = SetFixedAttributeNode.create(RRuntime.LEVELS_ATTR_KEY); + private static boolean isNA(String s, RAbstractStringVector naStrings) { // naStrings are in addition to NA_character_ if (RRuntime.isNA(s)) { @@ -178,7 +181,7 @@ public abstract class TypeConvert extends RExternalBuiltinNode.Arg5 { } } RIntVector res = RDataFactory.createIntVector(data, complete); - res.setAttr(RRuntime.LEVELS_ATTR_KEY, RDataFactory.createStringVector(levelsArray, RDataFactory.COMPLETE_VECTOR)); + setLevelsAttrNode.execute(res, RDataFactory.createStringVector(levelsArray, RDataFactory.COMPLETE_VECTOR)); return RVector.setVectorClassAttr(res, RDataFactory.createStringVector("factor")); } } 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 472fdc3f53b299f573acac83050b028769cddef2..14a7bd1687650116a8d7b22ee82b2c5f6fa1de90 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 @@ -23,13 +23,15 @@ import com.oracle.truffle.api.dsl.Cached; 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.GetDimNamesAttributeNode; +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; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; @@ -61,10 +63,12 @@ public abstract class APerm extends RBuiltinNode { } @Specialization - protected RAbstractVector aPerm(RAbstractVector vector, @SuppressWarnings("unused") RNull permVector, byte resize) { + protected RAbstractVector aPerm(RAbstractVector vector, @SuppressWarnings("unused") RNull permVector, byte resize, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimNode) { checkErrorConditions(vector); - int[] dim = vector.getDimensions(); + int[] dim = getDimsNode.getDimensions(vector); final int diml = dim.length; RVector<?> result = vector.createEmptySameType(vector.getLength(), vector.isComplete()); @@ -74,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 @@ -101,10 +105,12 @@ public abstract class APerm extends RBuiltinNode { } @Specialization - protected RAbstractVector aPerm(RAbstractVector vector, RAbstractIntVector permVector, byte resize) { + protected RAbstractVector aPerm(RAbstractVector vector, RAbstractIntVector permVector, byte resize, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode) { checkErrorConditions(vector); - int[] dim = vector.getDimensions(); + int[] dim = getDimsNode.getDimensions(vector); int[] perm = getPermute(dim, permVector); int[] posV = new int[dim.length]; @@ -112,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++) { @@ -126,8 +132,10 @@ public abstract class APerm extends RBuiltinNode { @Specialization protected RAbstractVector aPerm(RAbstractVector vector, RAbstractStringVector permVector, byte resize, - @Cached("create()") RAttributeProfiles dimNamesProfile) { - RList dimNames = vector.getDimNames(dimNamesProfile); + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) { + RList dimNames = getDimNamesNode.getDimNames(vector); if (dimNames == null) { // TODO: this error is reported after IS_OF_WRONG_LENGTH in GnuR errorProfile.enter(); @@ -146,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); + 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/Abbrev.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abbrev.java index 7f4e8cce164aac257f239c20c70fec86743ec20c..66b265248d07db9cba90963185681d91f64c38a3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abbrev.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abbrev.java @@ -11,7 +11,8 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; @@ -20,7 +21,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @@ -29,7 +29,6 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; @RBuiltin(name = "abbreviate", kind = INTERNAL, parameterNames = {"x", "minlength", "use.classes"}, behavior = PURE) public abstract class Abbrev extends RBuiltinNode { private final NACheck naCheck = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Override public void createCasts(CastBuilder casts) { @@ -56,7 +55,7 @@ public abstract class Abbrev extends RBuiltinNode { } } RStringVector result = RDataFactory.createStringVector(data, naCheck.neverSeenNA()); - result.copyAttributesFrom(attrProfiles, x); + result.copyAttributesFrom(x); return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java index 446875d8fee0449ccf2df866acde5d3cd2edcc2c..cb65b88f22320b3eb45e95941ebca3477833382b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java @@ -30,13 +30,13 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; @@ -50,7 +50,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; public abstract class AsCall extends RBuiltinNode { private final ConditionProfile nullNamesProfile = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Specialization protected RLanguage asCallFunction(RList x) { @@ -89,12 +89,12 @@ public abstract class AsCall extends RBuiltinNode { values[i] = x.getDataAtAsObject(i + 1); } ArgumentsSignature signature; - if (nullNamesProfile.profile(x.getNames(attrProfiles) == null)) { + if (nullNamesProfile.profile(getNamesNode.getNames(x) == null)) { signature = ArgumentsSignature.empty(values.length); } else { String[] names = new String[length]; // extract names, converting "" to null - RStringVector ns = x.getNames(attrProfiles); + RStringVector ns = getNamesNode.getNames(x); for (int i = 0; i < length; i++) { String name = ns.getDataAt(i + 1); if (name != null && !name.isEmpty()) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacterFactor.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacterFactor.java index 1db6100ba110523fc7cfe097d94b81480a216580..aa4fa4aae80e4c3c73d4609f7965677c5bfb9d74 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacterFactor.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacterFactor.java @@ -25,8 +25,9 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.dsl.Specialization; - import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; + +import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNode; import com.oracle.truffle.r.nodes.unary.InheritsNode; @@ -47,6 +48,7 @@ public abstract class AsCharacterFactor extends RBuiltinNode { @Child InheritsNode inheritsNode = InheritsNodeGen.create(); @Child CastToVectorNode castToVectorNode = CastToVectorNode.create(); + @Child private GetFixedAttributeNode getLevelsAttrNode = GetFixedAttributeNode.create(RRuntime.LEVELS_ATTR_KEY); @Specialization protected RStringVector doAsCharacterFactor(Object x) { @@ -57,7 +59,7 @@ public abstract class AsCharacterFactor extends RBuiltinNode { RIntVector xVec = (RIntVector) x; int n = xVec.getLength(); String[] data = new String[n]; - Object levsAttr = xVec.getAttr(RRuntime.LEVELS_ATTR_KEY); + Object levsAttr = getLevelsAttrNode.execute(xVec); Object levs; if (levsAttr == null || !((levs = castToVectorNode.execute(levsAttr)) instanceof RAbstractStringVector)) { throw RError.error(RError.SHOW_CALLER, RError.Message.MALFORMED_FACTOR); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java index c9e2d6aaf5be2238ac970c9e394ab5d1354f4615..10853a996c8aee8f4c672122aeb90f4cee0f4ebd 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java @@ -31,14 +31,15 @@ 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.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode; import com.oracle.truffle.r.nodes.attributes.GetAttributeNode; import com.oracle.truffle.r.nodes.attributes.IterableAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetRowNamesAttributeNode; import com.oracle.truffle.r.nodes.attributes.UpdateSharedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; @@ -62,7 +63,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class Attr extends RBuiltinNode { private final ConditionProfile searchPartialProfile = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile errorProfile = BranchProfile.create(); @CompilationFinal private String cachedName = ""; @@ -146,13 +146,14 @@ public abstract class Attr extends RBuiltinNode { } @Specialization(guards = "isRowNamesAttr(name)") - protected Object attrRowNames(RAbstractContainer container, @SuppressWarnings("unused") String name, @SuppressWarnings("unused") boolean exact) { + protected Object attrRowNames(RAbstractContainer container, @SuppressWarnings("unused") String name, @SuppressWarnings("unused") boolean exact, + @Cached("create()") GetRowNamesAttributeNode getRowNamesNode) { // TODO: if exact == false, check for partial match (there is an ignored tests for it) DynamicObject attributes = container.getAttributes(); if (attributes == null) { return RNull.instance; } else { - return getFullRowNames(container.getRowNames(attrProfiles)); + return getFullRowNames(getRowNamesNode.getRowNames(container)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java index d5579cf6151b85e0587b23fa51245d3452b81101..41a244f231512aea273734c48b29acbdf8bb28d7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java @@ -35,6 +35,7 @@ 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.r.nodes.attributes.ArrayAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; @@ -53,6 +54,7 @@ public abstract class Attributes extends RBuiltinNode { private final BranchProfile rownamesBranch = BranchProfile.create(); @Child private ArrayAttributeNode arrayAttrAccess = ArrayAttributeNode.create(); + @Child private SetNamesAttributeNode setNamesNode = SetNamesAttributeNode.create(); @Specialization protected Object attributesNull(RAbstractContainer container, // @@ -117,11 +119,11 @@ public abstract class Attributes extends RBuiltinNode { } } RList result = RDataFactory.createList(values); - result.setNames(RDataFactory.createStringVector(names, true)); + setNamesNode.setNames(result, RDataFactory.createStringVector(names, true)); return result; } private static boolean hasAttributes(RAttributable attributable) { - return attributable.getAttributes() != null && attributable.getAttributes().size() > 0; + return attributable.getAttributes() != null && !attributable.getAttributes().isEmpty(); } } 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 8fc0691a76e82d5d36fbb142623805bb51e7f335..0a95c508e5ae397f7717df4e96528108cb1d0c27 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 @@ -36,6 +36,11 @@ 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.RASTUtils; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode; @@ -61,7 +66,6 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; @@ -95,6 +99,7 @@ public abstract class Bind extends RBaseNode { @Child private CastToVectorNode castVector; @Child private UseMethodInternalNode dcn; @Child private CastLogicalNode castLogical; + @Child private GetDimAttributeNode getDimsNode; private final BindType type; @@ -103,7 +108,6 @@ public abstract class Bind extends RBaseNode { private final ConditionProfile allEmptyVectorProfile = ConditionProfile.createBinaryProfile(); private final BranchProfile nonNullNames = BranchProfile.create(); private final NACheck naCheck = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); protected final ValueProfile resultProfile = ValueProfile.createClassProfile(); protected final ValueProfile vectorProfile = ValueProfile.createClassProfile(); @@ -122,6 +126,14 @@ public abstract class Bind extends RBaseNode { this.type = type; } + protected int[] getVectorDimensions(RAbstractVector v) { + if (getDimsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimsNode = insert(GetDimAttributeNode.create()); + } + return getDimsNode.getDimensions(v); + } + protected RAbstractVector castVector(Object value) { if (castVector == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -161,7 +173,8 @@ 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, + SetDimNamesAttributeNode setDimNamesNode, GetDimNamesAttributeNode getDimNamesNode, GetNamesAttributeNode getNamesNode) { ArgumentsSignature signature = promiseArgs.getSignature(); String[] vecNames = nullNamesProfile.profile(signature.getNonNullCount() == 0) ? null : new String[signature.getLength()]; RAbstractVector[] vectors = new RAbstractVector[args.length]; @@ -217,46 +230,70 @@ 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, setDimNamesNode, getDimNamesNode, getNamesNode); } else { - return genericRBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel); + return genericRBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } } @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, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @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, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @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, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @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, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @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, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @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, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, false, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } /** @@ -267,16 +304,16 @@ public abstract class Bind extends RBaseNode { * @param dimLength * @return dimnames */ - protected Object getDimResultNamesFromElements(RAbstractVector vec, int dimLength, int dimInd) { + protected Object getDimResultNamesFromElements(RAbstractVector vec, int dimLength, int dimInd, GetDimNamesAttributeNode getDimNamesNode, GetNamesAttributeNode getNamesNode) { Object firstDimResultNames = RNull.instance; Object firstDimNames = RNull.instance; if (vec.isMatrix()) { - RList vecDimNames = vec.getDimNames(attrProfiles); + RList vecDimNames = getDimNamesNode.getDimNames(vec); if (vecDimNames != null) { firstDimNames = vecDimNames.getDataAt(dimInd); } - } else if (!vec.isArray() || vec.getDimensions().length == 1) { - RStringVector names = vec.getNames(attrProfiles); + } else if (!vec.isArray() || getVectorDimensions(vec).length == 1) { + RStringVector names = getNamesNode.getNames(vec); firstDimNames = names == null ? RNull.instance : names; } else { RInternalError.unimplemented("binding multi-dimensional arrays is not supported"); @@ -295,11 +332,10 @@ public abstract class Bind extends RBaseNode { * by deparsing. */ protected int getDimResultNamesFromVectors(RArgsValuesAndNames promiseArgs, RAbstractVector vec, String[] argNames, int resDim, int oldInd, int vecInd, int deparseLevel, - String[] dimNamesArray, - int dimNamesInd) { + String[] dimNamesArray, int dimNamesInd, GetDimNamesAttributeNode getDimNamesNode) { int ind = oldInd; if (vec.isMatrix()) { - RList vecDimNames = vec.getDimNames(attrProfiles); + RList vecDimNames = getDimNamesNode.getDimNames(vec); if (vecDimNames != null) { Object resDimNames = vecDimNames.getDataAt(dimNamesInd); if (resDimNames != RNull.instance) { @@ -319,7 +355,7 @@ public abstract class Bind extends RBaseNode { dimNamesArray[ind++] = RRuntime.NAMES_ATTR_EMPTY_VALUE; } return -ind; - } else if (!vec.isArray() || vec.getDimensions().length == 1) { + } else if (!vec.isArray() || getVectorDimensions(vec).length == 1) { if (argNames == null) { if (deparseLevel == 0) { dimNamesArray[ind++] = RRuntime.NAMES_ATTR_EMPTY_VALUE; @@ -377,9 +413,10 @@ public abstract class Bind extends RBaseNode { } protected int[] getDimensions(RAbstractVector vector) { - int[] dimensions = vector.getDimensions(); + RAbstractVector vectorProfiled = vectorProfile.profile(vector); + int[] dimensions = getVectorDimensions(vectorProfiled); if (dimensions == null || dimensions.length != 2) { - return type == BindType.cbind ? new int[]{vector.getLength(), 1} : new int[]{1, vector.getLength()}; + return type == BindType.cbind ? new int[]{vectorProfiled.getLength(), 1} : new int[]{1, vectorProfiled.getLength()}; } else { assert dimensions.length == 2; return dimensions; @@ -444,7 +481,9 @@ public abstract class Bind extends RBaseNode { private final BranchProfile everSeenNotEqualColumns = BranchProfile.create(); @Specialization(guards = {"precedence != NO_PRECEDENCE", "args.length == 1"}) - protected Object allOneElem(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence) { + protected Object allOneElem(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { RAbstractVector vec = castVector(args[0]); if (vec.isMatrix()) { return vec; @@ -452,7 +491,10 @@ public abstract class Bind extends RBaseNode { int[] dims = getDimensions(vec); // for cbind dimNamesA is names for the 1st dim and dimNamesB is names for 2nd dim; for // rbind the other way around - Object dimNamesA = vec.getNames(attrProfiles) == null ? RNull.instance : vec.getNames(attrProfiles); + Object dimNamesA = getNamesNode.getNames(vec); + if (dimNamesA == null) { + dimNamesA = RNull.instance; + } Object dimNamesB; ArgumentsSignature signature = promiseArgs.getSignature(); @@ -473,17 +515,19 @@ public abstract class Bind extends RBaseNode { } RVector<?> res = (RVector<?>) vec.copyWithNewDimensions(dims); - res.setDimNames(RDataFactory.createList(type == BindType.cbind ? new Object[]{dimNamesA, dimNamesB} : new Object[]{dimNamesB, dimNamesA})); + setDimNamesNode.execute(res, RDataFactory.createList(type == BindType.cbind ? new Object[]{dimNamesA, dimNamesB} : new Object[]{dimNamesB, dimNamesA})); res.copyRegAttributesFrom(vec); 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, SetDimNamesAttributeNode setDimNamesNode, GetDimNamesAttributeNode getDimNamesNode, GetNamesAttributeNode getNamesNode) { int[] resultDimensions = new int[2]; int[] secondDims = new int[vectors.length]; boolean notEqualRows = getResultDimensions(vectors, resultDimensions, secondDims); - RVector<?> result = resultProfile.profile(vectors[0].createEmptySameType(resultDimensions[0] * resultDimensions[1], complete)); + RAbstractVector first = vectorProfile.profile(vectors[0]); + RVector<?> result = resultProfile.profile(first.createEmptySameType(resultDimensions[0] * resultDimensions[1], complete)); int ind = 0; Object rowDimResultNames = RNull.instance; @@ -494,11 +538,11 @@ public abstract class Bind extends RBaseNode { RAbstractVector vec = vectorProfile.profile(vectors[i]); if (rowDimResultNames == RNull.instance) { // get the first valid names value - rowDimResultNames = getDimResultNamesFromElements(vec, resultDimensions[0], 0); + rowDimResultNames = getDimResultNamesFromElements(vec, resultDimensions[0], 0, getDimNamesNode, getNamesNode); } // compute dimnames for the second dimension - int newColInd = getDimResultNamesFromVectors(promiseArgs, vec, vecNames, secondDims[i], colInd, i, deparseLevel, colDimNamesArray, 1); + int newColInd = getDimResultNamesFromVectors(promiseArgs, vec, vecNames, secondDims[i], colInd, i, deparseLevel, colDimNamesArray, 1, getDimNamesNode); if (newColInd < 0) { colInd = -newColInd; } else { @@ -528,8 +572,8 @@ public abstract class Bind extends RBaseNode { } Object colDimResultNames = allColDimNamesNull ? RNull.instance : RDataFactory.createStringVector(colDimNamesArray, vecNamesComplete); - result.setDimensions(resultDimensions); - result.setDimNames(RDataFactory.createList(new Object[]{rowDimResultNames, colDimResultNames})); + setDimNode.setDimensions(result, resultDimensions); + setDimNamesNode.setDimNames(result, RDataFactory.createList(new Object[]{rowDimResultNames, colDimResultNames})); return result; } @@ -558,7 +602,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, SetDimNamesAttributeNode setDimNamesNode, GetDimNamesAttributeNode getDimNamesNode, GetNamesAttributeNode getNamesNode) { int[] resultDimensions = new int[2]; int[] firstDims = new int[vectors.length]; @@ -574,11 +619,11 @@ public abstract class Bind extends RBaseNode { RAbstractVector vec = vectorProfile.profile(vectors[i]); if (colDimResultNames == RNull.instance) { // get the first valid names value - colDimResultNames = getDimResultNamesFromElements(vec, resultDimensions[1], 1); + colDimResultNames = getDimResultNamesFromElements(vec, resultDimensions[1], 1, getDimNamesNode, getNamesNode); } // compute dimnames for the second dimension - int newRowInd = getDimResultNamesFromVectors(promiseArgs, vec, vecNames, firstDims[i], rowInd, i, deparseLevel, rowDimNamesArray, 0); + int newRowInd = getDimResultNamesFromVectors(promiseArgs, vec, vecNames, firstDims[i], rowInd, i, deparseLevel, rowDimNamesArray, 0, getDimNamesNode); if (newRowInd < 0) { rowInd = -newRowInd; } else { @@ -613,8 +658,8 @@ public abstract class Bind extends RBaseNode { } Object rowDimResultNames = allRowDimNamesNull ? RNull.instance : RDataFactory.createStringVector(rowDimNamesArray, vecNamesComplete); - result.setDimensions(resultDimensions); - result.setDimNames(RDataFactory.createList(new Object[]{rowDimResultNames, colDimResultNames})); + setDimNode.setDimensions(result, resultDimensions); + setDimNamesNode.setDimNames(result, 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 431cc73c7dddd20f1860c4fa3b9c862136391f6c..99f09dcce3d563e95b0a3292e91bb7de0395d97e 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 @@ -47,7 +47,8 @@ import com.oracle.truffle.api.nodes.ExplodeLoop; 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.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.CombineNodeGen.CombineInputCastNodeGen; @@ -96,7 +97,6 @@ public abstract class Combine extends RBuiltinNode { @Child private CombineInputCast inputCast = CombineInputCastNodeGen.create(null); @Child private CastToVectorNode castVector; - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile naBranch = BranchProfile.create(); private final NACheck naCheck = NACheck.create(); private final ConditionProfile fastNamesMerge = ConditionProfile.createBinaryProfile(); @@ -127,7 +127,8 @@ public abstract class Combine extends RBuiltinNode { @Cached("createCast(cachedPrecedence)") CastNode cast, // @Cached("create()") BranchProfile naNameBranch, // @Cached("create()") NACheck naNameCheck, // - @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile) { + @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile, + @Cached("create()") GetNamesAttributeNode getNamesNode) { CompilerAsserts.partialEvaluationConstant(cachedSignature); CompilerAsserts.partialEvaluationConstant(cachedPrecedence); @@ -142,7 +143,8 @@ public abstract class Combine extends RBuiltinNode { // prepare the names (if there are any) boolean signatureHasNames = signatureHasNames(cachedSignature); CompilerAsserts.partialEvaluationConstant(signatureHasNames); - RStringVector namesVector = hasNamesProfile.profile(signatureHasNames || hasNames(elements)) ? foldNames(naNameBranch, naNameCheck, elements, size, cachedSignature) : null; + RStringVector namesVector = hasNamesProfile.profile(signatureHasNames || hasNames(elements, getNamesNode)) ? foldNames(naNameBranch, naNameCheck, elements, size, cachedSignature, getNamesNode) + : null; // get the actual contents of the result RVector<?> result = foldContents(cachedPrecedence, elements, size, namesVector); @@ -159,8 +161,9 @@ public abstract class Combine extends RBuiltinNode { @Cached("createCast(cachedPrecedence)") CastNode cast, // @Cached("create()") BranchProfile naNameBranch, // @Cached("create()") NACheck naNameCheck, // - @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile) { - return combineCached(args, false, args.getSignature(), cachedPrecedence, cast, naNameBranch, naNameCheck, hasNamesProfile); + @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return combineCached(args, false, args.getSignature(), cachedPrecedence, cast, naNameBranch, naNameCheck, hasNamesProfile, getNamesNode); } @Specialization(guards = "recursive") @@ -226,7 +229,7 @@ public abstract class Combine extends RBuiltinNode { } @ExplodeLoop - private boolean hasNames(Object[] elements) { + private boolean hasNames(Object[] elements, GetNamesAttributeNode getNamesNode) { for (int i = 0; i < elements.length; i++) { Object element = elements[i]; if (i < argProfiles.length) { @@ -234,7 +237,7 @@ public abstract class Combine extends RBuiltinNode { } if (element instanceof RAbstractVector) { RAbstractVector vector = (RAbstractVector) element; - if (vector.getNames(attrProfiles) != null) { + if (getNamesNode.getNames(vector) != null) { return true; } } @@ -243,7 +246,7 @@ public abstract class Combine extends RBuiltinNode { } @ExplodeLoop - private RStringVector foldNames(BranchProfile naNameBranch, NACheck naNameCheck, Object[] elements, int size, ArgumentsSignature signature) { + private RStringVector foldNames(BranchProfile naNameBranch, NACheck naNameCheck, Object[] elements, int size, ArgumentsSignature signature, GetNamesAttributeNode getNamesNode) { RStringVector result = RDataFactory.createStringVector(new String[size], true); result.incRefCount(); int pos = 0; @@ -252,18 +255,19 @@ public abstract class Combine extends RBuiltinNode { if (i < argProfiles.length) { element = argProfiles[i].profile(element); } - pos += processNamesElement(naNameBranch, naNameCheck, result, pos, element, i, signature); + pos += processNamesElement(naNameBranch, naNameCheck, result, pos, element, i, signature, getNamesNode); } return result; } - private int processNamesElement(BranchProfile naNameBranch, NACheck naNameCheck, RStringVector result, int pos, Object element, int index, ArgumentsSignature signature) { + private int processNamesElement(BranchProfile naNameBranch, NACheck naNameCheck, RStringVector result, int pos, Object element, int index, ArgumentsSignature signature, + GetNamesAttributeNode getNamesNode) { String signatureName = signature.getName(index); if (element instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) element; int length = v.getLength(); - RStringVector newNames = v.getNames(attrProfiles); + RStringVector newNames = getNamesNode.getNames(v); if (signatureName != null && length > 0) { if (fastNamesMerge.profile(length == 1 && newNames == null)) { newNames = RDataFactory.createStringVector(new String[]{signatureName}, true); @@ -455,6 +459,8 @@ public abstract class Combine extends RBuiltinNode { protected abstract static class CombineInputCast extends RNode { private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); public abstract Object execute(Object operand); @@ -474,15 +480,13 @@ public abstract class Combine extends RBuiltinNode { RVector<?> materialized = vector.materialize(); RVector<?> result = materialized.copyDropAttributes(); - RStringVector vecNames = materialized.getInternalNames(); + RStringVector vecNames = getNamesNode.getNames(materialized); if (hasNamesProfile.profile(vecNames != null)) { result.initAttributes(RAttributesLayout.createNames(vecNames)); - result.setInternalNames(vecNames); } else { - RList dimNames = materialized.getInternalDimNames(); + RList dimNames = getDimNamesNode.getDimNames(materialized); if (hasDimNamesProfile.profile(dimNames != null)) { - result.initAttributes(RAttributesLayout.createDimNames(vecNames)); - result.setInternalDimNames(dimNames); + result.initAttributes(RAttributesLayout.createDimNames(dimNames)); } } return result; @@ -494,7 +498,7 @@ public abstract class Combine extends RBuiltinNode { } protected boolean needsCopy(RAbstractVector vector) { - return vector.getAttributes() != null || vector.getNames(attrProfiles) != null || vector.getDimNames(attrProfiles) != null; + return vector.getAttributes() != null || getNamesNode.getNames(vector) != null || getDimNamesNode.getDimNames(vector) != null; } } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java index bd91785573149dbf784c85774719cfbb211c6064..491c440ba79dbbd197522d28fb8ce694809b9ff9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java @@ -29,7 +29,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -37,12 +36,10 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @RBuiltin(name = "copyDFattr", kind = INTERNAL, parameterNames = {"", ""}, behavior = COMPLEX) public abstract class CopyDFAttr extends RBuiltinNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - @Specialization() protected RAttributable copy(RAbstractContainer in, RAbstractVector out) { RVector<?> res = out.materialize(); res.resetAllAttributes(false); - return res.copyAttributesFrom(attrProfiles, in); + return res.copyAttributesFrom(in); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java index 3aefffb5f6b5d7a8e3bc4f27c5d4f058c0e13fd1..9c6e521f08bfa375abdeec6ab6003d53c8d06ab0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java @@ -27,7 +27,11 @@ 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.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -62,21 +66,29 @@ public abstract class Crossprod extends RBuiltinNode { } @Specialization(guards = {"x.isMatrix()", "y.isMatrix()"}) - protected RDoubleVector crossprod(RAbstractDoubleVector x, RAbstractDoubleVector y) { - int xRows = x.getDimensions()[0]; - int xCols = x.getDimensions()[1]; - int yRows = y.getDimensions()[0]; - int yCols = y.getDimensions()[1]; - return matMult.doubleMatrixMultiply(x, y, xCols, xRows, yRows, yCols, xRows, 1, 1, yRows, false); + protected RDoubleVector crossprod(RAbstractDoubleVector x, RAbstractDoubleVector y, + @Cached("create()") GetDimAttributeNode getXDimsNode, + @Cached("create()") GetDimAttributeNode getYDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + int[] xDims = getXDimsNode.getDimensions(x); + int[] yDims = getYDimsNode.getDimensions(y); + int xRows = xDims[0]; + int xCols = xDims[1]; + int yRows = yDims[0]; + int yCols = yDims[1]; + return matMult.doubleMatrixMultiply(x, y, xCols, xRows, yRows, yCols, xRows, 1, 1, yRows, false, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } - private static RDoubleVector mirror(RDoubleVector result) { + private static RDoubleVector mirror(RDoubleVector result, GetDimAttributeNode getResultDimsNode) { /* * Mirroring the result is not only good for performance, but it is also required to produce * the same result as GNUR. */ - assert result.isMatrix() && result.getDimensions()[0] == result.getDimensions()[1]; - int size = result.getDimensions()[0]; + int[] resultDims = getResultDimsNode.getDimensions(result); + assert result.isMatrix() && resultDims[0] == resultDims[1]; + int size = resultDims[0]; double[] data = result.getDataWithoutCopying(); for (int row = 0; row < size; row++) { int destIndex = row * size + row + 1; @@ -96,10 +108,16 @@ public abstract class Crossprod extends RBuiltinNode { } @Specialization(guards = "x.isMatrix()") - protected RDoubleVector crossprodDoubleMatrix(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y) { - int xRows = x.getDimensions()[0]; - int xCols = x.getDimensions()[1]; - return mirror(matMult.doubleMatrixMultiply(x, x, xCols, xRows, xRows, xCols, xRows, 1, 1, xRows, true)); + protected RDoubleVector crossprodDoubleMatrix(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") GetDimAttributeNode getResultDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + int[] xDims = getDimsNode.getDimensions(x); + int xRows = xDims[0]; + int xCols = xDims[1]; + return mirror(matMult.doubleMatrixMultiply(x, x, xCols, xRows, xRows, xCols, xRows, 1, 1, xRows, true, setDimNamesNode, getADimNamesNode, getBDimNamesNode), getResultDimsNode); } @Specialization diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java index edf8441b58c47ee9bad392bd698d4bc1c72247d7..58cf95204c494529cf4eaff9eeb2710b2657b99c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java @@ -24,12 +24,12 @@ import java.util.Arrays; 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.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RIntSequence; @@ -43,7 +43,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class CumMax extends RBuiltinNode { private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -96,7 +96,7 @@ public abstract class CumMax extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(cmaxV, i, cmaxV.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createDoubleVector(cmaxV, na.neverSeenNA(), v.getNames(attrProfiles)); + return RDataFactory.createDoubleVector(cmaxV, na.neverSeenNA(), getNamesNode.getNames(v)); } @Specialization(contains = "cummaxIntSequence") @@ -118,7 +118,7 @@ public abstract class CumMax extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(cmaxV, i, cmaxV.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(cmaxV, na.neverSeenNA(), v.getNames(attrProfiles)); + return RDataFactory.createIntVector(cmaxV, na.neverSeenNA(), getNamesNode.getNames(v)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java index a1da7b792e40c8abb45fa505b7b76c03946a281f..b99ad15b12cf41a05b9bb5278ef605be97215766 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java @@ -24,12 +24,12 @@ import java.util.Arrays; 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.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RIntSequence; @@ -43,7 +43,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class CumMin extends RBuiltinNode { private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -96,7 +96,7 @@ public abstract class CumMin extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(cminV, i, cminV.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createDoubleVector(cminV, na.neverSeenNA(), v.getNames(attrProfiles)); + return RDataFactory.createDoubleVector(cminV, na.neverSeenNA(), getNamesNode.getNames(v)); } @Specialization(contains = "cumminIntSequence") @@ -118,7 +118,7 @@ public abstract class CumMin extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(cminV, i, cminV.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(cminV, na.neverSeenNA(), v.getNames(attrProfiles)); + return RDataFactory.createIntVector(cminV, na.neverSeenNA(), getNamesNode.getNames(v)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java index 56cda98a07fd8f9e13be1f2833356ff00be34526..254eaed5fb718f954495b90339e3955362a6ee0e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java @@ -24,11 +24,11 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import java.util.Arrays; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -45,7 +45,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class CumProd extends RBuiltinNode { private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Child private BinaryArithmetic mul = BinaryArithmetic.MULTIPLY.createOperation(); @@ -88,7 +88,7 @@ public abstract class CumProd extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(array, i, array.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(array, !na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createIntVector(array, !na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -110,7 +110,7 @@ public abstract class CumProd extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(array, i, array.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createDoubleVector(array, !na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createDoubleVector(array, !na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -133,6 +133,6 @@ public abstract class CumProd extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(array, 2 * i, array.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createComplexVector(array, !na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createComplexVector(array, !na.neverSeenNA(), getNamesNode.getNames(arg)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java index 06c1be88b75946797245a613f51c0f5a2578668a..3b6074626f3ab1dc0fc1aedf94739337cd75964d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java @@ -36,11 +36,11 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import java.util.Arrays; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -58,7 +58,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class CumSum extends RBuiltinNode { private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Child private BinaryArithmetic add = BinaryArithmetic.ADD.createOperation(); @@ -100,7 +100,7 @@ public abstract class CumSum extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(res, i, res.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(res, na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createIntVector(res, na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -119,7 +119,7 @@ public abstract class CumSum extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(res, i, res.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createDoubleVector(res, na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createDoubleVector(res, na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -141,7 +141,7 @@ public abstract class CumSum extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(res, i, res.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(res, na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createIntVector(res, na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -161,6 +161,6 @@ public abstract class CumSum extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(res, 2 * i, res.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createComplexVector(res, na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createComplexVector(res, na.neverSeenNA(), getNamesNode.getNames(arg)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java index c9a3e2826bcf8d325844e894e04922fb2c9f369a..c45cb05324403c8247e900ca5c64b8162defb836 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java @@ -36,7 +36,10 @@ import java.util.HashMap; import java.util.TimeZone; 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.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RInternalError; @@ -137,6 +140,7 @@ public class DatePOSIXFunctions { public abstract static class Date2POSIXlt extends RBuiltinNode { private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -161,7 +165,7 @@ public class DatePOSIXFunctions { } } RList result = builder.finish(); - RStringVector xNames = x.getNames(attrProfiles); + RStringVector xNames = getNamesNode.getNames(x); if (xNames != null) { ((RIntVector) result.getDataAt(5)).copyNamesFrom(attrProfiles, x); } @@ -173,6 +177,7 @@ public class DatePOSIXFunctions { public abstract static class AsPOSIXlt extends RBuiltinNode { private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -203,7 +208,7 @@ public class DatePOSIXFunctions { } } RList result = builder.finish(); - RStringVector xNames = x.getNames(attrProfiles); + RStringVector xNames = getNamesNode.getNames(x); if (xNames != null) { ((RIntVector) result.getDataAt(5)).copyNamesFrom(attrProfiles, x); } @@ -280,7 +285,8 @@ public class DatePOSIXFunctions { @Specialization @TruffleBoundary - protected RDoubleVector posix2date(RAbstractListVector x) { + protected RDoubleVector posix2date(RAbstractListVector x, + @Cached("create()") SetClassAttributeNode setClassAttrNode) { RAbstractVector secVector = (RAbstractVector) RRuntime.asAbstractVector(x.getDataAt(0)); RAbstractVector minVector = (RAbstractVector) RRuntime.asAbstractVector(x.getDataAt(1)); RAbstractVector hourVector = (RAbstractVector) RRuntime.asAbstractVector(x.getDataAt(2)); @@ -314,7 +320,7 @@ public class DatePOSIXFunctions { } } RDoubleVector result = RDataFactory.createDoubleVector(data, complete); - result.setClassAttr(CLASS_ATTR); + setClassAttrNode.execute(result, CLASS_ATTR); return result; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java index be4d0db5ec9a83264b3daeaf3390b780184ef2eb..95cb519bd8e14fe633c8a23426a03118a603379e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java @@ -29,6 +29,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; 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.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -40,9 +41,11 @@ public abstract class Dim extends RBuiltinNode { @Specialization protected Object dim(RAbstractContainer container, // - @Cached("createBinaryProfile()") ConditionProfile hasDimensionsProfile) { - if (hasDimensionsProfile.profile(container.hasDimensions())) { - return RDataFactory.createIntVector(container.getDimensions(), RDataFactory.COMPLETE_VECTOR); + @Cached("createBinaryProfile()") ConditionProfile hasDimensionsProfile, + @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(container); + if (hasDimensionsProfile.profile(dims != null && dims.length > 0)) { + return RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR); } else { return RNull.instance; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java index 17661779644a7b819009377f238888db6a8a9fde..6953af8262f8466702d2e38fc0a2a5af330a1b52 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java @@ -26,11 +26,12 @@ import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; +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.GetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @@ -38,7 +39,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @RBuiltin(name = "dimnames", kind = PRIMITIVE, parameterNames = {"x"}, dispatch = INTERNAL_GENERIC, behavior = PURE) public abstract class DimNames extends RBuiltinNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final ConditionProfile nullProfile = ConditionProfile.createBinaryProfile(); @Specialization(guards = "!isRAbstractContainer(operand)") @@ -47,8 +47,8 @@ public abstract class DimNames extends RBuiltinNode { } @Specialization - protected Object getDimNames(RAbstractContainer container) { - RList names = container.getDimNames(attrProfiles); + protected Object getDimNames(RAbstractContainer container, @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) { + RList names = getDimNamesNode.getDimNames(container); return nullProfile.profile(names == null) ? RNull.instance : names; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java index 7cb11a03f335315d7421134e3bb055a720266eed..dbcf174805a15697847c63c09643e27572a98e02 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java @@ -37,6 +37,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.FrameSlotNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen; @@ -50,7 +51,6 @@ import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RFunction; @@ -72,8 +72,8 @@ public abstract class DoCall extends RBuiltinNode implements InternalRSyntaxNode @Child private GetFunctions.Get getNode; @Child private GetCallerFrameNode getCallerFrame; + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile containsRLanguageProfile = BranchProfile.create(); private final BranchProfile containsRSymbolProfile = BranchProfile.create(); @@ -113,7 +113,7 @@ public abstract class DoCall extends RBuiltinNode implements InternalRSyntaxNode * To re-create the illusion of a normal call, turn the values in argsAsList into promises. */ Object[] argValues = argsAsList.getDataCopy(); - RStringVector n = argsAsList.getNames(attrProfiles); + RStringVector n = getNamesNode.getNames(argsAsList); ArgumentsSignature signature; if (n == null) { signature = ArgumentsSignature.empty(argValues.length); 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 43cfb6a97d7bde5e346af117e8b0e2762f640d5d..7104921f0dc2c92786597d31e9c707f6fadf5f1c 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 @@ -25,9 +25,15 @@ package com.oracle.truffle.r.nodes.builtin.base; 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.dsl.Cached; 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.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; @@ -47,8 +53,13 @@ public abstract class Drop extends RBuiltinNode { private final ConditionProfile noDimNamesProfile = ConditionProfile.createBinaryProfile(); @Specialization - protected RAbstractVector doDrop(RAbstractVector x) { - int[] dims = x.getDimensions(); + protected RAbstractVector doDrop(RAbstractVector x, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimsNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimsNamesNode, + @Cached("create()") SetNamesAttributeNode setNamesNode) { + int[] dims = getDimsNode.getDimensions(x); if (nullDimensions.profile(dims == null)) { return x; } @@ -67,15 +78,15 @@ public abstract class Drop extends RBuiltinNode { if (resultIsScalarProfile.profile(lastNonOneIndex == -1)) { @SuppressWarnings("unused") RAbstractVector r = x.copy(); - x.setDimensions(null); - x.setDimNames(null); - x.setNames(null); + setDimsNode.setDimensions(x, null); + setDimsNamesNode.setDimNames(x, null); + setNamesNode.setNames(x, null); return x; } // the result is vector if (resultIsVector.profile(newDimsLength <= 1)) { - return toVector(x, lastNonOneIndex); + return toVector(x, lastNonOneIndex, setDimsNode, getDimsNamesNode, setNamesNode); } // else: the result will be a matrix, copy non-1 dimensions @@ -88,10 +99,10 @@ 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); + RList oldDimNames = getDimsNamesNode.getDimNames(x); if (noDimNamesProfile.profile(oldDimNames != null)) { newDimsIdx = 0; Object[] newDimNames = new Object[newDimsLength]; @@ -100,9 +111,9 @@ public abstract class Drop extends RBuiltinNode { newDimNames[newDimsIdx++] = oldDimNames.getDataAt(i); } } - result.setDimNames(RDataFactory.createList(newDimNames)); + setDimsNamesNode.setDimNames(result, RDataFactory.createList(newDimNames)); } else { - result.setDimNames(null); + setDimsNamesNode.setDimNames(result, null); } return result; @@ -112,14 +123,14 @@ 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, GetDimNamesAttributeNode getDimNamesNode, SetNamesAttributeNode setNamesNode) { RAbstractVector result = x.copy(); // share? - result.setDimensions(null); + setDimsNode.setDimensions(result, null); // copy dimnames to names if possible - RList dimNames = x.getDimNames(dimNamesAttrProfile); + RList dimNames = getDimNamesNode.getDimNames(x); if (noDimNamesProfile.profile(dimNames != null) && nonOneIndex < dimNames.getLength()) { - result.setNames(ensureStringVector(dimNames.getDataAt(nonOneIndex))); + setNamesNode.setNames(result, ensureStringVector(dimNames.getDataAt(nonOneIndex))); } return result; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java index 91b440abc58300884c1fe7ce11b3eb9cdef5690f..943bd6ee74737e7f78df1db20db0fa42b51ab274 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java @@ -22,7 +22,11 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; import static com.oracle.truffle.r.runtime.RVisibility.OFF; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_STATE; @@ -32,6 +36,7 @@ import java.util.ArrayList; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -102,6 +107,9 @@ public class DynLoadFunctions { @RBuiltin(name = "getLoadedDLLs", kind = INTERNAL, parameterNames = {}, behavior = READS_STATE) public abstract static class GetLoadedDLLs extends RBuiltinNode { + + @Child private SetClassAttributeNode setClassAttrNode = SetClassAttributeNode.create(); + @Specialization @TruffleBoundary protected RList doGetLoadedDLLs() { @@ -115,7 +123,7 @@ public class DynLoadFunctions { data[i] = dllInfo.toRList(); } RList result = RDataFactory.createList(data, RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR)); - result.setClassAttr(RDataFactory.createStringVectorFromScalar(DLLINFOLIST_CLASS)); + setClassAttrNode.execute(result, RDataFactory.createStringVectorFromScalar(DLLINFOLIST_CLASS)); return result; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java index e5ae35b08c784065f46fd10c6b38abd451044f51..d7188cf48b1d06d525c8c64352f9844d7f4d5d0c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java @@ -49,6 +49,8 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.RRootNode; +import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RList2EnvNode; @@ -172,10 +174,14 @@ public class EnvFunctions { return list2Env.execute(list, env); } + protected GetFixedAttributeNode createGetXDataAttrNode() { + return GetFixedAttributeNode.create(RRuntime.DOT_XDATA); + } + @Specialization - protected Object asEnvironment(RS4Object obj) { + protected Object asEnvironment(RS4Object obj, @Cached("createGetXDataAttrNode()") GetFixedAttributeNode getXDataAttrNode) { // generic dispatch tried already - Object xData = obj.getAttr(RRuntime.DOT_XDATA); + Object xData = getXDataAttrNode.execute(obj); if (xData == null || !(xData instanceof REnvironment)) { throw RError.error(this, RError.Message.S4OBJECT_NX_ENVIRONMENT); } else { @@ -319,8 +325,8 @@ public class EnvFunctions { @RBuiltin(name = "environment", kind = INTERNAL, parameterNames = {"fun"}, behavior = COMPLEX) public abstract static class Environment extends RBuiltinNode { - private static RAttributeProfiles attributeProfile = RAttributeProfiles.create(); private final ConditionProfile attributable = ConditionProfile.createBinaryProfile(); + @Child private GetFixedAttributeNode getEnvAttrNode; @Specialization protected Object environment(VirtualFrame frame, @SuppressWarnings("unused") RNull fun, @@ -352,16 +358,24 @@ public class EnvFunctions { } @Specialization(guards = "isRFormula(formula)") - protected Object environment(RLanguage formula, - @Cached("create()") RAttributeProfiles attrProfiles) { - Object result = formula.getAttr(attrProfiles, RRuntime.DOT_ENVIRONMENT); + protected Object environment(RLanguage formula) { + if (getEnvAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getEnvAttrNode = insert(GetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT)); + } + + Object result = getEnvAttrNode.execute(formula); return result == null ? RNull.instance : result; } @Specialization(guards = {"!isRNull(fun)", "!isRFunction(fun)", "!isRFormula(fun)"}) protected Object environment(Object fun) { if (attributable.profile(fun instanceof RAttributable)) { - Object attr = ((RAttributable) fun).getAttr(attributeProfile, RRuntime.DOT_ENVIRONMENT); + if (getEnvAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getEnvAttrNode = insert(GetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT)); + } + Object attr = getEnvAttrNode.execute(fun); return attr == null ? RNull.instance : attr; } else { // Not an error according to GnuR @@ -401,16 +415,22 @@ public class EnvFunctions { throw RError.error(this, RError.Message.USE_NULL_ENV_DEFUNCT); } + protected SetFixedAttributeNode createSetEnvAttrNode() { + return SetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT); + } + @Specialization @TruffleBoundary - protected static Object updateEnvironment(RAbstractContainer obj, REnvironment env) { - return updateEnvironment((RAttributable) obj, env); + protected static Object updateEnvironment(RAbstractContainer obj, REnvironment env, + @Cached("createSetEnvAttrNode()") SetFixedAttributeNode setEnvAttrNode) { + return updateEnvironment((RAttributable) obj, env, setEnvAttrNode); } @Specialization @TruffleBoundary - protected static Object updateEnvironment(RAttributable obj, REnvironment env) { - obj.setAttr(RRuntime.DOT_ENVIRONMENT, env); + protected static Object updateEnvironment(RAttributable obj, REnvironment env, + @Cached("createSetEnvAttrNode()") SetFixedAttributeNode setEnvAttrNode) { + setEnvAttrNode.execute(obj, env); return obj; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java index 83bade1e3165ab0807caa023896b8a47890d2a4c..63d8b68047883562b4511b147b70663fb83c40ca 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java @@ -57,15 +57,16 @@ import java.util.stream.Stream; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.Utils; -import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.builtins.RBehavior; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.builtins.RBuiltinKind; @@ -266,6 +267,8 @@ public class FileFunctions { private static final RStringVector NAMES_VECTOR = RDataFactory.createStringVector(NAMES, RDataFactory.COMPLETE_VECTOR); private static final RStringVector OCTMODE = RDataFactory.createStringVectorFromScalar("octmode"); + @Child private SetClassAttributeNode setClassAttrNode; + @Override protected void createCasts(CastBuilder casts) { casts.arg("extra_cols").asLogicalVector().findFirst().map(toBoolean()); @@ -400,12 +403,19 @@ public class FileFunctions { // @formatter:on } - private static Object createColumnResult(Column column, Object data, boolean complete) { + private Object createColumnResult(Column column, Object data, boolean complete) { // @formatter:off switch(column) { case size: return RDataFactory.createDoubleVector((double[]) data, complete); case isdir: return RDataFactory.createLogicalVector((byte[]) data, complete); - case mode: RIntVector res = RDataFactory.createIntVector((int[]) data, complete); res.setClassAttr(OCTMODE); return res; + case mode: + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + RIntVector res = RDataFactory.createIntVector((int[]) data, complete); + setClassAttrNode.execute(res, OCTMODE); + return res; case mtime: case ctime: case atime: case uid: case gid: return RDataFactory.createIntVector((int[]) data, complete); case uname: case grname: return RDataFactory.createStringVector((String[]) data, complete); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java index 0ff9871785cb6fb0523d27ae4bae2b6f98f303e7..c69f2dac6af092d2932465d0d8d60fb9974cf2ee 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java @@ -15,7 +15,9 @@ 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.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; @@ -51,8 +53,10 @@ public abstract class FormatC extends RBuiltinNode { @SuppressWarnings("unused") @Specialization - RAttributable formatC(RAbstractContainer x, String mode, int width, int digits, String format, String flag, int iStrlen) { + RAttributable formatC(RAbstractContainer x, String mode, int width, int digits, String format, String flag, int iStrlen, + @Cached("create()") SetClassAttributeNode setClassAttrNode) { RStringVector res = castStringVector(x); - return res.setClassAttr(null); + setClassAttrNode.reset(res); + return res; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java index fbaf2c1d0ed89cda0558bcd0e1b6be5d675a333b..f873109da07b8215fc2cbf199541c0ec6dd8e2df 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java @@ -11,7 +11,8 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; @@ -26,6 +27,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -473,7 +475,7 @@ public class GrepFunctions { result[i] = value; } RStringVector ret = RDataFactory.createStringVector(result, vector.isComplete()); - ret.copyAttributesFrom(attrProfiles, vector); + ret.copyAttributesFrom(vector); return ret; } catch (PatternSyntaxException e) { CompilerDirectives.transferToInterpreter(); @@ -664,6 +666,13 @@ public class GrepFunctions { @RBuiltin(name = "regexpr", kind = INTERNAL, parameterNames = {"pattern", "text", "ignore.case", "perl", "fixed", "useBytes"}, behavior = PURE) public abstract static class Regexp extends CommonCodeAdapter { + @Child SetFixedAttributeNode setMatchLengthAttrNode = SetFixedAttributeNode.create("match.length"); + @Child SetFixedAttributeNode setUseBytesAttrNode = SetFixedAttributeNode.create("useBytes"); + @Child SetFixedAttributeNode setCaptureStartAttrNode = SetFixedAttributeNode.create("capture.start"); + @Child SetFixedAttributeNode setCaptureLengthAttrNode = SetFixedAttributeNode.create("capture.length"); + @Child SetFixedAttributeNode setCaptureNamesAttrNode = SetFixedAttributeNode.create("capture.names"); + @Child SetFixedAttributeNode setDimNamesAttrNode = SetFixedAttributeNode.createDimNames(); + @Override protected void createCasts(CastBuilder casts) { castPattern(casts); @@ -755,19 +764,19 @@ public class GrepFunctions { } } RIntVector ret = RDataFactory.createIntVector(result, RDataFactory.COMPLETE_VECTOR); - ret.setAttr("match.length", RDataFactory.createIntVector(matchLength, RDataFactory.COMPLETE_VECTOR)); + setMatchLengthAttrNode.execute(ret, RDataFactory.createIntVector(matchLength, RDataFactory.COMPLETE_VECTOR)); if (useBytes) { - ret.setAttr("useBytes", RRuntime.LOGICAL_TRUE); + setUseBytesAttrNode.execute(ret, RRuntime.LOGICAL_TRUE); } if (hasAnyCapture) { RStringVector captureNamesVec = RDataFactory.createStringVector(captureNames, RDataFactory.COMPLETE_VECTOR); RIntVector captureStartVec = RDataFactory.createIntVector(captureStart, RDataFactory.COMPLETE_VECTOR, new int[]{vector.getLength(), captureNames.length}); - captureStartVec.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, captureNamesVec.copy()})); - ret.setAttr("capture.start", captureStartVec); + setDimNamesAttrNode.execute(captureStartVec, RDataFactory.createList(new Object[]{RNull.instance, captureNamesVec.copy()})); + setCaptureStartAttrNode.execute(ret, captureStartVec); RIntVector captureLengthVec = RDataFactory.createIntVector(captureLength, RDataFactory.COMPLETE_VECTOR, new int[]{vector.getLength(), captureNames.length}); - captureLengthVec.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, captureNamesVec.copy()})); - ret.setAttr("capture.length", captureLengthVec); - ret.setAttr("capture.names", captureNamesVec); + setDimNamesAttrNode.execute(captureLengthVec, RDataFactory.createList(new Object[]{RNull.instance, captureNamesVec.copy()})); + setCaptureLengthAttrNode.execute(ret, captureLengthVec); + setCaptureNamesAttrNode.execute(ret, captureNamesVec); } return ret; } @@ -845,6 +854,13 @@ public class GrepFunctions { @RBuiltin(name = "gregexpr", kind = INTERNAL, parameterNames = {"pattern", "text", "ignore.case", "perl", "fixed", "useBytes"}, behavior = PURE) public abstract static class Gregexpr extends Regexp { + @Child SetFixedAttributeNode setMatchLengthAttrNode = SetFixedAttributeNode.create("match.length"); + @Child SetFixedAttributeNode setUseBytesAttrNode = SetFixedAttributeNode.create("useBytes"); + @Child SetFixedAttributeNode setCaptureStartAttrNode = SetFixedAttributeNode.create("capture.start"); + @Child SetFixedAttributeNode setCaptureLengthAttrNode = SetFixedAttributeNode.create("capture.length"); + @Child SetFixedAttributeNode setCaptureNamesAttrNode = SetFixedAttributeNode.create("capture.names"); + @Child SetFixedAttributeNode setDimNamesAttrNode = SetFixedAttributeNode.createDimNames(); + @Override protected void createCasts(CastBuilder casts) { castPattern(casts); @@ -855,19 +871,19 @@ public class GrepFunctions { castUseBytes(casts); } - private static void setNoCaptureAttributes(RIntVector vec, RStringVector captureNames) { + private void setNoCaptureAttributes(RIntVector vec, RStringVector captureNames) { int len = captureNames.getLength(); int[] captureStartData = new int[len]; int[] captureLengthData = new int[len]; Arrays.fill(captureStartData, -1); Arrays.fill(captureLengthData, -1); RIntVector captureStart = RDataFactory.createIntVector(captureStartData, RDataFactory.COMPLETE_VECTOR, new int[]{1, captureNames.getLength()}); - captureStart.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, captureNames.copy()})); + setDimNamesAttrNode.execute(captureStart, RDataFactory.createList(new Object[]{RNull.instance, captureNames.copy()})); RIntVector captureLength = RDataFactory.createIntVector(captureLengthData, RDataFactory.COMPLETE_VECTOR, new int[]{1, captureNames.getLength()}); - captureLength.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, captureNames.copy()})); - vec.setAttr("capture.start", captureStart); - vec.setAttr("capture.length", captureLength); - vec.setAttr("capture.names", captureNames); + setDimNamesAttrNode.execute(captureLength, RDataFactory.createList(new Object[]{RNull.instance, captureNames.copy()})); + setCaptureStartAttrNode.execute(vec, captureStart); + setCaptureLengthAttrNode.execute(vec, captureLength); + setCaptureNamesAttrNode.execute(vec, captureNames); } @Specialization @@ -899,16 +915,16 @@ public class GrepFunctions { for (int j = 0; j < txt.length(); j++) { res.setDataAt(res.getDataWithoutCopying(), j, j + 1); } - res.setAttr("match.length", RDataFactory.createIntVector(txt.length())); + setMatchLengthAttrNode.execute(res, RDataFactory.createIntVector(txt.length())); if (useBytes) { - res.setAttr("useBytes", RRuntime.LOGICAL_TRUE); + setUseBytesAttrNode.execute(res, RRuntime.LOGICAL_TRUE); } } else { List<Info> l = getInfo(pattern, vector.getDataAt(i), ignoreCase, perl, fixed); res = toIndexOrSizeVector(l, true); - res.setAttr("match.length", toIndexOrSizeVector(l, false)); + setMatchLengthAttrNode.execute(res, toIndexOrSizeVector(l, false)); if (useBytes) { - res.setAttr("useBytes", RRuntime.LOGICAL_TRUE); + setUseBytesAttrNode.execute(res, RRuntime.LOGICAL_TRUE); } RIntVector captureStart = toCaptureStartOrLength(l, true); if (captureStart != null) { @@ -923,9 +939,9 @@ public class GrepFunctions { } } hasAnyCapture = true; - res.setAttr("capture.start", captureStart); - res.setAttr("capture.length", captureLength); - res.setAttr("capture.names", captureNames); + setCaptureStartAttrNode.execute(res, captureStart); + setCaptureLengthAttrNode.execute(res, captureLength); + setCaptureNamesAttrNode.execute(res, captureNames); } else if (hasAnyCapture) { assert captureNames != null; // it's capture names from previous iteration, so copy @@ -947,7 +963,7 @@ public class GrepFunctions { return RDataFactory.createIntVector(arr, RDataFactory.COMPLETE_VECTOR); } - private static RIntVector toCaptureStartOrLength(List<Info> list, boolean start) { + private RIntVector toCaptureStartOrLength(List<Info> list, boolean start) { assert list.size() > 0; Info firstInfo = list.get(0); if (!firstInfo.hasCapture) { @@ -966,7 +982,7 @@ public class GrepFunctions { } } RIntVector ret = RDataFactory.createIntVector(arr, RDataFactory.COMPLETE_VECTOR, new int[]{list.size(), firstInfo.captureNames.length}); - ret.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, RDataFactory.createStringVector(firstInfo.captureNames, RDataFactory.COMPLETE_VECTOR)})); + setDimNamesAttrNode.execute(ret, RDataFactory.createList(new Object[]{RNull.instance, RDataFactory.createStringVector(firstInfo.captureNames, RDataFactory.COMPLETE_VECTOR)})); return ret; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java index 7b1275c1b1d5ffbe7a3539868b2d97a1a451e9a4..d04b57fd08082c853c5738796cd4fa9a5d2f151a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java @@ -27,6 +27,7 @@ import java.nio.ByteBuffer; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.MaterializedFrame; @@ -35,6 +36,7 @@ import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.PromiseHelperNode; @@ -284,7 +286,8 @@ public class HiddenInternalFunctions { @Specialization(guards = "isDLLInfo(externalPtr)") @TruffleBoundary - protected RList getRegisteredRoutines(RExternalPtr externalPtr) { + protected RList getRegisteredRoutines(RExternalPtr externalPtr, + @Cached("create()") SetClassAttributeNode setClassAttrNode) { Object[] data = new Object[NAMES.getLength()]; DLL.DLLInfo dllInfo = (DLLInfo) externalPtr.getExternalObject(); RInternalError.guarantee(dllInfo != null); @@ -301,7 +304,7 @@ public class HiddenInternalFunctions { symbolData[i] = symbolInfo.createRSymbolObject(rnt, true); } RList symbolDataList = RDataFactory.createList(symbolData); - symbolDataList.setClassAttr(NATIVE_ROUTINE_LIST); + setClassAttrNode.execute(symbolDataList, NATIVE_ROUTINE_LIST); data[nst.ordinal()] = symbolDataList; } return RDataFactory.createList(data, NAMES); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java index 984935f3b56ac9def0cdc4c4fcc437aafa1d79a3..4a85c00052164f5c2ea76442cfab799fb2cdf6ea 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java @@ -31,11 +31,14 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 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.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -54,8 +57,11 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class IsNA extends RBuiltinNode { @Child private IsNA recursiveIsNA; + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); + @Child private GetDimAttributeNode getDimsNode = GetDimAttributeNode.create(); + @Child private SetDimNamesAttributeNode setDimNamesNode = SetDimNamesAttributeNode.create(); + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final ConditionProfile nullDimNamesProfile = ConditionProfile.createBinaryProfile(); private Object isNARecursive(Object o) { @@ -194,10 +200,10 @@ public abstract class IsNA extends RBuiltinNode { } private RLogicalVector createResult(byte[] data, RAbstractVector originalVector) { - RLogicalVector result = RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR, originalVector.getDimensions(), originalVector.getNames(attrProfiles)); - RList dimNames = originalVector.getDimNames(attrProfiles); + RLogicalVector result = RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR, getDimsNode.getDimensions(originalVector), getNamesNode.getNames(originalVector)); + RList dimNames = getDimNamesNode.getDimNames(originalVector); if (nullDimNamesProfile.profile(dimNames != null)) { - result.setDimNames(dimNames); + setDimNamesNode.setDimNames(result, dimNames); } return result; } 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 2dad6301ea6eca72e44a2a179ab7ffb2d0f5c549..8d3ca0f3b4ef3d2c4cfe9763960769dca7ff01df 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 @@ -28,9 +28,16 @@ import java.util.function.Function; 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.Specialization; 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.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNode; @@ -95,8 +102,8 @@ public class LaFunctions { private final ConditionProfile hasComplexValues = ConditionProfile.createBinaryProfile(); @Specialization - protected Object doRg(RDoubleVector matrix, boolean onlyValues) { - int[] dims = matrix.getDimensions(); + protected Object doRg(RDoubleVector matrix, boolean onlyValues, @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(matrix); // copy array component of matrix as Lapack destroys it int n = dims[0]; double[] a = matrix.getDataCopy(); @@ -189,8 +196,8 @@ public class LaFunctions { @RBuiltin(name = "La_rs", kind = INTERNAL, parameterNames = {"matrix", "onlyValues"}, behavior = PURE) public abstract static class Rs extends RsgAdapter { @Specialization - protected Object doRs(RDoubleVector matrix, boolean onlyValues) { - int[] dims = matrix.getDimensions(); + protected Object doRs(RDoubleVector matrix, boolean onlyValues, @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(matrix); int n = dims[0]; char jobv = onlyValues ? 'N' : 'V'; char uplo = 'L'; @@ -256,13 +263,15 @@ public class LaFunctions { } @Specialization - protected RList doQr(RAbstractDoubleVector aIn) { + 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)"); } RDoubleVector daIn = (RDoubleVector) aIn; - int[] dims = daIn.getDimensions(); + int[] dims = getDimsNode.getDimensions(daIn); // copy array component of matrix as Lapack destroys it int n = dims[0]; int m = dims[1]; @@ -287,7 +296,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); @@ -311,7 +320,9 @@ public class LaFunctions { } @Specialization - protected RDoubleVector doQrCoefReal(RList qIn, RDoubleVector bIn) { + protected RDoubleVector doQrCoefReal(RList qIn, RDoubleVector bIn, + @Cached("create()") GetDimAttributeNode getBDimsNode, + @Cached("create()") GetDimAttributeNode getQDimsNode) { // If bIn was coerced this extra copy is unnecessary RDoubleVector b = (RDoubleVector) bIn.copy(); @@ -320,8 +331,8 @@ public class LaFunctions { RDoubleVector tau = (RDoubleVector) qIn.getDataAt(2); int k = tau.getLength(); - int[] bDims = bIn.getDimensions(); - int[] qrDims = qr.getDimensions(); + int[] bDims = getBDimsNode.getDimensions(bIn); + int[] qrDims = getQDimsNode.getDimensions(qr); int n = qrDims[0]; if (bDims[0] != n) { errorProfile.enter(); @@ -368,6 +379,8 @@ public class LaFunctions { private final ConditionProfile doUseLog = ConditionProfile.createBinaryProfile(); private final NACheck naCheck = NACheck.create(); + @Child private SetFixedAttributeNode setLogAttrNode = SetFixedAttributeNode.create("logarithm"); + @Override protected void createCasts(CastBuilder casts) { //@formatter:off @@ -384,9 +397,10 @@ public class LaFunctions { } @Specialization - protected RList doDetGeReal(RDoubleVector aIn, boolean useLog) { + protected RList doDetGeReal(RDoubleVector aIn, boolean useLog, + @Cached("create()") GetDimAttributeNode getDimsNode) { RDoubleVector a = (RDoubleVector) aIn.copy(); - int[] aDims = aIn.getDimensions(); + int[] aDims = getDimsNode.getDimensions(aIn); int n = aDims[0]; int[] ipiv = new int[n]; double modulus = 0; @@ -437,7 +451,7 @@ public class LaFunctions { } } RDoubleVector modulusVec = RDataFactory.createDoubleVectorFromScalar(modulus); - modulusVec.setAttr("logarithm", RRuntime.asLogical(useLog)); + setLogAttrNode.execute(modulusVec, RRuntime.asLogical(useLog)); RList result = RDataFactory.createList(new Object[]{modulusVec, sign}, NAMES_VECTOR); RVector.setVectorClassAttr(result, DET_CLASS); return result; @@ -450,6 +464,9 @@ public class LaFunctions { private final BranchProfile errorProfile = BranchProfile.create(); private final ConditionProfile noPivot = ConditionProfile.createBinaryProfile(); + @Child private SetFixedAttributeNode setPivotAttrNode = SetFixedAttributeNode.create("pivot"); + @Child private SetFixedAttributeNode setRankAttrNode = SetFixedAttributeNode.create("rank"); + @Override protected void createCasts(CastBuilder casts) { //@formatter:off @@ -469,9 +486,12 @@ public class LaFunctions { } @Specialization - protected RDoubleVector doDetGeReal(RDoubleVector aIn, boolean piv, double tol) { + protected RDoubleVector doDetGeReal(RDoubleVector aIn, boolean piv, double tol, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) { RDoubleVector a = (RDoubleVector) aIn.copy(); - int[] aDims = aIn.getDimensions(); + int[] aDims = getDimsNode.getDimensions(aIn); int n = aDims[0]; int m = aDims[1]; double[] aData = a.getDataWithoutCopying(); @@ -499,16 +519,16 @@ public class LaFunctions { // TODO informative error message (aka GnuR) throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dpotrf"); } - a.setAttr("pivot", RRuntime.asLogical(piv)); - a.setAttr("rank", rank[0]); - RList dn = a.getDimNames(); + setPivotAttrNode.execute(a, RRuntime.asLogical(piv)); + setRankAttrNode.execute(a, rank[0]); + RList dn = getDimNamesNode.getDimNames(a); if (dn != null && dn.getDataAt(0) != null) { Object[] dn2 = new Object[m]; // need to pivot the colnames for (int i = 0; i < m; i++) { dn2[i] = dn.getDataAt(ipiv[i] - 1); } - a.setDimNames(RDataFactory.createList(dn2)); + setDimNamesNode.setDimNames(a, RDataFactory.createList(dn2)); } } return a; @@ -540,8 +560,15 @@ public class LaFunctions { } @Specialization - protected RDoubleVector laSolve(RAbstractVector a, RDoubleVector bin, double tol) { - int[] aDims = a.getDimensions(); + protected RDoubleVector laSolve(RAbstractVector a, RDoubleVector bin, double tol, + @Cached("create()") GetDimAttributeNode getADimsNode, + @Cached("create()") GetDimAttributeNode getBinDimsNode, + @Cached("create()") SetDimAttributeNode setBDimsNode, + @Cached("create()") SetDimNamesAttributeNode setBDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBinDimNamesNode, + @Cached("create()") SetNamesAttributeNode setNamesNode) { + int[] aDims = getADimsNode.getDimensions(a); int n = aDims[0]; if (n == 0) { throw RError.error(this, RError.Message.GENERIC, "'a' is 0-diml"); @@ -550,12 +577,12 @@ public class LaFunctions { if (n2 != n) { throw RError.error(this, RError.Message.MUST_BE_SQUARE, "a", n, n2); } - RList aDn = a.getDimNames(attrProfiles); + RList aDn = getADimNamesNode.getDimNames(a); int p; double[] bData; RDoubleVector b; if (bin.isMatrix()) { - int[] bDims = bin.getDimensions(); + int[] bDims = getBinDimsNode.getDimensions(bin); p = bDims[1]; if (p == 0) { throw RError.error(this, RError.Message.GENERIC, "no right-hand side in 'b'"); @@ -566,8 +593,8 @@ public class LaFunctions { } bData = new double[n * p]; b = RDataFactory.createDoubleVector(bData, RDataFactory.COMPLETE_VECTOR); - b.setDimensions(new int[]{n, p}); - RList binDn = bin.getDimNames(); + setBDimsNode.setDimensions(b, new int[]{n, p}); + RList binDn = getBinDimNamesNode.getDimNames(bin); // This is somewhat odd, but Matrix relies on dropping NULL dimnames if (aDn != null || binDn != null) { // rownames(ans) = colnames(A), colnames(ans) = colnames(Bin) @@ -579,7 +606,7 @@ public class LaFunctions { bDnData[1] = binDn.getDataAt(1); } if (bDnData[0] != null || bDnData[1] != null) { - b.setDimNames(RDataFactory.createList(bDnData)); + setBDimNamesNode.setDimNames(b, RDataFactory.createList(bDnData)); } } } else { @@ -590,7 +617,7 @@ public class LaFunctions { bData = new double[n]; b = RDataFactory.createDoubleVector(bData, RDataFactory.COMPLETE_VECTOR); if (aDn != null) { - b.setNames(RDataFactory.createStringVector((String) aDn.getDataAt(1))); + setNamesNode.setNames(b, RDataFactory.createStringVector((String) aDn.getDataAt(1))); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java index a75fdbb515e1a6c46e2d4a92aedaf3d6a5d9a70a..54ecf0b6dc9db4eaf3fcfd74062c55e6372bb18c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java @@ -33,6 +33,7 @@ import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNodeGen; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.LapplyNodeGen.LapplyInternalNodeGen; @@ -45,7 +46,6 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RSource; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -69,8 +69,6 @@ public abstract class Lapply extends RBuiltinNode { private static final Source CALL_SOURCE = RSource.fromTextInternal("FUN(X[[i]], ...)", RSource.Internal.LAPPLY); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - @Child private LapplyInternalNode lapply = LapplyInternalNodeGen.create(); @Override @@ -83,10 +81,10 @@ public abstract class Lapply extends RBuiltinNode { } @Specialization - protected Object lapply(VirtualFrame frame, RAbstractVector vec, RFunction fun) { + protected Object lapply(VirtualFrame frame, RAbstractVector vec, RFunction fun, @Cached("create()") GetNamesAttributeNode getNamesNode) { Object[] result = lapply.execute(frame, vec, fun); // set here else it gets overridden by the iterator evaluation - return RDataFactory.createList(result, vec.getNames(attrProfiles)); + return RDataFactory.createList(result, getNamesNode.getNames(vec)); } private static final class ExtractElementInternal extends RSourceSectionNode implements RSyntaxCall { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java index 8532659c5be0afa030c0bac1a55a0e52f9406904..457eca9da958eace8975e6ec36c6fb2cd25d90ca 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java @@ -32,6 +32,8 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.UnaryArithmeticBuiltinNode; @@ -39,7 +41,6 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -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.RDoubleVector; @@ -80,7 +81,8 @@ public class LogFunctions { @Specialization protected RDoubleVector log(RAbstractIntVector vector, double base, @Cached("create()") CopyOfRegAttributesNode copyAttrsNode, - @Cached("create()") RAttributeProfiles attrProfiles) { + @Cached("create()") GetNamesAttributeNode getNamesNode, + @Cached("create()") GetDimAttributeNode getDimsNode) { double[] resultVector = new double[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { int inputValue = vector.getDataAt(i); @@ -90,13 +92,14 @@ public class LogFunctions { } resultVector[i] = result; } - return createResult(vector, resultVector, base, copyAttrsNode, attrProfiles); + return createResult(vector, resultVector, base, copyAttrsNode, getNamesNode, getDimsNode); } @Specialization protected RDoubleVector log(RAbstractDoubleVector vector, double base, @Cached("create()") CopyOfRegAttributesNode copyAttrsNode, - @Cached("create()") RAttributeProfiles attrProfiles) { + @Cached("create()") GetNamesAttributeNode getNamesNode, + @Cached("create()") GetDimAttributeNode getDimsNode) { double[] doubleVector = new double[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { double value = vector.getDataAt(i); @@ -105,7 +108,7 @@ public class LogFunctions { } doubleVector[i] = value; } - return createResult(vector, doubleVector, base, copyAttrsNode, attrProfiles); + return createResult(vector, doubleVector, base, copyAttrsNode, getNamesNode, getDimsNode); } private double logb(double x, double base) { @@ -121,8 +124,9 @@ public class LogFunctions { return Math.log(x) / Math.log(base); } - private static RDoubleVector createResult(RAbstractVector source, double[] resultData, double base, CopyOfRegAttributesNode copyAttrsNode, RAttributeProfiles attrProfiles) { - RDoubleVector result = RDataFactory.createDoubleVector(resultData, source.isComplete() && !RRuntime.isNA(base), source.getDimensions(), source.getNames(attrProfiles)); + private static RDoubleVector createResult(RAbstractVector source, double[] resultData, double base, CopyOfRegAttributesNode copyAttrsNode, GetNamesAttributeNode getNamesNode, + GetDimAttributeNode getDimsNode) { + RDoubleVector result = RDataFactory.createDoubleVector(resultData, source.isComplete() && !RRuntime.isNA(base), getDimsNode.getDimensions(source), getNamesNode.getNames(source)); copyAttrsNode.execute(source, result); return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java index f363a88b079d661e0154ec885754984e446561d8..372547fa0f8364b32aa5a51ea702a98dcaeaae62 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java @@ -37,6 +37,7 @@ import com.oracle.truffle.r.nodes.access.FrameSlotNode; import com.oracle.truffle.r.nodes.access.WriteVariableNode; import com.oracle.truffle.r.nodes.access.WriteVariableNode.Mode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.MapplyNodeGen.MapplyInternalNodeGen; @@ -49,7 +50,6 @@ import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLogicalVector; @@ -124,7 +124,7 @@ public abstract class Mapply extends RBuiltinNode { } } - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); public abstract Object[] execute(VirtualFrame frame, RAbstractListVector dots, RFunction function, RAbstractListVector additionalArguments); @@ -215,13 +215,13 @@ public abstract class Mapply extends RBuiltinNode { } Object[] values = new Object[dotsLength + moreArgsLength]; String[] names = new String[dotsLength + moreArgsLength]; - RStringVector dotsNames = dots.getNames(attrProfiles); + RStringVector dotsNames = getNames.getNames(dots); if (dotsNames != null) { for (int listIndex = 0; listIndex < dotsLength; listIndex++) { names[listIndex] = dotsNames.getDataAt(listIndex).isEmpty() ? null : dotsNames.getDataAt(listIndex); } } - RStringVector moreArgsNames = moreArgs.getNames(attrProfiles); + RStringVector moreArgsNames = getNames.getNames(moreArgs); for (int listIndex = dotsLength; listIndex < dotsLength + moreArgsLength; listIndex++) { values[listIndex] = moreArgs.getDataAt(listIndex - dotsLength); names[listIndex] = moreArgsNames == null ? null : (moreArgsNames.getDataAt(listIndex - dotsLength).isEmpty() ? null : moreArgsNames.getDataAt(listIndex - dotsLength)); @@ -260,11 +260,11 @@ public abstract class Mapply extends RBuiltinNode { protected ElementNode[] createElementNodeArray(RAbstractListVector dots, RAbstractListVector moreArgs) { int length = dots.getLength() + moreArgs.getLength(); ElementNode[] elementNodes = new ElementNode[length]; - RStringVector dotsNames = dots.getNames(attrProfiles); + RStringVector dotsNames = getNames.getNames(dots); for (int i = 0; i < dots.getLength(); i++) { elementNodes[i] = insert(new ElementNode(VECTOR_ELEMENT_PREFIX + (i + 1), dotsNames == null ? null : (dotsNames.getDataAt(i).isEmpty() ? null : dotsNames.getDataAt(i)))); } - RStringVector moreArgsNames = moreArgs.getNames(attrProfiles); + RStringVector moreArgsNames = getNames.getNames(moreArgs); for (int i = dots.getLength(); i < dots.getLength() + moreArgs.getLength(); i++) { elementNodes[i] = insert(new ElementNode(VECTOR_ELEMENT_PREFIX + (i + 1), moreArgsNames == null ? null : moreArgsNames.getDataAt(i - dots.getLength()).isEmpty() ? null : moreArgsNames.getDataAt(i - dots.getLength()))); @@ -289,14 +289,17 @@ public abstract class Mapply extends RBuiltinNode { } protected boolean sameNames(RAbstractListVector list, RAbstractListVector cachedList) { - if (list.getNames(attrProfiles) == null && cachedList.getNames(attrProfiles) == null) { + RStringVector listNames = getNames.getNames(list); + RStringVector cachedListNames = getNames.getNames(cachedList); + if (listNames == null && cachedListNames == null) { return true; - } else if (list.getNames(attrProfiles) == null || cachedList.getNames(attrProfiles) == null) { + } else if (listNames == null || cachedListNames == null) { return false; } else { + for (int i = 0; i < list.getLength(); i++) { - String name = list.getNames(attrProfiles).getDataAt(i); - String cachedName = cachedList.getNames(attrProfiles).getDataAt(i); + String name = listNames.getDataAt(i); + String cachedName = cachedListNames.getDataAt(i); if (name == cachedName) { continue; 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 c7a5ea146e47895dba8a926822b61db083c8c696..7bee0fa552fc045332ea15babf8bdaa0daca15f6 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 @@ -34,12 +34,15 @@ 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.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.binary.BinaryMapArithmeticFunctionNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -71,10 +74,12 @@ public abstract class MatMult extends RBuiltinNode { private final ConditionProfile notOneRow = ConditionProfile.createBinaryProfile(); private final ConditionProfile notOneColumn = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles aDimAttributeProfile = RAttributeProfiles.create(); - private final RAttributeProfiles bDimAttributeProfile = RAttributeProfiles.create(); private final ConditionProfile noDimAttributes = ConditionProfile.createBinaryProfile(); + @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); private final NACheck na; @@ -88,24 +93,26 @@ public abstract class MatMult extends RBuiltinNode { return MatMultNodeGen.create(true); } - @Specialization(guards = "bothZeroDim(a, b)") + @Specialization(guards = "bothZeroDim(a, b, getADimsNode, getBDimsNode)") protected RDoubleVector both0Dim(RAbstractDoubleVector a, RAbstractDoubleVector b) { - int r = b.getDimensions()[1]; - int c = a.getDimensions()[0]; + 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; } - @Specialization(guards = "hasZeroDim(a)") + @Specialization(guards = "hasZeroDim(a, getADimsNode)") protected RAbstractVector left0Dim(RAbstractVector a, RAbstractVector b) { - int[] dim = a.getDimensions()[0] == 0 ? new int[]{0, b.getDimensions()[1]} : new int[]{b.getDimensions()[0], 0}; + int[] aDim = getADimsNode.getDimensions(a); + int[] dim = aDim[0] == 0 ? new int[]{0, getBDimsNode.getDimensions(b)[1]} : new int[]{getBDimsNode.getDimensions(b)[0], 0}; return a.copyWithNewDimensions(dim); } - @Specialization(guards = "hasZeroDim(b)") + @Specialization(guards = "hasZeroDim(b, getBDimsNode)") protected RAbstractVector right0Dim(RAbstractVector a, RAbstractVector b) { - int[] dim = b.getDimensions()[0] == 0 ? new int[]{0, a.getDimensions()[1]} : new int[]{a.getDimensions()[0], 0}; + int[] bDim = getBDimsNode.getDimensions(b); + int[] dim = bDim[0] == 0 ? new int[]{0, getADimsNode.getDimensions(a)[1]} : new int[]{getADimsNode.getDimensions(a)[0], 0}; return b.copyWithNewDimensions(dim); } @@ -133,8 +140,9 @@ public abstract class MatMult extends RBuiltinNode { private final BranchProfile incompleteProfile = BranchProfile.create(); @CompilationFinal private boolean seenLargeMatrix; - private RDoubleVector doubleMatrixMultiply(RAbstractDoubleVector a, RAbstractDoubleVector b, int aRows, int aCols, int bRows, int bCols) { - return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols, 1, aRows, 1, bRows, false); + private RDoubleVector doubleMatrixMultiply(RAbstractDoubleVector a, RAbstractDoubleVector b, int aRows, int aCols, int bRows, int bCols, SetDimNamesAttributeNode setDimNamesNode, + GetDimNamesAttributeNode getADimNamesNode, GetDimNamesAttributeNode getBDimNamesNode) { + return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols, 1, aRows, 1, bRows, false, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } /** @@ -155,7 +163,7 @@ public abstract class MatMult extends RBuiltinNode { * @return the result vector */ public RDoubleVector doubleMatrixMultiply(RAbstractDoubleVector a, RAbstractDoubleVector b, int aRows, int aCols, int bRows, int bCols, int aRowStride, int aColStride, int bRowStride, - int bColStride, boolean mirrored) { + int bColStride, boolean mirrored, SetDimNamesAttributeNode setDimNamesNode, GetDimNamesAttributeNode getADimNamesNode, GetDimNamesAttributeNode getBDimNamesNode) { if (aCols != bRows) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -207,8 +215,8 @@ public abstract class MatMult extends RBuiltinNode { } RDoubleVector resultVec = RDataFactory.createDoubleVector(result, complete, new int[]{aRows, bCols}); - RList aDimNames = a.getDimNames(aDimAttributeProfile); - RList bDimNames = b.getDimNames(bDimAttributeProfile); + RList aDimNames = getADimNamesNode.getDimNames(a); + RList bDimNames = getBDimNamesNode.getDimNames(b); if (!promoteDimNames || noDimAttributes.profile(aDimNames == null && bDimNames == null)) { return resultVec; } @@ -220,7 +228,7 @@ public abstract class MatMult extends RBuiltinNode { if (bDimNames != null && bDimNames.getLength() > 1) { newDimsNames[1] = bDimNames.getDataAt(1); } - resultVec.setDimNames(RDataFactory.createList(newDimsNames)); + setDimNamesNode.setDimNames(resultVec, RDataFactory.createList(newDimsNames)); return resultVec; } @@ -265,15 +273,19 @@ public abstract class MatMult extends RBuiltinNode { protected RDoubleVector multiply(RAbstractDoubleVector a, RAbstractDoubleVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { if (aIsMatrix.profile(a.isMatrix())) { if (bIsMatrix.profile(b.isMatrix())) { - int[] aDimensions = a.getDimensions(); - int[] bDimensions = b.getDimensions(); - return doubleMatrixMultiply(a, b, aDimensions[0], aDimensions[1], bDimensions[0], bDimensions[1]); + int[] aDimensions = getADimsNode.getDimensions(a); + int[] bDimensions = getBDimsNode.getDimensions(b); + return doubleMatrixMultiply(a, b, aDimensions[0], aDimensions[1], bDimensions[0], bDimensions[1], setDimNamesNode, getADimNamesNode, getBDimNamesNode); } else { - int aRows = a.getDimensions()[0]; - int aCols = a.getDimensions()[1]; + int[] aDim = getADimsNode.getDimensions(a); + int aRows = aDim[0]; + int aCols = aDim[1]; int bRows; int bCols; if (lengthEquals.profile(aCols == b.getLength())) { @@ -283,12 +295,13 @@ public abstract class MatMult extends RBuiltinNode { bRows = 1; bCols = b.getLength(); } - return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols); + return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } } else { if (bIsMatrix.profile(b.isMatrix())) { - int bRows = b.getDimensions()[0]; - int bCols = b.getDimensions()[1]; + int[] bDim = getBDimsNode.getDimensions(b); + int bRows = bDim[0]; + int bCols = bDim[1]; int aRows; int aCols; if (lengthEquals.profile(bRows == a.getLength())) { @@ -298,7 +311,7 @@ public abstract class MatMult extends RBuiltinNode { aRows = a.getLength(); aCols = 1; } - return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols); + return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } else { if (a.getLength() != b.getLength()) { errorProfile.enter(); @@ -328,14 +341,16 @@ public abstract class MatMult extends RBuiltinNode { @Cached("createBinaryProfile()") ConditionProfile bIsMatrix) { if (aIsMatrix.profile(a.isMatrix())) { if (bIsMatrix.profile(b.isMatrix())) { - final int aCols = a.getDimensions()[1]; - final int bRows = b.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + int[] bDim = getBDimsNode.getDimensions(b); + final int aCols = aDim[1]; + final int bRows = bDim[0]; if (aCols != bRows) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); } - final int aRows = a.getDimensions()[0]; - final int bCols = b.getDimensions()[1]; + final int aRows = aDim[0]; + final int bCols = bDim[1]; double[] result = new double[(aRows * bCols) << 1]; na.enable(a); na.enable(b); @@ -353,8 +368,9 @@ public abstract class MatMult extends RBuiltinNode { } return RDataFactory.createComplexVector(result, na.neverSeenNA(), new int[]{aRows, bCols}); } else { - final int aCols = a.getDimensions()[1]; - final int aRows = a.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + final int aCols = aDim[1]; + final int aRows = aDim[0]; if (aCols != 1 && aCols != b.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -388,8 +404,9 @@ public abstract class MatMult extends RBuiltinNode { } } else { if (bIsMatrix.profile(b.isMatrix())) { - final int bRows = b.getDimensions()[0]; - final int bCols = b.getDimensions()[1]; + int[] bDim = getBDimsNode.getDimensions(b); + final int bRows = bDim[0]; + final int bCols = bDim[1]; if (bRows != 1 && bRows != a.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -445,14 +462,16 @@ public abstract class MatMult extends RBuiltinNode { @Cached("createBinaryProfile()") ConditionProfile bIsMatrix) { if (aIsMatrix.profile(a.isMatrix())) { if (bIsMatrix.profile(b.isMatrix())) { - final int aCols = a.getDimensions()[1]; - final int bRows = b.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + int[] bDim = getBDimsNode.getDimensions(b); + final int aCols = aDim[1]; + final int bRows = bDim[0]; if (aCols != bRows) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); } - final int aRows = a.getDimensions()[0]; - final int bCols = b.getDimensions()[1]; + final int aRows = aDim[0]; + final int bCols = bDim[1]; int[] result = new int[aRows * bCols]; na.enable(a); na.enable(b); @@ -468,8 +487,9 @@ public abstract class MatMult extends RBuiltinNode { } return RDataFactory.createIntVector(result, na.neverSeenNA(), new int[]{aRows, bCols}); } else { - final int aCols = a.getDimensions()[1]; - final int aRows = a.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + final int aCols = aDim[1]; + final int aRows = aDim[0]; if (aCols != 1 && aCols != b.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -500,9 +520,10 @@ public abstract class MatMult extends RBuiltinNode { } } } else { + int[] bDim = getBDimsNode.getDimensions(b); if (bIsMatrix.profile(b.isMatrix())) { - final int bCols = b.getDimensions()[1]; - final int bRows = b.getDimensions()[0]; + final int bCols = bDim[1]; + final int bRows = bDim[0]; if (bRows != 1 && bRows != a.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -622,32 +643,44 @@ public abstract class MatMult extends RBuiltinNode { protected RDoubleVector multiply(RAbstractIntVector a, RAbstractDoubleVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { - return multiply(RClosures.createIntToDoubleVector(a), b, aIsMatrix, bIsMatrix, lengthEquals); + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + return multiply(RClosures.createIntToDoubleVector(a), b, aIsMatrix, bIsMatrix, lengthEquals, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } @Specialization protected RDoubleVector multiply(RAbstractDoubleVector a, RAbstractIntVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { - return multiply(a, RClosures.createIntToDoubleVector(b), aIsMatrix, bIsMatrix, lengthEquals); + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + return multiply(a, RClosures.createIntToDoubleVector(b), aIsMatrix, bIsMatrix, lengthEquals, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } @Specialization protected RDoubleVector multiply(RAbstractLogicalVector a, RAbstractDoubleVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { - return multiply(RClosures.createLogicalToDoubleVector(a), b, aIsMatrix, bIsMatrix, lengthEquals); + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + return multiply(RClosures.createLogicalToDoubleVector(a), b, aIsMatrix, bIsMatrix, lengthEquals, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } @Specialization protected RDoubleVector multiply(RAbstractDoubleVector a, RAbstractLogicalVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { - return multiply(a, RClosures.createLogicalToDoubleVector(b), aIsMatrix, bIsMatrix, lengthEquals); + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + return multiply(a, RClosures.createLogicalToDoubleVector(b), aIsMatrix, bIsMatrix, lengthEquals, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } // errors @@ -660,15 +693,16 @@ public abstract class MatMult extends RBuiltinNode { // guards - protected static boolean bothZeroDim(RAbstractVector a, RAbstractVector b) { - return hasZeroDim(a) && hasZeroDim(b); + protected static boolean bothZeroDim(RAbstractVector a, RAbstractVector b, GetDimAttributeNode getADimsNode, GetDimAttributeNode getBDimsNode) { + return hasZeroDim(a, getADimsNode) && hasZeroDim(b, getBDimsNode); } - protected static boolean hasZeroDim(RAbstractVector v) { - if (!v.hasDimensions()) { + protected static boolean hasZeroDim(RAbstractVector v, GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(v); + if (dims == null || dims.length == 0) { return false; } - for (int d : v.getDimensions()) { + for (int d : dims) { if (d == 0) { return true; } 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/NChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java index 1f0a0a0deb44b0cb65f736923ed39858c624ab8f..c2faec1d69a4fca54a7103a68e8e3552c7ac485b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java @@ -33,11 +33,14 @@ 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.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RList; @@ -67,8 +70,11 @@ public abstract class NChar extends RBuiltinNode { @Specialization protected RIntVector ncharInt(RAbstractIntVector vector, String type, boolean allowNA, boolean keepNA, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, - @Cached("create()") RAttributeProfiles attrProfiles, - @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile) { + @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile, + @Cached("create()") GetDimAttributeNode getDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { int len = vector.getLength(); int[] result = new int[len]; loopProfile.profileCounted(len); @@ -80,10 +86,10 @@ public abstract class NChar extends RBuiltinNode { result[i] = (int) (Math.log10(x) + 1); // not the fastest one } } - RIntVector resultVector = RDataFactory.createIntVector(result, true, vector.getDimensions(), vector.getNames(attrProfiles)); - RList dimNames = vector.getDimNames(attrProfiles); + RIntVector resultVector = RDataFactory.createIntVector(result, true, getDimNode.getDimensions(vector), getNamesNode.getNames(vector)); + RList dimNames = getDimNamesNode.getDimNames(vector); if (nullDimNamesProfile.profile(dimNames != null)) { - resultVector.setDimNames(dimNames); + setDimNamesNode.setDimNames(resultVector, dimNames); } return resultVector; } @@ -92,18 +98,21 @@ public abstract class NChar extends RBuiltinNode { @Specialization protected RIntVector nchar(RAbstractStringVector vector, String type, boolean allowNA, boolean keepNA, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, - @Cached("create()") RAttributeProfiles attrProfiles, - @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile) { + @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile, + @Cached("create()") GetDimAttributeNode getDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { int len = vector.getLength(); int[] result = new int[len]; loopProfile.profileCounted(len); for (int i = 0; loopProfile.inject(i < len); i++) { result[i] = vector.getDataAt(i).length(); } - RIntVector resultVector = RDataFactory.createIntVector(result, true, vector.getDimensions(), vector.getNames(attrProfiles)); - RList dimNames = vector.getDimNames(attrProfiles); + RIntVector resultVector = RDataFactory.createIntVector(result, true, getDimNode.getDimensions(vector), getNamesNode.getNames(vector)); + RList dimNames = getDimNamesNode.getDimNames(vector); if (nullDimNamesProfile.profile(dimNames != null)) { - resultVector.setDimNames(dimNames); + setDimNamesNode.setDimNames(resultVector, dimNames); } return resultVector; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java index 91e6f763bcd36279b045cded3fa328d0a1cdf242..55c50f76361cc2080b1c84120370207135a03ece 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java @@ -30,10 +30,11 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 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.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -41,12 +42,13 @@ import com.oracle.truffle.r.runtime.env.REnvironment; public abstract class Names extends RBuiltinNode { private final ConditionProfile hasNames = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @Specialization protected Object getNames(RAbstractContainer container) { - if (hasNames.profile(container.getNames(attrProfiles) != null)) { - return container.getNames(attrProfiles); + RStringVector names = getNames.getNames(container); + if (hasNames.profile(names != null)) { + return names; } else { return RNull.instance; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java index f5487620db0fb63a21abd652f71710e0cf582d99..9486a8a9d9f6bde07fe95e17735384e70462fcb8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java @@ -22,7 +22,7 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import static com.oracle.truffle.r.runtime.RVisibility.CUSTOM; import static com.oracle.truffle.r.runtime.builtins.RBehavior.MODIFIES_STATE; import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_STATE; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java index 8ac93354d9a2fdb4f9223c82978ee91a8110bf19..07a3c5f15a5a4458d230723f3b594788c05983c8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java @@ -35,6 +35,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; @@ -96,6 +97,10 @@ public abstract class Parse extends RBuiltinNode { @Child private CastStringNode castStringNode; @Child private CastToVectorNode castVectorNode; + @Child private SetFixedAttributeNode setSrcRefAttrNode = SetFixedAttributeNode.create("srcref"); + @Child private SetFixedAttributeNode setWholeSrcRefAttrNode = SetFixedAttributeNode.create("wholeSrcref"); + @Child private SetFixedAttributeNode setSrcFileAttrNode = SetFixedAttributeNode.create("srcfile"); + @Override protected void createCasts(CastBuilder casts) { // Note: string is captured by the R wrapper and transformed to a file, other types not @@ -219,7 +224,7 @@ public abstract class Parse extends RBuiltinNode { } } - private static void addAttributes(RExpression exprs, Source source, REnvironment srcFile) { + private void addAttributes(RExpression exprs, Source source, REnvironment srcFile) { Object[] srcrefData = new Object[exprs.getLength()]; for (int i = 0; i < srcrefData.length; i++) { Object data = exprs.getDataAt(i); @@ -239,7 +244,7 @@ public abstract class Parse extends RBuiltinNode { } } - exprs.setAttr("srcref", RDataFactory.createList(srcrefData)); + setSrcRefAttrNode.execute(exprs, RDataFactory.createList(srcrefData)); int[] wholeSrcrefData = new int[8]; int endOffset = source.getCode().length() - 1; wholeSrcrefData[0] = source.getLineNumber(0); @@ -248,8 +253,8 @@ public abstract class Parse extends RBuiltinNode { wholeSrcrefData[6] = wholeSrcrefData[0]; wholeSrcrefData[6] = wholeSrcrefData[3]; - exprs.setAttr("wholeSrcref", RDataFactory.createIntVector(wholeSrcrefData, RDataFactory.COMPLETE_VECTOR)); - exprs.setAttr("srcfile", srcFile); + setWholeSrcRefAttrNode.execute(exprs, RDataFactory.createIntVector(wholeSrcrefData, RDataFactory.COMPLETE_VECTOR)); + setSrcFileAttrNode.execute(exprs, srcFile); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java index be182b91b23a5b1ef9147f6ae56359df1f2d456c..24496e3ae2d465157530b90cb0d3a2f76122ff08 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java @@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; @@ -44,6 +45,8 @@ public abstract class ProcTime extends RBuiltinNode { private static RStringVector RNAMES; + @Child private SetClassAttributeNode setClassAttrNode = SetClassAttributeNode.create(); + @Specialization @TruffleBoundary protected RDoubleVector procTime() { @@ -65,7 +68,8 @@ public abstract class ProcTime extends RBuiltinNode { RNAMES = RDataFactory.createStringVector(NAMES, RDataFactory.COMPLETE_VECTOR); } RDoubleVector result = RDataFactory.createDoubleVector(data, complete, RNAMES); - result.setClassAttr(PROC_TIME_CLASS); + setClassAttrNode.execute(result, PROC_TIME_CLASS); + return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java index 743d510865d5285d571a2fc60fcc33c6765e69e3..e89c2645f46e5482347b24152fbff85318ef7c3a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java @@ -37,14 +37,14 @@ import com.oracle.truffle.api.dsl.Cached; 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.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -83,7 +83,7 @@ public abstract class Repeat extends RBuiltinNode { private final BranchProfile errorBranch = BranchProfile.create(); private final ConditionProfile oneTimeGiven = ConditionProfile.createBinaryProfile(); private final ConditionProfile replicateOnce = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @Override public Object[] getDefaultParameterValues() { @@ -106,7 +106,7 @@ public abstract class Repeat extends RBuiltinNode { } protected boolean hasNames(RAbstractVector x) { - return x.getNames(attrProfiles) != null; + return getNames.getNames(x) != null; } private RError invalidTimes() { @@ -158,7 +158,7 @@ public abstract class Repeat extends RBuiltinNode { throw invalidTimes(); } RAbstractVector input = handleEach(x, each); - RStringVector names = (RStringVector) handleEach(x.getNames(attrProfiles), each); + RStringVector names = (RStringVector) handleEach(getNames.getNames(x), each); RVector<?> r; if (lengthOutOrTimes.profile(!RRuntime.isNA(lengthOut))) { names = (RStringVector) handleLengthOut(names, lengthOut, false); @@ -168,7 +168,6 @@ public abstract class Repeat extends RBuiltinNode { r = handleTimes(input, times, false); } putNames.execute(initAttributes.execute(r), names); - r.setInternalNames(names); return r; } @@ -179,14 +178,13 @@ public abstract class Repeat extends RBuiltinNode { RStringVector names; RVector<?> r; if (lengthOutOrTimes.profile(!RRuntime.isNA(lengthOut))) { - names = (RStringVector) handleLengthOut(x.getNames(attrProfiles), lengthOut, true); + names = (RStringVector) handleLengthOut(getNames.getNames(x), lengthOut, true); r = handleLengthOut(x, lengthOut, true); } else { - names = (RStringVector) handleTimes(x.getNames(attrProfiles), times, true); + names = (RStringVector) handleTimes(getNames.getNames(x), times, true); r = handleTimes(x, times, true); } putNames.execute(initAttributes.execute(r), names); - r.setInternalNames(names); return r; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java index e6bce9fd7f17f5cd0f3016bc0a853fa078a1aa93..8a5488c18d78944eeb4a906301b760a75846ef0b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java @@ -32,7 +32,6 @@ import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -55,7 +54,6 @@ public abstract class Round extends RBuiltinNode { @Child private RoundArithmetic roundOp = new RoundArithmetic(); private final NACheck check = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Override public Object[] getDefaultParameterValues() { @@ -124,7 +122,7 @@ public abstract class Round extends RBuiltinNode { result[i] = check.check(value) ? RRuntime.DOUBLE_NA : round(value, digits); } RDoubleVector ret = RDataFactory.createDoubleVector(result, check.neverSeenNA()); - ret.copyAttributesFrom(attrProfiles, x); + ret.copyAttributesFrom(x); return ret; } @@ -137,7 +135,7 @@ public abstract class Round extends RBuiltinNode { result[i] = check.check(value) ? RRuntime.DOUBLE_NA : roundDigits(value, digits); } RDoubleVector ret = RDataFactory.createDoubleVector(result, check.neverSeenNA()); - ret.copyAttributesFrom(attrProfiles, x); + ret.copyAttributesFrom(x); return ret; } @@ -165,7 +163,7 @@ public abstract class Round extends RBuiltinNode { check.check(r); } RComplexVector ret = RDataFactory.createComplexVector(result, check.neverSeenNA()); - ret.copyAttributesFrom(attrProfiles, x); + ret.copyAttributesFrom(x); return ret; } @@ -181,7 +179,7 @@ public abstract class Round extends RBuiltinNode { check.check(r); } RComplexVector ret = RDataFactory.createComplexVector(result, check.neverSeenNA()); - ret.copyAttributesFrom(attrProfiles, x); + ret.copyAttributesFrom(x); return ret; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java index 6a4d2b0e3a599bbb0089d72d2dd6ae6b81277597..d9396a717a28d8f3084ab5a169a2ab44bc4fa0ac 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java @@ -31,18 +31,18 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.conn.StdConnections; -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.RDouble; @@ -67,7 +67,7 @@ public abstract class Scan extends RBuiltinNode { private final NACheck naCheck = NACheck.create(); private final BranchProfile errorProfile = BranchProfile.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @Child private CastToVectorNode castVector; @@ -338,7 +338,7 @@ public abstract class Scan extends RBuiltinNode { list.updateDataAt(i, vec.createEmptySameType(blockSize, RDataFactory.COMPLETE_VECTOR), null); } } - list.setNames(what.getNames(attrProfiles)); + list.setNames(getNames.getNames(what)); naCheck.enable(true); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java index e318c352f9a7e3ded51e0bd78d06cfb50c9d1501..17a035de4a7ff78c82f6ecf809bc11439af6a064 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java @@ -31,12 +31,12 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.IntValueProfile; import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetRowNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -46,10 +46,11 @@ import com.oracle.truffle.r.runtime.env.REnvironment; public abstract class ShortRowNames extends RBuiltinNode { private final BranchProfile naValueMet = BranchProfile.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile errorProfile = BranchProfile.create(); private final ValueProfile operandTypeProfile = ValueProfile.createClassProfile(); + @Child private GetRowNamesAttributeNode getRowNamesNode = GetRowNamesAttributeNode.create(); + @Override protected void createCasts(CastBuilder casts) { casts.arg("type").asIntegerVector().findFirst().mustBe(gte0().and(lte(2))); @@ -62,9 +63,9 @@ public abstract class ShortRowNames extends RBuiltinNode { Object operand = operandTypeProfile.profile(originalOperand); Object rowNames; if (operand instanceof RAbstractContainer) { - rowNames = ((RAbstractContainer) operand).getRowNames(attrProfiles); + rowNames = getRowNamesNode.getRowNames((RAbstractContainer) operand); } else if (operand instanceof REnvironment) { - rowNames = ((REnvironment) operand).getAttr(attrProfiles, RRuntime.ROWNAMES_ATTR_KEY); + rowNames = getRowNamesNode.execute(operand); } else { // for any other type GnuR returns 0 return 0; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java index 0313cad4b98aec16177b01b33fe7021ffa3fa6ee..31023607abacfbcd6dffea008880f47efebf75ec 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java @@ -33,12 +33,13 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNodeGen; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @@ -52,9 +53,10 @@ public abstract class ToLowerOrUpper { private final VectorLengthProfile lengthProfile = VectorLengthProfile.create(); private final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile(); private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @Child private CopyOfRegAttributesNode copyAttributes = CopyOfRegAttributesNodeGen.create(); + @Child private GetDimAttributeNode getDimNode = GetDimAttributeNode.create(); private StringMapNode() { // nothing to do @@ -82,7 +84,7 @@ public abstract class ToLowerOrUpper { String value = vector.getDataAt(i); stringVector[i] = elementFunction(value, i, function); } - RStringVector result = RDataFactory.createStringVector(stringVector, vector.isComplete(), vector.getDimensions(), vector.getNames(attrProfiles)); + RStringVector result = RDataFactory.createStringVector(stringVector, vector.isComplete(), getDimNode.getDimensions(vector), getNames.getNames(vector)); copyAttributes.execute(vector, result); return result; } 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 ec945bb76c07a474ac8f40471b3ab7473c12b4d1..db8fcf308280a90a6933d6a4afd755b6a69584b6 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 @@ -25,14 +25,14 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNodeGen; -import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -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.RList; @@ -50,7 +50,6 @@ import com.oracle.truffle.r.runtime.nodes.RNode; @RBuiltin(name = "t.default", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE) public abstract class Transpose extends RBuiltinNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile hasDimNamesProfile = BranchProfile.create(); private final ConditionProfile isMatrixProfile = ConditionProfile.createBinaryProfile(); @@ -61,6 +60,7 @@ public abstract class Transpose extends RBuiltinNode { @Child private InitAttributesNode initAttributes = InitAttributesNode.create(); @Child private SetFixedAttributeNode putDimensions = SetFixedAttributeNode.createDim(); @Child private SetFixedAttributeNode putDimNames = SetFixedAttributeNode.createDimNames(); + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); public abstract Object execute(RAbstractVector o); @@ -96,15 +96,13 @@ public abstract class Transpose extends RBuiltinNode { copyRegAttributes.execute(vector, r); // set new dimensions int[] newDim = new int[]{secondDim, firstDim}; - r.setInternalDimensions(newDim); putDimensions.execute(initAttributes.execute(r), RDataFactory.createIntVector(newDim, RDataFactory.COMPLETE_VECTOR)); // set new dim names - RList dimNames = vector.getDimNames(attrProfiles); + RList dimNames = getDimNamesNode.getDimNames(vector); if (dimNames != null) { 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/Unlist.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java index 03cf59487b7a937e378b58662b29d18458f38740..8558fef08d71acb5d113e9d833217db0c34a7f97 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java @@ -22,6 +22,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.UnlistNodeGen.RecursiveLengthNodeGen; @@ -31,7 +32,6 @@ import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.context.RContext; -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.RFunction; @@ -57,8 +57,7 @@ public abstract class Unlist extends RBuiltinNode { @Child private PrecedenceNode precedenceNode = PrecedenceNodeGen.create(); @Child private Length lengthNode; @Child private RecursiveLength recursiveLengthNode; - - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @TypeSystemReference(RTypes.class) protected abstract static class RecursiveLength extends Node { @@ -189,7 +188,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.RAW_PRECEDENCE: { byte[] result = new byte[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -204,7 +204,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.LOGICAL_PRECEDENCE: { byte[] result = new byte[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -220,7 +221,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.INT_PRECEDENCE: { int[] result = new int[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -236,7 +238,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.DOUBLE_PRECEDENCE: { double[] result = new double[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -252,7 +255,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.COMPLEX_PRECEDENCE: { double[] result = new double[totalSize << 1]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -268,7 +272,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.STRING_PRECEDENCE: { String[] result = new String[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -285,7 +290,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.EXPRESSION_PRECEDENCE: { Object[] result = new Object[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -337,7 +343,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -373,7 +380,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -409,7 +417,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -445,7 +454,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -481,7 +491,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -522,7 +533,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -558,7 +570,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); 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 11bc95e938d5a7b6c2e3a9127e07b22fb9b2d582..34c1d680f8290eead7dfaabaed28894cabb35bd4 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 @@ -34,6 +34,10 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 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; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; @@ -66,6 +70,10 @@ public abstract class UpdateAttr extends RBuiltinNode { @Child private CastIntegerNode castInteger; @Child private CastToVectorNode castVector; @Child private CastListNode castList; + @Child private SetClassAttributeNode setClassAttrNode; + @Child private SetRowNamesAttributeNode setRowNamesAttrNode; + @Child private SetAttributeNode setGenAttrNode; + @Child private SetDimAttributeNode setDimNode; @CompilationFinal private String cachedName = ""; @CompilationFinal private String cachedInternedName = ""; @@ -138,15 +146,28 @@ 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) { return updateDimNames(result, value); } else if (internedName == RRuntime.CLASS_ATTR_KEY) { - return (RAbstractContainer) result.setClassAttr(null); + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + setClassAttrNode.reset(result); + return result; } else if (internedName == RRuntime.ROWNAMES_ATTR_KEY) { - result.setRowNames(null); + if (setRowNamesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setRowNamesAttrNode = insert(SetRowNamesAttributeNode.create()); + } + setRowNamesAttrNode.setRowNames(result, null); } else if (result.getAttributes() != null) { result.removeAttr(attrProfiles, internedName); } @@ -175,18 +196,35 @@ 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) { return updateDimNames(result, value); } else if (internedName == RRuntime.CLASS_ATTR_KEY) { - return (RAbstractContainer) result.setClassAttr(convertClassAttrFromObject(value)); + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + setClassAttrNode.execute(result, convertClassAttrFromObject(value)); + return result; } else if (internedName == RRuntime.ROWNAMES_ATTR_KEY) { - result.setRowNames(castVector(value)); + if (setRowNamesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setRowNamesAttrNode = insert(SetRowNamesAttributeNode.create()); + } + setRowNamesAttrNode.setRowNames(result, castVector(value)); } else { // generic attribute - result.setAttr(internedName, value); + if (setGenAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setGenAttrNode = insert(SetAttributeNode.create()); + } + setGenAttrNode.execute(result, internedName, value); } return result; 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 31ce0f85a414a66a52bc6d3757e9398960508d74..4e0c99102cbac929b1bff3705111ca5f2e9f4f43 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 @@ -31,6 +31,10 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +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; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; @@ -55,11 +59,15 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class UpdateAttributes extends RBuiltinNode { private final ConditionProfile numAttributesProfile = ConditionProfile.createBinaryProfile(); private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Child private UpdateNames updateNames; @Child private UpdateDimNames updateDimNames; @Child private CastIntegerNode castInteger; @Child private CastToVectorNode castVector; + @Child private SetAttributeNode setAttrNode; + @Child private SetDimAttributeNode setDimNode; + @Child private SetRowNamesAttributeNode setRowNamesNode; @Override protected void createCasts(CastBuilder casts) { @@ -113,7 +121,7 @@ public abstract class UpdateAttributes extends RBuiltinNode { @Specialization protected RAbstractContainer updateAttributes(RAbstractContainer container, RList list) { - Object listNamesObject = list.getNames(attrProfiles); + Object listNamesObject = getNamesNode.getNames(list); if (listNamesObject == null || listNamesObject == RNull.instance) { throw RError.error(this, RError.Message.ATTRIBUTES_NAMED); } @@ -154,28 +162,34 @@ public abstract class UpdateAttributes extends RBuiltinNode { } private void setDimAttribute(RAbstractContainer result, RList sourceList) { - RStringVector listNames = sourceList.getNames(attrProfiles); + RStringVector listNames = getNamesNode.getNames(sourceList); int length = sourceList.getLength(); assert length > 0 : "Length should be > 0 for ExplodeLoop"; for (int i = 0; i < sourceList.getLength(); i++) { 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()); } } } } private RAbstractContainer setRemainingAttributes(RAbstractContainer result, RList sourceList) { - RStringVector listNames = sourceList.getNames(attrProfiles); + RStringVector listNames = getNamesNode.getNames(sourceList); int length = sourceList.getLength(); assert length > 0 : "Length should be > 0 for ExplodeLoop"; RAbstractContainer res = result; @@ -190,17 +204,26 @@ public abstract class UpdateAttributes extends RBuiltinNode { res = updateDimNames(res, value); } else if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) { if (value == RNull.instance) { - res = (RAbstractContainer) result.setClassAttr(null); + res.setClassAttr(null); } else { - res = (RAbstractContainer) result.setClassAttr(UpdateAttr.convertClassAttrFromObject(value)); + res.setClassAttr(UpdateAttr.convertClassAttrFromObject(value)); } + res = result; } else if (attrName.equals(RRuntime.ROWNAMES_ATTR_KEY)) { - res.setRowNames(castVector(value)); + if (setRowNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setRowNamesNode = insert(SetRowNamesAttributeNode.create()); + } + setRowNamesNode.setRowNames(res, castVector(value)); } else { if (value == RNull.instance) { res.removeAttr(attrProfiles, attrName); } else { - res.setAttr(attrName.intern(), value); + if (setAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setAttrNode = insert(SetAttributeNode.create()); + } + setAttrNode.execute(res, attrName.intern(), value); } } } @@ -251,6 +274,7 @@ public abstract class UpdateAttributes extends RBuiltinNode { if (attrValue == null) { throw RError.error(this, RError.Message.SET_INVALID_CLASS_ATTR); } + attrObj.setClassAttr(UpdateAttr.convertClassAttrFromObject(attrValue)); } else { attrObj.setAttr(attrName.intern(), operand.getDataAt(i)); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java index 62799507ade961086ec2c43d64c72aa344899b69..094f7fb3b8b052cc251da25e495c326f181a1cf3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java @@ -18,6 +18,8 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.attributes.TypeFromModeNode; import com.oracle.truffle.r.nodes.binary.CastTypeNode; import com.oracle.truffle.r.nodes.binary.CastTypeNodeGen; @@ -48,6 +50,7 @@ public abstract class UpdateClass extends RBuiltinNode { @Child private CastTypeNode castTypeNode; @Child private TypeofNode typeof; + @Child private SetClassAttributeNode setClassAttrNode = SetClassAttributeNode.create(); private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @@ -61,7 +64,8 @@ public abstract class UpdateClass extends RBuiltinNode { @TruffleBoundary protected Object setClass(RAbstractContainer arg, @SuppressWarnings("unused") RNull className) { RAbstractContainer result = reuseNonShared(arg); - return result.setClassAttr(null); + setClassAttrNode.reset(result); + return result; } @Specialization(limit = "CACHE_LIMIT", guards = "cachedClassName == className") @@ -94,6 +98,7 @@ public abstract class UpdateClass extends RBuiltinNode { return setClass((RAbstractVector) result, RNull.instance); } } + RAbstractContainer result = reuseNonShared(arg); if (result instanceof RAbstractVector) { RAbstractVector resultVector = (RAbstractVector) result; @@ -114,73 +119,75 @@ public abstract class UpdateClass extends RBuiltinNode { } } - return result.setClassAttr(RDataFactory.createStringVector(className)); + setClassAttrNode.execute(result, RDataFactory.createStringVector(className)); + return result; } @Specialization @TruffleBoundary protected Object setClass(RAbstractContainer arg, RStringVector className) { RAbstractContainer result = reuseNonShared(arg); - return result.setClassAttr(className); + setClassAttrNode.execute(result, className); + return result; } @Specialization protected Object setClass(RFunction arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(RFunction arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } @Specialization protected Object setClass(REnvironment arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(REnvironment arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } @Specialization protected Object setClass(RSymbol arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(RSymbol arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } @Specialization protected Object setClass(RExternalPtr arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(RExternalPtr arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } @Specialization protected Object setClass(RS4Object arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(RS4Object arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } 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 0b7c49004d52e746b872d503f89b2e7fa32376aa..d30e638139ad629645041ed73dab870e8b043753 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 @@ -31,14 +31,12 @@ 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.api.profiles.ConditionProfile; -import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; +import com.oracle.truffle.r.nodes.attributes.RemoveFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.opt.ReuseNonSharedNode; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeStorage; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RNull; @@ -67,14 +65,13 @@ public abstract class UpdateDim extends RBuiltinNode { @Specialization protected RAbstractVector updateDim(RAbstractVector vector, RAbstractIntVector dimensions, @Cached("createBinaryProfile()") ConditionProfile initAttrProfile, - @Cached("createDim()") SetFixedAttributeNode putDimensions) { + @Cached("createDim()") SetFixedAttributeNode putDimensions, + @Cached("createNames()") RemoveFixedAttributeNode removeNames) { RIntVector dimensionsMaterialized = dimensions.materialize(); int[] dimsData = dimensionsMaterialized.getDataCopy(); RVector.verifyDimensions(vector.getLength(), dimsData, this); RVector<?> result = ((RAbstractVector) reuse.execute(vector)).materialize(); - result.setInternalDimensions(dimsData); - result.setInternalNames(null); - result.setInternalDimNames(null); + removeNames.execute(result); 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 b5ee7967ce49f2b74af6722eca32380187520043..35adf33049ff8328091ce27e59d1947407474c8e 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 @@ -31,7 +31,7 @@ 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.RemoveFixedAttributeNode; -import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; @@ -40,11 +40,8 @@ import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -54,7 +51,6 @@ public abstract class UpdateDimNames extends RBuiltinNode { protected static final String DIMNAMES_ATTR_KEY = RRuntime.DIMNAMES_ATTR_KEY; private final ConditionProfile shareListProfile = ConditionProfile.createBinaryProfile(); - private final ConditionProfile isRVectorProfile = ConditionProfile.createBinaryProfile(); @Child private CastStringNode castStringNode; @Child private CastToVectorNode castVectorNode; @@ -96,15 +92,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; } @@ -116,9 +104,9 @@ public abstract class UpdateDimNames extends RBuiltinNode { @Specialization(guards = "list.getLength() > 0") protected RAbstractContainer updateDimnames(RAbstractContainer container, RList list, // - @Cached("createDimNames()") SetFixedAttributeNode attrSetter) { + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode) { RAbstractContainer result = (RAbstractContainer) container.getNonShared(); - setDimNames(result, convertToListOfStrings(list), attrSetter); + setDimNamesNode.setDimNames(result, convertToListOfStrings(list)); return result; } @@ -128,58 +116,4 @@ public abstract class UpdateDimNames extends RBuiltinNode { throw RError.error(this, RError.Message.DIMNAMES_LIST); } - private void setDimNames(RAbstractContainer container, RList newDimNames, SetFixedAttributeNode attrSetter) { - assert newDimNames != null; - if (isRVectorProfile.profile(container instanceof RVector)) { - RVector<?> vector = (RVector<?>) container; - int[] dimensions = vector.getDimensions(); - if (dimensions == null) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(this, RError.Message.DIMNAMES_NONARRAY); - } - int newDimNamesLength = newDimNames.getLength(); - if (newDimNamesLength > dimensions.length) { - CompilerDirectives.transferToInterpreter(); - 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) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_EXTENT, i + 1); - } - } else { - RStringVector dimVector = (RStringVector) dimObject; - if (dimVector == null || dimVector.getLength() == 0) { - newDimNames.updateDataAt(i, RNull.instance, null); - } else if (dimVector.getLength() != dimensions[i]) { - CompilerDirectives.transferToInterpreter(); - 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); - } - } - if (vector.getAttributes() == null) { - vector.initAttributes(RAttributesLayout.createDimNames(resDimNames)); - } else { - 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/UpdateLevels.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java index b9f41698d5966fe4c557badf8f03da94e0b95225..329730c362cfc6ee005247514fa33506811d928e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java @@ -15,7 +15,9 @@ import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -44,10 +46,15 @@ public abstract class UpdateLevels extends RBuiltinNode { return v; } + protected SetFixedAttributeNode createSetLevelsAttrNode() { + return SetFixedAttributeNode.create(RRuntime.LEVELS_ATTR_KEY); + } + @Specialization(guards = "!isRNull(levels)") - protected RAbstractVector updateLevels(RAbstractVector vector, Object levels) { + protected RAbstractVector updateLevels(RAbstractVector vector, Object levels, + @Cached("createSetLevelsAttrNode()") SetFixedAttributeNode setLevelsAttrNode) { RVector<?> v = (RVector<?>) vector.getNonShared(); - v.setAttr(RRuntime.LEVELS_ATTR_KEY, levels); + setLevelsAttrNode.execute(v, levels); return v; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java index f05261a585f42113af69f41576f5a2897eddc6df..02c1ab3e723189351e01281fc7714e35326c9270 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java @@ -29,6 +29,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; @@ -45,6 +46,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class UpdateOldClass extends RBuiltinNode { @Child private CastStringNode castStringNode; + @Child private SetClassAttributeNode setClassAttributeNode = SetClassAttributeNode.create(); @Specialization(guards = "!isStringVector(className)") protected Object setOldClass(RAbstractContainer arg, RAbstractVector className) { @@ -73,14 +75,16 @@ public abstract class UpdateOldClass extends RBuiltinNode { @TruffleBoundary protected Object setOldClass(RAbstractContainer arg, RStringVector className) { RAbstractContainer result = (RAbstractContainer) arg.getNonShared(); - return result.setClassAttr(className); + setClassAttributeNode.execute(result, className); + return result; } @Specialization @TruffleBoundary protected Object setOldClass(RAbstractContainer arg, @SuppressWarnings("unused") RNull className) { RAbstractContainer result = (RAbstractContainer) arg.getNonShared(); - return result.setClassAttr(null); + setClassAttributeNode.reset(result); + return result; } protected boolean isStringVector(RAbstractVector className) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java index a2b8ddcf234c55e836d8af7397a79d7e2ea40423..804b73b66704a390fa5dee5d937b25a7c650b76d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java @@ -20,6 +20,8 @@ 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.r.nodes.attributes.ArrayAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.attributes.TypeFromModeNode; import com.oracle.truffle.r.nodes.attributes.TypeFromModeNodeGen; import com.oracle.truffle.r.nodes.binary.CastTypeNode; @@ -35,9 +37,7 @@ import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @RBuiltin(name = "storage.mode<-", kind = PRIMITIVE, parameterNames = {"x", "value"}, behavior = PURE) @@ -47,11 +47,14 @@ public abstract class UpdateStorageMode extends RBuiltinNode { @Child private TypeofNode typeof; @Child private CastTypeNode castTypeNode; @Child private IsFactorNode isFactor; + @Child private SetClassAttributeNode setClassAttrNode; private final BranchProfile errorProfile = BranchProfile.create(); @Specialization - protected Object update(Object x, String value, @Cached("create()") ArrayAttributeNode attrAttrAccess) { + protected Object update(Object x, String value, + @Cached("create()") ArrayAttributeNode attrAttrAccess, + @Cached("create()") SetAttributeNode setAttrNode) { RType mode = typeFromMode.execute(value); if (mode == RType.DefunctReal || mode == RType.DefunctSingle) { errorProfile.enter(); @@ -80,13 +83,19 @@ public abstract class UpdateStorageMode extends RBuiltinNode { String attrName = attr.getName(); Object v = attr.getValue(); if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) { + + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + if (v == RNull.instance) { - rresult = (RAbstractContainer) rresult.setClassAttr(null); + setClassAttrNode.reset(rresult); } else { - rresult = (RAbstractContainer) rresult.setClassAttr((RStringVector) v); + setClassAttrNode.execute(rresult, v); } } else { - rresult.setAttr(Utils.intern(attrName), v); + setAttrNode.execute(rresult, Utils.intern(attrName), v); } } return rresult; 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..83f99a9513a2e09bb32b33e7d754e008d0e4af4a 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 @@ -32,6 +32,9 @@ import com.oracle.truffle.api.CompilerDirectives; 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.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; 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; @@ -50,7 +53,6 @@ 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.builtins.RBuiltin; -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.RFunction; @@ -80,7 +82,6 @@ public abstract class VApply extends RBuiltinNode { private final ConditionProfile useNamesProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile dimsProfile = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final NACheck naCheck = NACheck.create(); @Child private LapplyInternalNode doApply = LapplyInternalNodeGen.create(); @@ -90,6 +91,9 @@ public abstract class VApply extends RBuiltinNode { @Child private CastIntegerNode castInteger; @Child private CastLogicalNode castLogical; @Child private CastStringNode castString; + @Child private SetDimAttributeNode setDimNode; + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); + @Child private SetNamesAttributeNode setNamesNode = SetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -186,12 +190,16 @@ 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 if (useNamesProfile.profile(RRuntime.fromLogical(useNames))) { - RStringVector names = vecMat.getNames(attrProfiles); + RStringVector names = getNamesNode.getNames(vecMat); RStringVector newNames = null; if (names != null) { newNames = names; @@ -199,7 +207,7 @@ public abstract class VApply extends RBuiltinNode { newNames = (RStringVector) vecMat.copy(); } if (newNames != null) { - result.setNames(newNames); + setNamesNode.setNames(result, newNames); } } return result; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java index ec76dd55c89e32226ef5eafac0317d653103d41b..14614074f986b56a2698b9eccd9b6a13189b4b8d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java @@ -30,6 +30,7 @@ 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.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.WhichFunctionsFactory.WhichMaxNodeGen; @@ -37,7 +38,6 @@ import com.oracle.truffle.r.nodes.builtin.base.WhichFunctionsFactory.WhichMinNod import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RNull; @@ -64,7 +64,7 @@ public class WhichFunctions { @Cached("create()") VectorLengthProfile lengthProfile, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile, - @Cached("create()") RAttributeProfiles attrProfiles, + @Cached("create()") GetNamesAttributeNode getNamesNode, @Cached("create()") NACheck naCheck) { int length = lengthProfile.profile(x.getLength()); loopProfile.profileCounted(length); @@ -83,7 +83,7 @@ public class WhichFunctions { result[pos++] = i + 1; } } - RStringVector names = x.getNames(attrProfiles); + RStringVector names = getNamesNode.getNames(x); if (hasNamesProfile.profile(names != null)) { // collect result names String[] resultNames = new String[resultLength]; @@ -122,7 +122,7 @@ public class WhichFunctions { @Cached("createCountingProfile()") LoopConditionProfile loopProfile, @Cached("createBinaryProfile()") ConditionProfile isNaNProfile, @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile, - @Cached("create()") RAttributeProfiles attrProfiles) { + @Cached("create()") GetNamesAttributeNode getNamesNode) { int length = lengthProfile.profile(x.getLength()); loopProfile.profileCounted(length); double extreme = Double.NaN; @@ -138,7 +138,7 @@ public class WhichFunctions { if (isNaNProfile.profile(extremeIndex == -1)) { return RDataFactory.createEmptyIntVector(); } - RStringVector names = x.getNames(attrProfiles); + RStringVector names = getNamesNode.getNames(x); if (hasNamesProfile.profile(names != null)) { // collect result names RStringVector resultNames = RDataFactory.createStringVectorFromScalar(names.getDataAt(extremeIndex)); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java index a8ac59b7406f81e36680f9a5cf2596b7d4b3c6d8..3ca0f0c97d0173a30490c3c5cdd8b0bf225426ec 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java @@ -49,7 +49,7 @@ public final class Dqrcf extends RExternalBuiltinNode { int[] info = infoVec.materialize().getDataTemp(); rApplRFFINode.dqrcf(x, n, k.getDataAt(0), qraux, y, ny, b, info); RDoubleVector coef = RDataFactory.createDoubleVector(b, RDataFactory.COMPLETE_VECTOR); - coef.copyAttributesFrom(attrProfiles, bVec); + coef.copyAttributesFrom(bVec); // @formatter:off Object[] data = new Object[]{ RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR), diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java index 7c9ae20b0b01c46ebfc2fb1f4fe44946c839c083..e63b42dd1195018bf6b83324ff0ca72ef2dcdfb1 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java @@ -11,6 +11,7 @@ */ package com.oracle.truffle.r.nodes.builtin.base.foreign; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; @@ -29,6 +30,8 @@ public final class Dqrdc2 extends RExternalBuiltinNode { private static final String E = RRuntime.NAMES_ATTR_EMPTY_VALUE; private static final RStringVector DQRDC2_NAMES = RDataFactory.createStringVector(new String[]{"qr", E, E, E, E, "rank", "qraux", "pivot", E}, RDataFactory.COMPLETE_VECTOR); + @Child private GetDimAttributeNode getDimNode = GetDimAttributeNode.create(); + @Override public RList call(RArgsValuesAndNames args) { Object[] argValues = args.getArguments(); @@ -49,7 +52,7 @@ public final class Dqrdc2 extends RExternalBuiltinNode { rApplRFFINode.dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, workVec.materialize().getDataCopy()); // @formatter:off Object[] data = new Object[]{ - RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR, xVec.getDimensions()), + RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR, getDimNode.getDimensions(xVec)), argValues[1], argValues[2], argValues[3], argValues[4], RDataFactory.createIntVector(rank, RDataFactory.COMPLETE_VECTOR), RDataFactory.createDoubleVector(qraux, RDataFactory.COMPLETE_VECTOR), diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java index 31db4963325002d4c9ddb1db5826bcefc7247f2a..b4bf5517d216c83e638f04f7e139142fa7278a16 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java @@ -11,8 +11,10 @@ */ package com.oracle.truffle.r.nodes.builtin.base.foreign; +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.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; @@ -36,15 +38,16 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { // TODO: handle more argument types (this is sufficient to run the b25 benchmarks) @Specialization - public Object execute(RAbstractComplexVector zVec, boolean inverse) { + public Object execute(RAbstractComplexVector zVec, boolean inverse, @Cached("create()") GetDimAttributeNode getDimNode) { double[] z = zVec.materialize().getDataTemp(); int inv = inverse ? 2 : -2; + int[] d = getDimNode.getDimensions(zVec); @SuppressWarnings("unused") int retCode = 7; if (zVecLgt1.profile(zVec.getLength() > 1)) { int[] maxf = new int[1]; int[] maxp = new int[1]; - if (noDims.profile(zVec.getDimensions() == null)) { + if (noDims.profile(d == null)) { int n = zVec.getLength(); fftNode.executeFactor(n, maxf, maxp); if (maxf[0] == 0) { @@ -57,7 +60,6 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { } else { int maxmaxf = 1; int maxmaxp = 1; - int[] d = zVec.getDimensions(); int ndims = d.length; /* do whole loop just for error checking and maxmax[fp] .. */ for (int i = 0; i < ndims; i++) { @@ -91,6 +93,6 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { } } } - return RDataFactory.createComplexVector(z, zVec.isComplete(), zVec.getDimensions()); + return RDataFactory.createComplexVector(z, zVec.isComplete(), d); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java index 36866074464c2b3f440152f76350d05a393b6dbc..9f848c51562ad640a6ac5c7331ebdd9be1c13c2b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java @@ -39,6 +39,7 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout; import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractListElement; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; @@ -69,8 +70,8 @@ abstract class AccessFieldSpecial extends SpecialsUtils.ListFieldSpecialBase { } @Specialization(contains = "doList", guards = {"isSimpleList(list)", "list.getNames() != null"}) - public Object doListDynamic(RList list, String field) { - return doList(list, field, getIndex(list.getNames(), field)); + public Object doListDynamic(RList list, String field, @Cached("create()") GetNamesAttributeNode getNamesNode) { + return doList(list, field, getIndex(getNamesNode.getNames(list), field)); } @Fallback diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java index a72d60cf059516649d731875c9f2352777135446..793d882e1a8121d8e29bcbdbcd993e9b78bbe6d3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java @@ -26,6 +26,7 @@ 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.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.data.RList; @@ -84,12 +85,13 @@ class SpecialsUtils { @CompilationFinal private String cachedField; @CompilationFinal private RStringVector cachedNames; @Child private ClassHierarchyNode hierarchyNode = ClassHierarchyNode.create(); + @Child protected GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); protected final void updateCache(RList list, String field) { if (cachedField == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); cachedField = field; - cachedNames = list.getNames(); + cachedNames = getNamesNode.getNames(list); } } @@ -98,7 +100,7 @@ class SpecialsUtils { } protected final boolean isCached(RList list, String field) { - return cachedField == null || (cachedField == field && list.getNames() == cachedNames); + return cachedField == null || (cachedField == field && getNamesNode.getNames(list) == cachedNames); } protected static int getIndex(RStringVector names, String field) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java index 4b3166024df80800419b87a3ec2843f9f62f46b7..9d693de22845ef0dba043d41824103eeda08015e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java @@ -34,12 +34,12 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout; import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractListElement; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RLogical; @@ -55,12 +55,12 @@ import com.oracle.truffle.r.runtime.nodes.RNode; @TypeSystemReference(EmptyTypeSystemFlatLayout.class) abstract class SubsetSpecial extends SubscriptSpecialBase { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected boolean simpleVector(RAbstractVector vector) { vector = vectorClassProfile.profile(vector); - return super.simpleVector(vector) && vector.getNames(attrProfiles) == null; + return super.simpleVector(vector) && getNamesNode.getNames(vector) == null; } @Override diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java index 771bc4bd590e1e2d170aacb2159ceca8c77d16c5..1918c7c7447a23370355b722e6bcf4ba139faeb0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java @@ -25,8 +25,11 @@ package com.oracle.truffle.r.nodes.builtin.base.infix; import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_FRAME; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; +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.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.RCallNode; import com.oracle.truffle.r.runtime.RRuntime; @@ -49,18 +52,25 @@ public abstract class Tilde extends RBuiltinNode { private static final RStringVector FORMULA_CLASS = RDataFactory.createStringVectorFromScalar(RRuntime.FORMULA_CLASS); + @Child private SetClassAttributeNode setClassAttrNode = SetClassAttributeNode.create(); + @Override public Object[] getDefaultParameterValues() { return new Object[]{RMissing.instance, RMissing.instance}; } + protected SetFixedAttributeNode createSetEnvAttrNode() { + return SetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT); + } + @Specialization - protected RLanguage tilde(VirtualFrame frame, @SuppressWarnings("unused") Object response, @SuppressWarnings("unused") Object model) { + protected RLanguage tilde(VirtualFrame frame, @SuppressWarnings("unused") Object response, @SuppressWarnings("unused") Object model, + @Cached("createSetEnvAttrNode()") SetFixedAttributeNode setEnvAttrNode) { RCallNode call = (RCallNode) ((RBaseNode) getParent()).asRSyntaxNode(); RLanguage lang = RDataFactory.createLanguage(call); - lang.setClassAttr(FORMULA_CLASS); + setClassAttrNode.execute(lang, FORMULA_CLASS); REnvironment env = REnvironment.frameToEnvironment(frame.materialize()); - lang.setAttr(RRuntime.DOT_ENVIRONMENT, env); + setEnvAttrNode.execute(lang, env); return lang; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java index da44b6344da226739efbb89c77cbb9067773ccbe..ebbd01a056c1e63bb5e0436186690bb062b07a2c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java @@ -83,7 +83,7 @@ abstract class UpdateFieldSpecial extends SpecialsUtils.ListFieldSpecialBase { @Specialization(contains = "doList", guards = {"isSimpleList(list)", "!list.isShared()", "list.getNames() != null", "isNotRNullRList(value)"}) public RList doListDynamic(RList list, String field, Object value) { - return doList(list, field, value, getIndex(list.getNames(), field)); + return doList(list, field, value, getIndex(getNamesNode.getNames(list), field)); } @SuppressWarnings("unused") 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 d8fcdd5d2926f7fbae17bbc8913cc2097940d3e5..6bbd827d0354c7ff5428f5c4a1bc7a1fbb82a087 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 @@ -26,8 +26,6 @@ import java.io.IOException; import java.io.PrintWriter; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -39,8 +37,6 @@ final class ExpressionPrinter extends AbstractValuePrinter<RExpression> { // singleton } - private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); - @Override @TruffleBoundary protected void printValue(RExpression expr, PrintContext printCtx) throws IOException { @@ -49,7 +45,7 @@ final class ExpressionPrinter extends AbstractValuePrinter<RExpression> { valPrintCtx.parameters().setSuppressIndexLabels(true); out.print("expression("); - RStringVector names = (RStringVector) expr.getAttr(dummyAttrProfiles, 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 ffc0c1db1b5e9877d742687455e746f049aa7cb3..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 @@ -44,20 +44,19 @@ 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 } - private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); - private static int TAGBUFLEN = 256; @Override @TruffleBoundary protected void printValue(RAbstractListVector s, PrintContext printCtx) throws IOException { RAbstractIntVector dims = Utils.<RAbstractIntVector> castTo( - s.getAttr(dummyAttrProfiles, RRuntime.DIM_ATTR_KEY)); + s.getAttr(RRuntime.DIM_ATTR_KEY)); if (dims != null && dims.getLength() > 1) { printDimList(s, printCtx); @@ -151,7 +150,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { } RStringVector tt = RDataFactory.createStringVector(t, true, s.getDimensions()); - Object dimNames = s.getAttr(dummyAttrProfiles, RRuntime.DIMNAMES_ATTR_KEY); + Object dimNames = s.getAttr(RRuntime.DIMNAMES_ATTR_KEY); tt.setAttr(RRuntime.DIMNAMES_ATTR_KEY, dimNames); PrintContext cc = printCtx.cloneContext(); @@ -171,7 +170,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { int ns = s.getLength(); RAbstractStringVector names; - names = Utils.castTo(RRuntime.asAbstractVector(s.getAttr(dummyAttrProfiles, RRuntime.NAMES_ATTR_KEY))); + names = Utils.castTo(RRuntime.asAbstractVector(s.getNames(dummyAttrProfiles))); if (ns > 0) { int npr = (ns <= pp.getMax() + 1) ? ns : pp.getMax(); @@ -216,7 +215,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { out.println(tagbuf); Object si = s.getDataAtAsObject(i); - if (si instanceof RAttributable && ((RAttributable) si).isObject(dummyAttrProfiles)) { + if (si instanceof RAttributable && ((RAttributable) si).isObject()) { RContext.getEngine().printResult(si); } else { ValuePrinters.INSTANCE.print(si, printCtx); @@ -236,7 +235,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { /* Formal classes are represented as empty lists */ String className = null; if (printCtx.printerNode().isObject(s) && printCtx.printerNode().isMethodDispatchOn()) { - RAbstractStringVector klass = Utils.castTo(RRuntime.asAbstractVector(s.getAttr(dummyAttrProfiles, RRuntime.CLASS_ATTR_KEY))); + RAbstractStringVector klass = Utils.castTo(RRuntime.asAbstractVector(s.getAttr(RRuntime.CLASS_ATTR_KEY))); if (klass != null && klass.getLength() == 1) { String ss = klass.getDataAt(0); String str = snprintf(200, ".__C__%s", ss); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java index 9dabad114d57463555f70c483b5dbc381a9abc9b..5927ddf98ec477d3b0d8c3dc191785040e0831f2 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java @@ -17,7 +17,6 @@ import java.io.IOException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RNull; @@ -42,13 +41,11 @@ final class PairListPrinter extends AbstractValuePrinter<RPairList> { // singleton } - private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); - @Override @TruffleBoundary protected void printValue(RPairList s, PrintContext printCtx) throws IOException { final RAbstractIntVector dims = Utils.<RAbstractIntVector> castTo( - s.getAttr(dummyAttrProfiles, RRuntime.DIM_ATTR_KEY)); + s.getAttr(RRuntime.DIM_ATTR_KEY)); final int ns = s.getLength(); @@ -82,7 +79,7 @@ final class PairListPrinter extends AbstractValuePrinter<RPairList> { t[i] = pbuf; RStringVector tt = RDataFactory.createStringVector(t, true, s.getDimensions()); - Object dimNames = s.getAttr(dummyAttrProfiles, RRuntime.DIMNAMES_ATTR_KEY); + Object dimNames = s.getAttr(RRuntime.DIMNAMES_ATTR_KEY); tt.setAttr(RRuntime.DIMNAMES_ATTR_KEY, dimNames); PrintContext cc = printCtx.cloneContext(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java index cbcb5e2af91c4a3884b2f87f57ca61a10498684b..7448ebc7516c8ea623afd1c3ca912f86528212e5 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java @@ -542,7 +542,7 @@ public final class ValuePrinterNode extends RBaseNode { } @Override - public void setNames(RStringVector newNames) { + public final void setNames(RStringVector newNames) { throw RInternalError.shouldNotReachHere(); } 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 dcbc682204eda47037bf0d17c584f364f162973f..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 @@ -19,7 +19,6 @@ import java.io.PrintWriter; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @@ -29,8 +28,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePrinter<T> { - private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); - @Override protected void printValue(T vector, PrintContext printCtx) throws IOException { printVector(vector, 1, printCtx); @@ -77,13 +74,13 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri MatrixDimNames mdn = null; - Object dimAttr = vector.getAttr(dummyAttrProfiles, RRuntime.DIM_ATTR_KEY); + Object dimAttr = vector.getAttr(RRuntime.DIM_ATTR_KEY); if (dimAttr instanceof RAbstractIntVector) { dims = (RAbstractIntVector) dimAttr; if (dims.getLength() == 1) { - RList t = Utils.<RList> castTo(vector.getAttr(dummyAttrProfiles, RRuntime.DIMNAMES_ATTR_KEY)); + 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(dummyAttrProfiles, RRuntime.NAMES_ATTR_KEY))); + RAbstractStringVector nn = Utils.castTo(RRuntime.asAbstractVector(t.getNames())); if (nn != null) { title = nn.getDataAt(0); @@ -111,7 +108,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri } } else { dims = null; - Object namesAttr = Utils.castTo(vector.getAttr(dummyAttrProfiles, RRuntime.NAMES_ATTR_KEY)); + Object namesAttr = Utils.castTo(vector.getAttr(RRuntime.NAMES_ATTR_KEY)); if (namesAttr != null) { if (vector.getLength() > 0) { names = Utils.castTo(RRuntime.asAbstractVector(namesAttr)); @@ -676,7 +673,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri final RAbstractStringVector axisNames; MatrixDimNames(RAbstractVector x) { - dimnames = Utils.<RList> castTo(x.getAttr(dummyAttrProfiles, RRuntime.DIMNAMES_ATTR_KEY)); + dimnames = Utils.<RList> castTo(x.getAttr(RRuntime.DIMNAMES_ATTR_KEY)); if (dimnames == null) { rl = null; @@ -688,7 +685,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri } else { rl = getDimNamesAt(0); cl = getDimNamesAt(1); - axisNames = Utils.<RAbstractStringVector> castTo(dimnames.getAttr(dummyAttrProfiles, 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.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java index c739ffe80e385fe6d6f4ea1f1241ffe44e63e9eb..714e8c2a381a8dd49dd583944e2439d4e5d3ef7d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java @@ -23,7 +23,6 @@ import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RList; @@ -44,10 +43,6 @@ public abstract class FastrDqrls extends RBuiltinNode { private static final String[] NAMES = new String[]{"qr", "coefficients", "residuals", "effects", "rank", "pivot", "qraux", "tol", "pivoted"}; private static RStringVector namesVector = null; - private final RAttributeProfiles coeffAttributeProfiles = RAttributeProfiles.create(); - private final RAttributeProfiles xAttributeProfiles = RAttributeProfiles.create(); - private final RAttributeProfiles residualsAttributesProfiles = RAttributeProfiles.create(); - @Override protected void createCasts(CastBuilder casts) { casts.arg("x").asDoubleVector(true, true, true); @@ -87,13 +82,13 @@ public abstract class FastrDqrls extends RBuiltinNode { rApplRFFINode.dqrls(x, n, p, y, ny, tol, coeff, residuals, effects, rank, pivot, qraux, work); RDoubleVector resultCoeffVect = RDataFactory.createDoubleVector(coeff, RDataFactory.COMPLETE_VECTOR); - resultCoeffVect.copyAttributesFrom(coeffAttributeProfiles, coeffVec); + resultCoeffVect.copyAttributesFrom(coeffVec); RDoubleVector resultX = RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR); - resultX.copyAttributesFrom(xAttributeProfiles, originalXVec); + resultX.copyAttributesFrom(originalXVec); RDoubleVector resultResiduals = RDataFactory.createDoubleVector(residuals, RDataFactory.COMPLETE_VECTOR); - resultResiduals.copyAttributesFrom(residualsAttributesProfiles, originalYVec); + resultResiduals.copyAttributesFrom(originalYVec); Object[] data = new Object[]{ resultX, diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java index 044773513f6598af456b3be185fda9108d69737c..78c4fd48204f108f6fb44bc9d9ff2eaa70ff7f1c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java @@ -27,6 +27,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.runtime.JumpToTopLevelException; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RCaller; @@ -69,6 +70,9 @@ public abstract class BrowserInteractNode extends RNode { public static final int CONTINUE = 2; public static final int FINISH = 3; + @Child private GetFixedAttributeNode getSrcRefAttrNode; + @Child private GetFixedAttributeNode getSrcFileAttrNode; + @Specialization protected int interact(VirtualFrame frame) { CompilerDirectives.transferToInterpreter(); @@ -179,11 +183,20 @@ public abstract class BrowserInteractNode extends RNode { return RCaller.create(null, currentCaller, builder.call(RSyntaxNode.INTERNAL, builder.lookup(RSyntaxNode.INTERNAL, "browser", true))); } - private static String getSrcinfo(RStringVector element) { - Object srcref = element.getAttr(RRuntime.R_SRCREF); + private String getSrcinfo(RStringVector element) { + if (getSrcRefAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getSrcRefAttrNode = insert(GetFixedAttributeNode.create(RRuntime.R_SRCREF)); + } + + Object srcref = getSrcRefAttrNode.execute(element); if (srcref != null) { + if (getSrcFileAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getSrcFileAttrNode = insert(GetFixedAttributeNode.create(RRuntime.R_SRCFILE)); + } RIntVector lloc = (RIntVector) srcref; - Object srcfile = lloc.getAttr(RRuntime.R_SRCFILE); + Object srcfile = getSrcFileAttrNode.execute(lloc); if (srcfile != null) { REnvironment env = (REnvironment) srcfile; return " at " + RRuntime.asString(env.get(RSrcref.SrcrefFields.filename.name())) + "#" + lloc.getDataAt(0); diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java index d17626bd61f79b6c3f08b544914cebc5fdca54c1..b0e55a5d0192eea5ba7efba7987f15b82d589f6f 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java @@ -64,7 +64,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.util.function.Consumer; import java.util.function.Function; import org.junit.After; @@ -75,7 +74,6 @@ import org.junit.Test; import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef; import com.oracle.truffle.r.nodes.builtin.casts.PipelineConfig; import com.oracle.truffle.r.nodes.builtin.casts.fluent.InitialPhaseBuilder; -import com.oracle.truffle.r.nodes.builtin.casts.fluent.PipelineConfigBuilder; import com.oracle.truffle.r.nodes.builtin.casts.fluent.PreinitialPhaseBuilder; import com.oracle.truffle.r.nodes.casts.CastNodeSampler; import com.oracle.truffle.r.nodes.casts.FilterSamplerFactory; diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java index 668afbfc228cf49e199438f87a448f9b7ef0b88f..ce538982b09d76218ae36524e3cb873e9f26cc20 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java @@ -67,7 +67,6 @@ import com.oracle.truffle.r.nodes.binary.BinaryArithmeticNode; import com.oracle.truffle.r.nodes.test.TestUtilities.NodeHandle; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RScalarVector; diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java index d231d368106ff91a044eb2fe90e2f943d1213b0c..5a7ef2b6e1eeb41b379c803ec9e26d2326f66b67 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java @@ -56,7 +56,6 @@ import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode; import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RScalarVector; import com.oracle.truffle.r.runtime.data.RSequence; 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 9013ee971727f511d890c57a113796f664921721..589acd316b992ddc87812d2e6fb7306c88c4562d 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,7 +33,10 @@ 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.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.profile.AlwaysOnBranchProfile; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -69,11 +72,15 @@ final class CachedExtractVectorNode extends CachedVectorNode { private final boolean dropDimensions; private final VectorLengthProfile vectorLengthProfile = VectorLengthProfile.create(); - private final RAttributeProfiles vectorNamesProfile = RAttributeProfiles.create(); @Child private WriteIndexedVectorNode writeVectorNode; @Child private PositionsCheckNode positionsCheckNode; @Child private SetNamesNode setNamesNode; + @Child private SetDimAttributeNode setDimNode; + @Child private SetDimNamesAttributeNode setDimNamesNode; + @Child private GetDimNamesAttributeNode getDimNamesNode; + @Child private GetNamesAttributeNode getNamesNode; + @Child private GetNamesAttributeNode getNamesFromDimNamesNode; @Children private final CachedExtractVectorNode[] extractNames; @Children private final CachedExtractVectorNode[] extractNamesAlternative; @@ -185,7 +192,11 @@ final class CachedExtractVectorNode extends CachedVectorNode { } if (oneDimensionProfile.profile(numberOfDimensions == 1)) { // names only need to be considered for single dimensional accesses - RStringVector originalNames = vector.getNames(vectorNamesProfile); + if (getNamesNode == null) { + CompilerDirectives.transferToInterpreter(); + getNamesNode = insert(GetNamesAttributeNode.create()); + } + RStringVector originalNames = getNamesNode.getNames(vector); if (originalNames != null) { metadataApplied.enter(); setNames(extractedVector, extractNames(originalNames, positions, positionProfiles, 0, originalExact, originalDropDimensions)); @@ -274,7 +285,6 @@ final class CachedExtractVectorNode extends CachedVectorNode { } private final ConditionProfile dimNamesNull = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles dimnamesNamesProfile = RAttributeProfiles.create(); private final ValueProfile foundDimNamesProfile = ValueProfile.createClassProfile(); private final ConditionProfile selectPositionsProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile originalDimNamesPRofile = ConditionProfile.createBinaryProfile(); @@ -285,8 +295,13 @@ final class CachedExtractVectorNode extends CachedVectorNode { // TODO speculate on the number of counted dimensions int dimCount = countDimensions(positionProfile); + if (getDimNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimNamesNode = insert(GetDimNamesAttributeNode.create()); + } + int[] newDimensions = new int[dimCount]; - RList originalDimNames = originalTarget.getDimNames(null); + RList originalDimNames = getDimNamesNode.getDimNames(originalTarget); RStringVector originalDimNamesNames; Object[] newDimNames; String[] newDimNamesNames; @@ -295,8 +310,12 @@ final class CachedExtractVectorNode extends CachedVectorNode { originalDimNamesNames = null; newDimNamesNames = null; } else { + if (getNamesFromDimNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getNamesFromDimNamesNode = insert(GetNamesAttributeNode.create()); + } newDimNames = new Object[dimCount]; - originalDimNamesNames = originalDimNames.getNames(dimnamesNamesProfile); + originalDimNamesNames = getNamesFromDimNamesNode.getNames(originalDimNames); newDimNamesNames = originalDimNamesNames == null ? null : new String[dimCount]; } @@ -326,9 +345,20 @@ 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()))); + if (setDimNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNamesNode = insert(SetDimNamesAttributeNode.create()); + } + setDimNamesNode.setDimNames(extractedTarget, + RDataFactory.createList(newDimNames, newDimNamesNames == null ? null : RDataFactory.createStringVector(newDimNamesNames, originalDimNames.isComplete()))); } } else if (newDimNames != null && originalDimNamesPRofile.profile(originalDimNames.getLength() > 0)) { RAbstractStringVector foundNames = translateDimNamesToNames(positionProfile, originalDimNames, extractedTargetLength, positions); @@ -445,7 +475,6 @@ final class CachedExtractVectorNode extends CachedVectorNode { if (container.getAttributes() == null) { // usual case container.initAttributes(RAttributesLayout.createNames(newNames1)); - container.setInternalNames(newNames1); } else { // from an RLanguage extraction that set a name RStringVector oldNames = (RStringVector) namesAttrGetter.execute(container.getAttributes()); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java index e951c3c9927316606423f3d313152a0bc252a6c4..2113155262a366925b79e1963772fda9a23f2806 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java @@ -40,6 +40,8 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.access.vector.CachedReplaceVectorNodeFactory.ValueProfileNodeGen; import com.oracle.truffle.r.nodes.access.vector.PositionsCheckNode.PositionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.binary.CastTypeNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.nodes.unary.CastListNodeGen; @@ -79,7 +81,6 @@ final class CachedReplaceVectorNode extends CachedVectorNode { private final VectorLengthProfile valueLengthProfile = VectorLengthProfile.create(); private final BranchProfile warningBranch = BranchProfile.create(); private final RAttributeProfiles vectorNamesProfile = RAttributeProfiles.create(); - private final RAttributeProfiles positionNamesProfile = RAttributeProfiles.create(); private final ConditionProfile valueIsNA = ConditionProfile.createBinaryProfile(); private final BranchProfile resizeProfile = BranchProfile.create(); private final BranchProfile sharedProfile = BranchProfile.create(); @@ -100,6 +101,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { @Child private CastNode castVectorNode; @Child private CachedReplaceVectorNode copyPositionNames; @Child private DeleteElementsNode deleteElementsNode; + @Child private SetNamesAttributeNode setNamesNode; CachedReplaceVectorNode(ElementAccessMode mode, RTypedValue vector, Object[] positions, RTypedValue value, boolean updatePositionNames, boolean recursive) { super(mode, vector, positions, recursive); @@ -438,6 +440,8 @@ final class CachedReplaceVectorNode extends CachedVectorNode { } private final ValueProfile positionCastProfile = ValueProfile.createClassProfile(); + @Child private GetNamesAttributeNode getNamesNode; + @Child private GetNamesAttributeNode getResultNamesNode; private void updateVectorWithPositionNames(RAbstractVector vector, Object[] positions) { Object position = positionCastProfile.profile(positions[0]); @@ -446,7 +450,11 @@ final class CachedReplaceVectorNode extends CachedVectorNode { if (position instanceof RMissing) { positionNames = null; } else { - positionNames = ((RAbstractVector) position).getNames(positionNamesProfile); + if (getNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getNamesNode = insert(GetNamesAttributeNode.create()); + } + positionNames = getNamesNode.getNames(position); } if (positionNames != null && positionNames.getLength() > 0) { updatePositionNames(vector, positionNames, positions); @@ -537,7 +545,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { RStringVector oldNames = vector.getNames(vectorNamesProfile); RVector<?> res = vector.copyResized(size, true).materialize(); if (vector instanceof RVector) { - res.copyAttributesFrom(positionNamesProfile, vector); + res.copyAttributesFrom(vector); } res.setDimensionsNoCheck(null); res.setDimNamesNoCheck(null); @@ -551,7 +559,11 @@ final class CachedReplaceVectorNode extends CachedVectorNode { private final ConditionProfile updateNamesProfile = ConditionProfile.createBinaryProfile(); private void updatePositionNames(RAbstractVector resultVector, RAbstractStringVector positionNames, Object[] positions) { - RTypedValue originalNames = resultVector.getNames(positionNamesProfile); + if (getResultNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getResultNamesNode = insert(GetNamesAttributeNode.create()); + } + RTypedValue originalNames = getResultNamesNode.getNames(resultVector); RTypedValue names = originalNames; if (names == null) { String[] emptyVector = new String[resultVector.getLength()]; @@ -565,7 +577,11 @@ final class CachedReplaceVectorNode extends CachedVectorNode { assert copyPositionNames.isSupported(names, positions, positionNames); RAbstractStringVector newNames = (RAbstractStringVector) copyPositionNames.apply(names, positions, positionNames); if (updateNamesProfile.profile(newNames != originalNames)) { - resultVector.setNames(newNames.materialize()); + if (setNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setNamesNode = insert(SetNamesAttributeNode.create()); + } + setNamesNode.setNames(resultVector, newNames.materialize()); } } @@ -580,7 +596,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { */ @CompilationFinal private int previousResultLength = PREVIOUS_RESULT_UNINITIALIZED; - private final RAttributeProfiles vectorNamesProfile = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); public RAbstractVector deleteElements(RAbstractVector vector, int vectorLength) { // we can speculate here that we delete always the same number of elements @@ -596,7 +612,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { } Object[] data = new Object[resultLength]; - RStringVector names = vector.getNames(vectorNamesProfile); + RStringVector names = getNamesNode.getNames(vector); boolean hasNames = names != null; String[] newNames = null; if (hasNames) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java index 2622dfc83ebb23d9920416d187264533e4ce06fe..ddd61957c7c5e09b7df428161eff08cd00e3ace4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java @@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.access.vector; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; @@ -60,6 +61,8 @@ abstract class CachedVectorNode extends RBaseNode { // if this is non-null, the node needs to throw the error whenever it is executed @CompilationFinal protected Runnable error; + @Child private GetDimAttributeNode getDimNode = GetDimAttributeNode.create(); + CachedVectorNode(ElementAccessMode mode, RTypedValue vector, Object[] positions, boolean recursive) { this.mode = mode; this.vectorType = vector.getRType(); @@ -151,14 +154,13 @@ abstract class CachedVectorNode extends RBaseNode { } } - @SuppressWarnings("static-method") protected final int[] loadVectorDimensions(RAbstractContainer vector) { // N.B. (stepan) this method used to be instance method and have special handling for // RDataFrame, which was removed and any test case, which would require this special // handling was not found (see TestBuiltin_extract_dataframe for tests used and further // explanation). This method and note will remain here for a while in case this behavior // crops up somewhere - return vector.getDimensions(); + return getDimNode.getDimensions(vector); } public ElementAccessMode getMode() { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCharacterLookupNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCharacterLookupNode.java index e437eef25787fc36433b988c3109a99dcd04ba6b..70e086e85722e0917405de4db7f6f82244cd5526 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCharacterLookupNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCharacterLookupNode.java @@ -24,9 +24,10 @@ package com.oracle.truffle.r.nodes.access.vector; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; @@ -38,12 +39,13 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; final class PositionCharacterLookupNode extends Node { private final ElementAccessMode mode; - private final RAttributeProfiles attributeProfiles = RAttributeProfiles.create(); private final int numDimensions; private final int dimensionIndex; private final BranchProfile emptyProfile = BranchProfile.create(); @Child private SearchFirstStringNode searchNode; + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); PositionCharacterLookupNode(ElementAccessMode mode, int numDimensions, int dimensionIndex, boolean useNAForNotFound, boolean exact) { this.numDimensions = numDimensions; @@ -56,14 +58,14 @@ final class PositionCharacterLookupNode extends Node { // lookup names for single dimension case RAbstractIntVector result; if (numDimensions <= 1) { - RStringVector names = target.getNames(attributeProfiles); + RStringVector names = getNamesNode.getNames(target); if (names == null) { emptyProfile.enter(); names = RDataFactory.createEmptyStringVector(); } result = searchNode.apply(names, position, notFoundStartIndex, position.materialize()); } else { - RList dimNames = target.getDimNames(attributeProfiles); + RList dimNames = getDimNamesNode.getDimNames(target); if (dimNames != null) { Object dataAt = dimNames.getDataAt(dimensionIndex); if (dataAt != RNull.instance) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java index 5ec428e5feefa3341125319e430de02631d25336..9dffa7e5111fdd7459b8c5f77352b2daa85eed54 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java @@ -30,6 +30,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.access.vector.PositionCheckNodeFactory.Mat2indsubNodeGen; import com.oracle.truffle.r.nodes.access.vector.PositionsCheckNode.PositionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.control.RLengthNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -110,6 +111,8 @@ abstract class PositionCheckNode extends Node { } @Child private Mat2indsubNode mat2indsub; + @Child private GetDimAttributeNode getVectorDimsNode; + @Child private GetDimAttributeNode getVectorPosDimsNode; public final Object execute(PositionProfile profile, RAbstractContainer vector, int[] vectorDimensions, int vectorLength, Object position) { Object castPosition = castNode.execute(positionClass.cast(position)); @@ -124,12 +127,20 @@ abstract class PositionCheckNode extends Node { } if (mode.isSubset() && numDimensions == 1) { - int[] vectorDim = vector.getDimensions(); + if (getVectorDimsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getVectorDimsNode = insert(GetDimAttributeNode.create()); + } + int[] vectorDim = getVectorDimsNode.getDimensions(vector); if (nullDimensionsProfile.profile(vectorDim != null) && vectorDim.length == 2) { if (vector instanceof RAbstractVector && ((RAbstractVector) vector).isArray()) { if (castPosition instanceof RAbstractVector) { + if (getVectorPosDimsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getVectorPosDimsNode = insert(GetDimAttributeNode.create()); + } RAbstractVector vectorPosition = (RAbstractVector) castPosition; - int[] posDim = vectorPosition.getDimensions(); + int[] posDim = getVectorPosDimsNode.getDimensions(vectorPosition); if (posDim != null && posDim.length == 2 && posDim[1] == vectorDim.length) { if (castPosition instanceof RAbstractIntVector || castPosition instanceof RAbstractDoubleVector) { if (mat2indsub == null) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java index 43486bf76a3b037d6e5eaf5ab11043ceba180ece..6aa4578656348d2c47e4ea9f19d82418716a06af 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java @@ -22,9 +22,11 @@ */ package com.oracle.truffle.r.nodes.access.vector; +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.access.vector.PositionsCheckNode.PositionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RRuntime; @@ -61,7 +63,8 @@ abstract class PositionCheckSubscriptNode extends PositionCheckNode { } @Specialization - protected RAbstractVector doLogical(PositionProfile statistics, int dimSize, RAbstractLogicalVector position, int positionLength) { + protected RAbstractVector doLogical(PositionProfile statistics, int dimSize, RAbstractLogicalVector position, int positionLength, + @Cached("create()") GetNamesAttributeNode getNamesNode) { positionNACheck.enable(position); byte value = position.getDataAt(0); if (positionLength != 1) { @@ -77,11 +80,12 @@ abstract class PositionCheckSubscriptNode extends PositionCheckNode { } } - return doIntegerImpl(statistics, dimSize, positionNACheck.convertLogicalToInt(value), position); + return doIntegerImpl(statistics, dimSize, positionNACheck.convertLogicalToInt(value), position, getNamesNode); } @Specialization - protected RAbstractVector doInteger(PositionProfile profile, int dimSize, RAbstractIntVector position, int positionLength) { + protected RAbstractVector doInteger(PositionProfile profile, int dimSize, RAbstractIntVector position, int positionLength, + @Cached("create()") GetNamesAttributeNode getNamesNode) { if (positionLength != 1) { error.enter(); Message message; @@ -99,12 +103,12 @@ abstract class PositionCheckSubscriptNode extends PositionCheckNode { } assert positionLength == 1; positionNACheck.enable(position); - RAbstractVector result = doIntegerImpl(profile, dimSize, position.getDataAt(0), position); + RAbstractVector result = doIntegerImpl(profile, dimSize, position.getDataAt(0), position, getNamesNode); return result; } - private RAbstractVector doIntegerImpl(PositionProfile profile, int dimSize, int value, RAbstractVector originalVector) { + private RAbstractVector doIntegerImpl(PositionProfile profile, int dimSize, int value, RAbstractVector originalVector, GetNamesAttributeNode getNamesNode) { int result; if (greaterZero.profile(value > 0)) { // fast path @@ -121,7 +125,7 @@ abstract class PositionCheckSubscriptNode extends PositionCheckNode { } profile.selectedPositionsCount = 1; - RStringVector names = originalVector.getNames(attributeProfile); + RStringVector names = getNamesNode.getNames(originalVector); if (names != null) { return RDataFactory.createIntVector(new int[]{result}, !profile.containsNA, names); } else { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java index bc29b18d2a136d3ebb10508126a66727b3b771a0..99ad2b78cab1e9f3630e33e9a8c1345da56e6735 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java @@ -31,12 +31,13 @@ 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.access.vector.PositionsCheckNode.PositionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.runtime.NullProfile; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.Utils; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RInteger; import com.oracle.truffle.r.runtime.data.RMissing; @@ -128,8 +129,6 @@ abstract class PositionCheckSubsetNode extends PositionCheckNode { return position; } - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - @Specialization(/* contains = "doSequence" */) protected RAbstractVector doDouble(PositionProfile profile, int dimensionLength, RAbstractDoubleVector position, int positionLength, // @Cached("create()") BranchProfile seenZeroProfile, // @@ -137,13 +136,15 @@ abstract class PositionCheckSubsetNode extends PositionCheckNode { @Cached("create()") BranchProfile seenNegativeProfile, // @Cached("create()") BranchProfile seenOutOfBounds, // @Cached("create()") NullProfile hasNamesProfile, // - @Cached("createCountingProfile()") LoopConditionProfile lengthProfile) { + @Cached("createCountingProfile()") LoopConditionProfile lengthProfile, + @Cached("create()") GetNamesAttributeNode getNamesNode, + @Cached("create()") SetNamesAttributeNode setNamesNode) { RAbstractIntVector intPosition = RDataFactory.createIntVector(positionLength); intPosition.setComplete(position.isComplete()); // requires names preservation - RStringVector names = hasNamesProfile.profile(position.getNames(attrProfiles)); + RStringVector names = hasNamesProfile.profile(getNamesNode.getNames(position)); if (names != null) { - intPosition.setNames(names); + setNamesNode.setNames(intPosition, names); } Object convertedStore = intPosition.getInternalStore(); 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 e1f30141ef54d7abc96f2dc4f0f5a5133c81f677..78faca3c4d6bfe0b214b34a5ee689421b0ccad47 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 @@ -28,8 +28,11 @@ 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.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -47,8 +50,9 @@ public abstract class CopyAttributesNode extends RBaseNode { private final boolean copyAllAttributes; - protected final RAttributeProfiles attrLeftProfiles = RAttributeProfiles.create(); - protected final RAttributeProfiles attrRightProfiles = RAttributeProfiles.create(); + @Child protected HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); + @Child protected GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + @Child protected GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); protected CopyAttributesNode(boolean copyAllAttributes) { this.copyAllAttributes = copyAllAttributes; @@ -60,9 +64,9 @@ public abstract class CopyAttributesNode extends RBaseNode { public abstract RAbstractVector execute(RAbstractVector target, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength); - protected boolean containsMetadata(RAbstractVector vector, RAttributeProfiles attrProfiles) { - return vector instanceof RVector && vector.hasDimensions() || (copyAllAttributes && vector.getAttributes() != null) || vector.getDimNames(attrProfiles) != null || - vector.getNames(attrProfiles) != null; + protected boolean containsMetadata(RAbstractVector vector) { + return vector instanceof RVector && hasDimNode.execute(vector) || (copyAllAttributes && vector.getAttributes() != null) || getDimNamesNode.getDimNames(vector) != null || + getNamesNode.getNames(vector) != null; } private static int countNo; @@ -98,7 +102,7 @@ public abstract class CopyAttributesNode extends RBaseNode { } @SuppressWarnings("unused") - @Specialization(guards = {"!containsMetadata(left, attrLeftProfiles)", "!containsMetadata(right, attrRightProfiles)"}) + @Specialization(guards = {"!containsMetadata(left)", "!containsMetadata(right)"}) protected RAbstractVector copyNoMetadata(RAbstractVector target, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength) { if (LOG) { log("copyAttributes: no"); @@ -107,7 +111,7 @@ public abstract class CopyAttributesNode extends RBaseNode { return target; } - @Specialization(guards = {"leftLength == rightLength", "containsMetadata(left, attrLeftProfiles) || containsMetadata(right, attrRightProfiles)"}) + @Specialization(guards = {"leftLength == rightLength", "containsMetadata(left) || containsMetadata(right)"}) protected RAbstractVector copySameLength(RAbstractVector target, RAbstractVector left, @SuppressWarnings("unused") int leftLength, RAbstractVector right, @SuppressWarnings("unused") int rightLength, @Cached("create()") CopyOfRegAttributesNode copyOfRegLeft, @@ -124,7 +128,10 @@ public abstract class CopyAttributesNode extends RBaseNode { @Cached("create()") BranchProfile noDimensions, @Cached("createBinaryProfile()") ConditionProfile hasNamesLeft, @Cached("createBinaryProfile()") ConditionProfile hasNamesRight, - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getLeftDimsNode, + @Cached("create()") GetDimAttributeNode getRightDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode) { if (LOG) { log("copyAttributes: =="); countEquals++; @@ -139,32 +146,28 @@ public abstract class CopyAttributesNode extends RBaseNode { } } - int[] newDimensions = left.getDimensions(); + int[] newDimensions = getLeftDimsNode.getDimensions(left); if (newDimensions == null) { - newDimensions = right.getDimensions(); + newDimensions = getRightDimsNode.getDimensions(right); if (newDimensions == null) { noDimensions.enter(); DynamicObject attributes = result.getAttributes(); if (hasAttributes.profile(attributes != null)) { removeDim.execute(attributes); removeDimNames.execute(attributes); - result.setInternalDimNames(null); } - result.setInternalDimensions(null); - RStringVector vecNames = left.getNames(attrLeftProfiles); + RStringVector vecNames = getNamesNode.getNames(left); if (hasNamesLeft.profile(vecNames != null)) { if (result != left) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); } return result; } if (result != right) { - vecNames = right.getNames(attrRightProfiles); + vecNames = getNamesNode.getNames(right); if (hasNamesRight.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); } } return result; @@ -176,28 +179,26 @@ public abstract class CopyAttributesNode extends RBaseNode { } putDim.execute(initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); - result.setInternalDimensions(newDimensions); if (result != left) { - RList newDimNames = left.getDimNames(attrLeftProfiles); + RList newDimNames = getDimNamesNode.getDimNames(left); if (hasDimNames.profile(newDimNames != null)) { putDimNames.execute(result.getAttributes(), newDimNames); newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; - result.setInternalDimNames(newDimNames); return result; } if (result != right) { - newDimNames = right.getDimNames(attrRightProfiles); + newDimNames = getDimNamesNode.getDimNames(right); if (hasDimNames.profile(newDimNames != null)) { - result.setDimNames(newDimNames); + setDimNamesNode.setDimNames(result, newDimNames); } } } return result; } - @Specialization(guards = {"leftLength < rightLength", "containsMetadata(left, attrLeftProfiles) || containsMetadata(right, attrRightProfiles)"}) + @Specialization(guards = {"leftLength < rightLength", "containsMetadata(left) || containsMetadata(right)"}) protected RAbstractVector copyShorter(RAbstractVector target, RAbstractVector left, @SuppressWarnings("unused") int leftLength, RAbstractVector right, @SuppressWarnings("unused") int rightLength, // @Cached("create()") CopyOfRegAttributesNode copyOfReg, // @Cached("createBinaryProfile()") ConditionProfile rightNotResultProfile, // @@ -208,7 +209,10 @@ public abstract class CopyAttributesNode extends RBaseNode { @Cached("createDim()") SetFixedAttributeNode putDim, // @Cached("create()") InitAttributesNode initAttributes, // @Cached("createBinaryProfile()") ConditionProfile hasNames, // - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getLeftDimsNode, + @Cached("create()") GetDimAttributeNode getRightDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode) { if (LOG) { log("copyAttributes: <"); countSmaller++; @@ -219,18 +223,17 @@ public abstract class CopyAttributesNode extends RBaseNode { copyOfReg.execute(right, result); } - int[] newDimensions = left.getDimensions(); + int[] newDimensions = getLeftDimsNode.getDimensions(left); if (newDimensions == null || (newDimensions.length == 2 && newDimensions[0] == 1 && newDimensions[1] == 1)) { // 1-element matrix should be treated as 1-element vector - newDimensions = right.getDimensions(); + newDimensions = getRightDimsNode.getDimensions(right); if (newDimensions == null || (newDimensions.length == 2 && newDimensions[0] == 1 && newDimensions[1] == 1)) { // 1-element matrix should be treated as 1-element vector noDimensions.enter(); if (rightNotResult) { - RStringVector vecNames = right.getNames(attrRightProfiles); + RStringVector vecNames = getNamesNode.getNames(right); if (hasNames.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); } } return result; @@ -243,17 +246,16 @@ public abstract class CopyAttributesNode extends RBaseNode { RVector.verifyDimensions(result.getLength(), newDimensions, this); putDim.execute(initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); - result.setInternalDimensions(newDimensions); if (rightNotResult) { - RList newDimNames = right.getDimNames(attrRightProfiles); + RList newDimNames = getDimNamesNode.getDimNames(right); if (hasDimNames.profile(newDimNames != null)) { - result.setDimNames(newDimNames); + setDimNamesNode.setDimNames(result, newDimNames); } } return result; } - @Specialization(guards = {"leftLength > rightLength", "containsMetadata(left, attrLeftProfiles) || containsMetadata(right, attrRightProfiles)"}) + @Specialization(guards = {"leftLength > rightLength", "containsMetadata(left) || containsMetadata(right)"}) protected RAbstractVector copyLonger(RAbstractVector target, RAbstractVector left, @SuppressWarnings("unused") int leftLength, RAbstractVector right, @SuppressWarnings("unused") int rightLength, // @Cached("create()") CopyOfRegAttributesNode copyOfReg, // @Cached("create()") BranchProfile leftHasDimensions, // @@ -263,7 +265,10 @@ public abstract class CopyAttributesNode extends RBaseNode { @Cached("createDim()") SetFixedAttributeNode putDim, // @Cached("create()") InitAttributesNode initAttributes, // @Cached("createBinaryProfile()") ConditionProfile hasNames, // - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getLeftDimsNode, + @Cached("create()") GetDimAttributeNode getRightDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode) { if (LOG) { log("copyAttributes: >"); countLarger++; @@ -272,16 +277,15 @@ public abstract class CopyAttributesNode extends RBaseNode { if (copyAllAttributes && result != left) { copyOfReg.execute(left, result); } - int[] newDimensions = left.getDimensions(); + int[] newDimensions = getLeftDimsNode.getDimensions(left); if (newDimensions == null) { - newDimensions = right.getDimensions(); + newDimensions = getRightDimsNode.getDimensions(right); if (newDimensions == null) { noDimensions.enter(); if (left != result) { - RStringVector vecNames = left.getNames(attrLeftProfiles); + RStringVector vecNames = getNamesNode.getNames(left); if (hasNames.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); } } return result; @@ -292,11 +296,10 @@ public abstract class CopyAttributesNode extends RBaseNode { leftHasDimensions.enter(); } putDim.execute(initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); - result.setInternalDimensions(newDimensions); if (left != result) { - RList newDimNames = left.getDimNames(attrLeftProfiles); + RList newDimNames = getDimNamesNode.getDimNames(left); if (hasDimNames.profile(newDimNames != null)) { - result.setDimNames(newDimNames); + setDimNamesNode.setDimNames(result, newDimNames); } } return result; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java index 7b6897b18b8ecdd0cc42a7c8aff3085a9b3c0a1e..d1422eebc32fb87cfcdb041b1b411aae9a1a2c35 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java @@ -22,7 +22,6 @@ */ package com.oracle.truffle.r.nodes.attributes; -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.api.object.Property; @@ -30,7 +29,6 @@ import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @@ -112,20 +110,14 @@ public abstract class CopyOfRegAttributesNode extends RBaseNode { protected void copyGeneric(RAbstractVector source, RVector<?> target) { DynamicObject orgAttributes = source.getAttributes(); if (orgAttributes != null) { - Object newRowNames = null; - Shape shape = orgAttributes.getShape(); for (Property p : shape.getProperties()) { String name = (String) p.getKey(); if (name != RRuntime.DIM_ATTR_KEY && name != RRuntime.DIMNAMES_ATTR_KEY && name != RRuntime.NAMES_ATTR_KEY) { Object val = p.get(orgAttributes, shape); target.initAttributes().define(name, val); - if (name == RRuntime.ROWNAMES_ATTR_KEY) { - newRowNames = val; - } } } - target.setInternalRowNames(newRowNames == null ? RNull.instance : newRowNames); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java index 0a28d002af32b82684ecf48e4f815256e363c859..858530667ff7dc7246205f084dd710e3e0b2d631 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java @@ -22,16 +22,29 @@ */ package com.oracle.truffle.r.nodes.attributes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; 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.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; +/** + * This node is responsible for retrieving a value from an arbitrary attribute. It accepts both + * {@link DynamicObject} and {@link RAttributable} instances as the first argument. If the first + * argument is {@link RAttributable} and its attributes are initialized, the recursive instance of + * this class is used to get the attribute value from the attributes. + */ public abstract class GetAttributeNode extends AttributeAccessNode { + @Child private GetAttributeNode recursive; + protected GetAttributeNode() { } @@ -39,7 +52,7 @@ public abstract class GetAttributeNode extends AttributeAccessNode { return GetAttributeNodeGen.create(); } - public abstract Object execute(DynamicObject attrs, String name); + public abstract Object execute(Object attrs, String name); @Specialization(limit = "3", // guards = {"cachedName.equals(name)", "shapeCheck(shape, attrs)"}, // @@ -58,4 +71,30 @@ public abstract class GetAttributeNode extends AttributeAccessNode { return attrs.get(name); } + @Specialization + protected Object getAttrFromAttributable(RAttributable x, String name, + @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 null; + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create()); + } + + return recursive.execute(attributes, name); + } + } 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 35b79c0d788b2e5f0ac8b45900b880778437d283..5b1b1963faebb517b9f6156dad202f17cfa632b8 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 @@ -22,38 +22,57 @@ */ package com.oracle.truffle.r.nodes.attributes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; 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.r.runtime.RRuntime; +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.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; +/** + * This node is responsible for retrieving a value from the predefined (fixed) attribute. It accepts + * both {@link DynamicObject} and {@link RAttributable} instances as the first argument. If the + * first argument is {@link RAttributable} and its attributes are initialized, the recursive + * instance of this class is used to get the attribute value from the attributes. + */ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode { + @Child private GetFixedAttributeNode recursive; + protected GetFixedAttributeNode(String name) { super(name); } 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 GetFixedAttributeNode createDim() { - return GetFixedAttributeNode.create(RRuntime.DIM_ATTR_KEY); + public static GetDimAttributeNode createDim() { + return GetDimAttributeNode.create(); } - public static GetFixedAttributeNode createClass() { - return GetFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); + public static GetClassAttributeNode createClass() { + return GetClassAttributeNode.create(); } - public abstract Object execute(DynamicObject attrs); + public abstract Object execute(Object attr); protected boolean hasProperty(Shape shape) { return shape.hasProperty(name); @@ -74,4 +93,31 @@ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode { protected Object getAttrFallback(DynamicObject attrs) { return attrs.get(name); } + + @Specialization + protected Object getAttrFromAttributable(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 null; + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create(name)); + } + + return recursive.execute(attributes); + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/HasFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/HasFixedAttributeNode.java new file mode 100644 index 0000000000000000000000000000000000000000..fdff7b2c0f7c3418a2847f03020d043e0473e74f --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/HasFixedAttributeNode.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.nodes.attributes; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.object.DynamicObject; +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.RRuntime; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; + +/** + * This node is responsible for determining the existence of the predefined (fixed) attribute. It + * accepts both {@link DynamicObject} and {@link RAttributable} instances as the first argument. If + * the first argument is {@link RAttributable} and its attributes are initialized, the recursive + * instance of this class is used to determine the existence from the attributes. + */ +public abstract class HasFixedAttributeNode extends FixedAttributeAccessNode { + + @Child private HasFixedAttributeNode recursive; + + protected HasFixedAttributeNode(String name) { + super(name); + } + + public static HasFixedAttributeNode create(String name) { + return HasFixedAttributeNodeGen.create(name); + } + + public static HasFixedAttributeNode createDim() { + return HasFixedAttributeNodeGen.create(RRuntime.DIM_ATTR_KEY); + } + + public abstract boolean execute(Object attr); + + protected boolean hasProperty(Shape shape) { + return shape.hasProperty(name); + } + + @Specialization(limit = "3", // + guards = {"shapeCheck(shape, attrs)"}, // + assumptions = {"shape.getValidAssumption()"}) + @SuppressWarnings("unused") + protected boolean hasAttrCached(DynamicObject attrs, + @Cached("lookupShape(attrs)") Shape shape, + @Cached("lookupLocation(shape, name)") Location location) { + return location != null; + } + + @Specialization(contains = "hasAttrCached") + @TruffleBoundary + protected boolean hasAttrFallback(DynamicObject attrs) { + return attrs.containsKey(name); + } + + @Specialization + protected boolean hasAttrFromAttributable(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 false; + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create(name)); + } + + return recursive.execute(attributes); + } + +} 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 5d41dae1dbc3861f24152719abd03b86707050e0..b9c737057e670e1ed1d3938bbedabf588c48c737 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 @@ -26,10 +26,17 @@ 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.api.object.Property; +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.r.runtime.RRuntime; +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 { @@ -38,42 +45,64 @@ 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(limit = "3", // - guards = {"shapeCheck(shape, attrs)"}, // + guards = {"shapeCheck(shape, attrs)", "location == null"}, // assumptions = {"shape.getValidAssumption()"}) - protected void removeAttrCached(DynamicObject attrs, - @Cached("lookupShape(attrs)") Shape shape, - @Cached("lookupProperty(shape, name)") Property property) { - if (property != null) { - Shape newShape = attrs.getShape().removeProperty(property); - attrs.setShapeAndResize(shape, newShape); - } + protected void removeNonExistantAttr(@SuppressWarnings("unused") DynamicObject attrs, + @SuppressWarnings("unused") @Cached("lookupShape(attrs)") Shape shape, + @SuppressWarnings("unused") @Cached("lookupLocation(shape, name)") Location location) { + // do nothing } - @Specialization(contains = "removeAttrCached") + @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 b669fa8b59fdef3af23f82a6455888e6c742d45e..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 @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.nodes.attributes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -30,10 +31,27 @@ import com.oracle.truffle.api.object.FinalLocationException; 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 + * {@link DynamicObject} and {@link RAttributable} instances as the first argument. If the first + * argument is {@link RAttributable} and the attribute is a special one (i.e. names, dims, dimnames, + * rownames), a corresponding node defined in the {@link SpecialAttributesFunctions} class is + * created and the processing is delegated to it. If the first argument is {@link RAttributable} and + * the attribute is not a special one, it is made sure that the attributes in the first argument are + * initialized. Then the recursive instance of this class is used to set the attribute value to the + * attributes. + */ public abstract class SetAttributeNode extends AttributeAccessNode { + @Child SetAttributeNode recursive; + protected SetAttributeNode() { } @@ -41,7 +59,7 @@ public abstract class SetAttributeNode extends AttributeAccessNode { return SetAttributeNodeGen.create(); } - public abstract void execute(DynamicObject attrs, String name, Object value); + public abstract void execute(Object attrs, String name, Object value); @Specialization(limit = "3", // guards = { @@ -100,6 +118,57 @@ public abstract class SetAttributeNode extends AttributeAccessNode { receiver.define(name, value); } + protected static SpecialAttributesFunctions.SetSpecialAttributeNode createSpecAttrNode(String name) { + return SpecialAttributesFunctions.createSetSpecialAttributeNode(name); + } + + @Specialization(limit = "3", // + guards = { + "isSpecialAttributeNode.execute(name)", + "cachedName.equals(name)" + }) + @SuppressWarnings("unused") + protected void setSpecAttrInAttributable(RAttributable x, String name, Object value, + @Cached("create()") SpecialAttributesFunctions.IsSpecialAttributeNode isSpecialAttributeNode, + @Cached("name") String cachedName, + @Cached("createSpecAttrNode(cachedName)") SpecialAttributesFunctions.SetSpecialAttributeNode setSpecAttrNode) { + setSpecAttrNode.execute(x, value); + } + + @Specialization(contains = "setSpecAttrInAttributable", // + guards = "isSpecialAttributeNode.execute(name)") + @SuppressWarnings("unused") + protected void setSpecAttrInAttributable(RAttributable x, String name, Object value, + @Cached("create()") SpecialAttributesFunctions.IsSpecialAttributeNode isSpecialAttributeNode, + @Cached("create()") SpecialAttributesFunctions.GenericSpecialAttributeNode genericSpecialAttrNode) { + genericSpecialAttrNode.execute(x, name, value); + } + + @Specialization + protected void setAttrInAttributable(RAttributable x, String name, Object 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 { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + attributes = x.initAttributes(); + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create()); + } + + recursive.execute(attributes, name, value); + } + /** * Try to find the given property in the shape. Also returns null when the value cannot be store * into the location. 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 3f6b8b6bebd444f5cc1fd567b60b71d6cda3b159..fd79ede63e6e57041d801f7eecbd7355ca1f50e6 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 @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.nodes.attributes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -30,36 +31,58 @@ import com.oracle.truffle.api.object.FinalLocationException; 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 + * {@link DynamicObject} and {@link RAttributable} instances as the first argument. If the first + * argument is {@link RAttributable} and the attribute is a special one (i.e. names, dims, dimnames, + * rownames), a corresponding node defined in the {@link SpecialAttributesFunctions} class is + * created and the processing is delegated to it. If the first argument is {@link RAttributable} and + * the attribute is not a special one, it is made sure that the attributes in the first argument are + * initialized. Then the recursive instance of this class is used to set the attribute value to the + * attributes. + */ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { + @Child private SetFixedAttributeNode recursive; + @Child private SetSpecialAttributeNode setSpecialAttrNode; + protected SetFixedAttributeNode(String name) { super(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(DynamicObject attrs, Object value); + public abstract void execute(Object attr, Object value); @Specialization(limit = "3", // guards = {"shapeCheck(shape, attrs)", "location != null"}, // @@ -74,10 +97,54 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { } } + @Specialization(limit = "3", // + guards = {"shapeCheck(oldShape, attrs)", "oldLocation == null"}, // + assumptions = {"oldShape.getValidAssumption()", "newShape.getValidAssumption()"}) + protected static void setNewAttrCached(DynamicObject attrs, Object value, + @Cached("lookupShape(attrs)") Shape oldShape, + @SuppressWarnings("unused") @Cached("lookupLocation(oldShape, name)") Location oldLocation, + @Cached("defineProperty(oldShape, name, value)") Shape newShape, + @Cached("lookupLocation(newShape, name)") Location newLocation) { + try { + newLocation.set(attrs, value, oldShape, newShape); + } catch (IncompatibleLocationException ex) { + RInternalError.reportError(ex); + } + } + + protected static Shape defineProperty(Shape oldShape, Object name, Object value) { + return oldShape.defineProperty(name, value, 0); + } + @Specialization(contains = "setAttrCached") @TruffleBoundary protected void setFallback(DynamicObject attrs, Object value) { attrs.define(name, value); } + @Specialization + protected void setAttrInAttributable(RAttributable x, Object 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 { + 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 new file mode 100644 index 0000000000000000000000000000000000000000..e596ca4f5b734b8f433cb47a4b912ab49de67e0a --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java @@ -0,0 +1,1045 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.nodes.attributes; + +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.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.RAttributeProfiles; +import com.oracle.truffle.r.runtime.data.RAttributesLayout; +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.RLanguage; +import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.RScalarVector; +import com.oracle.truffle.r.runtime.data.RSequence; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.nodes.RBaseNode; + +/** + * This class defines a number of nodes used to handle the special attributes, such as names, dims, + * dimnames and rownames. + */ +public final class SpecialAttributesFunctions { + + /** + * A node used in guards, for example, to determine whether an attribute is a special one. + */ + public static final class IsSpecialAttributeNode extends RBaseNode { + + private final BranchProfile namesProfile = BranchProfile.create(); + private final BranchProfile dimProfile = BranchProfile.create(); + private final BranchProfile dimNamesProfile = BranchProfile.create(); + private final BranchProfile rowNamesProfile = BranchProfile.create(); + private final BranchProfile classProfile = BranchProfile.create(); + + public static IsSpecialAttributeNode create() { + return new IsSpecialAttributeNode(); + } + + /** + * The fast-path method. + */ + public boolean execute(String name) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + namesProfile.enter(); + return true; + } else if (name == RRuntime.DIM_ATTR_KEY) { + dimProfile.enter(); + return true; + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + dimNamesProfile.enter(); + return true; + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + rowNamesProfile.enter(); + return true; + } else if (name == RRuntime.CLASS_ATTR_KEY) { + classProfile.enter(); + return false; + } + return false; + } + + /** + * The slow-path method. + */ + public static boolean isSpecialAttribute(String name) { + assert name.intern() == name; + return name == RRuntime.NAMES_ATTR_KEY || + name == RRuntime.DIM_ATTR_KEY || + name == RRuntime.DIMNAMES_ATTR_KEY || + name == RRuntime.ROWNAMES_ATTR_KEY || + name == RRuntime.CLASS_ATTR_KEY; + + } + } + + /** + * A node for setting a value to any special attribute. + */ + public static final class GenericSpecialAttributeNode extends RBaseNode { + + private final BranchProfile namesProfile = BranchProfile.create(); + private final BranchProfile dimProfile = BranchProfile.create(); + private final BranchProfile dimNamesProfile = BranchProfile.create(); + private final BranchProfile rowNamesProfile = BranchProfile.create(); + + @Child private SetNamesAttributeNode namesAttrNode; + @Child private SetDimAttributeNode dimAttrNode; + @Child private SetDimNamesAttributeNode dimNamesAttrNode; + @Child private SetRowNamesAttributeNode rowNamesAttrNode; + + public static GenericSpecialAttributeNode create() { + return new GenericSpecialAttributeNode(); + } + + public void execute(RAttributable x, String name, Object value) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + namesProfile.enter(); + if (namesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + namesAttrNode = insert(SetNamesAttributeNode.create()); + } + namesAttrNode.execute(x, value); + } else if (name == RRuntime.DIM_ATTR_KEY) { + dimProfile.enter(); + if (dimAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + dimAttrNode = insert(SetDimAttributeNode.create()); + } + dimAttrNode.execute(x, value); + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + dimNamesProfile.enter(); + if (dimNamesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + dimNamesAttrNode = insert(SetDimNamesAttributeNode.create()); + } + dimNamesAttrNode.execute(x, value); + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + rowNamesProfile.enter(); + if (rowNamesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + rowNamesAttrNode = insert(SetRowNamesAttributeNode.create()); + } + rowNamesAttrNode.execute(x, value); + } else if (name == RRuntime.CLASS_ATTR_KEY) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw RInternalError.unimplemented("The \"class\" attribute should be set using a separate method"); + } else { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw RInternalError.shouldNotReachHere(); + } + } + } + + /** + * A factory method for creating a node setting the given special attribute. + * + * @param name the special attribute name + * @return the node + */ + public static SetSpecialAttributeNode createSetSpecialAttributeNode(String name) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + return SetNamesAttributeNode.create(); + } else if (name == RRuntime.DIM_ATTR_KEY) { + return SetDimAttributeNode.create(); + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + return SetDimNamesAttributeNode.create(); + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + return SetRowNamesAttributeNode.create(); + } else if (name == RRuntime.CLASS_ATTR_KEY) { + return SetClassAttributeNode.create(); + } else { + throw RInternalError.shouldNotReachHere(); + } + } + + /** + * 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 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; + } + + attributes.delete(name); + + if (attributes.isEmpty()) { + attrEmptyProfile.enter(); + x.initAttributes(null); + } + } + + } + + public abstract static class SetNamesAttributeNode extends SetSpecialAttributeNode { + + private final ConditionProfile nullDimNamesProfile = ConditionProfile.createBinaryProfile(); + + protected SetNamesAttributeNode() { + super(RRuntime.NAMES_ATTR_KEY); + } + + public static SetNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetNamesAttributeNodeGen.create(); + } + + public void setNames(RAbstractContainer x, RStringVector newNames) { + if (nullDimNamesProfile.profile(newNames == null)) { + execute(x, RNull.instance); + } else { + execute(x, newNames); + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void resetDimNames(RAbstractContainer x, @SuppressWarnings("unused") RNull rnull, + @Cached("create()") RemoveNamesAttributeNode removeNamesAttrNode) { + removeNamesAttrNode.execute(x); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setNamesInVector(RVector<?> x, RStringVector newNames, + @Cached("create()") BranchProfile namesTooLongProfile, + @Cached("createBinaryProfile()") ConditionProfile useDimNamesProfile, + @Cached("create()") GetDimAttributeNode getDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + RVector<?> xProfiled = xTypeProfile.profile(x); + if (newNames.getLength() > xProfiled.getLength()) { + namesTooLongProfile.enter(); + throw RError.error(this, RError.Message.ATTRIBUTE_VECTOR_SAME_LENGTH, RRuntime.NAMES_ATTR_KEY, newNames.getLength(), xProfiled.getLength()); + } + + int[] dimensions = getDimNode.getDimensions(x); + if (useDimNamesProfile.profile(dimensions != null && dimensions.length == 1)) { + // for one dimensional array, "names" is really "dimnames[[1]]" (see R + // documentation for "names" function) + RList newDimNames = RDataFactory.createList(new Object[]{newNames}); + newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; + setDimNamesNode.setDimNames(xProfiled, newDimNames); + } else { + assert newNames != xProfiled; + DynamicObject attrs = xProfiled.getAttributes(); + if (attrs == null) { + attrNullProfile.enter(); + attrs = RAttributesLayout.createNames(newNames); + xProfiled.initAttributes(attrs); + return; + } + + super.setAttrInAttributable(xProfiled, newNames, attrNullProfile, attrStorageProfile, xTypeProfile); + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setNamesInContainer(RAbstractContainer x, RStringVector newNames, + @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setNames(newNames); + } + } + + 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(); + } + + public final RStringVector getNames(Object x) { + return (RStringVector) execute(x); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorNames(RVector<?> x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") BranchProfile namesNullProfile, + @Cached("create()") BranchProfile dimNamesAvlProfile, + @Cached("create()") GetDimNamesAttributeNode getDimNames) { + RStringVector names = (RStringVector) super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + if (names == null) { + namesNullProfile.enter(); + RList dimNames = getDimNames.getDimNames(x); + if (dimNames != null && dimNames.getLength() == 1) { + dimNamesAvlProfile.enter(); + return dimNames.getDataAt(0); + } + return null; + } + + return names; + + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorNames(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") RAttributeProfiles attrProfiles) { + return xTypeProfile.profile(x).getNames(attrProfiles); + } + } + + 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(); + } + + public void setDimensions(RAbstractContainer x, int[] dims) { + if (nullDimProfile.profile(dims == null)) { + execute(x, RNull.instance); + } else { + 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("create()") SetDimNamesAttributeNode setDimNamesNode) { + removeDimAttrNode.execute(x); + setDimNamesNode.setDimNames(x, null); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setOneDimInVector(RVector<?> x, int dim, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + RAbstractContainer xProfiled = contArgClassProfile.profile(x); + + int[] dims = new int[]{dim}; + verifyOneDimensions(xProfiled.getLength(), dim); + + RIntVector dimVec = RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR); + + DynamicObject attrs = xProfiled.getAttributes(); + if (attrs == null) { + attrNullProfile.enter(); + attrs = RAttributesLayout.createDim(dimVec); + xProfiled.initAttributes(attrs); + return; + } + + super.setAttrInAttributable(x, dimVec, 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); + + DynamicObject attrs = xProfiled.getAttributes(); + if (attrs == null) { + attrNullProfile.enter(); + attrs = RAttributesLayout.createDim(dims); + xProfiled.initAttributes(attrs); + return; + } + + 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(); + 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 BranchProfile isLanguageProfile = BranchProfile.create(); + private final BranchProfile isPairListProfile = BranchProfile.create(); + private final ConditionProfile nullDimsProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile nonEmptyDimsProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile twoDimsOrMoreProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile isContainerProfile = ConditionProfile.createBinaryProfile(); + + protected GetDimAttributeNode() { + super(RRuntime.DIM_ATTR_KEY); + } + + public static GetDimAttributeNode create() { + return GetDimAttributeNodeGen.create(); + } + + public final int[] getDimensions(Object x) { + // Let's handle the following two types directly so as to avoid wrapping and unwrapping + // RIntVector. The getContainerDims spec would be invoked otherwise. + if (x instanceof RLanguage) { + isLanguageProfile.enter(); + return ((RLanguage) x).getDimensions(); + } + if (x instanceof RPairList) { + isPairListProfile.enter(); + return ((RPairList) x).getDimensions(); + } + RIntVector dims = (RIntVector) execute(x); + return nullDimsProfile.profile(dims == null) ? null : dims.getInternalStore(); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getScalarVectorDims(@SuppressWarnings("unused") RScalarVector x) { + return null; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getScalarVectorDims(@SuppressWarnings("unused") RSequence x) { + return null; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorDims(RAbstractVector x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + return super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getContainerDims(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("createBinaryProfile()") ConditionProfile nullResultProfile) { + int[] res = xTypeProfile.profile(x).getDimensions(); + return nullResultProfile.profile(res == null) ? null : RDataFactory.createIntVector(res, true); + } + + public int nrows(Object x) { + if (isContainerProfile.profile(x instanceof RAbstractContainer)) { + RAbstractContainer xa = (RAbstractContainer) x; + int[] dims = getDimensions(xa); + if (nonEmptyDimsProfile.profile(dims != null && dims.length > 0)) { + return dims[0]; + } else { + return xa.getLength(); + } + } else { + throw RError.error(RError.SHOW_CALLER2, RError.Message.OBJECT_NOT_MATRIX); + } + } + + public int ncols(Object x) { + if (isContainerProfile.profile(x instanceof RAbstractContainer)) { + RAbstractContainer xa = (RAbstractContainer) x; + int[] dims = getDimensions(xa); + if (nonEmptyDimsProfile.profile(dims != null && dims.length > 0)) { + if (twoDimsOrMoreProfile.profile(dims.length >= 2)) { + return dims[1]; + } else { + return 1; + } + } else { + return 1; + } + } else { + throw RError.error(RError.SHOW_CALLER2, RError.Message.OBJECT_NOT_MATRIX); + } + } + + } + + 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(); + } + + 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); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setDimNamesInVector(RVector<?> x, RList newDimNames, + @Cached("create()") GetDimAttributeNode getDimNode, + @Cached("create()") BranchProfile nullDimsProfile, + @Cached("create()") BranchProfile dimsLengthProfile, + @Cached("createCountingProfile()") LoopConditionProfile loopProfile, + @Cached("create()") BranchProfile invalidDimProfile, + @Cached("create()") BranchProfile nullDimProfile, + @Cached("create()") BranchProfile resizeDimsProfile, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + int[] dimensions = getDimNode.getDimensions(x); + if (dimensions == null) { + nullDimsProfile.enter(); + throw RError.error(this, RError.Message.DIMNAMES_NONARRAY); + } + int newDimNamesLength = newDimNames.getLength(); + if (newDimNamesLength > dimensions.length) { + dimsLengthProfile.enter(); + throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_DIMS, newDimNamesLength, + dimensions.length); + } + + loopProfile.profileCounted(newDimNamesLength); + for (int i = 0; loopProfile.inject(i < newDimNamesLength); i++) { + Object dimObject = newDimNames.getDataAt(i); + + if ((dimObject instanceof String && dimensions[i] != 1) || + (dimObject instanceof RStringVector && !isValidDimLength((RStringVector) dimObject, dimensions[i]))) { + invalidDimProfile.enter(); + throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_EXTENT, i + 1); + } + + if (dimObject == null || (dimObject instanceof RStringVector && ((RStringVector) dimObject).getLength() == 0)) { + nullDimProfile.enter(); + newDimNames.updateDataAt(i, RNull.instance, null); + } + } + + RList resDimNames = newDimNames; + if (newDimNamesLength < dimensions.length) { + resizeDimsProfile.enter(); + // 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; + + if (x.getAttributes() == null) { + attrNullProfile.enter(); + x.initAttributes(RAttributesLayout.createDimNames(resDimNames)); + return; + } + + super.setAttrInAttributable(x, resDimNames, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + private static boolean isValidDimLength(RStringVector x, int expectedDim) { + int len = x.getLength(); + return len == 0 || len == expectedDim; + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setDimNamesInContainer(RAbstractContainer x, RList dimNames, @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setDimNames(dimNames); + } + + } + + 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); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorDimNames(RVector<?> x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + return super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorDimNames(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") RAttributeProfiles attrProfiles) { + return xTypeProfile.profile(x).getDimNames(attrProfiles); + } + + } + + public abstract static class SetRowNamesAttributeNode extends SetSpecialAttributeNode { + + private final ConditionProfile nullRowNamesProfile = ConditionProfile.createBinaryProfile(); + + protected SetRowNamesAttributeNode() { + super(RRuntime.ROWNAMES_ATTR_KEY); + } + + public static SetRowNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetRowNamesAttributeNodeGen.create(); + } + + public void setRowNames(RAbstractContainer x, RAbstractVector rowNames) { + if (nullRowNamesProfile.profile(rowNames == null)) { + execute(x, RNull.instance); + } else { + execute(x, rowNames); + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void resetRowNames(RVector<?> x, @SuppressWarnings("unused") RNull rnull, + @Cached("create()") RemoveRowNamesAttributeNode removeRowNamesAttrNode) { + removeRowNamesAttrNode.execute(x); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setRowNamesInVector(RVector<?> x, RAbstractVector newRowNames, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + if (x.getAttributes() == null) { + attrNullProfile.enter(); + x.initAttributes(RAttributesLayout.createRowNames(newRowNames)); + return; + } + setAttrInAttributable(x, newRowNames, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setRowNamesInContainer(RAbstractContainer x, RAbstractVector rowNames, @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setRowNames(rowNames); + } + + } + + 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(); + } + + public Object getRowNames(RAbstractContainer x) { + return execute(x); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getScalarVectorRowNames(@SuppressWarnings("unused") RScalarVector x) { + return RNull.instance; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getScalarVectorRowNames(@SuppressWarnings("unused") RSequence x) { + return RNull.class; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorRowNames(RAbstractVector x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("createBinaryProfile()") ConditionProfile nullRowNamesProfile) { + Object res = super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + return nullRowNamesProfile.profile(res == null) ? RNull.instance : res; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorRowNames(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") RAttributeProfiles attrProfiles) { + return xTypeProfile.profile(x).getRowNames(attrProfiles); + } + + } + + public abstract static class SetClassAttributeNode extends SetSpecialAttributeNode { + + protected SetClassAttributeNode() { + super(RRuntime.CLASS_ATTR_KEY); + } + + public static SetClassAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetClassAttributeNodeGen.create(); + } + + public void reset(RAttributable x) { + execute(x, RNull.instance); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected <T> void handleVectorNullClass(RVector<T> vector, @SuppressWarnings("unused") RNull classAttr, + @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, + @Cached("createBinaryProfile()") ConditionProfile initAttrProfile, + @Cached("create()") BranchProfile nullAttrProfile, + @Cached("createBinaryProfile()") ConditionProfile nullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + handleVector(vector, null, removeClassAttrNode, initAttrProfile, nullAttrProfile, nullClassProfile, notNullClassProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected <T> void handleVector(RVector<T> vector, RStringVector classAttr, + @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, + @Cached("createBinaryProfile()") ConditionProfile initAttrProfile, + @Cached("create()") BranchProfile nullAttrProfile, + @Cached("createBinaryProfile()") ConditionProfile nullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + + DynamicObject attrs = vector.getAttributes(); + boolean initializeAttrs = initAttrProfile.profile(attrs == null && classAttr != null && classAttr.getLength() != 0); + if (initializeAttrs) { + nullAttrProfile.enter(); + attrs = RAttributesLayout.createClass(classAttr); + vector.initAttributes(attrs); + } + if (nullClassProfile.profile(attrs != null && (classAttr == null || classAttr.getLength() == 0))) { + removeAttributeMapping(vector, attrs, removeClassAttrNode); + } else if (notNullClassProfile.profile(classAttr != null && classAttr.getLength() != 0)) { + for (int i = 0; i < classAttr.getLength(); i++) { + String attr = classAttr.getDataAt(i); + if (RRuntime.CLASS_FACTOR.equals(attr)) { + // TODO: Isn't this redundant when the same operation is done after the + // loop? + if (!initializeAttrs) { + super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile); + } + // setClassAttrNode.execute(attrs, classAttr); + if (vector.getElementClass() != RInteger.class) { + // N.B. there used to be conversion to integer under certain + // circumstances. + // However, it seems that it was dead/obsolete code so it was removed. + // Notes: this can only happen if the class is set by hand to some + // non-integral vector, i.e. attr(doubles, 'class') <- 'factor'. GnuR + // also + // does not update the 'class' attr with other, possibly + // valid classes when it reaches this error. + throw RError.error(RError.SHOW_CALLER2, RError.Message.ADDING_INVALID_CLASS, "factor"); + } + } + } + + if (!initializeAttrs) { + super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile); + } + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void handleAttributable(RAttributable x, @SuppressWarnings("unused") RNull classAttr) { + x.setClassAttr(null); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void handleAttributable(RAttributable x, RStringVector classAttr) { + x.setClassAttr(classAttr); + } + + private static void removeAttributeMapping(RAttributable x, DynamicObject attrs, RemoveFixedAttributeNode removeClassAttrNode) { + if (attrs != null) { + removeClassAttrNode.execute(attrs); + if (attrs.isEmpty()) { + x.initAttributes(null); + } + } + } + + } + + 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(); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorClass(RVector<?> x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + return super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorClass(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") RAttributeProfiles attrProfiles) { + return xTypeProfile.profile(x).getClassAttr(attrProfiles); + } + + } + +} 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 16ae928994e5501164d6c035d71ee336d91c4284..c31cd1da74a52ee0c2792e5dba579aafb2a7be56 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 @@ -26,8 +26,10 @@ 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.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -47,7 +49,9 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { protected final boolean copyAllAttributes; - protected final RAttributeProfiles attrSourceProfiles = RAttributeProfiles.create(); + @Child protected HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); + @Child protected GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + @Child protected GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); protected UnaryCopyAttributesNode(boolean copyAllAttributes) { this.copyAllAttributes = copyAllAttributes; @@ -59,13 +63,13 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { public abstract RAbstractVector execute(RAbstractVector target, RAbstractVector left); - protected boolean containsMetadata(RAbstractVector vector, RAttributeProfiles attrProfiles) { - return vector instanceof RVector && vector.hasDimensions() || (copyAllAttributes && vector.getAttributes() != null) || vector.getNames(attrProfiles) != null || - vector.getDimNames(attrProfiles) != null; + protected boolean containsMetadata(RAbstractVector vector) { + return vector instanceof RVector && hasDimNode.execute(vector) || (copyAllAttributes && vector.getAttributes() != null) || getNamesNode.getNames(vector) != null || + getDimNamesNode.getDimNames(vector) != null; } @SuppressWarnings("unused") - @Specialization(guards = "!containsMetadata(source, attrSourceProfiles)") + @Specialization(guards = "!containsMetadata(source)") protected RAbstractVector copyNoMetadata(RAbstractVector target, RAbstractVector source) { return target; } @@ -76,7 +80,7 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { return target; } - @Specialization(guards = {"!copyAllAttributes || target != source", "containsMetadata(source, attrSourceProfiles)"}) + @Specialization(guards = {"!copyAllAttributes || target != source", "containsMetadata(source)"}) protected RAbstractVector copySameLength(RAbstractVector target, RAbstractVector source, // @Cached("create()") CopyOfRegAttributesNode copyOfReg, // @Cached("createDim()") RemoveFixedAttributeNode removeDim, // @@ -87,40 +91,36 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { @Cached("createDimNames()") SetFixedAttributeNode putDimNames, // @Cached("createBinaryProfile()") ConditionProfile noDimensions, // @Cached("createBinaryProfile()") ConditionProfile hasNamesSource, // - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getDimsNode) { RVector<?> result = target.materialize(); if (copyAllAttributes) { copyOfReg.execute(source, result); } - int[] newDimensions = source.getDimensions(); + int[] newDimensions = getDimsNode.getDimensions(source); if (noDimensions.profile(newDimensions == null)) { DynamicObject attributes = result.getAttributes(); if (attributes != null) { removeDim.execute(attributes); removeDimNames.execute(attributes); - result.setInternalDimNames(null); } - result.setInternalDimensions(null); - RStringVector vecNames = source.getNames(attrSourceProfiles); + RStringVector vecNames = getNamesNode.getNames(source); if (hasNamesSource.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); return result; } return result; } putDim.execute(initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); - result.setInternalDimensions(newDimensions); - RList newDimNames = source.getDimNames(attrSourceProfiles); + RList newDimNames = getDimNamesNode.getDimNames(source); 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/builtin/RExternalBuiltinNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java index d535ea92bc02fa1d2c8c9afeac907fcbb0c97534..7d7294095202e7f5ee95e789e947a12832a2e9c4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java @@ -38,7 +38,6 @@ import com.oracle.truffle.r.nodes.unary.CastToVectorNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RTypes; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -74,7 +73,6 @@ public abstract class RExternalBuiltinNode extends RBaseNode { @Child private CastToVectorNode castVector; @Children private final CastNode[] argumentCasts; - protected final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); protected final BranchProfile errorProfile = BranchProfile.create(); public RExternalBuiltinNode() { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetS4DataSlot.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetS4DataSlot.java index 3b7dc03d2d930df8d37386cc0fd332e510823f56..8dc96975ebadf202edc586ede634c365eb3475df 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetS4DataSlot.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetS4DataSlot.java @@ -19,6 +19,7 @@ import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.RemoveFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNode; import com.oracle.truffle.r.nodes.unary.TypeofNode; import com.oracle.truffle.r.nodes.unary.TypeofNodeGen; @@ -28,7 +29,6 @@ import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RS4Object; import com.oracle.truffle.r.runtime.data.RShareable; -import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTypedValue; // transcribed from src/main/attrib.c @@ -42,6 +42,7 @@ public abstract class GetS4DataSlot extends Node { @Child private GetFixedAttributeNode dotDataAttrAccess; @Child private GetFixedAttributeNode dotXDataAttrAccess; @Child private TypeofNode typeOf = TypeofNodeGen.create(); + @Child private SetClassAttributeNode setClassAttrNode; private final BranchProfile shareable = BranchProfile.create(); @@ -72,6 +73,12 @@ public abstract class GetS4DataSlot extends Node { shareable.enter(); obj = (RAttributable) ((RShareable) obj).copy(); } + + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + if (s3Class != null) { if (s3ClassAttrRemove == null) { assert castToVector == null; @@ -81,9 +88,9 @@ public abstract class GetS4DataSlot extends Node { } s3ClassAttrRemove.execute(obj.initAttributes()); - obj = obj.setClassAttr((RStringVector) castToVector.execute(s3Class)); + setClassAttrNode.execute(obj, castToVector.execute(s3Class)); } else { - obj = obj.setClassAttr(null); + setClassAttrNode.reset(obj); } obj.unsetS4(); if (type == RType.S4Object) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java index b02d46ea7312a68103d2a0488edad5a155c4bc29..025378e9745a42cfa016d1f36041b5e97e88b84b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java @@ -12,10 +12,12 @@ */ package com.oracle.truffle.r.nodes.objects; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.access.AccessSlotNode; import com.oracle.truffle.r.nodes.access.AccessSlotNodeGen; import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastNode; @@ -26,7 +28,6 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RStringVector; // transcribed from src/main/objects.c public abstract class NewObject extends RExternalBuiltinNode.Arg1 { @@ -36,6 +37,7 @@ public abstract class NewObject extends RExternalBuiltinNode.Arg1 { @Child private AccessSlotNode accessSlotPrototypeName = AccessSlotNodeGen.create(true, null, null); @Child private DuplicateNode duplicate = DuplicateNodeGen.create(true); @Child private GetFixedAttributeNode pckgAttrAccess = GetFixedAttributeNode.create(RRuntime.PCKG_ATTR_KEY); + @Child private SetClassAttributeNode setClassAttrNode; @Child private CastNode castStringScalar; @Child private CastNode castLogicalScalar; @@ -62,7 +64,13 @@ public abstract class NewObject extends RExternalBuiltinNode.Arg1 { RAttributable valueAttr = (RAttributable) value; if (valueAttr instanceof RS4Object || (e instanceof RAttributable && ((RAttributable) e).getAttributes() != null && pckgAttrAccess.execute(((RAttributable) e).getAttributes()) != null)) { - valueAttr = valueAttr.setClassAttr((RStringVector) e); + + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + + setClassAttrNode.execute(valueAttr, e); valueAttr.setS4(); } return value; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java index bb33f7c87e692865c85bb056adbd3b6cb32987b2..a720fcbc354a2185eb2dfda7551dedf61aa7cce1 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java @@ -29,6 +29,8 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.CopyAttributesNode; import com.oracle.truffle.r.nodes.attributes.CopyAttributesNodeGen; +import com.oracle.truffle.r.nodes.attributes.HasFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.primitive.BinaryMapNodeFactory.VectorMapBinaryInternalNodeGen; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -63,6 +65,10 @@ public final class BinaryMapNode extends RBaseNode { @Child private VectorMapBinaryInternalNode vectorNode; @Child private BinaryMapFunctionNode function; @Child private CopyAttributesNode copyAttributes; + @Child private GetDimAttributeNode getLeftDimNode = GetDimAttributeNode.create(); + @Child private GetDimAttributeNode getRightDimNode = GetDimAttributeNode.create(); + @Child private HasFixedAttributeNode hasLeftDimNode = HasFixedAttributeNode.createDim(); + @Child private HasFixedAttributeNode hasRightDimNode = HasFixedAttributeNode.createDim(); // profiles private final Class<? extends RAbstractVector> leftClass; @@ -142,9 +148,9 @@ public final class BinaryMapNode extends RBaseNode { } } - private static boolean differentDimensions(RAbstractVector left, RAbstractVector right) { - int[] leftDimensions = left.getDimensions(); - int[] rightDimensions = right.getDimensions(); + private boolean differentDimensions(RAbstractVector left, RAbstractVector right) { + int[] leftDimensions = getLeftDimNode.getDimensions(left); + int[] rightDimensions = getRightDimNode.getDimensions(right); int leftLength = leftDimensions.length; int rightLength = rightDimensions.length; if (leftLength != rightLength) { @@ -227,7 +233,7 @@ public final class BinaryMapNode extends RBaseNode { } private Object applyVectorized(RAbstractVector left, RAbstractVector leftCast, int leftLength, RAbstractVector right, RAbstractVector rightCast, int rightLength) { - if (mayContainMetadata && (dimensionsProfile.profile(left.hasDimensions() && right.hasDimensions()))) { + if (mayContainMetadata && (dimensionsProfile.profile(hasLeftDimNode.execute(left) && hasRightDimNode.execute(right)))) { if (differentDimensions(left, right)) { CompilerDirectives.transferToInterpreter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARRAYS); 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 bb49fe7f101598457022b1d5854d3b0901d8de16..e0b9d614cae4b1e9d6a0fff7d469b945ce70213c 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 @@ -22,12 +22,18 @@ */ package com.oracle.truffle.r.nodes.primitive; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; 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.HasFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +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; @@ -50,6 +56,9 @@ public final class UnaryMapNode extends RBaseNode { @Child private UnaryMapFunctionNode scalarNode; @Child private MapUnaryVectorInternalNode vectorNode; + @Child private GetDimAttributeNode getDimNode; + @Child private SetDimAttributeNode setDimNode; + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); // profiles private final Class<? extends RAbstractVector> operandClass; @@ -170,6 +179,19 @@ public final class UnaryMapNode extends RBaseNode { if (containsMetadata(operand) && operand != target) { hasAttributesProfile.enter(); result = result.materialize(); + + if (getDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimNode = insert(GetDimAttributeNode.create()); + } + + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + + setDimNode.setDimensions(result, getDimNode.getDimensions(operand)); + copyAttributesInternal((RVector<?>) result, operand); } return result; @@ -178,16 +200,18 @@ public final class UnaryMapNode extends RBaseNode { private final ConditionProfile hasDimensionsProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile hasNamesProfile = ConditionProfile.createBinaryProfile(); + @Child private HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + private boolean containsMetadata(RAbstractVector vector) { return vector instanceof RVector && - (hasDimensionsProfile.profile(vector.hasDimensions()) || vector.getAttributes() != null || hasNamesProfile.profile(vector.getNames(attrProfiles) != null) || - vector.getDimNames(attrProfiles) != null); + (hasDimensionsProfile.profile(hasDimNode.execute(vector)) || vector.getAttributes() != null || hasNamesProfile.profile(getNamesNode.getNames(vector) != null) || + getDimNamesNode.getDimNames(vector) != null); } @TruffleBoundary private void copyAttributesInternal(RVector<?> result, RAbstractVector attributeSource) { result.copyRegAttributesFrom(attributeSource); - result.setDimensions(attributeSource.getDimensions()); result.copyNamesFrom(attrProfiles, attributeSource); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java index e9b89627095e03cd06329d0eee7a0082a7ea2ab5..860e6461885dec3ed983f115cc5e3e2b81ca9abe 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java @@ -22,17 +22,21 @@ */ package com.oracle.truffle.r.nodes.unary; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.interop.TruffleObject; 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.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.runtime.NullProfile; 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.RType; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTypedValue; @@ -46,7 +50,10 @@ public abstract class CastBaseNode extends CastNode { private final ConditionProfile hasDimNamesProfile = ConditionProfile.createBinaryProfile(); private final NullProfile hasDimensionsProfile = NullProfile.create(); private final NullProfile hasNamesProfile = NullProfile.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); + @Child private GetDimAttributeNode getDimNode; + @Child private SetDimNamesAttributeNode setDimNamesNode; + @Child private GetDimNamesAttributeNode getDimNamesNode; private final boolean preserveNames; private final boolean preserveDimensions; @@ -56,13 +63,16 @@ public abstract class CastBaseNode extends CastNode { this.preserveNames = preserveNames; this.preserveDimensions = preserveDimensions; this.preserveAttributes = preserveAttributes; + if (preserveDimensions) { + getDimNamesNode = GetDimNamesAttributeNode.create(); + } } public boolean preserveNames() { return preserveNames; } - public boolean preserveDimensions() { + public final boolean preserveDimensions() { return preserveDimensions; } @@ -79,7 +89,11 @@ public abstract class CastBaseNode extends CastNode { protected int[] getPreservedDimensions(RAbstractContainer operand) { if (preserveDimensions()) { - return hasDimensionsProfile.profile(operand.getDimensions()); + if (getDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimNode = insert(GetDimAttributeNode.create()); + } + return hasDimensionsProfile.profile(getDimNode.getDimensions(operand)); } else { return null; } @@ -87,7 +101,7 @@ public abstract class CastBaseNode extends CastNode { protected RStringVector getPreservedNames(RAbstractContainer operand) { if (preserveNames()) { - return hasNamesProfile.profile(operand.getNames(attrProfiles)); + return hasNamesProfile.profile(getNamesNode.getNames(operand)); } else { return null; } @@ -95,9 +109,13 @@ public abstract class CastBaseNode extends CastNode { protected void preserveDimensionNames(RAbstractContainer operand, RVector<?> ret) { if (preserveDimensions()) { - RList dimNames = operand.getDimNames(attrProfiles); + RList dimNames = getDimNamesNode.getDimNames(operand); if (hasDimNamesProfile.profile(dimNames != null)) { - ret.setDimNames((RList) dimNames.copy()); + if (setDimNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNamesNode = insert(SetDimNamesAttributeNode.create()); + } + setDimNamesNode.setDimNames(ret, (RList) dimNames.copy()); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java index 60f816057c901fbe6863f0c7cc5460d7c54c4cf1..1178f3762ee7743577fe611918c14242c8f9592d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java @@ -22,10 +22,11 @@ */ package com.oracle.truffle.r.nodes.unary; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; @@ -36,8 +37,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; public abstract class CastExpressionNode extends CastBaseNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - public abstract Object executeExpression(Object o); protected CastExpressionNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { @@ -85,7 +84,8 @@ public abstract class CastExpressionNode extends CastBaseNode { } @Specialization - protected RExpression doAbstractContainer(RAbstractContainer obj) { + protected RExpression doAbstractContainer(RAbstractContainer obj, + @Cached("create()") GetNamesAttributeNode getNamesNode) { int len = obj.getLength(); Object[] data = new Object[len]; for (int i = 0; i < len; i++) { @@ -94,7 +94,7 @@ public abstract class CastExpressionNode extends CastBaseNode { if (obj instanceof RList) { RList list = (RList) obj; // TODO other attributes - return RDataFactory.createExpression(data, list.getNames(attrProfiles)); + return RDataFactory.createExpression(data, getNamesNode.getNames(list)); } else { return RDataFactory.createExpression(data); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java index 9d53e8623b97de1e410dd4ae8b0619e7fae4f224..14ea322f9f4f9e49447990349ea395b987d9f135 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java @@ -22,11 +22,14 @@ */ package com.oracle.truffle.r.nodes.unary; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.context.RContext; @@ -38,13 +41,14 @@ import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; public abstract class CastListNode extends CastBaseNode { + @Child private SetClassAttributeNode setClassAttrNode; + public abstract RList executeList(Object o); protected CastListNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { @@ -86,16 +90,24 @@ public abstract class CastListNode extends CastBaseNode { } @Specialization - protected RList doLanguage(RLanguage operand, @Cached("create()") ArrayAttributeNode attrAttrAccess) { + protected RList doLanguage(RLanguage operand, + @Cached("create()") ArrayAttributeNode attrAttrAccess, + @Cached("create()") SetAttributeNode setAttrNode) { RList result = RContext.getRRuntimeASTAccess().asList(operand); DynamicObject operandAttrs = operand.getAttributes(); if (operandAttrs != null) { // result may already have names, so can't call RVector.copyAttributesFrom for (RAttributesLayout.RAttribute attr : attrAttrAccess.execute(operandAttrs)) { if (attr.getName().equals(RRuntime.CLASS_ATTR_KEY)) { - result.setClassAttr((RStringVector) attr.getValue()); + + if (setClassAttrNode == null) { + setClassAttrNode = insert(SetClassAttributeNode.create()); + CompilerDirectives.transferToInterpreterAndInvalidate(); + } + + setClassAttrNode.execute(result, attr.getValue()); } else { - result.setAttr(attr.getName(), attr.getValue()); + setAttrNode.execute(result, attr.getName(), attr.getValue()); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java index f46b860eaa0bb01f6161abce902c1a7bd32ae362..11fc0d9c9361611a2cf8e797fdf7282527963218 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java @@ -110,7 +110,7 @@ public abstract class UnaryNotNode extends RBuiltinNode { } } RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA()); - resultVector.copyAttributesFrom(attrProfiles, vector); + resultVector.copyAttributesFrom(vector); return resultVector; } @@ -184,7 +184,7 @@ public abstract class UnaryNotNode extends RBuiltinNode { } } RRawVector resultVector = RDataFactory.createRawVector(result); - resultVector.copyAttributesFrom(attrProfiles, vector); + resultVector.copyAttributesFrom(vector); return resultVector; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java index f5a84fb5c59a96e77b0457446cf562667c2ac246..13475477da4af40a519467e8e5d31948d45e7923 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java @@ -35,7 +35,6 @@ import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributeStorage; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index ff6d84758b526a9a736b6bb7afe2e83c2be3fafd..88c9bc23ee170a940db7ad22673a263e0f771b9d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -41,7 +41,6 @@ import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java index a0f6d36b867504ad6a268ad5117452ca4f91f07a..b699372ccaae032d19a0777b141c5d47ba662ce7 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java @@ -30,7 +30,6 @@ import java.util.LinkedList; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.object.DynamicObject; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.conn.ConnectionSupport.BaseRConnection; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributesLayout; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java index 6d1ed9e4e3e8da595a2591307208691b93364e0a..2fcc8fee9eb0465109998dde9517ad8123ffda69 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java @@ -142,7 +142,7 @@ public interface RAttributable extends RTypedValue { * initialized and will be just cleared, unless nullify is {@code true}. * * @param nullify Some implementations can force nullifying attributes instance if this flag is - * set to {@code true}. Nullifying is not guaranteed for al implementations. + * set to {@code true}. Nullifying is not guaranteed for all implementations. */ default void resetAllAttributes(boolean nullify) { DynamicObject attributes = getAttributes(); @@ -164,6 +164,10 @@ public interface RAttributable extends RTypedValue { return (RStringVector) getAttr(profiles, RRuntime.CLASS_ATTR_KEY); } + default RStringVector getClassAttr() { + return (RStringVector) getAttr(RRuntime.CLASS_ATTR_KEY); + } + /** * Returns {@code true} if and only if the value has a {@code class} attribute added explicitly. * When {@code true}, it is possible to call {@link RAttributable#getClassHierarchy()}. @@ -172,6 +176,10 @@ public interface RAttributable extends RTypedValue { return getClassAttr(profiles) != null ? true : false; } + default boolean isObject() { + return getClassAttr() != null ? true : false; + } + static void copyAttributes(RAttributable obj, DynamicObject attrs) { if (attrs == null) { return; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java index 70c54ef9df0bf9ac8ab717578d672f8fc221402a..8f35974969087a286e79230a3b7af3788e483ff2 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java @@ -27,7 +27,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.object.DynamicObject; @@ -59,12 +58,13 @@ public final class RAttributesLayout { private static final AttrsLayout NAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.NAMES_ATTR_KEY); private static final AttrsLayout DIM_ATTRS_LAYOUT = new AttrsLayout(RRuntime.DIM_ATTR_KEY); private static final AttrsLayout DIMNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.DIMNAMES_ATTR_KEY); + private static final AttrsLayout ROWNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.ROWNAMES_ATTR_KEY); private static final AttrsLayout NAMES_AND_DIM_ATTRS_LAYOUT = new AttrsLayout(RRuntime.NAMES_ATTR_KEY, RRuntime.DIM_ATTR_KEY); private static final AttrsLayout DIM_AND_DIMNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.DIM_ATTR_KEY, RRuntime.DIMNAMES_ATTR_KEY); private static final AttrsLayout CLASS_AND_CONNID_ATTRS_LAYOUT = new AttrsLayout(RRuntime.CLASS_ATTR_KEY, RRuntime.CONN_ID_ATTR_KEY); - public static final AttrsLayout[] LAYOUTS = {EMPTY_ATTRS_LAYOUT, CLASS_ATTRS_LAYOUT, NAMES_ATTRS_LAYOUT, DIM_ATTRS_LAYOUT, DIMNAMES_ATTRS_LAYOUT, NAMES_AND_DIM_ATTRS_LAYOUT, - DIM_AND_DIMNAMES_ATTRS_LAYOUT}; + public static final AttrsLayout[] LAYOUTS = {EMPTY_ATTRS_LAYOUT, CLASS_ATTRS_LAYOUT, NAMES_ATTRS_LAYOUT, DIM_ATTRS_LAYOUT, DIMNAMES_ATTRS_LAYOUT, ROWNAMES_ATTRS_LAYOUT, + NAMES_AND_DIM_ATTRS_LAYOUT, DIM_AND_DIMNAMES_ATTRS_LAYOUT}; private static final Map<String, ConstantShapesAndProperties> constantShapesAndLocationsForAttribute = new HashMap<>(); @@ -114,6 +114,13 @@ public final class RAttributesLayout { new Property[]{ CLASS_AND_CONNID_ATTRS_LAYOUT.properties[0] })); + constantShapesAndLocationsForAttribute.put(RRuntime.ROWNAMES_ATTR_KEY, new ConstantShapesAndProperties( + new Shape[]{ + ROWNAMES_ATTRS_LAYOUT.shape + }, + new Property[]{ + ROWNAMES_ATTRS_LAYOUT.properties[0] + })); } @@ -147,6 +154,10 @@ public final class RAttributesLayout { return DIMNAMES_ATTRS_LAYOUT.factory.newInstance(dimNames); } + public static DynamicObject createRowNames(Object rowNames) { + return ROWNAMES_ATTRS_LAYOUT.factory.newInstance(rowNames); + } + public static DynamicObject createNamesAndDim(Object names, Object dim) { return NAMES_AND_DIM_ATTRS_LAYOUT.factory.newInstance(names, dim); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java index 94d1d71fb49c3ac82b4b3f74a69a2f5fa3e18356..65d16aef9b115d138c0defe6e90f03ab43125e2b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java @@ -47,14 +47,14 @@ public class RExpression extends RListBase implements RAbstractVector { @Override protected RExpression internalCopy() { - return new RExpression(Arrays.copyOf(data, data.length), dimensions, null); + return new RExpression(Arrays.copyOf(data, data.length), getDimensions(), null); } @Override protected RExpression internalDeepCopy() { // TOOD: only used for nested list updates, but still could be made faster (through a // separate AST node?) - RExpression listCopy = new RExpression(Arrays.copyOf(data, data.length), dimensions, null); + RExpression listCopy = new RExpression(Arrays.copyOf(data, data.length), getDimensions(), null); for (int i = 0; i < listCopy.getLength(); i++) { Object el = listCopy.getDataAt(i); if (el instanceof RVector) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java index dd1d78c81978adf1ae7cd562a1042a5c9c0e90e1..cd52a76a925b0dc067d7554f1c8ea060c24942f1 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java @@ -196,7 +196,7 @@ public class RLanguage extends RSharingAttributeStorage implements RAbstractCont } @Override - public void setNames(RStringVector newNames) { + public final void setNames(RStringVector newNames) { if (list == null) { /* See getNames */ RContext.getRRuntimeASTAccess().setNames(this, newNames); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java index dd97f6ea0d42c018c7089d82c5b38b1a1609dddd..8632d8f56dbb440bf7ed0b0722ea33c34bc0a5cd 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java @@ -44,14 +44,14 @@ public final class RList extends RListBase implements RAbstractListVector { @Override protected RList internalCopy() { - return new RList(Arrays.copyOf(data, data.length), dimensions, null); + return new RList(Arrays.copyOf(data, data.length), getDimensions(), null); } @Override protected RList internalDeepCopy() { // TOOD: only used for nested list updates, but still could be made faster (through a // separate AST node?) - RList listCopy = new RList(Arrays.copyOf(data, data.length), dimensions, null); + RList listCopy = new RList(Arrays.copyOf(data, data.length), getDimensions(), null); for (int i = 0; i < listCopy.getLength(); i++) { Object el = listCopy.getDataAt(i); if (el instanceof RVector) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java index 4ed316e9098910dadca1a832ced61ce207fdfee0..537d54d73051c4026054cb467d2661f4b271bf06 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java @@ -146,6 +146,7 @@ public abstract class RListBase extends RVector<Object[]> implements RAbstractLi @TruffleBoundary public final Object getNameAt(int index) { + RStringVector names = getNamesFromAttrs(); if (names != null && names != null) { String name = names.getDataAt(index); if (name == RRuntime.STRING_NA) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java index fabe9e5c925816dc58e278f0f2cd4aef95f55b2b..4b514edb83a7774ebb4e417fa35b4ab3373beb86 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java @@ -329,7 +329,7 @@ public class RPairList extends RSharingAttributeStorage implements RAbstractCont } @Override - public void setNames(RStringVector newNames) { + public final void setNames(RStringVector newNames) { Object p = this; for (int i = 0; i < newNames.getLength() && !isNull(p); i++) { RPairList pList = (RPairList) p; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRaw.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRaw.java index e95a99e462d65a1da3124913f6ce212b761a123f..138c53d05712073d0e6941b8a566ef0c2db40e20 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRaw.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRaw.java @@ -22,7 +22,6 @@ */ package com.oracle.truffle.r.runtime.data; -import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RType; 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 4d9c43afdf1371f48b3e288e73d3c4bd153d17de..310bde8f45d7ac97bb6a82e9f6275a0cf11847a2 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 @@ -33,7 +33,6 @@ import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.SuppressFBWarnings; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -60,18 +59,10 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement private static final RStringVector implicitClassHeaderMatrix = RDataFactory.createStringVector(new String[]{RType.Matrix.getName()}, true); protected boolean complete; // "complete" means: does not contain NAs - protected int[] dimensions; - 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; if (names != null) { // since this constructor is for internal use only, the assertion shouldn't fail assert names.getLength() == length : "size mismatch: " + names.getLength() + " vs. " + length; @@ -85,7 +76,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 { @@ -95,6 +85,39 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } } + private int[] getDimensionsFromAttrs() { + if (attributes == null) { + return null; + } else { + RIntVector dims = (RIntVector) attributes.get(RRuntime.DIM_ATTR_KEY); + return dims == null ? null : dims.getInternalStore(); + } + } + + private RList getDimNamesFromAttrs() { + if (attributes == null) { + return null; + } else { + return (RList) attributes.get(RRuntime.DIMNAMES_ATTR_KEY); + } + } + + private Object getRowNamesFromAttrs() { + if (attributes == null) { + return null; + } else { + return attributes.get(RRuntime.ROWNAMES_ATTR_KEY); + } + } + + protected final RStringVector getNamesFromAttrs() { + if (attributes == null) { + return null; + } else { + return (RStringVector) attributes.get(RRuntime.NAMES_ATTR_KEY); + } + } + /** * Intended for external calls where a mutable copy is needed. */ @@ -127,36 +150,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final int[] getInternalDimensions() { - return dimensions; - } - - public final void setInternalDimensions(int[] newDimensions) { - dimensions = newDimensions; - } - - public final RStringVector getInternalNames() { - return names; - } - - public final void setInternalNames(RStringVector newNames) { - assert newNames != this; - names = newNames; - } - - public final RList getInternalDimNames() { - return dimNames; - } - - public final void setInternalDimNames(RList newDimNames) { - dimNames = newDimNames; - } - - public final Object getInternalRowNames() { - return rowNames; - } - - public final void setInternalRowNames(Object newRowNames) { - rowNames = newRowNames; + return getDimensionsFromAttrs(); } @Override @@ -179,7 +173,9 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement if (attrProfiles.attrNullProfile(attributes == null)) { return null; } else { + RStringVector names = getNamesFromAttrs(); if (attrProfiles.attrNullNamesProfile(names == null)) { + RList dimNames = getDimNames(); if (dimNames != null && dimNames.getLength() == 1) { return (RStringVector) dimNames.getDataAt(0); } else { @@ -196,7 +192,9 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement * performance-critical) */ public final RStringVector getNames() { + RStringVector names = getNamesFromAttrs(); if (names == null) { + RList dimNames = getDimNames(); if (dimNames != null && dimNames.getLength() == 1) { return (RStringVector) dimNames.getDataAt(0); } else { @@ -212,6 +210,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement if (getNames(attrProfiles) == null) { return -1; } + RStringVector names = getNamesFromAttrs(); for (int i = 0; i < names.getLength(); i++) { if (names.getDataAt(i).equals(name)) { return i; @@ -232,6 +231,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } boolean oneMatch = false; int match = -1; + RStringVector names = getNamesFromAttrs(); for (int i = 0; i < names.getLength(); i++) { if (names.getDataAt(i).startsWith(name)) { if (oneMatch) { @@ -339,7 +339,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement putAttribute(RRuntime.NAMES_ATTR_KEY, newNames); } assert newNames != this; - this.names = newNames; } @Override @@ -354,22 +353,20 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement // whether it's one dimensional array or not, assigning null always removes the "names" // attribute removeAttributeMapping(RRuntime.NAMES_ATTR_KEY); - this.names = null; } else if (newNames != null) { if (newNames.getLength() > this.getLength()) { throw RError.error(invokingNode, RError.Message.ATTRIBUTE_VECTOR_SAME_LENGTH, RRuntime.NAMES_ATTR_KEY, newNames.getLength(), this.getLength()); } - if (this.dimensions != null && dimensions.length == 1) { + int[] dimensions = getDimensionsFromAttrs(); + if (dimensions != null && dimensions.length == 1) { // for one dimensional array, "names" is really "dimnames[[1]]" (see R documentation // for "names" function) 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; - this.names = newNames; } } } @@ -380,7 +377,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final RList getDimNames() { - return dimNames; + return getDimNamesFromAttrs(); } /** @@ -394,7 +391,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } else { putAttribute(RRuntime.DIMNAMES_ATTR_KEY, newDimNames); } - this.dimNames = newDimNames; } @Override @@ -407,8 +403,8 @@ 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) { throw RError.error(invokingNode, RError.Message.DIMNAMES_NONARRAY); } @@ -445,7 +441,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; } } @@ -455,17 +450,16 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final Object getRowNames() { - return rowNames; + Object rn = getRowNamesFromAttrs(); + return rn == null ? RNull.instance : rn; } @Override public final void setRowNames(RAbstractVector newRowNames) { if (newRowNames == null) { removeAttributeMapping(RRuntime.ROWNAMES_ATTR_KEY); - this.rowNames = RNull.instance; } else { putAttribute(RRuntime.ROWNAMES_ATTR_KEY, newRowNames); - this.rowNames = newRowNames; } } @@ -476,22 +470,36 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @Override public final boolean hasDimensions() { - return dimensions != null; + return attributes == null ? false : attributes.containsKey(RRuntime.DIM_ATTR_KEY); + } + + public final boolean hasDimNames() { + return attributes == null ? false : attributes.containsKey(RRuntime.DIMNAMES_ATTR_KEY); + } + + public final boolean hasRowNames() { + return attributes == null ? false : attributes.containsKey(RRuntime.ROWNAMES_ATTR_KEY); + } + + public final boolean hasNames() { + return attributes == null ? false : attributes.containsKey(RRuntime.NAMES_ATTR_KEY); } @Override public final boolean isMatrix() { + int[] dimensions = getDimensionsFromAttrs(); return dimensions != null && dimensions.length == 2; } @Override public final boolean isArray() { + int[] dimensions = getDimensionsFromAttrs(); return dimensions != null && dimensions.length > 0; } @Override public final int[] getDimensions() { - return dimensions; + return getDimensionsFromAttrs(); } /** @@ -505,7 +513,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } else { putAttribute(RRuntime.DIM_ATTR_KEY, RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); } - this.dimensions = newDimensions; } @Override @@ -521,7 +528,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement verifyDimensions(getLength(), newDimensions, invokingNode); putAttribute(RRuntime.DIM_ATTR_KEY, RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); } - this.dimensions = newDimensions; } @Override @@ -533,6 +539,10 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement return setClassAttrInternal(vector, classAttr); } + public abstract class CNode extends RBaseNode { + + } + private static RAbstractContainer setClassAttrInternal(RVector<?> vector, RStringVector classAttr) { if (vector.attributes == null && classAttr != null && classAttr.getLength() != 0) { vector.initAttributes(); @@ -562,10 +572,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; - result.dimensions = this.dimensions; if (this.attributes != null) { result.initAttributes(RAttributesLayout.copy(this.attributes)); } @@ -659,21 +665,13 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement public abstract void transferElementSameType(int toIndex, RAbstractVector fromVector, int fromIndex); - public final RAttributable copyAttributesFrom(RAttributeProfiles attrProfiles, RAbstractContainer vector) { + public final RAttributable copyAttributesFrom(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 (this.rowNames == RNull.instance); - assert (this.dimensions == null); + assert (!hasNames()); + assert (!hasDimNames()); + assert (!hasRowNames()); + assert (!hasDimensions()); assert (this.attributes == null || this.attributes.size() == 0) : this.attributes.size(); - if (vector.getDimensions() == null || vector.getDimensions().length != 1) { - // only assign name attribute if it's not represented as dimnames (as is the case for - // one-dimensional array) - this.names = vector.getNames(attrProfiles); - } - this.dimNames = vector.getDimNames(attrProfiles); - this.rowNames = vector.getRowNames(attrProfiles); - this.dimensions = vector.getDimensions(); DynamicObject vecAttributes = vector.getAttributes(); if (vecAttributes != null) { initAttributes(RAttributesLayout.copy(vecAttributes)); @@ -687,13 +685,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement * Internal version without profiles used in a rare (and already slow) case of double-to-int * vector conversion when setting class attribute */ - protected final RAttributable copyAttributesFrom(RVector<?> vector) { - if (vector.getDimensions() == null || vector.getDimensions().length != 1) { - this.names = vector.getNames(); - } - this.dimNames = vector.getDimNames(); - this.rowNames = vector.getRowNames(); - this.dimensions = vector.getDimensions(); + protected final RAttributable copyAttributesFromVector(RVector<?> vector) { DynamicObject vecAttributes = vector.getAttributes(); if (vecAttributes != null) { initAttributes(RAttributesLayout.copy(vecAttributes)); @@ -705,9 +697,9 @@ 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 (this.dimensions == null); + assert (!hasDimNames()); + assert (!hasDimNames()); + assert (!hasDimensions()); assert (this.attributes == null); // for some reason, names is copied first, then dims, then dimnames if (vector.getDimensions() == null || vector.getDimensions().length != 1) { @@ -720,7 +712,8 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final boolean copyNamesFrom(RAttributeProfiles attrProfiles, RAbstractVector vector) { - if (this.dimensions == null) { + int[] dimensions = getDimensionsFromAttrs(); + if (dimensions == null) { RStringVector vecNames = vector.getNames(attrProfiles); if (vecNames != null) { this.setNames(vecNames); @@ -742,18 +735,13 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement public final RVector<ArrayT> copyRegAttributesFrom(RAbstractContainer vector) { DynamicObject orgAttributes = vector.getAttributes(); if (orgAttributes != null) { - Object newRowNames = null; for (RAttributesLayout.RAttribute e : RAttributesLayout.asIterable(orgAttributes)) { String name = e.getName(); if (name != RRuntime.DIM_ATTR_KEY && name != RRuntime.DIMNAMES_ATTR_KEY && name != RRuntime.NAMES_ATTR_KEY) { Object val = e.getValue(); putAttribute(name, val); - if (name == RRuntime.ROWNAMES_ATTR_KEY) { - newRowNames = val; - } } } - this.rowNames = newRowNames == null ? RNull.instance : newRowNames; } return this; } @@ -766,7 +754,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement private RVector<ArrayT> resize(int size, boolean resetAll) { this.complete &= getLength() >= size; RVector<ArrayT> res = this; - RStringVector oldNames = res.names; + RStringVector oldNames = res.getNamesFromAttrs(); res = copyResized(size, true); if (this.isShared()) { assert res.isTemporary(); @@ -775,14 +763,13 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement if (resetAll) { resetAllAttributes(oldNames == null); } else { - res.copyAttributesFrom(this); + res.copyAttributesFromVector(this); res.setDimensionsNoCheck(null); res.setDimNamesNoCheck(null); } if (oldNames != null) { oldNames = oldNames.resizeWithEmpty(size); res.putAttribute(RRuntime.NAMES_ATTR_KEY, oldNames); - res.names = oldNames; } return res; } @@ -790,13 +777,10 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @TruffleBoundary public final void resetDimensions(int[] newDimensions) { // reset all attributes other than dimensions; - this.dimensions = newDimensions; // 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 (this.dimensions != null) { - putAttribute(RRuntime.DIM_ATTR_KEY, RDataFactory.createIntVector(this.dimensions, true)); + if (newDimensions != null) { + putAttribute(RRuntime.DIM_ATTR_KEY, RDataFactory.createIntVector(newDimensions, true)); } else { // nullifying dimensions does not reset regular attributes if (this.attributes != null) { @@ -809,10 +793,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @Override public final void resetAllAttributes(boolean nullify) { - this.dimensions = null; - this.names = null; - this.dimNames = null; - this.rowNames = RNull.instance; if (nullify) { this.attributes = null; } else { diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index ca08ecfb6f6aab0c1e0ef5a998114127aaba55f3..8fef252e8753cf9ccc3ec41ebc0250fcd584ecfe 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -17948,6 +17948,10 @@ NULL [,1] [1,] NA +##com.oracle.truffle.r.test.builtins.TestBuiltin_dimassign.testdimassign12# +#b <- c(a=1+2i,b=3+4i);dim(b) <- c(2,1);attributes(x) +Error: object 'x' not found + ##com.oracle.truffle.r.test.builtins.TestBuiltin_dimassign.testdimassign2# #argv <- list(structure(logical(0), .Dim = c(0L, 0L)), value = c(0L, 0L));`dim<-`(argv[[1]],argv[[2]]); <0 x 0 matrix> diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimassign.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimassign.java index da6bda1e0cb7cc2ebe39516bfc246518da3e8a63..f76298ead2b14bf7a33e0e1fee0011b14932c8af 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimassign.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimassign.java @@ -71,4 +71,10 @@ public class TestBuiltin_dimassign extends TestBase { public void testdimassign11() { assertEval("argv <- list(structure(NA, .Dim = c(1L, 1L)), value = c(1L, 1L));`dim<-`(argv[[1]],argv[[2]]);"); } + + @Test + public void testdimassign12() { + assertEval("b <- c(a=1+2i,b=3+4i);dim(b) <- c(2,1);attributes(x)"); + } + }