diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java
index 920f33a652d25854fd3e1f341e68ba6e4d7966df..0431b88c2d7884d2095f7bf821e6398afff913c9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java
@@ -25,10 +25,11 @@ package com.oracle.truffle.r.nodes.builtin.base;
 import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.RInvisibleBuiltinNode;
+import com.oracle.truffle.r.nodes.function.opt.ReuseNonSharedNode;
 import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
-import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen;
 import com.oracle.truffle.r.runtime.RBuiltin;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.data.RNull;
@@ -39,34 +40,27 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 @RBuiltin(name = "dim<-", kind = PRIMITIVE, parameterNames = {"x", "value"})
 public abstract class UpdateDim extends RInvisibleBuiltinNode {
 
-    @Child private CastIntegerNode castInteger;
-
-    private RAbstractIntVector castInteger(RAbstractVector vector) {
-        if (castInteger == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castInteger = insert(CastIntegerNodeGen.create(true, false, false));
-        }
-        return (RAbstractIntVector) castInteger.execute(vector);
-    }
+    @Child private ReuseNonSharedNode reuse = ReuseNonSharedNode.create();
 
     @Specialization
     protected RAbstractVector updateDim(RAbstractVector vector, @SuppressWarnings("unused") RNull dimensions) {
         controlVisibility();
-        RVector result = (RVector) vector.getNonShared();
+        RVector result = ((RAbstractVector) reuse.execute(vector)).materialize();
         result.resetDimensions(null);
         return result;
     }
 
     @Specialization
-    protected RAbstractVector updateDim(RAbstractVector vector, RAbstractVector dimensions) {
+    protected RAbstractVector updateDim(RAbstractVector vector, RAbstractVector dimensions, //
+                    @Cached("createPreserveNames()") CastIntegerNode castInteger) {
         controlVisibility();
         if (dimensions.getLength() == 0) {
             CompilerDirectives.transferToInterpreter();
             throw RError.error(this, RError.Message.LENGTH_ZERO_DIM_INVALID);
         }
-        int[] dimsData = castInteger(dimensions).materialize().getDataCopy();
+        int[] dimsData = ((RAbstractIntVector) castInteger.execute(dimensions)).materialize().getDataCopy();
         RVector.verifyDimensions(vector.getLength(), dimsData, this);
-        RVector result = (RVector) vector.getNonShared();
+        RVector result = ((RAbstractVector) reuse.execute(vector)).materialize();
         result.resetDimensions(dimsData);
         return result;
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ReuseNonSharedNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ReuseNonSharedNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..70aa1febcc3f89bd62a47e8a2adedf89b42c399a
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ReuseNonSharedNode.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.nodes.function.opt;
+
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.runtime.data.RShareable;
+import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage;
+
+public abstract class ReuseNonSharedNode extends Node {
+
+    public static ReuseNonSharedNode create() {
+        return ReuseNonSharedNodeGen.create();
+    }
+
+    public abstract Object execute(Object value);
+
+    @Specialization
+    protected RShareable getStorage(RSharingAttributeStorage value, //
+                    @Cached("createBinaryProfile()") ConditionProfile isSharedProfile, //
+                    @Cached("createBinaryProfile()") ConditionProfile isTemporaryProfile, //
+                    @Cached("createClassProfile()") ValueProfile copyProfile) {
+        if (isSharedProfile.profile(value.isShared())) {
+            RShareable res = copyProfile.profile(value).copy();
+            assert res.isTemporary();
+            res.incRefCount();
+            return res;
+        }
+        if (isTemporaryProfile.profile(value.isTemporary())) {
+            value.incRefCount();
+        }
+        return value;
+    }
+
+    @Specialization(contains = "getStorage")
+    protected static RShareable getRShareable(RShareable value, //
+                    @Cached("createBinaryProfile()") ConditionProfile isSharedProfile, //
+                    @Cached("createBinaryProfile()") ConditionProfile isTemporaryProfile) {
+        if (isSharedProfile.profile(value.isShared())) {
+            RShareable res = value.copy();
+            assert res.isTemporary();
+            res.incRefCount();
+            return res;
+        }
+        if (isTemporaryProfile.profile(value.isTemporary())) {
+            value.incRefCount();
+        }
+        return value;
+    }
+
+    protected static boolean isRShareable(Object value) {
+        return value instanceof RShareable;
+    }
+
+    @Specialization(guards = "!isRShareable(value)")
+    protected static Object getNonShareable(Object value) {
+        return value;
+    }
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
index 7b15cf7fede1479f5f3718de78a5bbf3983a8978..617d540e4023f0f517cc36627f4d69d645515f8f 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
@@ -224,4 +224,8 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
     public static CastIntegerNode createNonPreserving() {
         return CastIntegerNodeGen.create(false, false, false);
     }
+
+    public static CastIntegerNode createPreserveNames() {
+        return CastIntegerNodeGen.create(false, false, false);
+    }
 }