diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java
index 0895f7591631e6d7ef4c4630ecd35884c4923457..2d074407e72638d387c0077ef46907d1cafb1e1e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java
@@ -28,6 +28,7 @@ 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.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -89,7 +90,7 @@ public abstract class Matrix extends RBuiltinNode {
         if (empty.profile(data.getLength() == 0)) {
             if (isList.profile(data instanceof RAbstractListVector)) {
                 // matrix of NULL-s
-                res = data.copyResizedWithDimensions(dim, true);
+                res = copyResizedWithDimensions(data, dim);
                 if (byrowProfile.profile(byrow)) {
                     if (transpose == null) {
                         CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -120,6 +121,11 @@ public abstract class Matrix extends RBuiltinNode {
         return res;
     }
 
+    @TruffleBoundary
+    private static RVector<?> copyResizedWithDimensions(RAbstractVector data, int[] dim) {
+        return data.copyResizedWithDimensions(dim, true);
+    }
+
     private int[] computeDimByCol(int size, int nrow, int ncol, boolean missingNr, boolean missingNc) {
         if (bothNrowNcolMissing.profile(missingNr && missingNc)) {
             return new int[]{size, 1};
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 5daa1ab7ddd5e6022c21a24a673e20d6012270bf..f264855e7e247876ee24c162f2442ead75a88a7b 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
@@ -18,6 +18,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.BranchProfile;
@@ -27,6 +28,7 @@ import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode;
 import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNodeGen;
 import com.oracle.truffle.r.nodes.attributes.InitAttributesNode;
 import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode;
+import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.profile.VectorLengthProfile;
@@ -61,6 +63,7 @@ public abstract class Transpose extends RBuiltinNode {
     @Child private SetFixedAttributeNode putDimensions = SetFixedAttributeNode.createDim();
     @Child private SetFixedAttributeNode putDimNames = SetFixedAttributeNode.createDimNames();
     @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create();
+    @Child private GetDimAttributeNode getDimNode;
 
     public abstract Object execute(RAbstractVector o);
 
@@ -74,8 +77,13 @@ public abstract class Transpose extends RBuiltinNode {
         int firstDim;
         int secondDim;
         if (isMatrixProfile.profile(vector.isMatrix())) {
-            firstDim = vector.getDimensions()[0];
-            secondDim = vector.getDimensions()[1];
+            if (getDimNode == null) {
+                CompilerDirectives.transferToInterpreter();
+                getDimNode = insert(GetDimAttributeNode.create());
+            }
+            int[] dims = getDimNode.getDimensions(vector);
+            firstDim = dims[0];
+            secondDim = dims[1];
         } else {
             firstDim = length;
             secondDim = 1;
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java
index 3b5127cfdc49baa0b22b8650a00cd468686ed978..15fa71a5d7fc48867f0749057b532fc4731091ea 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java
@@ -548,11 +548,16 @@ public class JavaUpCallsRFFI implements UpCallsRFFI {
             n *= newDims[i];
         }
         RAbstractVector result = (RAbstractVector) Rf_allocateVector(mode, n);
-        result.setDimensions(newDims);
+        setDims(newDims, result);
         return result;
 
     }
 
+    @TruffleBoundary
+    private static void setDims(int[] newDims, RAbstractVector result) {
+        result.setDimensions(newDims);
+    }
+
     @Override
     public Object Rf_allocateMatrix(int mode, int nrow, int ncol) {
         if (tracer != null) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
index 010680f45f3b636f568729999e256e139915e704..fa6ffc8f7f391192e193033001b15b6284966e62 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
@@ -868,8 +868,8 @@ public class RRuntime {
     public static int nrows(Object x) {
         if (x instanceof RAbstractContainer) {
             RAbstractContainer xa = (RAbstractContainer) x;
-            if (xa.hasDimensions()) {
-                return xa.getDimensions()[0];
+            if (hasDims(xa)) {
+                return getDims(xa)[0];
             } else {
                 return xa.getLength();
             }
@@ -881,8 +881,8 @@ public class RRuntime {
     public static int ncols(Object x) {
         if (x instanceof RAbstractContainer) {
             RAbstractContainer xa = (RAbstractContainer) x;
-            if (xa.hasDimensions()) {
-                int[] dims = xa.getDimensions();
+            if (hasDims(xa)) {
+                int[] dims = getDims(xa);
                 if (dims.length >= 2) {
                     return dims[1];
                 } else {
@@ -896,4 +896,14 @@ public class RRuntime {
         }
     }
 
+    @TruffleBoundary
+    private static int[] getDims(RAbstractContainer xa) {
+        return xa.getDimensions();
+    }
+
+    @TruffleBoundary
+    private static boolean hasDims(RAbstractContainer xa) {
+        return xa.hasDimensions();
+    }
+
 }
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 65d16aef9b115d138c0defe6e90f03ab43125e2b..f6d994371560fb83167772d867a0148a6fa0cf15 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
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.runtime.data;
 
 import java.util.Arrays;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
@@ -47,14 +48,19 @@ public class RExpression extends RListBase implements RAbstractVector {
 
     @Override
     protected RExpression internalCopy() {
-        return new RExpression(Arrays.copyOf(data, data.length), getDimensions(), null);
+        return new RExpression(Arrays.copyOf(data, data.length), getDimensionsInternal(), null);
+    }
+
+    @TruffleBoundary
+    private int[] getDimensionsInternal() {
+        return getDimensions();
     }
 
     @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), getDimensions(), null);
+        RExpression listCopy = new RExpression(Arrays.copyOf(data, data.length), getDimensionsInternal(), 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/RList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
index 8632d8f56dbb440bf7ed0b0722ea33c34bc0a5cd..92e3d161fab6d2b4da6df580e8fe7db5f00c9dd6 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
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.runtime.data;
 
 import java.util.Arrays;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 
@@ -44,14 +45,19 @@ public final class RList extends RListBase implements RAbstractListVector {
 
     @Override
     protected RList internalCopy() {
-        return new RList(Arrays.copyOf(data, data.length), getDimensions(), null);
+        return new RList(Arrays.copyOf(data, data.length), getDimensionsInternal(), null);
+    }
+
+    @TruffleBoundary
+    private int[] getDimensionsInternal() {
+        return getDimensions();
     }
 
     @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), getDimensions(), null);
+        RList listCopy = new RList(Arrays.copyOf(data, data.length), getDimensionsInternal(), 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/RScalarVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalarVector.java
index 57e5d18f0fcd068225914536ed9d96d849032989..80779a0ebd120e37835be53be4d2eac83912c770 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalarVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalarVector.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.runtime.data;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
@@ -156,6 +157,7 @@ public abstract class RScalarVector extends RScalar implements RAbstractVector {
     }
 
     @Override
+    @TruffleBoundary
     public RVector<?> copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
         RVector<?> result = materialize().copyResizedWithDimensions(newDimensions, fillNA);
         MemoryCopyTracer.reportCopying(this, result);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractContainer.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractContainer.java
index d00fa73b5f154cf78e0597c8000778d0a4b27f51..925f190e4475b931a82967efb70a372e45714b1d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractContainer.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractContainer.java
@@ -23,9 +23,12 @@
 package com.oracle.truffle.r.runtime.data.model;
 
 import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.object.DynamicObject;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
+import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.data.RStringVector;