diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java
index 001941ccdb546784bc4f94e5434124cdffaf6a7a..4a85c00052164f5c2ea76442cfab799fb2cdf6ea 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java
@@ -28,7 +28,6 @@ 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.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -40,7 +39,6 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RComplexVector;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -60,8 +58,10 @@ public abstract class IsNA extends RBuiltinNode {
 
     @Child private IsNA recursiveIsNA;
     @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
+    @Child private GetDimAttributeNode getDimsNode = GetDimAttributeNode.create();
+    @Child private SetDimNamesAttributeNode setDimNamesNode = SetDimNamesAttributeNode.create();
+    @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create();
 
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
     private final ConditionProfile nullDimNamesProfile = ConditionProfile.createBinaryProfile();
 
     private Object isNARecursive(Object o) {
@@ -80,15 +80,12 @@ public abstract class IsNA extends RBuiltinNode {
     }
 
     @Specialization
-    protected RLogicalVector isNA(RAbstractIntVector vector,
-                    @Cached("create()") GetDimAttributeNode getDimsNode,
-                    @Cached("create()") SetDimNamesAttributeNode setDimNamesNode,
-                    @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) {
+    protected RLogicalVector isNA(RAbstractIntVector vector) {
         byte[] resultVector = new byte[vector.getLength()];
         for (int i = 0; i < vector.getLength(); i++) {
             resultVector[i] = RRuntime.asLogical(RRuntime.isNA(vector.getDataAt(i)));
         }
-        return createResult(resultVector, vector, getDimsNode, setDimNamesNode, getDimNamesNode);
+        return createResult(resultVector, vector);
     }
 
     @Specialization
@@ -97,28 +94,22 @@ public abstract class IsNA extends RBuiltinNode {
     }
 
     @Specialization
-    protected RLogicalVector isNA(RAbstractDoubleVector vector,
-                    @Cached("create()") GetDimAttributeNode getDimsNode,
-                    @Cached("create()") SetDimNamesAttributeNode setDimNamesNode,
-                    @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) {
+    protected RLogicalVector isNA(RAbstractDoubleVector vector) {
         byte[] resultVector = new byte[vector.getLength()];
         for (int i = 0; i < vector.getLength(); i++) {
             resultVector[i] = RRuntime.asLogical(RRuntime.isNAorNaN(vector.getDataAt(i)));
         }
-        return createResult(resultVector, vector, getDimsNode, setDimNamesNode, getDimNamesNode);
+        return createResult(resultVector, vector);
     }
 
     @Specialization
-    protected RLogicalVector isNA(RComplexVector vector,
-                    @Cached("create()") GetDimAttributeNode getDimsNode,
-                    @Cached("create()") SetDimNamesAttributeNode setDimNamesNode,
-                    @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) {
+    protected RLogicalVector isNA(RComplexVector vector) {
         byte[] resultVector = new byte[vector.getLength()];
         for (int i = 0; i < vector.getLength(); i++) {
             RComplex complex = vector.getDataAt(i);
             resultVector[i] = RRuntime.asLogical(RRuntime.isNA(complex));
         }
-        return createResult(resultVector, vector, getDimsNode, setDimNamesNode, getDimNamesNode);
+        return createResult(resultVector, vector);
     }
 
     @Specialization
@@ -127,15 +118,12 @@ public abstract class IsNA extends RBuiltinNode {
     }
 
     @Specialization
-    protected RLogicalVector isNA(RStringVector vector,
-                    @Cached("create()") GetDimAttributeNode getDimsNode,
-                    @Cached("create()") SetDimNamesAttributeNode setDimNamesNode,
-                    @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) {
+    protected RLogicalVector isNA(RStringVector vector) {
         byte[] resultVector = new byte[vector.getLength()];
         for (int i = 0; i < vector.getLength(); i++) {
             resultVector[i] = RRuntime.asLogical(RRuntime.isNA(vector.getDataAt(i)));
         }
-        return createResult(resultVector, vector, getDimsNode, setDimNamesNode, getDimNamesNode);
+        return createResult(resultVector, vector);
     }
 
     @Specialization
@@ -170,15 +158,12 @@ public abstract class IsNA extends RBuiltinNode {
     }
 
     @Specialization
-    protected RLogicalVector isNA(RLogicalVector vector,
-                    @Cached("create()") GetDimAttributeNode getDimsNode,
-                    @Cached("create()") SetDimNamesAttributeNode setDimNamesNode,
-                    @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) {
+    protected RLogicalVector isNA(RLogicalVector vector) {
         byte[] resultVector = new byte[vector.getLength()];
         for (int i = 0; i < vector.getLength(); i++) {
             resultVector[i] = (RRuntime.isNA(vector.getDataAt(i)) ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE);
         }
-        return createResult(resultVector, vector, getDimsNode, setDimNamesNode, getDimNamesNode);
+        return createResult(resultVector, vector);
     }
 
     @Specialization
@@ -192,15 +177,12 @@ public abstract class IsNA extends RBuiltinNode {
     }
 
     @Specialization
-    protected RLogicalVector isNA(RRawVector vector,
-                    @Cached("create()") GetDimAttributeNode getDimsNode,
-                    @Cached("create()") SetDimNamesAttributeNode setDimNamesNode,
-                    @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) {
+    protected RLogicalVector isNA(RRawVector vector) {
         byte[] resultVector = new byte[vector.getLength()];
         for (int i = 0; i < vector.getLength(); i++) {
             resultVector[i] = RRuntime.LOGICAL_FALSE;
         }
-        return createResult(resultVector, vector, getDimsNode, setDimNamesNode, getDimNamesNode);
+        return createResult(resultVector, vector);
     }
 
     @Specialization
@@ -217,8 +199,7 @@ public abstract class IsNA extends RBuiltinNode {
         return RRuntime.LOGICAL_FALSE;
     }
 
-    private RLogicalVector createResult(byte[] data, RAbstractVector originalVector, GetDimAttributeNode getDimsNode, SetDimNamesAttributeNode setDimNamesNode,
-                    GetDimNamesAttributeNode getDimNamesNode) {
+    private RLogicalVector createResult(byte[] data, RAbstractVector originalVector) {
         RLogicalVector result = RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR, getDimsNode.getDimensions(originalVector), getNamesNode.getNames(originalVector));
         RList dimNames = getDimNamesNode.getDimNames(originalVector);
         if (nullDimNamesProfile.profile(dimNames != null)) {
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 0ea914972ddd148f9d8fbdc952edf6d85898de32..17a035de4a7ff78c82f6ecf809bc11439af6a064 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java
@@ -27,20 +27,16 @@ 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.Cached;
 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.attributes.SpecialAttributesFunctions.GetRowNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
@@ -53,7 +49,7 @@ public abstract class ShortRowNames extends RBuiltinNode {
     private final BranchProfile errorProfile = BranchProfile.create();
     private final ValueProfile operandTypeProfile = ValueProfile.createClassProfile();
 
-    @Child private GetFixedAttributeNode getRowNamesAttrNode;
+    @Child private GetRowNamesAttributeNode getRowNamesNode = GetRowNamesAttributeNode.create();
 
     @Override
     protected void createCasts(CastBuilder casts) {
@@ -63,18 +59,13 @@ public abstract class ShortRowNames extends RBuiltinNode {
     private final IntValueProfile typeProfile = IntValueProfile.createIdentityProfile();
 
     @Specialization
-    protected Object getNames(Object originalOperand, int originalType,
-                    @Cached("create()") GetRowNamesAttributeNode getRowNamesNode) {
+    protected Object getNames(Object originalOperand, int originalType) {
         Object operand = operandTypeProfile.profile(originalOperand);
         Object rowNames;
         if (operand instanceof RAbstractContainer) {
             rowNames = getRowNamesNode.getRowNames((RAbstractContainer) operand);
         } else if (operand instanceof REnvironment) {
-            if (getRowNamesAttrNode == null) {
-                CompilerDirectives.transferToInterpreterAndInvalidate();
-                getRowNamesAttrNode = insert(GetFixedAttributeNode.create(RRuntime.ROWNAMES_ATTR_KEY));
-            }
-            rowNames = getRowNamesAttrNode.execute(operand);
+            rowNames = getRowNamesNode.execute(operand);
         } else {
             // for any other type GnuR returns 0
             return 0;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java
index e2e71f8036f6998ea186efe8519321eb01e1a98b..094f7fb3b8b052cc251da25e495c326f181a1cf3 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java
@@ -18,6 +18,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.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.TypeFromModeNode;
 import com.oracle.truffle.r.nodes.binary.CastTypeNode;
@@ -97,6 +98,7 @@ public abstract class UpdateClass extends RBuiltinNode {
                 return setClass((RAbstractVector) result, RNull.instance);
             }
         }
+
         RAbstractContainer result = reuseNonShared(arg);
         if (result instanceof RAbstractVector) {
             RAbstractVector resultVector = (RAbstractVector) result;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java
index c674cb5390f0e779a5a56bf6b0dace5db84c530b..714e8c2a381a8dd49dd583944e2439d4e5d3ef7d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java
@@ -65,7 +65,7 @@ public abstract class FastrDqrls extends RBuiltinNode {
         return call(xVec, ((RAbstractDoubleVector) castNode.execute(xVec)).materialize(), n, p, yVec, ((RAbstractDoubleVector) castNode.execute(yVec)).materialize(), ny, tol, coeffVec);
     }
 
-    private static RList call(RAbstractVector originalXVec, RDoubleVector xVec, int n, int p, RAbstractVector originalYVec, RDoubleVector yVec, int ny, double tol, RAbstractDoubleVector coeffVec) {
+    private RList call(RAbstractVector originalXVec, RDoubleVector xVec, int n, int p, RAbstractVector originalYVec, RDoubleVector yVec, int ny, double tol, RAbstractDoubleVector coeffVec) {
         double[] x = xVec.getDataTemp();
         double[] y = yVec.getDataTemp();
         double[] coeff = coeffVec.materialize().getDataTemp();
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 3cd9524ce9949607b19f7a3bfe54ff0407f85bf7..5b1b1963faebb517b9f6156dad202f17cfa632b8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java
@@ -68,7 +68,7 @@ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode {
         return GetDimAttributeNode.create();
     }
 
-    public static GetFixedAttributeNode createClass() {
+    public static GetClassAttributeNode createClass() {
         return GetClassAttributeNode.create();
     }
 
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 1b1477258b980a07db9bec92b44c427a04247b4f..fd79ede63e6e57041d801f7eecbd7355ca1f50e6 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java
@@ -143,6 +143,7 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             recursive = insert(create(name));
         }
+
         recursive.execute(attributes, value);
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java
index d064aeb7d7548c7975134f5cc5e1ce03aac6df99..e596ca4f5b734b8f433cb47a4b912ab49de67e0a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java
@@ -188,7 +188,7 @@ public final class SpecialAttributesFunctions {
         } else if (name == RRuntime.ROWNAMES_ATTR_KEY) {
             return SetRowNamesAttributeNode.create();
         } else if (name == RRuntime.CLASS_ATTR_KEY) {
-            throw RInternalError.unimplemented("The \"class\" attribute should be set using a separate method");
+            return SetClassAttributeNode.create();
         } else {
             throw RInternalError.shouldNotReachHere();
         }
@@ -274,7 +274,6 @@ public final class SpecialAttributesFunctions {
                 return;
             }
 
-            attrNullProfile.enter();
             attributes.delete(name);
 
             if (attributes.isEmpty()) {
@@ -325,6 +324,7 @@ public final class SpecialAttributesFunctions {
                 namesTooLongProfile.enter();
                 throw RError.error(this, RError.Message.ATTRIBUTE_VECTOR_SAME_LENGTH, RRuntime.NAMES_ATTR_KEY, newNames.getLength(), xProfiled.getLength());
             }
+
             int[] dimensions = getDimNode.getDimensions(x);
             if (useDimNamesProfile.profile(dimensions != null && dimensions.length == 1)) {
                 // for one dimensional array, "names" is really "dimnames[[1]]" (see R
@@ -333,8 +333,16 @@ public final class SpecialAttributesFunctions {
                 newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX;
                 setDimNamesNode.setDimNames(xProfiled, newDimNames);
             } else {
-                super.setAttrInAttributable(xProfiled, newNames, attrNullProfile, attrStorageProfile, xTypeProfile);
                 assert newNames != xProfiled;
+                DynamicObject attrs = xProfiled.getAttributes();
+                if (attrs == null) {
+                    attrNullProfile.enter();
+                    attrs = RAttributesLayout.createNames(newNames);
+                    xProfiled.initAttributes(attrs);
+                    return;
+                }
+
+                super.setAttrInAttributable(xProfiled, newNames, attrNullProfile, attrStorageProfile, xTypeProfile);
             }
         }
 
@@ -447,9 +455,22 @@ public final class SpecialAttributesFunctions {
                         @Cached("create()") BranchProfile attrNullProfile,
                         @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
                         @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+            RAbstractContainer xProfiled = contArgClassProfile.profile(x);
+
             int[] dims = new int[]{dim};
-            verifyOneDimensions(x.getLength(), dim);
-            super.setAttrInAttributable(x, RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR), attrNullProfile, attrStorageProfile, xTypeProfile);
+            verifyOneDimensions(xProfiled.getLength(), dim);
+
+            RIntVector dimVec = RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR);
+
+            DynamicObject attrs = xProfiled.getAttributes();
+            if (attrs == null) {
+                attrNullProfile.enter();
+                attrs = RAttributesLayout.createDim(dimVec);
+                xProfiled.initAttributes(attrs);
+                return;
+            }
+
+            super.setAttrInAttributable(x, dimVec, attrNullProfile, attrStorageProfile, xTypeProfile);
         }
 
         @Specialization(insertBefore = "setAttrInAttributable")
@@ -459,6 +480,15 @@ public final class SpecialAttributesFunctions {
                         @Cached("createClassProfile()") ValueProfile xTypeProfile) {
             RAbstractContainer xProfiled = contArgClassProfile.profile(x);
             verifyDimensions(xProfiled.getLength(), dims);
+
+            DynamicObject attrs = xProfiled.getAttributes();
+            if (attrs == null) {
+                attrNullProfile.enter();
+                attrs = RAttributesLayout.createDim(dims);
+                xProfiled.initAttributes(attrs);
+                return;
+            }
+
             super.setAttrInAttributable(x, dims, attrNullProfile, attrStorageProfile, xTypeProfile);
         }
 
@@ -785,11 +815,24 @@ public final class SpecialAttributesFunctions {
         }
 
         @Specialization(insertBefore = "setAttrInAttributable")
-        protected void resetRowNames(RAbstractContainer x, @SuppressWarnings("unused") RNull rnull,
+        protected void resetRowNames(RVector<?> x, @SuppressWarnings("unused") RNull rnull,
                         @Cached("create()") RemoveRowNamesAttributeNode removeRowNamesAttrNode) {
             removeRowNamesAttrNode.execute(x);
         }
 
+        @Specialization(insertBefore = "setAttrInAttributable")
+        protected void setRowNamesInVector(RVector<?> x, RAbstractVector newRowNames,
+                        @Cached("create()") BranchProfile attrNullProfile,
+                        @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+            if (x.getAttributes() == null) {
+                attrNullProfile.enter();
+                x.initAttributes(RAttributesLayout.createRowNames(newRowNames));
+                return;
+            }
+            setAttrInAttributable(x, newRowNames, attrNullProfile, attrStorageProfile, xTypeProfile);
+        }
+
         @Specialization(insertBefore = "setAttrInAttributable")
         protected void setRowNamesInContainer(RAbstractContainer x, RAbstractVector rowNames, @Cached("createClassProfile()") ValueProfile contClassProfile) {
             RAbstractContainer xProfiled = contClassProfile.profile(x);
@@ -875,25 +918,31 @@ public final class SpecialAttributesFunctions {
         @Specialization(insertBefore = "setAttrInAttributable")
         protected <T> void handleVectorNullClass(RVector<T> vector, @SuppressWarnings("unused") RNull classAttr,
                         @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode,
-                        @Cached("createClass()") SetFixedAttributeNode setClassAttrNode,
+                        @Cached("createBinaryProfile()") ConditionProfile initAttrProfile,
                         @Cached("create()") BranchProfile nullAttrProfile,
                         @Cached("createBinaryProfile()") ConditionProfile nullClassProfile,
-                        @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile) {
-            handleVector(vector, null, removeClassAttrNode, setClassAttrNode, nullAttrProfile, nullClassProfile, notNullClassProfile);
+                        @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile,
+                        @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+            handleVector(vector, null, removeClassAttrNode, initAttrProfile, nullAttrProfile, nullClassProfile, notNullClassProfile, attrStorageProfile, xTypeProfile);
         }
 
         @Specialization(insertBefore = "setAttrInAttributable")
         protected <T> void handleVector(RVector<T> vector, RStringVector classAttr,
                         @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode,
-                        @Cached("createClass()") SetFixedAttributeNode setClassAttrNode,
+                        @Cached("createBinaryProfile()") ConditionProfile initAttrProfile,
                         @Cached("create()") BranchProfile nullAttrProfile,
                         @Cached("createBinaryProfile()") ConditionProfile nullClassProfile,
-                        @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile) {
+                        @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile,
+                        @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
 
             DynamicObject attrs = vector.getAttributes();
-            if (attrs == null && classAttr != null && classAttr.getLength() != 0) {
+            boolean initializeAttrs = initAttrProfile.profile(attrs == null && classAttr != null && classAttr.getLength() != 0);
+            if (initializeAttrs) {
                 nullAttrProfile.enter();
-                attrs = vector.initAttributes();
+                attrs = RAttributesLayout.createClass(classAttr);
+                vector.initAttributes(attrs);
             }
             if (nullClassProfile.profile(attrs != null && (classAttr == null || classAttr.getLength() == 0))) {
                 removeAttributeMapping(vector, attrs, removeClassAttrNode);
@@ -903,7 +952,10 @@ public final class SpecialAttributesFunctions {
                     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 (!initializeAttrs) {
+                            super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile);
+                        }
+                        // setClassAttrNode.execute(attrs, classAttr);
                         if (vector.getElementClass() != RInteger.class) {
                             // N.B. there used to be conversion to integer under certain
                             // circumstances.
@@ -917,7 +969,10 @@ public final class SpecialAttributesFunctions {
                         }
                     }
                 }
-                setClassAttrNode.execute(attrs, classAttr);
+
+                if (!initializeAttrs) {
+                    super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile);
+                }
             }
         }
 
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 411ae2d4db7950997d12e94a39d17d3fc96514e8..025378e9745a42cfa016d1f36041b5e97e88b84b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java
@@ -66,8 +66,8 @@ public abstract class NewObject extends RExternalBuiltinNode.Arg1 {
                         (e instanceof RAttributable && ((RAttributable) e).getAttributes() != null && pckgAttrAccess.execute(((RAttributable) e).getAttributes()) != null)) {
 
             if (setClassAttrNode == null) {
-                setClassAttrNode = insert(SetClassAttributeNode.create());
                 CompilerDirectives.transferToInterpreterAndInvalidate();
+                setClassAttrNode = insert(SetClassAttributeNode.create());
             }
 
             setClassAttrNode.execute(valueAttr, e);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java
index fb8d1096a8d1d5f015cdad766be051b59054954e..a720fcbc354a2185eb2dfda7551dedf61aa7cce1 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java
@@ -67,8 +67,8 @@ public final class BinaryMapNode extends RBaseNode {
     @Child private CopyAttributesNode copyAttributes;
     @Child private GetDimAttributeNode getLeftDimNode = GetDimAttributeNode.create();
     @Child private GetDimAttributeNode getRightDimNode = GetDimAttributeNode.create();
-    @Child protected HasFixedAttributeNode hasLeftDimNode = HasFixedAttributeNode.createDim();
-    @Child protected HasFixedAttributeNode hasRightDimNode = HasFixedAttributeNode.createDim();
+    @Child private HasFixedAttributeNode hasLeftDimNode = HasFixedAttributeNode.createDim();
+    @Child private HasFixedAttributeNode hasRightDimNode = HasFixedAttributeNode.createDim();
 
     // profiles
     private final Class<? extends RAbstractVector> leftClass;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java
index c92b663f2002689d97a7e26a779d293a7d0ae5bd..e0b9d614cae4b1e9d6a0fff7d469b945ce70213c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java
@@ -200,7 +200,7 @@ public final class UnaryMapNode extends RBaseNode {
     private final ConditionProfile hasDimensionsProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile hasNamesProfile = ConditionProfile.createBinaryProfile();
 
-    @Child protected HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim();
+    @Child private HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim();
     @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create();
 
     private boolean containsMetadata(RAbstractVector vector) {
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 5f109b8a5279bad1db9c13838cca75c9efa61d94..8f35974969087a286e79230a3b7af3788e483ff2 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java
@@ -58,12 +58,13 @@ public final class RAttributesLayout {
     private static final AttrsLayout NAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.NAMES_ATTR_KEY);
     private static final AttrsLayout DIM_ATTRS_LAYOUT = new AttrsLayout(RRuntime.DIM_ATTR_KEY);
     private static final AttrsLayout DIMNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.DIMNAMES_ATTR_KEY);
+    private static final AttrsLayout ROWNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.ROWNAMES_ATTR_KEY);
     private static final AttrsLayout NAMES_AND_DIM_ATTRS_LAYOUT = new AttrsLayout(RRuntime.NAMES_ATTR_KEY, RRuntime.DIM_ATTR_KEY);
     private static final AttrsLayout DIM_AND_DIMNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.DIM_ATTR_KEY, RRuntime.DIMNAMES_ATTR_KEY);
     private static final AttrsLayout CLASS_AND_CONNID_ATTRS_LAYOUT = new AttrsLayout(RRuntime.CLASS_ATTR_KEY, RRuntime.CONN_ID_ATTR_KEY);
 
-    public static final AttrsLayout[] LAYOUTS = {EMPTY_ATTRS_LAYOUT, CLASS_ATTRS_LAYOUT, NAMES_ATTRS_LAYOUT, DIM_ATTRS_LAYOUT, DIMNAMES_ATTRS_LAYOUT, NAMES_AND_DIM_ATTRS_LAYOUT,
-                    DIM_AND_DIMNAMES_ATTRS_LAYOUT};
+    public static final AttrsLayout[] LAYOUTS = {EMPTY_ATTRS_LAYOUT, CLASS_ATTRS_LAYOUT, NAMES_ATTRS_LAYOUT, DIM_ATTRS_LAYOUT, DIMNAMES_ATTRS_LAYOUT, ROWNAMES_ATTRS_LAYOUT,
+                    NAMES_AND_DIM_ATTRS_LAYOUT, DIM_AND_DIMNAMES_ATTRS_LAYOUT};
 
     private static final Map<String, ConstantShapesAndProperties> constantShapesAndLocationsForAttribute = new HashMap<>();
 
@@ -113,6 +114,13 @@ public final class RAttributesLayout {
                         new Property[]{
                                         CLASS_AND_CONNID_ATTRS_LAYOUT.properties[0]
                         }));
+        constantShapesAndLocationsForAttribute.put(RRuntime.ROWNAMES_ATTR_KEY, new ConstantShapesAndProperties(
+                        new Shape[]{
+                                        ROWNAMES_ATTRS_LAYOUT.shape
+                        },
+                        new Property[]{
+                                        ROWNAMES_ATTRS_LAYOUT.properties[0]
+                        }));
 
     }
 
@@ -146,6 +154,10 @@ public final class RAttributesLayout {
         return DIMNAMES_ATTRS_LAYOUT.factory.newInstance(dimNames);
     }
 
+    public static DynamicObject createRowNames(Object rowNames) {
+        return ROWNAMES_ATTRS_LAYOUT.factory.newInstance(rowNames);
+    }
+
     public static DynamicObject createNamesAndDim(Object names, Object dim) {
         return NAMES_AND_DIM_ATTRS_LAYOUT.factory.newInstance(names, dim);
     }