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 af6abfd1cd8adcc7790c0f1671ba73214f58f1ef..1cfa2b74dfa57ff0db9fdb43852431bc135a9491 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,8 +17,9 @@ 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.SetClassAttributeNode; +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; @@ -33,6 +34,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(); @@ -54,7 +57,8 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { 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); 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/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..6976f884cf4c3686b2f3531b5f7c86514ee4342e 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 @@ -36,7 +36,6 @@ 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.UpdateSharedAttributeNode; 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..e5e26a5b22a1c7c348fa222a89e21828b2a2a377 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,6 @@ 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.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.CombineNodeGen.CombineInputCastNodeGen; 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 9836382db9156393a1fa64d3e2f8920a2128585c..16c0b8f946f59b79edba83cd41086a2275e68f8e 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 @@ -38,7 +38,7 @@ 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.SetClassAttributeNode; +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; 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 b40823209066398f4129d631f1ff02d4ee801705..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 @@ -36,7 +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.SetClassAttributeNode; +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; 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 c9dbe8b0ba2d04b46c492967c385033af323ada0..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 @@ -56,18 +56,17 @@ import java.util.stream.Stream; 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.r.nodes.attributes.SetClassAttributeNode; +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; 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 04403d4fbfa08dfd3911b9516908144f8df1f931..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 @@ -17,7 +17,7 @@ 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.SetClassAttributeNode; +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; 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..a8b9153cca4d87d8d0b780f24af7d5d44adb7460 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; @@ -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 2bffe1729c707c3512447a5c71924a3aa09ada6a..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 @@ -36,7 +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.SetClassAttributeNode; +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; 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..45b9ae431e3b2dc55480c1af8cf867d546772e07 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 @@ -31,6 +31,7 @@ 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.api.profiles.ConditionProfile; +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.CastDoubleNode; @@ -368,6 +369,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 @@ -437,7 +440,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 +453,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 @@ -499,8 +505,8 @@ 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]); + setPivotAttrNode.execute(a, RRuntime.asLogical(piv)); + setRankAttrNode.execute(a, rank[0]); RList dn = a.getDimNames(); if (dn != null && dn.getDataAt(0) != null) { Object[] dn2 = new Object[m]; 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..34cbb98adf6ac194f07664c75e3dca24394bfd46 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 @@ -33,8 +33,10 @@ import java.net.URISyntaxException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node.Child; 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 +98,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 +225,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 +245,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 +254,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 ea86a45e96d6237e66ad4ff52cf3c3a1b3d8417e..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,7 +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.SetClassAttributeNode; +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; 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..0676f6ba7a00f0dfb1b9e1480e269abf701ee2a9 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 @@ -27,10 +27,12 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lte; 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.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.GetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -50,6 +52,8 @@ public abstract class ShortRowNames extends RBuiltinNode { private final BranchProfile errorProfile = BranchProfile.create(); private final ValueProfile operandTypeProfile = ValueProfile.createClassProfile(); + @Child private GetFixedAttributeNode getRowNamesAttrNode; + @Override protected void createCasts(CastBuilder casts) { casts.arg("type").asIntegerVector().findFirst().mustBe(gte0().and(lte(2))); @@ -64,7 +68,11 @@ public abstract class ShortRowNames extends RBuiltinNode { if (operand instanceof RAbstractContainer) { rowNames = ((RAbstractContainer) operand).getRowNames(attrProfiles); } else if (operand instanceof REnvironment) { - rowNames = ((REnvironment) operand).getAttr(attrProfiles, RRuntime.ROWNAMES_ATTR_KEY); + if (getRowNamesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getRowNamesAttrNode = insert(GetFixedAttributeNode.create(RRuntime.ROWNAMES_ATTR_KEY)); + } + rowNames = getRowNamesAttrNode.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/Transpose.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java index ec945bb76c07a474ac8f40471b3ab7473c12b4d1..2d936337b0bc60b2ab1a52ec21a3f8db25a27733 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 @@ -96,7 +96,6 @@ 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); 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 a7104255300fc675b12928e8c6be4c528e3f913f..f1fcfd5dc4d34b48cc357681924abb28a819d7dd 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java @@ -31,12 +31,12 @@ 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.nodes.Node.Child; import com.oracle.truffle.api.profiles.BranchProfile; -import com.oracle.truffle.r.nodes.attributes.SetClassAttributeNode; +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.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; @@ -70,6 +70,8 @@ public abstract class UpdateAttr extends RBuiltinNode { @Child private CastToVectorNode castVector; @Child private CastListNode castList; @Child private SetClassAttributeNode setClassAttrNode; + @Child private SetRowNamesAttributeNode setRowNamesAttrNode; + @Child private SetAttributeNode setGenAttrNode; @CompilationFinal private String cachedName = ""; @CompilationFinal private String cachedInternedName = ""; @@ -197,10 +199,18 @@ public abstract class UpdateAttr extends RBuiltinNode { 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.execute(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 de564de8968fe28cd0597085e810fb9fc0f8d70e..744664502bc6512cc64e74509f98b5f846dd6d30 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 @@ -30,11 +30,10 @@ 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.api.nodes.Node.Child; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; -import com.oracle.truffle.r.nodes.attributes.SetClassAttributeNode; +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.CastIntegerNode; @@ -64,8 +63,6 @@ public abstract class UpdateAttributes extends RBuiltinNode { @Child private UpdateDimNames updateDimNames; @Child private CastIntegerNode castInteger; @Child private CastToVectorNode castVector; - @Child private SetClassAttributeNode setClassAttrNode; - @Child private InitAttributesNode initAttrNode; @Child private SetAttributeNode setAttrNode; @Override @@ -196,14 +193,10 @@ public abstract class UpdateAttributes extends RBuiltinNode { } else if (attrName.equals(RRuntime.DIMNAMES_ATTR_KEY)) { res = updateDimNames(res, value); } else if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) { - if (setClassAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - setClassAttrNode = insert(SetClassAttributeNode.create()); - } if (value == RNull.instance) { - setClassAttrNode.reset(result); + res.setClassAttr(null); } else { - setClassAttrNode.execute(res, UpdateAttr.convertClassAttrFromObject(value)); + res.setClassAttr(UpdateAttr.convertClassAttrFromObject(value)); } res = result; } else if (attrName.equals(RRuntime.ROWNAMES_ATTR_KEY)) { @@ -212,7 +205,11 @@ public abstract class UpdateAttributes extends RBuiltinNode { 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); } } } @@ -234,12 +231,7 @@ public abstract class UpdateAttributes extends RBuiltinNode { Object obj = getNonShared(o); RAttributable attrObj = (RAttributable) obj; attrObj.removeAllAttributes(); - - if (setClassAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - setClassAttrNode = insert(SetClassAttributeNode.create()); - } - setClassAttrNode.reset(attrObj); + attrObj.setClassAttr(null); return obj; } @@ -269,21 +261,9 @@ public abstract class UpdateAttributes extends RBuiltinNode { throw RError.error(this, RError.Message.SET_INVALID_CLASS_ATTR); } - if (setClassAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - setClassAttrNode = insert(SetClassAttributeNode.create()); - } - setClassAttrNode.execute(attrObj, UpdateAttr.convertClassAttrFromObject(attrValue)); + attrObj.setClassAttr(UpdateAttr.convertClassAttrFromObject(attrValue)); } else { - if (setAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - setAttrNode = insert(SetAttributeNode.create()); - } - if (initAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - initAttrNode = insert(InitAttributesNode.create()); - } - setAttrNode.execute(initAttrNode.execute(attrObj), attrName.intern(), operand.getDataAt(i)); + attrObj.setAttr(attrName.intern(), operand.getDataAt(i)); } } return obj; 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 674c82de1633d6a8529a51e3fe5e6de7b882d048..e2e71f8036f6998ea186efe8519321eb01e1a98b 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,9 +18,7 @@ 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.nodes.Node.Child; -import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; -import com.oracle.truffle.r.nodes.attributes.SetClassAttributeNode; +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; 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..319577028597641d7bd356acd485e0de78775405 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,11 @@ 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.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; @@ -72,7 +69,6 @@ public abstract class UpdateDim extends RBuiltinNode { 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); 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 375dc81129642bbb03ba5b814b44f63f51236bfe..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,7 +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.SetClassAttributeNode; +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; 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 2828a0bcc5dc8d618467bfdb08544a31a5e5a6a3..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,7 +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.SetClassAttributeNode; +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; @@ -36,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) @@ -53,7 +52,9 @@ public abstract class UpdateStorageMode extends RBuiltinNode { 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(); @@ -94,7 +95,7 @@ public abstract class UpdateStorageMode extends RBuiltinNode { 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/infix/Tilde.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java index 00771501a3095b30554c164c0fa60bd45bf81f47..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,10 +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.api.nodes.Node.Child; -import com.oracle.truffle.r.nodes.attributes.SetClassAttributeNode; +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; @@ -58,13 +59,18 @@ public abstract class Tilde extends RBuiltinNode { 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); 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/printer/ExpressionPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java index d8fcdd5d2926f7fbae17bbc8913cc2097940d3e5..5e15b1beafcee1c2817788f538d1cbca51dd7a33 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 @@ -27,7 +27,6 @@ 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 +38,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 +46,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 = (RStringVector) expr.getAttr(RRuntime.NAMES_ATTR_KEY); 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..cf6378f2f601ac71a5c613e9fb4146d3ac127e5f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java @@ -24,7 +24,6 @@ import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RLanguage; @@ -49,15 +48,13 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { // 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 +148,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 +168,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.getAttr(RRuntime.NAMES_ATTR_KEY))); if (ns > 0) { int npr = (ns <= pp.getMax() + 1) ? ns : pp.getMax(); @@ -216,7 +213,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 +233,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..3167f0062c999d7e372a005dd4461eeb15869e1e 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.getAttr(RRuntime.NAMES_ATTR_KEY))); 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.getAttr(RRuntime.NAMES_ATTR_KEY)); if (axisNames == null) { rn = null; cn = null; 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/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..b81069298c0f33afa77acd3a240c2e86f059c492 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,6 @@ 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.profile.AlwaysOnBranchProfile; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; 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..31b4442825912ce16498bf016335ff54bb7eec2d 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 @@ -150,7 +150,6 @@ public abstract class CopyAttributesNode extends RBaseNode { removeDimNames.execute(attributes); result.setInternalDimNames(null); } - result.setInternalDimensions(null); RStringVector vecNames = left.getNames(attrLeftProfiles); if (hasNamesLeft.profile(vecNames != null)) { @@ -176,7 +175,6 @@ 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); @@ -243,7 +241,6 @@ 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); if (hasDimNames.profile(newDimNames != null)) { @@ -292,7 +289,6 @@ 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); if (hasDimNames.profile(newDimNames != null)) { 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..af0a87e247e0baf67eaad54bf2c46ab1f511e491 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; 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..a3d0c24731ed45b61ab4eb67754cddb5ccbad4d9 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,20 @@ */ 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.ConditionProfile; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.runtime.data.RAttributable; public abstract class GetAttributeNode extends AttributeAccessNode { + @Child private GetAttributeNode recursive; + protected GetAttributeNode() { } @@ -39,7 +43,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 +62,21 @@ public abstract class GetAttributeNode extends AttributeAccessNode { return attrs.get(name); } + @Specialization + protected Object getAttrFromAttributable(RAttributable x, String name, + @Cached("create()") BranchProfile attrNullProfile) { + DynamicObject attributes = 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..00044e606d58dd6db224a26d58f530b20607e515 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,17 +22,21 @@ */ 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.ConditionProfile; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.data.RAttributable; public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode { + @Child private GetFixedAttributeNode recursive; + protected GetFixedAttributeNode(String name) { super(name); } @@ -53,7 +57,7 @@ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode { return GetFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); } - public abstract Object execute(DynamicObject attrs); + public abstract Object execute(Object attrs); protected boolean hasProperty(Shape shape) { return shape.hasProperty(name); @@ -74,4 +78,22 @@ 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) { + DynamicObject attributes = 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/RemoveFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java index bb698a4a4540121e0655b46d7bf2f290ccdf2767..1b7ed881a0436f587d0587a99227c258e100467e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java @@ -23,12 +23,8 @@ package com.oracle.truffle.r.nodes.attributes; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; -import com.oracle.truffle.api.object.Property; -import com.oracle.truffle.api.object.Shape; -import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.runtime.RRuntime; public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode { 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..2856f8b339b29a8bc6536916fe3ae17e45b1758e 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,14 @@ 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.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.data.RAttributable; public abstract class SetAttributeNode extends AttributeAccessNode { + @Child SetAttributeNode recursive; + protected SetAttributeNode() { } @@ -41,7 +46,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 +105,49 @@ public abstract class SetAttributeNode extends AttributeAccessNode { receiver.define(name, value); } + protected static SpecialAttributesFunctions.SetSpecialAttributeNode createSpecAttrNode(String name) { + return SpecialAttributesFunctions.createSpecialAttributeNode(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) { + DynamicObject attributes = 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/SetClassAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetClassAttributeNode.java deleted file mode 100644 index ef5dbf6859ecef9b78eef9d39e3ff1e00d758101..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetClassAttributeNode.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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.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.r.runtime.RError; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RInteger; -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.nodes.RBaseNode; - -public abstract class SetClassAttributeNode extends RBaseNode { - - public static SetClassAttributeNode create() { - return SetClassAttributeNodeGen.create(); - } - - public abstract void execute(RAttributable x, Object classAttr); - - public void reset(RAttributable x) { - execute(x, RNull.instance); - } - - @Specialization - protected <T> void handleVectorNullClass(RVector<T> vector, @SuppressWarnings("unused") RNull classAttr, - @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, - @Cached("createClass()") SetFixedAttributeNode setClassAttrNode, - @Cached("create()") BranchProfile nullAttrProfile, - @Cached("createBinaryProfile()") ConditionProfile nullClassProfile, - @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile) { - handleVector(vector, null, removeClassAttrNode, setClassAttrNode, nullAttrProfile, nullClassProfile, notNullClassProfile); - } - - @Specialization - protected <T> void handleVector(RVector<T> vector, RStringVector classAttr, - @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, - @Cached("createClass()") SetFixedAttributeNode setClassAttrNode, - @Cached("create()") BranchProfile nullAttrProfile, - @Cached("createBinaryProfile()") ConditionProfile nullClassProfile, - @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile) { - - DynamicObject attrs = vector.getAttributes(); - if (attrs == null && classAttr != null && classAttr.getLength() != 0) { - nullAttrProfile.enter(); - attrs = vector.initAttributes(); - } - 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? - 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"); - } - } - } - setClassAttrNode.execute(attrs, classAttr); - } - } - - @Specialization - protected void handleAttributable(RAttributable x, @SuppressWarnings("unused") RNull classAttr) { - x.setClassAttr(null); - } - - @Specialization - 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); - } - } - } - -} 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..e427dc9cb466830c2bfce0a53b04646dbfddaf7e 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,13 +31,22 @@ 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.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; public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { + @Child private SetFixedAttributeNode recursive; + @Child private SetSpecialAttributeNode setSpecialAttrNode; + + private final boolean isSpecialAttribute; + protected SetFixedAttributeNode(String name) { super(name); + this.isSpecialAttribute = SpecialAttributesFunctions.IsSpecialAttributeNode.isSpecialAttribute(name); } public static SetFixedAttributeNode create(String name) { @@ -59,7 +69,7 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { return SetFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); } - 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"}, // @@ -80,4 +90,29 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { attrs.define(name, value); } + @Specialization + protected void setAttrInAttributable(RAttributable x, Object value, + @Cached("create()") BranchProfile attrNullProfile) { + if (isSpecialAttribute) { + if (setSpecialAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setSpecialAttrNode = insert(SpecialAttributesFunctions.createSpecialAttributeNode(name)); + } + setSpecialAttrNode.execute(x, value); + } else { + DynamicObject attributes = x.getAttributes(); + if (attributes == null) { + attrNullProfile.enter(); + attributes = x.initAttributes(); + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create(name)); + } + recursive.execute(attributes, value); + } + + } + } 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..fa9375895a6cfbd5a4c67f1dc661fd9d1537cc3d --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java @@ -0,0 +1,318 @@ +/* + * 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.ValueProfile; +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.RInteger; +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.RAbstractIntVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.nodes.RBaseNode; + +public final class SpecialAttributesFunctions { + + 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; + + } + } + + 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(); + } + } + } + + public static SetSpecialAttributeNode createSpecialAttributeNode(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 SpecialAttributesFunctions.SetDimNamesAttributeNode.create(); + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + return SpecialAttributesFunctions.SetRowNamesAttributeNode.create(); + } else if (name == RRuntime.CLASS_ATTR_KEY) { + throw RInternalError.unimplemented("The \"class\" attribute should be set using a separate method"); + } else { + throw RInternalError.shouldNotReachHere(); + } + } + + public abstract static class SetSpecialAttributeNode extends RBaseNode { + + public abstract void execute(RAttributable x, Object attrValue); + + } + + public abstract static class SetNamesAttributeNode extends SetSpecialAttributeNode { + + public static SetNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetNamesAttributeNodeGen.create(); + } + + @Specialization + protected void setNamesInContainer(RAbstractContainer x, RStringVector names, @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setNames(names); + } + } + + public abstract static class SetDimAttributeNode extends SetSpecialAttributeNode { + + public static SetDimAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetDimAttributeNodeGen.create(); + } + + @Specialization + protected void setOneDimInContainer(RAbstractContainer x, Integer dim, @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setDimensions(new int[]{dim}); + } + + @Specialization + protected void setDimsInContainer(RAbstractContainer x, RAbstractIntVector dims, @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setDimensions(dims.materialize().getDataCopy()); + } + + } + + public abstract static class SetDimNamesAttributeNode extends SetSpecialAttributeNode { + + public static SetDimNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetDimNamesAttributeNodeGen.create(); + } + + @Specialization + protected void setDimNamesInContainer(RAbstractContainer x, RList dimNames, @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setDimNames(dimNames); + } + + } + + public abstract static class SetRowNamesAttributeNode extends SetSpecialAttributeNode { + + public static SetRowNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetRowNamesAttributeNodeGen.create(); + } + + @Specialization + protected void setRowNamesInContainer(RAbstractContainer x, RAbstractVector rowNames, @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setRowNames(rowNames); + } + + } + + public abstract static class SetClassAttributeNode extends SetSpecialAttributeNode { + + public static SetClassAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetClassAttributeNodeGen.create(); + } + + public void reset(RAttributable x) { + execute(x, RNull.instance); + } + + @Specialization + protected <T> void handleVectorNullClass(RVector<T> vector, @SuppressWarnings("unused") RNull classAttr, + @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, + @Cached("createClass()") SetFixedAttributeNode setClassAttrNode, + @Cached("create()") BranchProfile nullAttrProfile, + @Cached("createBinaryProfile()") ConditionProfile nullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile) { + handleVector(vector, null, removeClassAttrNode, setClassAttrNode, nullAttrProfile, nullClassProfile, notNullClassProfile); + } + + @Specialization + protected <T> void handleVector(RVector<T> vector, RStringVector classAttr, + @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, + @Cached("createClass()") SetFixedAttributeNode setClassAttrNode, + @Cached("create()") BranchProfile nullAttrProfile, + @Cached("createBinaryProfile()") ConditionProfile nullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile) { + + DynamicObject attrs = vector.getAttributes(); + if (attrs == null && classAttr != null && classAttr.getLength() != 0) { + nullAttrProfile.enter(); + attrs = vector.initAttributes(); + } + 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? + 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"); + } + } + } + setClassAttrNode.execute(attrs, classAttr); + } + } + + @Specialization + protected void handleAttributable(RAttributable x, @SuppressWarnings("unused") RNull classAttr) { + x.setClassAttr(null); + } + + @Specialization + 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); + } + } + } + + } + +} 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..fe2840463b46335b24eabe2075bab1007f50e33f 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 @@ -102,7 +102,6 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { removeDimNames.execute(attributes); result.setInternalDimNames(null); } - result.setInternalDimensions(null); RStringVector vecNames = source.getNames(attrSourceProfiles); if (hasNamesSource.profile(vecNames != null)) { @@ -114,7 +113,6 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { } putDim.execute(initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); - result.setInternalDimensions(newDimensions); RList newDimNames = source.getDimNames(attrSourceProfiles); if (hasDimNames.profile(newDimNames != null)) { 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 2c495a67ce421a9c7dccf4e07beaf546033c93fa..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,8 +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.SetAttributeNode; -import com.oracle.truffle.r.nodes.attributes.SetClassAttributeNode; +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; @@ -30,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 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 0929f696f491a144ca332bab105074b6109ec94d..411ae2d4db7950997d12e94a39d17d3fc96514e8 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 @@ -17,7 +17,7 @@ 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.SetClassAttributeNode; +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; @@ -28,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 { 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 0b01117753dd91c60670b8d9d1fb3c9c72bfc694..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 @@ -26,10 +26,10 @@ 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.nodes.Node.Child; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode; -import com.oracle.truffle.r.nodes.attributes.SetClassAttributeNode; +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; @@ -41,7 +41,6 @@ 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; @@ -91,7 +90,9 @@ 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) { @@ -106,7 +107,7 @@ public abstract class CastListNode extends CastBaseNode { 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.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..5f109b8a5279bad1db9c13838cca75c9efa61d94 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; 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/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/RVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java index d0983a3caf8b7884217835b32be0f036feb33274..06c7279cc4862b2d689fc5b9a5f460de77367ad5 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 @@ -28,12 +28,14 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.api.object.Location; +import com.oracle.truffle.api.object.Property; +import com.oracle.truffle.api.object.Shape; 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.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,7 +62,8 @@ 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; + private Shape attrShape; + private Location dimensionsLoc; protected RStringVector names; private RList dimNames; // cache rownames for data frames as they are accessed at every data frame access @@ -68,7 +71,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement protected RVector(boolean complete, int length, int[] dimensions, RStringVector names) { this.complete = complete; - this.dimensions = dimensions; + // this.dimensions = dimensions; assert names != this; this.names = names; this.rowNames = RNull.instance; @@ -93,6 +96,35 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement initAttributes(RAttributesLayout.createDim(RDataFactory.createIntVector(dimensions, true))); } } + updateLocationsFromAttrs(); + } + + private void updateLocationsFromAttrs() { + if (attributes == null) { + attrShape = null; + dimensionsLoc = null; + } else if (attributes.getShape() != attrShape) { + attrShape = attributes.getShape(); + Property prop = attrShape.getProperty(RRuntime.DIM_ATTR_KEY); + if (prop == null) { + dimensionsLoc = null; + } else { + dimensionsLoc = prop.getLocation(); + } + // TODO: the same for the other special attributes + } + } + + private int[] getDimensionsFromAttrs() { + // Sync the shape + updateLocationsFromAttrs(); + + if (dimensionsLoc == null) { + return null; + } else { + RIntVector dims = (RIntVector) dimensionsLoc.get(attributes); + return dims.getInternalStore(); + } } /** @@ -127,11 +159,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final int[] getInternalDimensions() { - return dimensions; - } - - public final void setInternalDimensions(int[] newDimensions) { - dimensions = newDimensions; + return getDimensionsFromAttrs(); } public final RStringVector getInternalNames() { @@ -359,7 +387,8 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement 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}); @@ -409,6 +438,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement 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); } @@ -476,22 +506,27 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @Override public final boolean hasDimensions() { - return dimensions != null; + // Sync the shape + updateLocationsFromAttrs(); + + return dimensionsLoc != null; } @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 +540,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 +555,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 @@ -569,7 +602,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement 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)); } @@ -668,7 +700,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement assert (this.names == null); assert (this.dimNames == null); assert (this.rowNames == RNull.instance); - assert (this.dimensions == null); + 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 @@ -677,7 +709,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } 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)); @@ -697,7 +728,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } this.dimNames = vector.getDimNames(); this.rowNames = vector.getRowNames(); - this.dimensions = vector.getDimensions(); DynamicObject vecAttributes = vector.getAttributes(); if (vecAttributes != null) { initAttributes(RAttributesLayout.copy(vecAttributes)); @@ -711,7 +741,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement // 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 (!hasDimensions()); assert (this.attributes == null); // for some reason, names is copied first, then dims, then dimnames if (vector.getDimensions() == null || vector.getDimensions().length != 1) { @@ -724,7 +754,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); @@ -794,13 +825,12 @@ 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) { @@ -813,7 +843,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;