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 a44c45ec7e53a2b1c5573d9b8e95511b6b98a377..ef5fb88f7cb06c6a13dc38ee7dccb3fecb069b6f 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
@@ -23,10 +23,8 @@
 package com.oracle.truffle.r.runtime.data;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.CompilerDirectives.ValueType;
@@ -59,72 +57,16 @@ 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 NAMES_AND_DIMNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.NAMES_ATTR_KEY, 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 NAMES_AND_DIM_AND_DIMNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.NAMES_ATTR_KEY, 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, ROWNAMES_ATTRS_LAYOUT,
                     NAMES_AND_DIM_ATTRS_LAYOUT, DIM_AND_DIMNAMES_ATTRS_LAYOUT};
 
-    private static final Map<String, ConstantShapesAndProperties> constantShapesAndLocationsForAttribute = new HashMap<>();
-
-    static {
-        constantShapesAndLocationsForAttribute.put(RRuntime.CLASS_ATTR_KEY, new ConstantShapesAndProperties(
-                        new Shape[]{
-                                        CLASS_ATTRS_LAYOUT.shape,
-                                        CLASS_AND_CONNID_ATTRS_LAYOUT.shape
-                        },
-                        new Property[]{
-                                        CLASS_ATTRS_LAYOUT.properties[0],
-                                        CLASS_AND_CONNID_ATTRS_LAYOUT.properties[0]
-                        }));
-        constantShapesAndLocationsForAttribute.put(RRuntime.NAMES_ATTR_KEY, new ConstantShapesAndProperties(
-                        new Shape[]{
-                                        NAMES_ATTRS_LAYOUT.shape,
-                                        NAMES_AND_DIM_ATTRS_LAYOUT.shape
-                        },
-                        new Property[]{
-                                        NAMES_ATTRS_LAYOUT.properties[0],
-                                        NAMES_AND_DIM_ATTRS_LAYOUT.properties[0]
-                        }));
-        constantShapesAndLocationsForAttribute.put(RRuntime.DIM_ATTR_KEY, new ConstantShapesAndProperties(
-                        new Shape[]{
-                                        DIM_ATTRS_LAYOUT.shape,
-                                        NAMES_AND_DIM_ATTRS_LAYOUT.shape,
-                                        DIM_AND_DIMNAMES_ATTRS_LAYOUT.shape
-                        },
-                        new Property[]{
-                                        DIM_ATTRS_LAYOUT.properties[0],
-                                        NAMES_AND_DIM_ATTRS_LAYOUT.properties[1],
-                                        DIM_AND_DIMNAMES_ATTRS_LAYOUT.properties[0]
-                        }));
-        constantShapesAndLocationsForAttribute.put(RRuntime.DIMNAMES_ATTR_KEY, new ConstantShapesAndProperties(
-                        new Shape[]{
-                                        DIMNAMES_ATTRS_LAYOUT.shape,
-                                        DIM_AND_DIMNAMES_ATTRS_LAYOUT.shape
-                        },
-                        new Property[]{
-                                        DIMNAMES_ATTRS_LAYOUT.properties[0],
-                                        DIM_AND_DIMNAMES_ATTRS_LAYOUT.properties[1]
-                        }));
-        constantShapesAndLocationsForAttribute.put(RRuntime.CONN_ID_ATTR_KEY, new ConstantShapesAndProperties(
-                        new Shape[]{
-                                        CLASS_AND_CONNID_ATTRS_LAYOUT.shape
-                        },
-                        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]
-                        }));
-
-    }
-
     private RAttributesLayout() {
     }
 
@@ -155,6 +97,10 @@ public final class RAttributesLayout {
         return DIMNAMES_ATTRS_LAYOUT.factory.newInstance(dimNames);
     }
 
+    public static DynamicObject createNamesAndDimNames(Object names, Object dimNames) {
+        return NAMES_AND_DIMNAMES_ATTRS_LAYOUT.factory.newInstance(names, dimNames);
+    }
+
     public static DynamicObject createRowNames(Object rowNames) {
         return ROWNAMES_ATTRS_LAYOUT.factory.newInstance(rowNames);
     }
@@ -167,12 +113,12 @@ public final class RAttributesLayout {
         return DIM_AND_DIMNAMES_ATTRS_LAYOUT.factory.newInstance(dim, dimNames);
     }
 
