diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java
index be5061a268fa9bbfd1d1560566e0a00e9d0b897c..8296211d643dc69235a343f191d063d8f7783d9f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java
@@ -36,9 +36,8 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.attributes.GetAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.IterableAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.builtin.base.UpdateAttr.InternStringNode;
-import com.oracle.truffle.r.nodes.builtin.base.UpdateAttrNodeGen.InternStringNodeGen;
 import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode;
+import com.oracle.truffle.r.nodes.unary.InternStringNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -55,7 +54,7 @@ public abstract class Attr extends RBuiltinNode.Arg3 {
     private final ConditionProfile searchPartialProfile = ConditionProfile.createBinaryProfile();
 
     @Child private UpdateShareableChildValueNode sharedAttrUpdate = UpdateShareableChildValueNode.create();
-    @Child private InternStringNode intern = InternStringNodeGen.create();
+    @Child private InternStringNode intern = InternStringNode.create();
 
     @Child private GetAttributeNode attrAccess = GetAttributeNode.create();
     @Child private IterableAttributeNode iterAttrAccess = IterableAttributeNode.create();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java
index 66bda17ce960afd19a8d753153de9fe9120a66a6..4181d6cf1b658e0591300a950aad62378df58b5a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java
@@ -32,24 +32,22 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
-import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.nodes.attributes.RemoveAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SetAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetRowNamesAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.builtin.base.UpdateAttrNodeGen.InternStringNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
 import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastListNode;
 import com.oracle.truffle.r.nodes.unary.CastToVectorNode;
 import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen;
 import com.oracle.truffle.r.nodes.unary.GetNonSharedNode;
+import com.oracle.truffle.r.nodes.unary.InternStringNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
-import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -73,24 +71,7 @@ public abstract class UpdateAttr extends RBuiltinNode.Arg3 {
     @Child private SetAttributeNode setGenAttrNode;
     @Child private SetDimAttributeNode setDimNode;
 
-    @Child private InternStringNode intern = InternStringNodeGen.create();
-
-    public abstract static class InternStringNode extends Node {
-
-        public abstract String execute(String value);
-
-        @Specialization(limit = "3", guards = "value == cachedValue")
-        protected static String internCached(@SuppressWarnings("unused") String value,
-                        @SuppressWarnings("unused") @Cached("value") String cachedValue,
-                        @Cached("intern(value)") String interned) {
-            return interned;
-        }
-
-        @Specialization(replaces = "internCached")
-        protected static String intern(String value) {
-            return Utils.intern(value);
-        }
-    }
+    @Child private InternStringNode intern = InternStringNode.create();
 
     static {
         Casts casts = new Casts(UpdateAttr.class);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSlotAssign.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSlotAssign.java
index cf6e4a9e7f76a1dd96f477693132057fa4c75574..e5bb37c018fc58615608c1de0f5cc09eb24b2591 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSlotAssign.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSlotAssign.java
@@ -35,9 +35,8 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.r.nodes.access.UpdateSlotNode;
 import com.oracle.truffle.r.nodes.access.UpdateSlotNodeGen;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.builtin.base.UpdateAttr.InternStringNode;
-import com.oracle.truffle.r.nodes.builtin.base.UpdateAttrNodeGen.InternStringNodeGen;
 import com.oracle.truffle.r.nodes.builtin.base.UpdateSlot.CheckSlotAssignNode;
+import com.oracle.truffle.r.nodes.unary.InternStringNode;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
@@ -54,7 +53,7 @@ public abstract class FastRSlotAssign extends RBuiltinNode.Arg4 {
         casts.arg("value").castForeignObjects(false).mustNotBeMissing();
     }
 
-    @Child private InternStringNode intern = InternStringNodeGen.create();
+    @Child private InternStringNode intern = InternStringNode.create();
     @Child private UpdateSlotNode updateSlotNode = UpdateSlotNodeGen.create();
 
     @Override
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java
index bc99584c8518c803e716d61942f0b79e28d08440..dfbec21e3c516a0221519e52d52037c6d2246e81 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java
@@ -21,10 +21,10 @@ import com.oracle.truffle.r.nodes.attributes.GetAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.InitAttributesNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetClassAttributeNode;
 import com.oracle.truffle.r.nodes.function.ImplicitClassHierarchyNode;
+import com.oracle.truffle.r.nodes.unary.InternStringNode;
 import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
-import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -52,12 +52,12 @@ public abstract class AccessSlotNode extends BaseAccessSlotNode {
 
     @Specialization(guards = {"slotAccessAllowed(object)"})
     protected Object getSlotS4Cached(RAttributable object, String name,
+                    @Cached("create()") InternStringNode intern,
                     @Cached("createAttrAccess()") GetAttributeNode attrAccess,
                     @Cached("create()") InitAttributesNode initAttrNode,
                     @Cached("create()") GetClassAttributeNode getClassNode) {
         Object value = attrAccess.execute(initAttrNode.execute(object), name);
-        String internedName = Utils.intern(name);
-        return getSlotS4Internal(object, internedName, value, getClassNode);
+        return getSlotS4Internal(object, intern.execute(name), value, getClassNode);
     }
 
     @Specialization(guards = {"!slotAccessAllowed(object)", "isDotData(name)"})
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InternStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InternStringNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..8eda43f1b4719e02c7ea059ed22824f577c2c934
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InternStringNode.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 2018, 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.unary;
+
+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.r.runtime.Utils;
+
+public abstract class InternStringNode extends Node {
+
+    public abstract String execute(String value);
+
+    @Specialization(limit = "3", guards = "value == cachedValue")
+    protected static String internCached(@SuppressWarnings("unused") String value,
+                    @SuppressWarnings("unused") @Cached("value") String cachedValue,
+                    @Cached("intern(value)") String interned) {
+        return interned;
+    }
+
+    @Specialization(replaces = "internCached")
+    protected static String intern(String value) {
+        return Utils.intern(value);
+    }
+
+    public static InternStringNode create() {
+        return InternStringNodeGen.create();
+    }
+}