-    public static DynamicObject createClassWithConnId(Object cls, Object connId) {
-        return CLASS_AND_CONNID_ATTRS_LAYOUT.factory.newInstance(cls, connId);
+    public static DynamicObject createNamesAndDimAndDimNames(Object names, Object dim, Object dimNames) {
+        return NAMES_AND_DIM_AND_DIMNAMES_ATTRS_LAYOUT.factory.newInstance(names, dim, dimNames);
     }
 
-    public static ConstantShapesAndProperties getConstantShapesAndProperties(String attrName) {
-        return constantShapesAndLocationsForAttribute.getOrDefault(attrName, ConstantShapesAndProperties.EMPTY);
+    public static DynamicObject createClassWithConnId(Object cls, Object connId) {
+        return CLASS_AND_CONNID_ATTRS_LAYOUT.factory.newInstance(cls, connId);
     }
 
     public static boolean isRAttributes(Object attrs) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
index be21c056a32b4f8646992314359d6a836e43bcc4..2587193a855ef1fc6a9fd79822a15f1459f97366 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
@@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import com.oracle.truffle.api.Assumption;
+import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.RootCallTarget;
@@ -35,10 +36,14 @@ import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.frame.FrameDescriptor;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.instrumentation.AllocationReporter;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.nodes.NodeCost;
+import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.runtime.FastROptions;
 import com.oracle.truffle.r.runtime.RCaller;
 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.Utils;
 import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor;
 import com.oracle.truffle.r.runtime.context.RContext;
@@ -49,6 +54,729 @@ import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
 
 public final class RDataFactory {
+    private abstract static class StaticVectorFactory extends BaseVectorFactory {
+
+        @Override
+        public void reinitializeAttributes(RVector<?> vector, int[] dims, RStringVector names, RList dimNames) {
+            vector.initAttributes(dims != null || names != null || dimNames != null ? RVector.createAttributes(dims, names, dimNames) : null);
+        }
+
+        @Override
+        protected <T extends RVector<?>> T initializeAttributes(T result, int[] dims, RStringVector names, RList dimNames) {
+            if (dims != null || names != null || dimNames != null) {
+                result.initDimsNamesDimNames(dims, names, dimNames);
+            }
+            return result;
+        }
+
+        @Override
+        protected <T extends RVector<?>> T initializeAttributes(T result, int[] dims) {
+            if (dims != null) {
+                result.initDimsNamesDimNames(dims, null, null);
+            }
+            return result;
+        }
+
+        @Override
+        protected <T extends RVector<?>> T initializeAttributes(T result, RStringVector names) {
+            if (names != null) {
+                result.initDimsNamesDimNames(null, names, null);
+            }
+            return result;
+        }
+    }
+
+    private static final class DefaultStaticVectorFactory extends StaticVectorFactory {
+
+    }
+
+    private static final class PermanentStaticVectorFactory extends StaticVectorFactory {
+
+        @Override
+        protected <T> T traceDataCreated(T data) {
+            if (data instanceof RShareable) {
+                ((RShareable) data).makeSharedPermanent();
+            } else {
+                assert data instanceof Integer || data instanceof Double || data instanceof Byte || data instanceof String || data instanceof RRaw ||
+                                data instanceof RComplex : "cannot make permanent instance of non-shareable object";
+            }
+            return super.traceDataCreated(data);
+        }
+    }
+
+    private static final StaticVectorFactory INSTANCE = new DefaultStaticVectorFactory();
+    private static final StaticVectorFactory PERMANENT = new PermanentStaticVectorFactory();
+
+    /**
+     * This factory is only intended for use on slow paths, all places where a node context is
+     * available should use a dynamic {@link VectorFactory} instance.
+     */
+    public static BaseVectorFactory getInstance() {
+        CompilerAsserts.neverPartOfCompilation("RDataFactory.getInstance() can only be used in slow paths");
+        return INSTANCE;
+    }
+
+    /**
+     * This factory is intended for use in initializers that want to create "permanent" objects,
+     * i.e., objects that have their reference count set to "permanently shared".
+     */
+    public static BaseVectorFactory getPermanent() {
+        CompilerAsserts.neverPartOfCompilation("RDataFactory.getPermanent() can only be used in slow paths");
+        return PERMANENT;
+    }
+
+    public static final class VectorFactory extends BaseVectorFactory {
+
+        private VectorFactory() {
+            // private constructor
+        }
+
+        private final ConditionProfile hasAttributes = ConditionProfile.createBinaryProfile();
+
+        @Override
+        public void reinitializeAttributes(RVector<?> vector, int[] dims, RStringVector names, RList dimNames) {
+            vector.initAttributes(hasAttributes.profile(dims != null || names != null || dimNames != null) ? RVector.createAttributes(dims, names, dimNames) : null);
+        }
+
+        @Override
+        protected <T extends RVector<?>> T initializeAttributes(T result, int[] dims, RStringVector names, RList dimNames) {
+            if (hasAttributes.profile(dims != null || names != null || dimNames != null)) {
+                result.initDimsNamesDimNames(dims, names, dimNames);
+            }
+            return result;
+        }
+
+        @Override
+        protected <T extends RVector<?>> T initializeAttributes(T result, int[] dims) {
+            if (hasAttributes.profile(dims != null)) {
+                result.initDimsNamesDimNames(dims, null, null);
+            }
+            return result;
+        }
+
+        @Override
+        protected <T extends RVector<?>> T initializeAttributes(T result, RStringVector names) {
+            if (hasAttributes.profile(names != null)) {
+                result.initDimsNamesDimNames(null, names, null);
+            }
+            return result;
+        }
+
+        public static VectorFactory create() {
+            return new VectorFactory();
+        }
+    }
+
+    @SuppressWarnings("static-method")
+    public abstract static class BaseVectorFactory extends Node {
+
+        @Override
+        public final NodeCost getCost() {
+            return NodeCost.NONE;
+        }
+
+        public abstract void reinitializeAttributes(RVector<?> vector, int[] dims, RStringVector names, RList dimNames);
+
+        protected abstract <T extends RVector<?>> T initializeAttributes(T result, int[] dims, RStringVector names, RList dimNames);
+
+        protected abstract <T extends RVector<?>> T initializeAttributes(T result, int[] dims);
+
+        protected abstract <T extends RVector<?>> T initializeAttributes(T result, RStringVector names);
+
+        protected <T> T traceDataCreated(T data) {
+            if (stateAssumption.isEnabled()) {
+                reportDataCreated(data);
+            }
+            return data;
+        }
+
+        public final RIntVector createIntVector(int[] data, boolean complete) {
+            return traceDataCreated(new RIntVector(data, complete));
+        }
+
+        public final RIntVector createIntVector(int[] data, boolean complete, int[] dims, RStringVector names, RList dimNames) {
+            return traceDataCreated(initializeAttributes(new RIntVector(data, complete), dims, names, dimNames));
+        }
+
+        public final RIntVector createIntVector(int[] data, boolean complete, int[] dims) {
+            return traceDataCreated(initializeAttributes(new RIntVector(data, complete), dims));
+        }
+
+        public final RIntVector createIntVector(int[] data, boolean complete, RStringVector names) {
+            return traceDataCreated(initializeAttributes(new RIntVector(data, complete), names));
+        }
+
+        public final RDoubleVector createDoubleVector(double[] data, boolean complete) {
+            return traceDataCreated(new RDoubleVector(data, complete));
+        }
+
+        public final RDoubleVector createDoubleVector(double[] data, boolean complete, int[] dims, RStringVector names, RList dimNames) {
+            return traceDataCreated(initializeAttributes(new RDoubleVector(data, complete), dims, names, dimNames));
+        }
+
+        public final RDoubleVector createDoubleVector(double[] data, boolean complete, int[] dims) {
+            return traceDataCreated(initializeAttributes(new RDoubleVector(data, complete), dims));
+        }
+
+        public final RDoubleVector createDoubleVector(double[] data, boolean complete, RStringVector names) {
+            return traceDataCreated(initializeAttributes(new RDoubleVector(data, complete), names));
+        }
+
+        public final RLogicalVector createLogicalVector(byte[] data, boolean complete) {
+            return traceDataCreated(new RLogicalVector(data, complete));
+        }
+
+        public final RLogicalVector createLogicalVector(byte[] data, boolean complete, int[] dims, RStringVector names, RList dimNames) {
+            return traceDataCreated(initializeAttributes(new RLogicalVector(data, complete), dims, names, dimNames));
+        }
+
+        public final RLogicalVector createLogicalVector(byte[] data, boolean complete, int[] dims) {
+            return traceDataCreated(initializeAttributes(new RLogicalVector(data, complete), dims));
+        }
+
+        public final RLogicalVector createLogicalVector(byte[] data, boolean complete, RStringVector names) {
+            return traceDataCreated(initializeAttributes(new RLogicalVector(data, complete), names));
+        }
+
+        public final RStringVector createStringVector(String[] data, boolean complete) {
+            return traceDataCreated(new RStringVector(data, complete));
+        }
+
+        public final RStringVector createStringVector(String[] data, boolean complete, int[] dims, RStringVector names, RList dimNames) {
+            return traceDataCreated(initializeAttributes(new RStringVector(data, complete), dims, names, dimNames));
+        }
+
+        public final RStringVector createStringVector(String[] data, boolean complete, int[] dims) {
+            return traceDataCreated(initializeAttributes(new RStringVector(data, complete), dims));
+        }
+
+        public final RStringVector createStringVector(String[] data, boolean complete, RStringVector names) {
+            return traceDataCreated(initializeAttributes(new RStringVector(data, complete), names));
+        }
+
+        public final RComplexVector createComplexVector(double[] data, boolean complete) {
+            return traceDataCreated(new RComplexVector(data, complete));
+        }
+
+        public final RComplexVector createComplexVector(double[] data, boolean complete, int[] dims, RStringVector names, RList dimNames) {
+            return traceDataCreated(initializeAttributes(new RComplexVector(data, complete), dims, names, dimNames));
+        }
+
+        public final RComplexVector createComplexVector(double[] data, boolean complete, int[] dims) {
+            return traceDataCreated(initializeAttributes(new RComplexVector(data, complete), dims));
+        }
+
+        public final RComplexVector createComplexVector(double[] data, boolean complete, RStringVector names) {
+            return traceDataCreated(initializeAttributes(new RComplexVector(data, complete), names));
+        }
+
+        public final RRawVector createRawVector(byte[] data) {
+            return traceDataCreated(new RRawVector(data));
+        }
+
+        public final RRawVector createRawVector(byte[] data, int[] dims, RStringVector names, RList dimNames) {
+            return traceDataCreated(initializeAttributes(new RRawVector(data), dims, names, dimNames));
+        }
+
+        public final RRawVector createRawVector(byte[] data, int[] dims) {
+            return traceDataCreated(initializeAttributes(new RRawVector(data), dims));
+        }
+
+        public final RRawVector createRawVector(byte[] data, RStringVector names) {
+            return traceDataCreated(initializeAttributes(new RRawVector(data), names));
+        }
+
+        public final RList createList(Object[] data) {
+            return traceDataCreated(new RList(data));
+        }
+
+        public final RList createList(Object[] data, int[] dims, RStringVector names, RList dimNames) {
+            return traceDataCreated(initializeAttributes(new RList(data), dims, names, dimNames));
+        }
+
+        public final RList createList(Object[] data, int[] dims) {
+            return traceDataCreated(initializeAttributes(new RList(data), dims));
+        }
+
+        public final RList createList(Object[] data, RStringVector names) {
+            return traceDataCreated(initializeAttributes(new RList(data), names));
+        }
+
+        public RExpression createExpression(int size) {
+            return createExpression(createRNullArray(size));
+        }
+
+        public RExpression createExpression(int size, RStringVector names) {
+            if (names == null) {
+                return createExpression(size);
+            }
+            assert size == names.getLength();
+            return createExpression(createRNullArray(size), names);
+        }
+
+        public RExpression createExpression(Object[] data, int[] newDimensions) {
+            return traceDataCreated(new RExpression(data, newDimensions, null, null));
+        }
+
+        public RExpression createExpression(Object[] data, RStringVector names) {
+            return traceDataCreated(new RExpression(data, null, names, null));
+        }
+
+        public RExpression createExpression(Object[] data, int[] newDimensions, RStringVector names, RList dimNames) {
+            return traceDataCreated(new RExpression(data, newDimensions, names, dimNames));
+        }
+
+        public RExpression createExpression(Object[] data) {
+            return traceDataCreated(new RExpression(data, null, null, null));
+        }
+
+        public final RVector<?> createEmptyVector(RType type) {
+            switch (type) {
+                case Double:
+                    return createEmptyDoubleVector();
+                case Integer:
+                    return createEmptyIntVector();
+                case Complex:
+                    return createEmptyComplexVector();
+                case Logical:
+                    return createEmptyLogicalVector();
+                case Character:
+                    return createEmptyStringVector();
+                case Raw:
+                    return createEmptyRawVector();
+                case List:
+                    return createList(new Object[0]);
+                default:
+                    throw RInternalError.shouldNotReachHere();
+            }
+        }
+
+        public final RVector<?> createUninitializedVector(RType type, int length, int[] dims, RStringVector names, RList dimNames) {
+            switch (type) {
+                case Logical:
+                    return createLogicalVector(new byte[length], false, dims, names, dimNames);
+                case Integer:
+                    return createIntVector(new int[length], false, dims, names, dimNames);
+                case Double:
+                    return createDoubleVector(new double[length], false, dims, names, dimNames);
+                case Complex:
+                    return createComplexVector(new double[length * 2], false, dims, names, dimNames);
+                case Character:
+                    return createStringVector(new String[length], false, dims, names, dimNames);
+                case Expression: {
+                    Object[] data = new Object[length];
+                    Arrays.fill(data, RNull.instance);
+                    return createExpression(data, dims, names, dimNames);
+                }
+                case List: {
+                    Object[] data = new Object[length];
+                    Arrays.fill(data, RNull.instance);
+                    return createList(data, dims, names, dimNames);
+                }
+                case Raw:
+                    return createRawVector(new byte[length], dims, names, dimNames);
+                default:
+                    throw RInternalError.shouldNotReachHere();
+            }
+
+        }
+
+        public final RVector<?> createVector(RType type, int length, boolean fillNA) {
+            switch (type) {
+                case Logical: {
+                    byte[] data = new byte[length];
+                    if (fillNA) {
+                        Arrays.fill(data, RRuntime.LOGICAL_NA);
+                    }
+                    return createLogicalVector(data, !fillNA);
+                }
+                case Integer: {
+                    int[] data = new int[length];
+                    if (fillNA) {
+                        Arrays.fill(data, RRuntime.INT_NA);
+                    }
+                    return createIntVector(data, !fillNA);
+                }
+                case Double: {
+                    double[] data = new double[length];
+                    if (fillNA) {
+                        Arrays.fill(data, RRuntime.LOGICAL_NA);
+                    }
+                    return createDoubleVector(data, !fillNA);
+                }
+                case Complex: {
+                    double[] data = new double[length * 2];
+                    if (fillNA) {
+                        Arrays.fill(data, RRuntime.LOGICAL_NA);
+                        for (int i = 0; i < data.length; i += 2) {
+                            data[i] = RRuntime.COMPLEX_NA_REAL_PART;
+                            data[i + 1] = RRuntime.COMPLEX_NA_IMAGINARY_PART;
+                        }
+                    }
+                    return createComplexVector(data, !fillNA);
+                }
+                case Character: {
+                    String[] data = new String[length];
+                    Arrays.fill(data, fillNA ? RRuntime.STRING_NA : "");
+                    return createStringVector(data, !fillNA);
+                }
+                case Expression: {
+                    Object[] data = new Object[length];
+                    Arrays.fill(data, RNull.instance);
+                    return createExpression(data);
+                }
+                case List: {
+                    Object[] data = new Object[length];
+                    Arrays.fill(data, RNull.instance);
+                    return createList(data);
+                }
+                case Raw:
+                    return createRawVector(new byte[length]);
+                default:
+                    throw RInternalError.shouldNotReachHere();
+            }
+        }
+
+        /*
+         * the following functions are not cleaned up yet:
+         */
+
+        public final RIntVector createIntVectorFromNative(long address, int length) {
+            return traceDataCreated(RIntVector.fromNative(address, length));
+        }
+
+        public final RIntVector createIntVector(int length) {
+            return createIntVector(new int[length], true);
+        }
+
+        public final RDoubleVector createDoubleVectorFromNative(long address, int length) {
+            return traceDataCreated(RDoubleVector.fromNative(address, length));
+        }
+
+        public final RDoubleVector createDoubleVector(int length) {
+            return createDoubleVector(new double[length], true);
+        }
+
+        public final RRawVector createRawVector(int length) {
+            return createRawVector(new byte[length]);
+        }
+
+        public final RComplexVector createComplexVectorFromNative(long address, int length) {
+            return traceDataCreated(RComplexVector.fromNative(address, length));
+        }
+
+        public final RComplexVector createComplexVector(int length) {
+            return createComplexVector(new double[length << 1], true);
+        }
+
+        public final RStringVector createStringVector(String value) {
+            return createStringVector(new String[]{value}, !RRuntime.isNA(value));
+        }
+
+        public final RStringVector createStringVector(int length) {
+            return createStringVector(createAndfillStringVector(length, ""), true);
+        }
+
+        private static String[] createAndfillStringVector(int length, String string) {
+            String[] strings = new String[length];
+            Arrays.fill(strings, string);
+            return strings;
+        }
+
+        public final RLogicalVector createLogicalVectorFromNative(long address, int length) {
+            return traceDataCreated(RLogicalVector.fromNative(address, length));
+        }
+
+        public final RLogicalVector createLogicalVector(int length) {
+            return createLogicalVector(length, false);
+        }
+
+        public final RLogicalVector createLogicalVector(int length, boolean fillNA) {
+            byte[] data = new byte[length];
+            if (fillNA) {
+                Arrays.fill(data, RRuntime.LOGICAL_NA);
+            }
+            return createLogicalVector(data, !fillNA);
+        }
+
+        public final RIntSequence createAscendingRange(int start, int end) {
+            assert start <= end;
+            return traceDataCreated(new RIntSequence(start, 1, end - start + 1));
+        }
+
+        public final RIntSequence createDescendingRange(int start, int end) {
+            assert start > end;
+            return traceDataCreated(new RIntSequence(start, -1, start - end + 1));
+        }
+
+        public final RIntSequence createIntSequence(int start, int stride, int length) {
+            return traceDataCreated(new RIntSequence(start, stride, length));
+        }
+
+        public final RDoubleSequence createAscendingRange(double start, double end) {
+            assert start <= end;
+            return traceDataCreated(new RDoubleSequence(start, 1, (int) ((end - start) + 1)));
+        }
+
+        public final RDoubleSequence createDescendingRange(double start, double end) {
+            assert start > end;
+            return traceDataCreated(new RDoubleSequence(start, -1, (int) ((start - end) + 1)));
+        }
+
+        public final RDoubleSequence createDoubleSequence(double start, double stride, int length) {
+            return traceDataCreated(new RDoubleSequence(start, stride, length));
+        }
+
+        public final RIntVector createEmptyIntVector() {
+            return createIntVector(new int[0], true);
+        }
+
+        public final RDoubleVector createEmptyDoubleVector() {
+            return createDoubleVector(new double[0], true);
+        }
+
+        public final RStringVector createEmptyStringVector() {
+            return createStringVector(new String[0], true);
+        }
+
+        public final RStringVector createNAStringVector() {
+            return createStringVector(new String[]{RRuntime.STRING_NA}, false);
+        }
+
+        public final RStringSequence createStringSequence(String prefix, String suffix, int start, int stride, int length) {
+            return traceDataCreated(new RStringSequence(prefix, suffix, start, stride, length));
+        }
+
+        public final RComplexVector createEmptyComplexVector() {
+            return createComplexVector(new double[0], true);
+        }
+
+        public final RLogicalVector createEmptyLogicalVector() {
+            return createLogicalVector(new byte[0], true);
+        }
+
+        public final RRawVector createEmptyRawVector() {
+            return createRawVector(new byte[0]);
+        }
+
+        public final RList createEmptyList() {
+            return createList(new Object[0]);
+        }
+
+        public final RComplex createComplex(double realPart, double imaginaryPart) {
+            return traceDataCreated(RComplex.valueOf(realPart, imaginaryPart));
+        }
+
+        public final RRawVector createRawVectorFromNative(long address, int length) {
+            return traceDataCreated(RRawVector.fromNative(address, length));
+        }
+
+        public final RRaw createRaw(byte value) {
+            return traceDataCreated(new RRaw(value));
+        }
+
+        /*
+         * Shared scalar conversion functions: these need to be replaced with
+         * createXyzVectorFromScalar(...).makeSharedPermanent() if scalar types are removed.
+         */
+
+        public final Object createSharedStringVectorFromScalar(String value) {
+            return value;
+        }
+
+        public final Object createSharedLogicalVectorFromScalar(boolean value) {
+            return RRuntime.asLogical(value);
+        }
+
+        public final Object createSharedLogicalVectorFromScalar(byte value) {
+            return value;
+        }
+
+        public final Object createSharedIntVectorFromScalar(int value) {
+            return value;
+        }
+
+        public final Object createSharedDoubleVectorFromScalar(double value) {
+            return value;
+        }
+
+        public final Object createSharedComplexVectorFromScalar(RComplex value) {
+            return value;
+        }
+
+        public final Object createSharedRawVectorFromScalar(RRaw value) {
+            return value;
+        }
+
+        public final RList createList(int n) {
+            return createList(createRNullArray(n));
+        }
+
+        public final RList createList(Object[] data, int[] newDimensions, RStringVector names) {
+            return traceDataCreated(new RList(data, newDimensions, names, null));
+        }
+
+        public final RSymbol createSymbol(String name) {
+            assert Utils.isInterned(name);
+            return traceDataCreated(new RSymbol(name));
+        }
+
+        /*
+         * A version of {@link createSymbol} method mostly used from native code and in
+         * serialization/deparsing.
+         */
+        public final RSymbol createSymbolInterned(String name) {
+            return createSymbol(Utils.intern(name));
+        }
+
+        public final RLanguage createLanguage(Closure closure) {
+            return traceDataCreated(new RLanguage(closure));
+        }
+
+        public final RPromise createPromise(PromiseState state, Closure closure, MaterializedFrame env) {
+            assert closure != null;
+            assert closure.getExpr() != null;
+            return traceDataCreated(new RPromise(state, env, closure));
+        }
+
+        public final RPromise createEvaluatedPromise(PromiseState state, Closure closure, Object argumentValue) {
+            return traceDataCreated(new RPromise(state, closure, argumentValue));
+        }
+
+        public final RPromise createEvaluatedPromise(Closure closure, Object value) {
+            return traceDataCreated(new RPromise(PromiseState.Explicit, closure, value));
+        }
+
+        public RPromise createEagerPromise(PromiseState state, Closure exprClosure, Object eagerValue, Assumption notChangedNonLocally, RCaller targetFrame, EagerFeedback feedback,
+                        int wrapIndex, MaterializedFrame execFrame) {
+            if (FastROptions.noEagerEval()) {
+                throw RInternalError.shouldNotReachHere();
+            }
+            return traceDataCreated(new RPromise.EagerPromise(state, exprClosure, eagerValue, notChangedNonLocally, targetFrame, feedback, wrapIndex, execFrame));
+        }
+
+        public RPromise createPromisedPromise(Closure exprClosure, Object eagerValue, Assumption notChangedNonLocally, RCaller targetFrame, EagerFeedback feedback, MaterializedFrame execFrame) {
+            if (FastROptions.noEagerEval()) {
+                throw RInternalError.shouldNotReachHere();
+            }
+            return traceDataCreated(new RPromise.EagerPromise(PromiseState.Promised, exprClosure, eagerValue, notChangedNonLocally, targetFrame, feedback, -1, execFrame));
+        }
+
+        public final Object createLangPairList(int size) {
+            if (size == 0) {
+                return RNull.instance;
+            } else {
+                return traceDataCreated(RPairList.create(size, SEXPTYPE.LANGSXP));
+            }
+        }
+
+        public final Object createPairList(int size) {
+            if (size == 0) {
+                return RNull.instance;
+            } else {
+                return traceDataCreated(RPairList.create(size));
+            }
+        }
+
+        public final RPairList createPairList() {
+            return traceDataCreated(new RPairList());
+        }
+
+        public final RPairList createPairList(Object car) {
+
+            return traceDataCreated(new RPairList(car, RNull.instance, RNull.instance, null));
+        }
+
+        public final RPairList createPairList(Object car, Object cdr) {
+            return traceDataCreated(new RPairList(car, cdr, RNull.instance, null));
+        }
+
+        public final RPairList createPairList(Object car, Object cdr, Object tag) {
+            return traceDataCreated(new RPairList(car, cdr, tag, null));
+        }
+
+        public final RPairList createPairList(Object car, Object cdr, Object tag, SEXPTYPE type) {
+            return traceDataCreated(new RPairList(car, cdr, tag, type));
+        }
+
+        public final RFunction createFunction(String name, String packageName, RootCallTarget target, RBuiltinDescriptor builtin, MaterializedFrame enclosingFrame) {
+            return traceDataCreated(new RFunction(name, packageName, target, builtin, enclosingFrame));
+        }
+
+        private static final AtomicInteger environmentCount = new AtomicInteger();
+
+        @TruffleBoundary
+        public final REnvironment createInternalEnv() {
+            return traceDataCreated(new REnvironment.NewEnv(RRuntime.createNonFunctionFrame("<internal-env-" + environmentCount.incrementAndGet() + ">"), REnvironment.UNNAMED));
+        }
+
+        @TruffleBoundary
+        public final REnvironment.NewEnv createNewEnv(FrameDescriptor desc, String name) {
+            return traceDataCreated(new REnvironment.NewEnv(RRuntime.createNewFrame(desc), name));
+        }
+
+        @TruffleBoundary
+        public final REnvironment.NewEnv createNewEnv(String name) {
+            return traceDataCreated(new REnvironment.NewEnv(RRuntime.createNonFunctionFrame("<new-env-" + environmentCount.incrementAndGet() + ">"), name));
+        }
+
+        @TruffleBoundary
+        public final REnvironment createNewEnv(String name, boolean hashed, int initialSize) {
+            REnvironment.NewEnv env = new REnvironment.NewEnv(RRuntime.createNonFunctionFrame("<new-env-" + environmentCount.incrementAndGet() + ">"), name);
+            env.setHashed(hashed);
+            env.setInitialSize(initialSize);
+            return traceDataCreated(env);
+        }
+
+        public final RS4Object createS4Object() {
+            return traceDataCreated(new RS4Object());
+        }
+
+        public final RExternalPtr createExternalPtr(SymbolHandle value, Object externalObject, Object tag, Object prot) {
+            assert tag != null : "null tag, use RNull.instance instead";
+            assert prot != null : "null prot, use RNull.instance instead";
+            return traceDataCreated(new RExternalPtr(value, externalObject, tag, prot));
+        }
+
+        public final RExternalPtr createExternalPtr(SymbolHandle value, Object tag, Object prot) {
+            assert tag != null : "null tag, use RNull.instance instead";
+            assert prot != null : "null prot, use RNull.instance instead";
+            return traceDataCreated(new RExternalPtr(value, null, tag, prot));
+        }
+
+        public final RExternalPtr createExternalPtr(SymbolHandle value, Object tag) {
+            assert tag != null : "null tag, use RNull.instance instead";
+            return traceDataCreated(new RExternalPtr(value, null, tag, RNull.instance));
+        }
+
+        public RStringVector createStringVectorFromScalar(String value) {
+            return traceDataCreated(RDataFactory.createStringVectorFromScalar(value));
+        }
+
+        public RLogicalVector createLogicalVectorFromScalar(boolean value) {
+            return traceDataCreated(RDataFactory.createLogicalVectorFromScalar(value));
+        }
+
+        public RLogicalVector createLogicalVectorFromScalar(byte value) {
+            return traceDataCreated(RDataFactory.createLogicalVectorFromScalar(value));
+        }
+
+        public RIntVector createIntVectorFromScalar(int value) {
+            return traceDataCreated(RDataFactory.createIntVectorFromScalar(value));
+        }
+
+        public RDoubleVector createDoubleVectorFromScalar(double value) {
+            return traceDataCreated(RDataFactory.createDoubleVectorFromScalar(value));
+        }
+
+        public RComplexVector createComplexVectorFromScalar(RComplex value) {
+            return traceDataCreated(RDataFactory.createComplexVectorFromScalar(value));
+        }
+
+        public RRawVector createRawVectorFromScalar(RRaw value) {
+            return traceDataCreated(RDataFactory.createRawVectorFromScalar(value));
+        }
+    }
 
     public static final boolean INCOMPLETE_VECTOR = false;
     public static final boolean COMPLETE_VECTOR = true;
@@ -456,15 +1184,15 @@ public final class RDataFactory {
     }
 
     public static RExpression createExpression(Object[] data, int[] newDimensions) {
-        return traceDataCreated(new RExpression(data, newDimensions, null));
+        return traceDataCreated(new RExpression(data, newDimensions, null, null));
     }
 
     public static RExpression createExpression(Object[] data, RStringVector names) {
-        return traceDataCreated(new RExpression(data, null, names));
+        return traceDataCreated(new RExpression(data, null, names, null));
     }
 
     public static RExpression createExpression(Object[] data) {
-        return traceDataCreated(new RExpression(data, null, null));
+        return traceDataCreated(new RExpression(data, null, null, null));
     }
 
     public static RSymbol createSymbol(String name) {
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 2e0463d5598a60d179459766246a95f4569ab2c7..f30f71ef14388241a401c846a96e843c82f2f28d 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
@@ -30,8 +30,12 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
 public final class RExpression extends RListBase implements RAbstractVector {
 
-    RExpression(Object[] data, int[] dims, RStringVector names) {
-        super(data, dims, names, null);
+    RExpression(Object[] data) {
+        super(data);
+    }
+
+    RExpression(Object[] data, int[] dims, RStringVector names, RList dimNames) {
+        super(data, dims, names, dimNames);
     }
 
     @Override
@@ -47,7 +51,7 @@ public final class RExpression extends RListBase implements RAbstractVector {
     @Override
     @TruffleBoundary
     protected RExpression internalCopy() {
-        return new RExpression(Arrays.copyOf(data, data.length), getDimensions(), null);
+        return new RExpression(Arrays.copyOf(data, data.length), getDimensions(), null, null);
     }
 
     @Override
@@ -55,7 +59,7 @@ public final class RExpression extends RListBase implements RAbstractVector {
     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), getDimensions(), null);
+        RExpression listCopy = new RExpression(Arrays.copyOf(data, data.length), getDimensions(), null, 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/RFunction.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java
index 6aa8daa0c098e2863619e687adda0594003a5387..7f7bd897580a991874dfb294c3693ce0e0abf08c 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java
@@ -70,7 +70,7 @@ public final class RFunction extends RSharingAttributeStorage implements RTypedV
     public RType getRType() {
         // Note: GnuR distinguishes "builtins" and "specials" (BUILTINSXP vs SPECIALSXP). The later
         // has non-evaluated args. FastR and GnuR built-ins differ in whether they have evaluated
-        // args, so we cannot correcly choose RType.Special here.
+        // args, so we cannot correctly choose RType.Special here.
         return isBuiltin() ? RType.Builtin : RType.Closure;
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringSequence.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringSequence.java
index ee79af03a47bf35cf4c2b2577b3f09edbcedf22d..1b90cafe41f46ec79bbf280cecf1a123d12bf097 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringSequence.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringSequence.java
@@ -32,7 +32,7 @@ import com.oracle.truffle.r.runtime.data.closures.RClosures;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
-public class RStringSequence extends RSequence implements RAbstractStringVector {
+public final class RStringSequence extends RSequence implements RAbstractStringVector {
 
     private final int start;
     private final int stride;
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 5f7239c993e84846c1d3b7a57d589b66788301e5..8956b2df5df31620f29bf45c679853ad160e61d2 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
@@ -607,50 +607,52 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
      * Inits dims, names and dimnames attributes and it should only be invoked if no attributes were
      * initialized yet.
      */
-    @TruffleBoundary
-    protected final void initDimsNamesDimNames(int[] dimensions, RStringVector names, RList dimNames) {
+    final void initDimsNamesDimNames(int[] dimensions, RStringVector names, RList dimNames) {
         assert (this.attributes == null) : "Vector attributes must be null";
         assert names != this;
         assert dimNames != this;
+        assert names == null || names.getLength() == getLength() : "size mismatch: names.length=" + names.getLength() + " vs. length=" + getLength();
+        initAttributes(createAttributes(dimensions, names, dimNames));
+    }
+
+    @TruffleBoundary
+    static DynamicObject createAttributes(int[] dimensions, RStringVector names, RList dimNames) {
         if (dimNames != null) {
-            DynamicObject attrs;
             if (dimensions != null) {
                 RIntVector dimensionsVector = RDataFactory.createIntVector(dimensions, true);
-                attrs = RAttributesLayout.createDimAndDimNames(dimensionsVector, dimNames);
                 // one-dimensional arrays do not have names, only dimnames with one value so do not
                 // init names in that case
                 if (names != null && dimensions.length != 1) {
-                    assert names.getLength() == getLength() : "size mismatch: names.length=" + names.getLength() + " vs. length=" + getLength();
-                    attrs.define(RRuntime.NAMES_ATTR_KEY, names);
+                    return RAttributesLayout.createNamesAndDimAndDimNames(names, dimensionsVector, dimNames);
+                } else {
+                    return RAttributesLayout.createDimAndDimNames(dimensionsVector, dimNames);
                 }
             } else {
-                attrs = RAttributesLayout.createDimNames(dimNames);
                 if (names != null) {
-                    assert names.getLength() == getLength() : "size mismatch: names.length=" + names.getLength() + " vs. length=" + getLength();
-                    attrs.define(RRuntime.NAMES_ATTR_KEY, names);
+                    return RAttributesLayout.createNamesAndDimNames(names, dimNames);
+                } else {
+                    return RAttributesLayout.createDimNames(dimNames);
                 }
             }
-            initAttributes(attrs);
         } else {
-            if (names != null) {
-                // since this constructor is for internal use only, the assertion shouldn't fail
-                assert names.getLength() == getLength() : "size mismatch: " + names.getLength() + " vs. " + getLength();
-                if (dimensions != null) {
-                    RIntVector dimensionsVector = RDataFactory.createIntVector(dimensions, true);
+            if (dimensions != null) {
+                RIntVector dimensionsVector = RDataFactory.createIntVector(dimensions, true);
+                if (names != null) {
                     if (dimensions.length != 1) {
-                        initAttributes(RAttributesLayout.createNamesAndDim(names, dimensionsVector));
+                        return RAttributesLayout.createNamesAndDim(names, dimensionsVector);
                     } else {
                         // one-dimensional arrays do not have names, only dimnames with one value
                         RList newDimNames = RDataFactory.createList(new Object[]{names});
-                        initAttributes(RAttributesLayout.createDimAndDimNames(dimensionsVector, newDimNames));
+                        return RAttributesLayout.createDimAndDimNames(dimensionsVector, newDimNames);
                     }
                 } else {
-                    initAttributes(RAttributesLayout.createNames(names));
+                    return RAttributesLayout.createDim(dimensionsVector);
                 }
             } else {
-                if (dimensions != null) {
-                    RIntVector dimensionsVector = RDataFactory.createIntVector(dimensions, true);
-                    initAttributes(RAttributesLayout.createDim(dimensionsVector));
+                if (names != null) {
+                    return RAttributesLayout.createNames(names);
+                } else {
+                    return null;
                 }
             }
         }