diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
index f5c37b9d496285ae269cdf0078e4ac883bd67ff2..1bce5b339efe8e3d0e31ef878a81b9ebae5367db 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -627,7 +627,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
                     sresult = RDataFactory.createStringVector(lines, RDataFactory.COMPLETE_VECTOR);
                 }
                 if (status != 0) {
-                    sresult.setAttr("status", RDataFactory.createIntVectorFromScalar(status));
+                    setResultAttr(status, sresult);
                 }
                 return sresult;
             } else {
@@ -635,6 +635,11 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
             }
 
         }
+
+        @TruffleBoundary
+        private static void setResultAttr(int status, RStringVector sresult) {
+            sresult.setAttr("status", RDataFactory.createIntVectorFromScalar(status));
+        }
     }
 
     private static IORedirect handleIORedirect(String[] args, boolean intern) {
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java
index 80d764515eef04f25d408662217f208623651a3e..2cdaa424d967533c38b78414ca0ec0bd4deb251b 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
  * Copyright (C) 1998--2012  The R Core Team
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -16,7 +16,6 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -43,13 +42,12 @@ public class SplineFunctions {
     }
 
     public abstract static class SplineEval extends RExternalBuiltinNode.Arg2 {
-        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
         @Specialization
         @TruffleBoundary
         protected Object splineEval(RAbstractDoubleVector xout, RList z) {
             // This is called with the result of SplineCoef, so it is surely an RList
-            return SplineFunctions.splineEval(attrProfiles, xout.materialize(), z);
+            return SplineFunctions.splineEval(xout.materialize(), z);
         }
     }
 
@@ -362,16 +360,16 @@ public class SplineFunctions {
         return;
     }
 
-    private static RDoubleVector splineEval(RAttributeProfiles attrProfiles, RDoubleVector xout, RList z) {
+    private static RDoubleVector splineEval(RDoubleVector xout, RList z) {
         int nu = xout.getLength();
         double[] yout = new double[nu];
-        int method = (int) z.getDataAt(z.getElementIndexByName(attrProfiles, "method"));
-        int nx = (int) z.getDataAt(z.getElementIndexByName(attrProfiles, "n"));
-        RDoubleVector x = (RDoubleVector) z.getDataAt(z.getElementIndexByName(attrProfiles, "x"));
-        RDoubleVector y = (RDoubleVector) z.getDataAt(z.getElementIndexByName(attrProfiles, "y"));
-        RDoubleVector b = (RDoubleVector) z.getDataAt(z.getElementIndexByName(attrProfiles, "b"));
-        RDoubleVector c = (RDoubleVector) z.getDataAt(z.getElementIndexByName(attrProfiles, "c"));
-        RDoubleVector d = (RDoubleVector) z.getDataAt(z.getElementIndexByName(attrProfiles, "d"));
+        int method = (int) z.getDataAt(z.getElementIndexByName("method"));
+        int nx = (int) z.getDataAt(z.getElementIndexByName("n"));
+        RDoubleVector x = (RDoubleVector) z.getDataAt(z.getElementIndexByName("x"));
+        RDoubleVector y = (RDoubleVector) z.getDataAt(z.getElementIndexByName("y"));
+        RDoubleVector b = (RDoubleVector) z.getDataAt(z.getElementIndexByName("b"));
+        RDoubleVector c = (RDoubleVector) z.getDataAt(z.getElementIndexByName("c"));
+        RDoubleVector d = (RDoubleVector) z.getDataAt(z.getElementIndexByName("d"));
 
         splineEval(method, nu, xout.getDataWithoutCopying(), yout, nx, x.getDataWithoutCopying(), y.getDataWithoutCopying(), b.getDataWithoutCopying(), c.getDataWithoutCopying(),
                         d.getDataWithoutCopying());
diff --git a/com.oracle.truffle.r.native/.project b/com.oracle.truffle.r.native/.project
deleted file mode 100644
index 9a92f723f84de80e3e352ce7db2cc9c58a867e93..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.native/.project
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>com.oracle.truffle.r.native</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-			<triggers>full,incremental,</triggers>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.cdt.core.cnature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-	</natures>
-</projectDescription>
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
index 4c7ca302a832f3e56e0e2f08733f2e77564cdcd6..d36f0d5089b3d68b0359f70cba925bdb3d72441b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -46,7 +46,6 @@ 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.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -66,8 +65,6 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 @RBuiltin(name = "as.function.default", kind = INTERNAL, parameterNames = {"x", "envir"}, behavior = PURE)
 public abstract class AsFunction extends RBuiltinNode {
 
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
     @Override
     protected void createCasts(CastBuilder casts) {
         casts.arg("x").mustBe(instanceOf(RAbstractListVector.class).or(instanceOf(RExpression.class)), RError.SHOW_CALLER2, RError.Message.TYPE_EXPECTED, RType.List.getName());
@@ -87,8 +84,8 @@ public abstract class AsFunction extends RBuiltinNode {
             saveArguments = SaveArgumentsNode.NO_ARGS;
             formals = FormalArguments.NO_ARGS;
         } else {
-            assert x.getNames(attrProfiles) != null;
-            RStringVector names = x.getNames(attrProfiles);
+            assert x.getNames() != null;
+            RStringVector names = x.getNames();
             String[] argumentNames = new String[x.getLength() - 1];
             RNode[] defaultValues = new RNode[x.getLength() - 1];
             AccessArgumentNode[] argAccessNodes = new AccessArgumentNode[x.getLength() - 1];
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
index 6f3c3bc9c082d8bd0b8362e9ead3982deed14382..3add337eeddb6b8c2ec068284a7ee9ed4014c114 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -63,7 +63,6 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RLanguage;
@@ -209,8 +208,6 @@ public abstract class AsVector extends RBuiltinNode {
 
         protected abstract static class CastPairListNode extends CastNode {
 
-            private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
             @Specialization
             @TruffleBoundary
             protected Object castPairlist(RAbstractListVector x) {
@@ -220,7 +217,7 @@ public abstract class AsVector extends RBuiltinNode {
                     return RNull.instance;
                 } else {
                     Object list = RNull.instance;
-                    RStringVector names = x.getNames(attrProfiles);
+                    RStringVector names = x.getNames();
                     for (int i = x.getLength() - 1; i >= 0; i--) {
                         Object name = names == null ? RNull.instance : RDataFactory.createSymbolInterned(names.getDataAt(i));
                         Object data = x.getDataAt(i);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AttachFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AttachFunctions.java
index 7aa2a9e377a79c7ff78ff600516a84f1fafb6a78..b9103fc9e473631071871f388771dbeda2e494e9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AttachFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AttachFunctions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -36,7 +36,6 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RStringVector;
@@ -50,8 +49,6 @@ public class AttachFunctions {
     @RBuiltin(name = "attach", visibility = OFF, kind = INTERNAL, parameterNames = {"what", "pos", "name"}, behavior = COMPLEX)
     public abstract static class Attach extends RBuiltinNode {
 
-        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
         @Override
         protected void createCasts(CastBuilder casts) {
             casts.arg("what").allowNull().mustBe(instanceOf(REnvironment.class).or(instanceOf(RAbstractListVector.class)), RError.Message.ATTACH_BAD_TYPE);
@@ -86,7 +83,7 @@ public class AttachFunctions {
         @TruffleBoundary
         protected REnvironment doAttach(RAbstractListVector what, RAbstractIntVector pos, RAbstractStringVector name) {
             REnvironment env = RDataFactory.createNewEnv(name.getDataAt(0));
-            RStringVector names = what.getNames(attrProfiles);
+            RStringVector names = what.getNames();
             for (int i = 0; i < names.getLength(); i++) {
                 // TODO: copy/sharing?
                 env.safePut(names.getDataAt(i), what.getDataAt(i));
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
index c45cb05324403c8247e900ca5c64b8162defb836..8709521c226523cb7b6e9f1f64463ff6f4745378 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -46,7 +46,6 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RIntVector;
@@ -139,7 +138,6 @@ public class DatePOSIXFunctions {
     @RBuiltin(name = "Date2POSIXlt", kind = INTERNAL, parameterNames = "x", behavior = PURE)
     public abstract static class Date2POSIXlt extends RBuiltinNode {
 
-        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
         @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
 
         @Override
@@ -167,7 +165,7 @@ public class DatePOSIXFunctions {
             RList result = builder.finish();
             RStringVector xNames = getNamesNode.getNames(x);
             if (xNames != null) {
-                ((RIntVector) result.getDataAt(5)).copyNamesFrom(attrProfiles, x);
+                ((RIntVector) result.getDataAt(5)).copyNamesFrom(x);
             }
             return result;
         }
@@ -176,7 +174,6 @@ public class DatePOSIXFunctions {
     @RBuiltin(name = "as.POSIXlt", kind = INTERNAL, parameterNames = {"x", "tz"}, behavior = READS_STATE)
     public abstract static class AsPOSIXlt extends RBuiltinNode {
 
-        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
         @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
 
         @Override
@@ -210,7 +207,7 @@ public class DatePOSIXFunctions {
             RList result = builder.finish();
             RStringVector xNames = getNamesNode.getNames(x);
             if (xNames != null) {
-                ((RIntVector) result.getDataAt(5)).copyNamesFrom(attrProfiles, x);
+                ((RIntVector) result.getDataAt(5)).copyNamesFrom(x);
             }
             return result;
         }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
index 6524fe6c95208ee96dde730340309187dd5d71ee..492de2059bebd686ce332451bbdd290ddbe774ce 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -65,7 +65,6 @@ import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.VirtualEvalFrame;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLanguage;
@@ -390,8 +389,6 @@ public class EnvFunctions {
     @RBuiltin(name = "environment<-", kind = PRIMITIVE, parameterNames = {"env", "value"}, behavior = COMPLEX)
     public abstract static class UpdateEnvironment extends RBuiltinNode {
 
-        private final RAttributeProfiles attributeProfile = RAttributeProfiles.create();
-
         @Override
         protected void createCasts(CastBuilder casts) {
             casts.arg("value").allowNull().mustBe(REnvironment.class, Message.REPLACEMENT_NOT_ENVIRONMENT);
@@ -446,7 +443,7 @@ public class EnvFunctions {
         @Specialization
         @TruffleBoundary
         protected Object updateEnvironment(RAttributable obj, @SuppressWarnings("unused") RNull env) {
-            obj.removeAttr(attributeProfile, RRuntime.DOT_ENVIRONMENT);
+            obj.removeAttr(RRuntime.DOT_ENVIRONMENT);
             return obj;
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java
index 3ec1ff4596e8f8042abbe916d4057c778c076765..aba09031a868723789bc7c17e3b7efdd2c8c5736 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -48,7 +48,6 @@ import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -75,8 +74,6 @@ public abstract class Eval extends RBuiltinNode {
 
         public abstract REnvironment execute(VirtualFrame frame, Object env, Object enclos);
 
-        private final RAttributeProfiles attributeProfiles = RAttributeProfiles.create();
-
         @Specialization
         protected REnvironment cast(@SuppressWarnings("unused") RNull env, @SuppressWarnings("unused") RNull enclos) {
             return REnvironment.baseEnv();
@@ -101,24 +98,24 @@ public abstract class Eval extends RBuiltinNode {
 
         @Specialization
         protected REnvironment cast(RList list, REnvironment enclos) {
-            return REnvironment.createFromList(attributeProfiles, list, enclos);
+            return REnvironment.createFromList(list, enclos);
         }
 
         @Specialization
         protected REnvironment cast(RPairList list, REnvironment enclos) {
-            return REnvironment.createFromList(attributeProfiles, list.toRList(), enclos);
+            return REnvironment.createFromList(list.toRList(), enclos);
         }
 
         @Specialization
         protected REnvironment cast(RList list, @SuppressWarnings("unused") RNull enclos) {
             // This can happen when envir is a list and enclos is explicitly set to NULL
-            return REnvironment.createFromList(attributeProfiles, list, REnvironment.baseEnv());
+            return REnvironment.createFromList(list, REnvironment.baseEnv());
         }
 
         @Specialization
         protected REnvironment cast(RPairList list, @SuppressWarnings("unused") RNull enclos) {
             // This can happen when envir is a pairlist and enclos is explicitly set to NULL
-            return REnvironment.createFromList(attributeProfiles, list.toRList(), REnvironment.baseEnv());
+            return REnvironment.createFromList(list.toRList(), REnvironment.baseEnv());
         }
 
         @Specialization
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetOldClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetOldClass.java
index 947f79ac432bb838bd8752d3e99a8b45c199cff2..b0820a927cc0fa1444fc16fa9b14ff258fe5f274 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetOldClass.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetOldClass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -26,10 +26,11 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.nodes.Node.Child;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetClassAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
@@ -38,11 +39,11 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 public abstract class GetOldClass extends RBuiltinNode {
 
     private final ConditionProfile isObjectProfile = ConditionProfile.createBinaryProfile();
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+    @Child private GetClassAttributeNode getClassNode = GetClassAttributeNode.create();
 
     @Specialization
     protected Object getOldClass(RAbstractContainer arg) {
-        if (isObjectProfile.profile(arg.isObject(attrProfiles))) {
+        if (isObjectProfile.profile(getClassNode.isObject(arg))) {
             return arg.getClassHierarchy();
         } else {
             return RNull.instance;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java
index e8ba62ceb910f093217c88d5664abb3c49933115..5685606cb72602bd367f07eabb12b1666c1514e0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java
@@ -35,7 +35,6 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RegExp;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -67,11 +66,6 @@ public class GrepFunctions {
     public abstract static class CommonCodeAdapter extends RBuiltinNode {
         @Child protected PCRERFFI.PCRERFFINode pcreRFFINode = RFFIFactory.getRFFI().getPCRERFFI().createPCRERFFINode();
 
-        /**
-         * This profile is needed to satisfy API requirements.
-         */
-        protected final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
         protected void castPattern(CastBuilder casts) {
             // with default error message, NO_CALLER does not work
             casts.arg("pattern").mustBe(stringValue(), RError.NO_CALLER, RError.Message.INVALID_ARGUMENT, "pattern").asVector().mustBe(notEmpty(), RError.NO_CALLER, RError.Message.INVALID_ARGUMENT,
@@ -275,7 +269,7 @@ public class GrepFunctions {
                 return value ? RDataFactory.createEmptyStringVector() : RDataFactory.createEmptyIntVector();
             } else {
                 if (value) {
-                    RStringVector oldNames = vector.getNames(attrProfiles);
+                    RStringVector oldNames = vector.getNames();
                     String[] newNames = null;
                     if (oldNames != null) {
                         newNames = new String[nmatches];
@@ -1244,8 +1238,8 @@ public class GrepFunctions {
                 }
             }
             RList ret = RDataFactory.createList(result);
-            if (x.getNames(attrProfiles) != null) {
-                ret.copyNamesFrom(attrProfiles, x);
+            if (x.getNames() != null) {
+                ret.copyNamesFrom(x);
             }
             return ret;
         }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java
index 310b8758f5361a305ff6a03a777169ae0d993d37..ad9e3470a938118b7d8915451fa77b59e7809d78 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java
@@ -32,11 +32,13 @@ 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.Child;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode;
+import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetClassAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctionsFactory.GetDimAttributeNodeGen;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
@@ -47,7 +49,6 @@ import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -425,14 +426,13 @@ public class IsTypeFunctions {
     @RBuiltin(name = "is.object", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE)
     public abstract static class IsObject extends MissingAdapter {
 
-        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+        @Child private GetClassAttributeNode getClassNode = GetClassAttributeNode.create();
 
         public abstract byte execute(Object value);
 
         @Specialization
-        protected byte isObject(RAttributable arg, //
-                        @Cached("createClassProfile()") ValueProfile profile) {
-            return RRuntime.asLogical(profile.profile(arg).isObject(attrProfiles));
+        protected byte isObject(RAttributable arg) {
+            return RRuntime.asLogical(getClassNode.isObject(arg));
         }
 
         @Specialization(guards = {"!isRMissing(value)", "!isRAttributable(value)"})
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java
index 8d3ca0f3b4ef3d2c4cfe9763960769dca7ff01df..bdc10f0d379636fd814581fb027a3a017528caf8 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -46,7 +46,6 @@ import com.oracle.truffle.r.runtime.RAccuracyInfo;
 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.RComplexVector;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
@@ -537,7 +536,6 @@ public class LaFunctions {
 
     @RBuiltin(name = "La_solve", kind = INTERNAL, parameterNames = {"a", "bin", "tolin"}, behavior = PURE)
     public abstract static class LaSolve extends Adapter {
-        protected final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
         @Child private CastDoubleNode castDouble = CastDoubleNodeGen.create(false, false, false);
 
         private static Function<RAbstractDoubleVector, Object> getDimVal(int dim) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lengths.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lengths.java
index 13ff33c5bba1590ed62227d174789a4e4eb0c865..a798172fa77b927d988537a0fa02bb0658e63e6f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lengths.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lengths.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -33,6 +33,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 import java.util.Arrays;
 
 import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
@@ -40,7 +41,6 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.control.RLengthNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -52,8 +52,6 @@ public abstract class Lengths extends RBuiltinNode {
 
     @Child private RLengthNode lengthNode;
 
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
     @Override
     protected void createCasts(CastBuilder casts) {
         casts.arg("x").defaultError(RError.SHOW_CALLER, X_LIST_ATOMIC).allowNull().mustBe(abstractVectorValue());
@@ -93,8 +91,13 @@ public abstract class Lengths extends RBuiltinNode {
     private RIntVector createResult(RAbstractVector x, int[] data, boolean useNames) {
         RIntVector result = RDataFactory.createIntVector(data, RDataFactory.COMPLETE_VECTOR);
         if (useNames) {
-            result.copyNamesFrom(attrProfiles, x);
+            copyNames(x, result);
         }
         return result;
     }
+
+    @TruffleBoundary
+    private void copyNames(RAbstractVector x, RIntVector result) {
+        result.copyNamesFrom(x);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java
index 56288f90caae83a7a6386f6229ff967146890fef..2a8369465f6c1330f6da4b55e5c67a0dca713758 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java
@@ -36,12 +36,12 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode;
+import com.oracle.truffle.r.nodes.helpers.RFactorNodes;
 import com.oracle.truffle.r.nodes.unary.CastStringNode;
 import com.oracle.truffle.r.nodes.unary.CastStringNodeGen;
 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.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -72,7 +72,6 @@ public abstract class Match extends RBuiltinNode {
 
     private final NACheck naCheck = NACheck.create();
     private final ConditionProfile bigTableProfile = ConditionProfile.createBinaryProfile();
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
     @Override
     protected void createCasts(CastBuilder casts) {
@@ -127,22 +126,26 @@ public abstract class Match extends RBuiltinNode {
     }
 
     @Specialization(guards = {"isFactor(x)", "isFactor(table)"})
-    protected Object matchFactor(RAbstractIntVector x, RAbstractIntVector table, int nomatch, Object incomparables) {
+    protected Object matchFactor(RAbstractIntVector x, RAbstractIntVector table, int nomatch, Object incomparables,
+                    @Cached("create()") RFactorNodes.GetLevels getLevelsNode) {
         naCheck.enable(x);
         naCheck.enable(table);
-        return matchRecursive(RClosures.createFactorToVector(x, true, attrProfiles), RClosures.createFactorToVector(table, true, attrProfiles), nomatch, incomparables);
+        return matchRecursive(RClosures.createFactorToVector(x, true, getLevelsNode.execute(x)),
+                        RClosures.createFactorToVector(table, true, getLevelsNode.execute(table)), nomatch, incomparables);
     }
 
     @Specialization(guards = {"isFactor(x)", "!isFactor(table)"})
-    protected Object matchFactor(RAbstractIntVector x, RAbstractVector table, int nomatch, Object incomparables) {
+    protected Object matchFactor(RAbstractIntVector x, RAbstractVector table, int nomatch, Object incomparables,
+                    @Cached("create()") RFactorNodes.GetLevels getLevelsNode) {
         naCheck.enable(x);
-        return matchRecursive(RClosures.createFactorToVector(x, true, attrProfiles), table, nomatch, incomparables);
+        return matchRecursive(RClosures.createFactorToVector(x, true, getLevelsNode.execute(x)), table, nomatch, incomparables);
     }
 
     @Specialization(guards = {"!isFactor(x)", "isFactor(table)"})
-    protected Object matchFactor(RAbstractVector x, RAbstractIntVector table, int nomatch, Object incomparables) {
+    protected Object matchFactor(RAbstractVector x, RAbstractIntVector table, int nomatch, Object incomparables,
+                    @Cached("create()") RFactorNodes.GetLevels getLevelsNode) {
         naCheck.enable(table);
-        return matchRecursive(x, RClosures.createFactorToVector(table, true, attrProfiles), nomatch, incomparables);
+        return matchRecursive(x, RClosures.createFactorToVector(table, true, getLevelsNode.execute(table)), nomatch, incomparables);
     }
 
     @Specialization
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..45ca370e1f58679ad502a6889f47e8f939f8b90d 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -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/OptionsFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java
index a75137a175ebe463aa7778ce77e3d3f050eda038..9b0c0e76b8e1f08e9b81f8135f91f73074363d03 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java
@@ -49,7 +49,6 @@ import com.oracle.truffle.r.runtime.ROptions.OptionsException;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RMissing;
@@ -68,7 +67,6 @@ public class OptionsFunctions {
         @Child private SetVisibilityNode visibility = SetVisibilityNode.create();
 
         private final ConditionProfile argNameNull = ConditionProfile.createBinaryProfile();
-        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
         @Specialization
         @TruffleBoundary
@@ -136,7 +134,7 @@ public class OptionsFunctions {
                         // setting
                         RList list = (RList) value;
                         RStringVector thisListnames = null;
-                        Object nn = list.getNames(attrProfiles);
+                        Object nn = list.getNames();
                         if (nn instanceof RStringVector) {
                             thisListnames = (RStringVector) nn;
                         } else {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrintFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrintFunctions.java
index 40de6fe16663d549c10a5b99967cb28a8b72f9b5..cd77e962271bf23188e42337d6689bed320e0e10 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrintFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrintFunctions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -36,6 +36,7 @@ import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
+import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetClassAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.printer.PrintParameters;
@@ -46,7 +47,6 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RString;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
@@ -56,7 +56,7 @@ public class PrintFunctions {
     @RBuiltin(name = "print.default", visibility = OFF, kind = INTERNAL, parameterNames = {"x", "digits", "quote", "na.print", "print.gap", "right", "max", "useSource", "noOpt"}, behavior = IO)
     public abstract static class PrintDefault extends RBuiltinNode {
 
-        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+        @Child private GetClassAttributeNode getClassNode = GetClassAttributeNode.create();
 
         @Child private ValuePrinterNode valuePrinter = new ValuePrinterNode();
 
@@ -102,7 +102,7 @@ public class PrintFunctions {
         }
 
         protected boolean isS4(Object o) {
-            return o instanceof RAttributable && ((RAttributable) o).isS4() && ((RAttributable) o).getClassAttr(attrProfiles) != null;
+            return o instanceof RAttributable && ((RAttributable) o).isS4() && getClassNode.getClassAttr(o) != null;
         }
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java
index 91aa642cb77db7cde6343807f75c40d3cd2de3af..af2a1c06d97844d84e11e5508c55af787c58926f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -16,7 +16,6 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.SUBSTITUTE;
 
 import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
 import com.oracle.truffle.api.frame.MaterializedFrame;
@@ -46,7 +45,6 @@ import com.oracle.truffle.r.runtime.ReturnException;
 import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
@@ -184,7 +182,6 @@ public abstract class S3DispatchFunctions extends RBuiltinNode {
         @Child private CombineSignaturesNode combineSignatures;
         @Child private CollectArgumentsNode collectArguments = CollectArgumentsNodeGen.create();
 
-        @CompilationFinal private RAttributeProfiles attrProfiles;
         @Child private PromiseHelperNode promiseHelper;
 
         private final BranchProfile errorProfile = BranchProfile.create();
@@ -281,7 +278,6 @@ public abstract class S3DispatchFunctions extends RBuiltinNode {
         private RStringVector getAlternateClassHr(VirtualFrame frame) {
             if (promiseHelper == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                attrProfiles = RAttributeProfiles.create();
                 promiseHelper = insert(new PromiseHelperNode());
             }
             if (RArguments.getArgumentsLength(frame) == 0 || RArguments.getArgument(frame, 0) == null ||
@@ -296,5 +292,6 @@ public abstract class S3DispatchFunctions extends RBuiltinNode {
             RAbstractContainer enclosingArg = (RAbstractContainer) arg;
             return enclosingArg.getClassHierarchy();
         }
+
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strrep.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strrep.java
index 3776ec0d6498e173935c8b501379c5f1b4a66408..1e68622ebcfe72396d2ceca6c685baca99c6dc44 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strrep.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strrep.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -31,7 +31,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.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
@@ -41,7 +40,6 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck;
 @RBuiltin(name = "strrep", kind = INTERNAL, parameterNames = {"x", "times"}, behavior = PURE)
 public abstract class Strrep extends RBuiltinNode {
     private final NACheck naCheck = NACheck.create();
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
     @Override
     protected void createCasts(CastBuilder casts) {
@@ -86,8 +84,12 @@ public abstract class Strrep extends RBuiltinNode {
         }
         RStringVector result = RDataFactory.createStringVector(data, naCheck.neverSeenNA());
         if (resultLen == xLen) {
-            result.copyNamesFrom(attrProfiles, xVec);
+            copyNames(xVec, result);
         }
         return result;
     }
+
+    private void copyNames(RAbstractStringVector xVec, RStringVector result) {
+        result.copyNamesFrom(xVec);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java
index 71586ca2e2dc19bff65266864d0078db10a370e3..f6077ad1c69a944453c2c1ed3298e0555b525425 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -26,7 +26,6 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.CompilerDirectives;
-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.frame.VirtualFrame;
@@ -36,7 +35,6 @@ import com.oracle.truffle.r.nodes.control.IfNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RSubstitute;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RMissing;
@@ -60,9 +58,8 @@ public abstract class Substitute extends RBuiltinNode {
     }
 
     @Specialization
-    protected Object doSubstitute(RPromise expr, RList list,
-                    @Cached("create()") RAttributeProfiles attrProfiles) {
-        return doSubstituteWithEnv(expr, REnvironment.createFromList(attrProfiles, list, REnvironment.baseEnv()));
+    protected Object doSubstitute(RPromise expr, RList list) {
+        return doSubstituteWithEnv(expr, REnvironment.createFromList(list, REnvironment.baseEnv()));
     }
 
     @Fallback
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.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java
index 1309e5de475eba4e880f97c5ed1757a62d7fa863..c0caf0bd8563996de9fca84587db0f1fc6c103d9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -15,14 +15,15 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 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.GetClassAttributeNode;
+import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.RemoveClassAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.data.RVector;
@@ -32,7 +33,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 public abstract class UnClass extends RBuiltinNode {
     private final BranchProfile objectProfile = BranchProfile.create();
     private final BranchProfile shareableProfile = BranchProfile.create();
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
     @Override
     protected void createCasts(CastBuilder casts) {
@@ -57,8 +57,8 @@ public abstract class UnClass extends RBuiltinNode {
     // TODO: this specialization could go away if connections were simple vectors (we wouldn't need
     // special method for setting class attributes then)
     @Specialization
-    protected Object unClass(RAbstractVector arg) {
-        if (arg.isObject(attrProfiles)) {
+    protected Object unClass(RAbstractVector arg, @Cached("create()") GetClassAttributeNode getClassNode) {
+        if (getClassNode.isObject(arg)) {
             objectProfile.enter();
             return unClassVector(arg);
         }
@@ -66,8 +66,8 @@ public abstract class UnClass extends RBuiltinNode {
     }
 
     @Specialization(guards = "notAbstractVector(arg)")
-    protected Object unClass(RAttributable arg) {
-        if (arg.getClassAttr(attrProfiles) != null) {
+    protected Object unClass(RAttributable arg, @Cached("create()") RemoveClassAttributeNode removeClassNode, @Cached("create()") GetClassAttributeNode getClassNode) {
+        if (getClassNode.getClassAttr(arg) != null) {
             objectProfile.enter();
             if (arg instanceof RShareable) {
                 shareableProfile.enter();
@@ -77,7 +77,7 @@ public abstract class UnClass extends RBuiltinNode {
                     shareable.incRefCount();
                 }
             }
-            arg.removeAttr(attrProfiles, RRuntime.CLASS_ATTR_KEY);
+            removeClassNode.execute(arg);
         }
         return arg;
     }
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 44c90112eea01405a565a31844f320978bcabf50..3966e259a972c5da85f4531895fed8bb147fdf61 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -37,6 +37,7 @@ import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
+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;
@@ -54,7 +55,6 @@ 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.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RShareable;
@@ -67,7 +67,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 public abstract class UpdateAttr extends RBuiltinNode {
 
     private final BranchProfile errorProfile = BranchProfile.create();
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
     @Child private UpdateNames updateNames;
     @Child private UpdateDimNames updateDimNames;
@@ -140,7 +139,7 @@ public abstract class UpdateAttr extends RBuiltinNode {
     }
 
     @Specialization
-    protected RAbstractContainer updateAttr(RAbstractContainer container, String name, RNull value) {
+    protected RAbstractContainer updateAttr(RAbstractContainer container, String name, RNull value, @Cached("create()") RemoveAttributeNode removeAttrNode) {
         String internedName = intern.execute(name);
         RAbstractContainer result = (RAbstractContainer) container.getNonShared();
         // the name is interned, so identity comparison is sufficient
@@ -168,7 +167,7 @@ public abstract class UpdateAttr extends RBuiltinNode {
             }
             setRowNamesAttrNode.setRowNames(result, null);
         } else if (result.getAttributes() != null) {
-            result.removeAttr(attrProfiles, internedName);
+            removeAttrNode.execute(result, internedName);
         }
         return result;
     }
@@ -239,6 +238,7 @@ public abstract class UpdateAttr extends RBuiltinNode {
      * All other, non-performance centric, {@link RAttributable} types.
      */
     @Fallback
+    @TruffleBoundary
     protected Object updateAttr(Object obj, Object name, Object value) {
         assert name instanceof String : "casts should not pass anything but String";
         Object object = obj;
@@ -249,7 +249,7 @@ public abstract class UpdateAttr extends RBuiltinNode {
         if (object instanceof RAttributable) {
             RAttributable attributable = (RAttributable) object;
             if (value == RNull.instance) {
-                attributable.removeAttr(attrProfiles, internedName);
+                attributable.removeAttr(internedName);
             } else {
                 attributable.setAttr(internedName, value);
             }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java
index 4e0c99102cbac929b1bff3705111ca5f2e9f4f43..e346d88aad6254f16a80066f34dd1b0064f22e01 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -31,8 +31,10 @@ import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.attributes.RemoveAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SetAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
+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.CastBuilder;
@@ -45,7 +47,6 @@ 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.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RShareable;
@@ -58,7 +59,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 @RBuiltin(name = "attributes<-", kind = PRIMITIVE, parameterNames = {"obj", "value"}, behavior = PURE)
 public abstract class UpdateAttributes extends RBuiltinNode {
     private final ConditionProfile numAttributesProfile = ConditionProfile.createBinaryProfile();
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
     @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
 
     @Child private UpdateNames updateNames;
@@ -66,8 +66,10 @@ public abstract class UpdateAttributes extends RBuiltinNode {
     @Child private CastIntegerNode castInteger;
     @Child private CastToVectorNode castVector;
     @Child private SetAttributeNode setAttrNode;
+    @Child private SetClassAttributeNode setClassNode;
     @Child private SetDimAttributeNode setDimNode;
     @Child private SetRowNamesAttributeNode setRowNamesNode;
+    @Child private RemoveAttributeNode removeAttrNode;
 
     @Override
     protected void createCasts(CastBuilder casts) {
@@ -150,7 +152,7 @@ public abstract class UpdateAttributes extends RBuiltinNode {
 
     @TruffleBoundary
     private void checkAttributeForEmptyValue(RList rlist) {
-        RStringVector listNames = rlist.getNames(attrProfiles);
+        RStringVector listNames = rlist.getNames();
         int length = rlist.getLength();
         assert length > 0 : "Length should be > 0 for ExplodeLoop";
         for (int i = 1; i < length; i++) {
@@ -203,10 +205,14 @@ public abstract class UpdateAttributes extends RBuiltinNode {
             } else if (attrName.equals(RRuntime.DIMNAMES_ATTR_KEY)) {
                 res = updateDimNames(res, value);
             } else if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) {
+                if (setClassNode == null) {
+                    CompilerDirectives.transferToInterpreter();
+                    setClassNode = insert(SetClassAttributeNode.create());
+                }
                 if (value == RNull.instance) {
-                    res.setClassAttr(null);
+                    setClassNode.reset(res);
                 } else {
-                    res.setClassAttr(UpdateAttr.convertClassAttrFromObject(value));
+                    setClassNode.execute(res, UpdateAttr.convertClassAttrFromObject(value));
                 }
                 res = result;
             } else if (attrName.equals(RRuntime.ROWNAMES_ATTR_KEY)) {
@@ -217,7 +223,11 @@ public abstract class UpdateAttributes extends RBuiltinNode {
                 setRowNamesNode.setRowNames(res, castVector(value));
             } else {
                 if (value == RNull.instance) {
-                    res.removeAttr(attrProfiles, attrName);
+                    if (removeAttrNode == null) {
+                        CompilerDirectives.transferToInterpreter();
+                        removeAttrNode = insert(RemoveAttributeNode.create());
+                    }
+                    removeAttrNode.execute(res, attrName);
                 } else {
                     if (setAttrNode == null) {
                         CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -260,7 +270,7 @@ public abstract class UpdateAttributes extends RBuiltinNode {
         Object obj = getNonShared(o);
         RAttributable attrObj = (RAttributable) obj;
         attrObj.removeAllAttributes();
-        RStringVector listNames = operand.getNames(attrProfiles);
+        RStringVector listNames = operand.getNames();
         if (listNames == null) {
             throw RError.error(this, RError.Message.ATTRIBUTES_NAMED);
         }
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 1133d63fa879b46b5bba99865a40c045c87690ab..30ca1d44d95a5934edd6b0b2be253baf13e545c2 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
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -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.r.nodes.attributes.SpecialAttributesFunctions.GetClassAttributeNode;
 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;
@@ -29,7 +30,6 @@ import com.oracle.truffle.r.nodes.unary.TypeofNodeGen;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -51,8 +51,6 @@ public abstract class UpdateClass extends RBuiltinNode {
     @Child private TypeofNode typeof;
     @Child private SetClassAttributeNode setClassAttrNode = SetClassAttributeNode.create();
 
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
     @Override
     protected void createCasts(CastBuilder casts) {
         casts.arg("x"); // disallows null
@@ -70,19 +68,21 @@ public abstract class UpdateClass extends RBuiltinNode {
     @Specialization(limit = "CACHE_LIMIT", guards = "cachedClassName == className")
     protected Object setClassCached(RAbstractContainer arg, @SuppressWarnings("unused") String className, //
                     @Cached("className") String cachedClassName, //
-                    @Cached("fromMode(className)") RType cachedMode) {
-        return setClassInternal(arg, cachedClassName, cachedMode);
+                    @Cached("fromMode(className)") RType cachedMode,
+                    @Cached("create()") GetClassAttributeNode getClassNode) {
+        return setClassInternal(arg, cachedClassName, cachedMode, getClassNode);
     }
 
     @Specialization(contains = "setClassCached")
     protected Object setClass(RAbstractContainer arg, String className, //
-                    @Cached("create()") TypeFromModeNode typeFromMode) {
+                    @Cached("create()") TypeFromModeNode typeFromMode,
+                    @Cached("create()") GetClassAttributeNode getClassNode) {
         RType mode = typeFromMode.execute(className);
-        return setClassInternal(arg, className, mode);
+        return setClassInternal(arg, className, mode, getClassNode);
     }
 
-    private Object setClassInternal(RAbstractContainer arg, String className, RType mode) {
-        if (!arg.isObject(attrProfiles)) {
+    private Object setClassInternal(RAbstractContainer arg, String className, RType mode, GetClassAttributeNode getClassNode) {
+        if (!getClassNode.isObject(arg)) {
             initTypeof();
             RType argType = typeof.execute(arg);
             if (argType.equals(className) || (mode == RType.Double && (argType == RType.Integer || argType == RType.Double))) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java
index 329730c362cfc6ee005247514fa33506811d928e..472dc7388aede531c59cf4a9ac9e43687ebaacab 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -17,6 +17,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.attributes.RemoveFixedAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -24,7 +25,6 @@ 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.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.RVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
@@ -37,12 +37,15 @@ public abstract class UpdateLevels extends RBuiltinNode {
         casts.arg("value").allowNull().asVector(false);
     }
 
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+    protected RemoveFixedAttributeNode createRemoveAttrNode() {
+        return RemoveFixedAttributeNode.create(RRuntime.LEVELS_ATTR_KEY);
+    }
 
     @Specialization
-    protected RAbstractVector updateLevels(RAbstractVector vector, @SuppressWarnings("unused") RNull levels) {
+    protected RAbstractVector updateLevels(RAbstractVector vector, @SuppressWarnings("unused") RNull levels,
+                    @Cached("createRemoveAttrNode()") RemoveFixedAttributeNode removeAttrNode) {
         RVector<?> v = (RVector<?>) vector.getNonShared();
-        v.removeAttr(attrProfiles, RRuntime.LEVELS_ATTR_KEY);
+        removeAttrNode.execute(v);
         return v;
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AnyVectorToStringVectorWriter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AnyVectorToStringVectorWriter.java
index c556c9894e44b8a315d46d8ecd3f55cc0f85fca2..3e0b1acd76e8b16ad4d795c12c0b7d648b0c20ba 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AnyVectorToStringVectorWriter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AnyVectorToStringVectorWriter.java
@@ -26,7 +26,7 @@ import java.io.IOException;
 import java.io.Writer;
 import java.util.Arrays;
 
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.data.RAttributeStorage;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RStringVector;
@@ -40,8 +40,6 @@ public class AnyVectorToStringVectorWriter extends Writer implements PrettyWrite
     private int levelCounter = 0;
     private boolean addSpaces;
 
-    private static final RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create();
-
     @Override
     public void begin(Object value) {
         levelCounter++;
@@ -117,13 +115,14 @@ public class AnyVectorToStringVectorWriter extends Writer implements PrettyWrite
     }
 
     @Override
+    @TruffleBoundary
     public RStringVector getPrintReport() {
         RStringVector sv = RDataFactory.createStringVector(stringElements, vector.isComplete());
         if (vector.getDimensions() != null) {
             sv.setDimensions(vector.getDimensions());
-            sv.setDimNames(vector.getDimNames(dummyAttrProfiles));
+            sv.setDimNames(vector.getDimNames());
         } else {
-            sv.setNames(vector.getNames(dummyAttrProfiles));
+            sv.setNames(vector.getNames());
         }
         return sv;
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AttributesPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AttributesPrinter.java
index 2642d0756547017c4af5f08670a55b78afbf00f4..785cf3c27351237d39f0f91cd62ea00901050e91 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AttributesPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AttributesPrinter.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995, 1996  Robert Gentleman and Ross Ihaka
  * Copyright (c) 1997-2013,  The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -20,7 +20,6 @@ import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 
 //Transcribed from GnuR, src/main/print.c
@@ -29,8 +28,6 @@ final class AttributesPrinter implements ValuePrinter<RAttributable> {
 
     static final AttributesPrinter INSTANCE = new AttributesPrinter(false);
 
-    private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create();
-
     private final boolean useSlots;
 
     private AttributesPrinter(boolean useSlots) {
@@ -100,7 +97,7 @@ final class AttributesPrinter implements ValuePrinter<RAttributable> {
                 S4ObjectPrinter.printS4(printCtx, a.getValue());
                 // throw new UnsupportedOperationException("TODO");
             } else {
-                if (a.getValue() instanceof RAttributable && ((RAttributable) a.getValue()).isObject(dummyAttrProfiles)) {
+                if (a.getValue() instanceof RAttributable && ((RAttributable) a.getValue()).isObject()) {
                     RContext.getEngine().printResult(a.getValue());
                 } else {
                     ValuePrinters.INSTANCE.print(a.getValue(), printCtx);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java
index 9cbb2a9c13abdb8102a4f3d5ffb622989a457e23..3b73b818581de8d060ad6627c2e4f3f225fed12b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -26,7 +26,6 @@ import java.io.IOException;
 import java.io.PrintWriter;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RFactor;
 import com.oracle.truffle.r.runtime.data.RVector;
 import com.oracle.truffle.r.runtime.data.closures.RClosures;
@@ -41,8 +40,6 @@ final class FactorPrinter extends AbstractValuePrinter<RAbstractIntVector> {
         // singleton
     }
 
-    @SuppressWarnings("unused") private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create();
-
     @Override
     @TruffleBoundary
     protected void printValue(RAbstractIntVector operand, PrintContext printCtx) throws IOException {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java
index 62a994e753e86d30a52158f32994a1dbba4891ae..c86cafe1db361ba2bd4ca6db5f6b5abe9442a0bf 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995, 1996  Robert Gentleman and Ross Ihaka
  * Copyright (c) 1997-2013,  The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -24,7 +24,6 @@ import com.oracle.truffle.r.runtime.RDeparse;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLanguage;
@@ -44,7 +43,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
 
     static final ListPrinter INSTANCE = new ListPrinter();
-    private static final RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create();
 
     private ListPrinter() {
         // singleton
@@ -66,6 +64,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
         }
     }
 
+    @TruffleBoundary
     private static void printDimList(RAbstractListVector s, PrintContext printCtx) throws IOException {
         final PrintParameters pp = printCtx.parameters();
 
@@ -170,7 +169,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> {
         int ns = s.getLength();
 
         RAbstractStringVector names;
-        names = Utils.castTo(RRuntime.asAbstractVector(s.getNames(dummyAttrProfiles)));
+        names = Utils.castTo(RRuntime.asAbstractVector(s.getNames()));
 
         if (ns > 0) {
             int npr = (ns <= pp.getMax() + 1) ? ns : pp.getMax();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java
index 7448ebc7516c8ea623afd1c3ca912f86528212e5..054694527590d54bc10a70afcb427ac8d5a1c36a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -56,7 +56,6 @@ import com.oracle.truffle.r.runtime.RError;
 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.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributeStorage;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -356,7 +355,7 @@ public final class ValuePrinterNode extends RBaseNode {
                         }
 
                         @Override
-                        public RStringVector getNames(RAttributeProfiles attrProfiles) {
+                        public RStringVector getNames() {
                             return names;
                         }
 
@@ -537,7 +536,7 @@ public final class ValuePrinterNode extends RBaseNode {
         }
 
         @Override
-        public RStringVector getNames(RAttributeProfiles attrProfiles) {
+        public RStringVector getNames() {
             return null;
         }
 
@@ -547,7 +546,7 @@ public final class ValuePrinterNode extends RBaseNode {
         }
 
         @Override
-        public RList getDimNames(RAttributeProfiles attrProfiles) {
+        public RList getDimNames() {
             return null;
         }
 
@@ -557,7 +556,7 @@ public final class ValuePrinterNode extends RBaseNode {
         }
 
         @Override
-        public Object getRowNames(RAttributeProfiles attrProfiles) {
+        public Object getRowNames() {
             return null;
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java
index aa6cd266a90167869b79d0974c54fd6fca3228ca..dfa54ca7918858defa742bee17d5b510b23d9433 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -26,6 +26,7 @@ import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -86,7 +87,7 @@ final class ValuePrinters implements ValuePrinter<Object> {
             x = printCtx.printerNode().boxPrimitive(x);
             ValuePrinter printer = printers.get(x.getClass());
             if (printer == null) {
-                if (x instanceof RAbstractIntVector && ((RAttributable) x).hasClass(RRuntime.CLASS_FACTOR)) {
+                if (x instanceof RAbstractIntVector && hasClass(x)) {
                     printer = FactorPrinter.INSTANCE;
                 } else if (x instanceof RAbstractStringVector) {
                     printer = StringVectorPrinter.INSTANCE;
@@ -115,6 +116,11 @@ final class ValuePrinters implements ValuePrinter<Object> {
         }
     }
 
+    @TruffleBoundary
+    private static boolean hasClass(Object x) {
+        return ((RAttributable) x).hasClass(RRuntime.CLASS_FACTOR);
+    }
+
     public static void printNewLine(PrintContext printCtx) {
         if (!Boolean.TRUE.equals(printCtx.getAttribute(DONT_PRINT_NL_ATTR))) {
             printCtx.output().println();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java
index 5577dd7c283cd4f934d3edcdee26c1a71687af24..1415244a6ac382626e0a2ce9bc137ad67b8d8b7e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995, 1996  Robert Gentleman and Ross Ihaka
  * Copyright (c) 1997-2013,  The R Core Team
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -17,6 +17,7 @@ import static com.oracle.truffle.r.nodes.builtin.base.printer.Utils.indexWidth;
 import java.io.IOException;
 import java.io.PrintWriter;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -74,11 +75,11 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri
 
             MatrixDimNames mdn = null;
 
-            Object dimAttr = vector.getAttr(RRuntime.DIM_ATTR_KEY);
+            Object dimAttr = getDims(vector);
             if (dimAttr instanceof RAbstractIntVector) {
                 dims = (RAbstractIntVector) dimAttr;
                 if (dims.getLength() == 1) {
-                    RList t = Utils.<RList> castTo(vector.getAttr(RRuntime.DIMNAMES_ATTR_KEY));
+                    RList t = Utils.<RList> castTo(getDimNames(vector));
                     if (t != null && t.getDataAt(0) != null) {
                         RAbstractStringVector nn = Utils.castTo(RRuntime.asAbstractVector(t.getNames()));
 
@@ -108,7 +109,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri
                 }
             } else {
                 dims = null;
-                Object namesAttr = Utils.castTo(vector.getAttr(RRuntime.NAMES_ATTR_KEY));
+                Object namesAttr = Utils.castTo(getNames(vector));
                 if (namesAttr != null) {
                     if (vector.getLength() > 0) {
                         names = Utils.castTo(RRuntime.asAbstractVector(namesAttr));
@@ -673,7 +674,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri
         final RAbstractStringVector axisNames;
 
         MatrixDimNames(RAbstractVector x) {
-            dimnames = Utils.<RList> castTo(x.getAttr(RRuntime.DIMNAMES_ATTR_KEY));
+            dimnames = Utils.<RList> castTo(getDimNames(x));
 
             if (dimnames == null) {
                 rl = null;
@@ -702,4 +703,19 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri
             return dimLevel < dimnames.getLength() ? Utils.castTo(RRuntime.asAbstractVector(dimnames.getDataAt(dimLevel))) : null;
         }
     }
+
+    @TruffleBoundary
+    private static Object getDims(RAbstractVector v) {
+        return v.getAttr(RRuntime.DIM_ATTR_KEY);
+    }
+
+    @TruffleBoundary
+    private static Object getDimNames(RAbstractVector x) {
+        return x.getAttr(RRuntime.DIMNAMES_ATTR_KEY);
+    }
+
+    @TruffleBoundary
+    private static Object getNames(RAbstractVector vector) {
+        return vector.getAttr(RRuntime.NAMES_ATTR_KEY);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java
index feed03a995c0cd4b41744f860b91bc34eae25467..3ab1c524bd645a7433532a374d2ece8a840d099b 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java
@@ -45,7 +45,6 @@ import com.oracle.truffle.r.nodes.test.TestBase;
 import com.oracle.truffle.r.nodes.test.TestUtilities.NodeHandle;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RInteger;
 import com.oracle.truffle.r.runtime.data.RLogical;
@@ -189,7 +188,7 @@ public class ExtractVectorNodeTest extends TestBase {
         vector.setNames(names);
         RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(2));
 
-        RStringVector newNames = result.getNames(RAttributeProfiles.create());
+        RStringVector newNames = result.getNames();
         assertThat(newNames.getLength(), is(1));
         assertThat(newNames.getDataAt(0), is(names.getDataAt(1)));
     }
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNodeTest.java
index dc19ae2b7b5e40e01d991a7f955bf7002ac7a76a..8884df7446550e5f95b01546f691a4d2ecae6d0c 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNodeTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNodeTest.java
@@ -46,7 +46,6 @@ import com.oracle.truffle.r.nodes.test.TestBase;
 import com.oracle.truffle.r.nodes.test.TestUtilities.NodeHandle;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RInteger;
 import com.oracle.truffle.r.runtime.data.RLogical;
@@ -179,7 +178,7 @@ public class ReplaceVectorNodeTest extends TestBase {
 
         RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, value, RLogical.TRUE);
 
-        RStringVector newNames = result.getNames(RAttributeProfiles.create());
+        RStringVector newNames = result.getNames();
         assertThat(newNames.getLength(), is(names.getLength()));
         assertThat(newNames.getDataAt(0), is(names.getDataAt(0)));
         assertThat(newNames.getDataAt(1), is(names.getDataAt(1)));
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java
index 1330c6f54b2556920131be33fd8a92ba425367df..f7ccff7b8f7bd9a25acb213a673153795ea78f32 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -68,7 +68,7 @@ class DefaultArgsExtractor {
 
             if (defArgVal.get() instanceof RPairList) {
                 RPairList formals = (RPairList) defArgVal.get();
-                RStringVector names = formals.getNames(null);
+                RStringVector names = formals.getNames();
 
                 for (int i = 0; i < names.getLength(); i++) {
                     String name = names.getDataAt(i);
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 6b0743a08d06e22bd1666b8304b55b9b07e169a6..81c6c2ef97eebefb8c5efa7a355bd814bf556d83 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
@@ -6,7 +6,7 @@
  * Copyright (c) 1995, 1996, 1997  Robert Gentleman and Ross Ihaka
  * Copyright (c) 1995-2014, The R Core Team
  * Copyright (c) 2002-2008, The R Foundation
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -22,6 +22,7 @@ import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.RASTUtils;
 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.ClassHierarchyNode;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen;
 import com.oracle.truffle.r.nodes.unary.TypeofNode;
@@ -32,7 +33,6 @@ 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.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RStringVector;
@@ -54,7 +54,6 @@ public abstract class AccessSlotNode extends RNode {
     @Child private ClassHierarchyNode classHierarchy;
     @Child private TypeofNode typeofNode;
 
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
     private final BranchProfile noSlot = BranchProfile.create();
     private final BranchProfile symbolValue = BranchProfile.create();
     private final boolean asOperator;
@@ -67,7 +66,7 @@ public abstract class AccessSlotNode extends RNode {
         return GetAttributeNode.create();
     }
 
-    private Object getSlotS4Internal(RAttributable object, String name, Object value) {
+    private Object getSlotS4Internal(RAttributable object, String name, Object value, GetClassAttributeNode getClassNode) {
         if (value == null) {
             noSlot.enter();
             assert Utils.isInterned(name);
@@ -87,7 +86,7 @@ public abstract class AccessSlotNode extends RNode {
                 return RNull.instance;
             }
 
-            RStringVector classAttr = object.getClassAttr(attrProfiles);
+            RStringVector classAttr = getClassNode.getClassAttr(object);
             if (classAttr == null) {
                 if (typeofNode == null) {
                     CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -115,10 +114,11 @@ public abstract class AccessSlotNode extends RNode {
     @Specialization(guards = {"slotAccessAllowed(object)"})
     protected Object getSlotS4Cached(RAttributable object, String name,
                     @Cached("createAttrAccess()") GetAttributeNode attrAccess, //
-                    @Cached("create()") InitAttributesNode initAttrNode) {
+                    @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);
+        return getSlotS4Internal(object, internedName, value, getClassNode);
     }
 
     @TruffleBoundary
@@ -140,8 +140,8 @@ public abstract class AccessSlotNode extends RNode {
     // this is really a fallback specialization but @Fallback does not work here (because of the
     // type of "object"?)
     @Specialization(guards = {"!slotAccessAllowed(object)", "!isDotData(name)"})
-    protected Object getSlot(RAttributable object, String name) {
-        RStringVector classAttr = object.getClassAttr(attrProfiles);
+    protected Object getSlot(RAttributable object, String name, @Cached("create()") GetClassAttributeNode getClassNode) {
+        RStringVector classAttr = getClassNode.getClassAttr(object);
         if (classAttr == null) {
             RStringVector implicitClassVec = object.getImplicitClass();
             assert implicitClassVec.getLength() > 0;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
index 85dcea77b1c86b3275668ad63b373fa3f24ac1fa..0a70b646516a39021a6709818020b48120918378 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
@@ -43,7 +43,6 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.context.RContext;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLanguage;
@@ -240,9 +239,9 @@ final class CachedExtractVectorNode extends CachedVectorNode {
              * the primitive value from the vector. This branch has to fold to a constant because we
              * want to avoid the toggling of the return types depending on input values.
              */
-            assert extractedVector.getNames(RAttributeProfiles.create()) == null;
+            assert extractedVector.getNames() == null;
             assert extractedVector.getDimensions() == null;
-            assert extractedVector.getDimNames(null) == null;
+            assert extractedVector.getDimNames() == null;
             return extractedVector.getDataAtAsObject(0);
         }
         return extractedVector;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
index a7c9dee70e9e192371a8479730adbc0d96baa1a0..d1453fcae8e2071afd83f0180bdb97fa1ef5c814 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
@@ -50,7 +50,6 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.context.RContext;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLanguage;
@@ -80,7 +79,6 @@ final class CachedReplaceVectorNode extends CachedVectorNode {
     private final VectorLengthProfile targetLengthProfile = VectorLengthProfile.create();
     private final VectorLengthProfile valueLengthProfile = VectorLengthProfile.create();
     private final BranchProfile warningBranch = BranchProfile.create();
-    private final RAttributeProfiles vectorNamesProfile = RAttributeProfiles.create();
     private final ConditionProfile valueIsNA = ConditionProfile.createBinaryProfile();
     private final BranchProfile resizeProfile = BranchProfile.create();
     private final BranchProfile sharedProfile = BranchProfile.create();
@@ -542,7 +540,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode {
     // its not yet worth compiling it we need a better attribute system
     @TruffleBoundary
     private RVector<?> resizeVector(RAbstractVector vector, int size) {
-        RStringVector oldNames = vector.getNames(vectorNamesProfile);
+        RStringVector oldNames = vector.getNames();
         RVector<?> res = vector.copyResized(size, true).materialize();
         if (vector instanceof RVector) {
             res.copyAttributesFrom(vector);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveAttributeNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7556cd1613c14159e1d1e8ca7310a8241ab76976
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveAttributeNode.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017, 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.attributes;
+
+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.object.DynamicObject;
+import com.oracle.truffle.api.object.Location;
+import com.oracle.truffle.api.object.Shape;
+import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.runtime.data.RAttributable;
+import com.oracle.truffle.r.runtime.data.RAttributeStorage;
+
+public abstract class RemoveAttributeNode extends AttributeAccessNode {
+
+    @Child RemoveAttributeNode recursive;
+
+    protected RemoveAttributeNode() {
+    }
+
+    public static RemoveAttributeNode create() {
+        return RemoveAttributeNodeGen.create();
+    }
+
+    public abstract void execute(Object attrs, String name);
+
+    @Specialization(limit = "3", //
+                    guards = {
+                                    "cachedName.equals(name)",
+                                    "shapeCheck(shape, attrs)",
+                                    "location == null"
+                    }, //
+                    assumptions = {
+                                    "shape.getValidAssumption()"
+                    })
+    @SuppressWarnings("unused")
+    protected void removeNonExistantAttr(DynamicObject attrs, String name,
+                    @Cached("name") String cachedName,
+                    @Cached("lookupShape(attrs)") Shape shape,
+                    @Cached("lookupLocation(shape, cachedName)") Location location) {
+        // do nothing
+    }
+
+    @Specialization
+    @TruffleBoundary
+    protected void removeAttrFallback(DynamicObject attrs, String name) {
+        attrs.delete(name);
+    }
+
+    @Specialization
+    protected void removeAttrFromAttributable(RAttributable x, String name,
+                    @Cached("create()") BranchProfile attrNullProfile,
+                    @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                    @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                    @Cached("create()") BranchProfile emptyAttrProfile) {
+        DynamicObject attributes;
+        if (attrStorageProfile.profile(x instanceof RAttributeStorage)) {
+            attributes = ((RAttributeStorage) x).getAttributes();
+        } else {
+            attributes = xTypeProfile.profile(x).getAttributes();
+        }
+
+        if (attributes == null) {
+            attrNullProfile.enter();
+            return;
+        }
+
+        if (recursive == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            recursive = insert(create());
+        }
+
+        recursive.execute(attributes, name);
+
+        if (attributes.isEmpty()) {
+            emptyAttrProfile.enter();
+            x.initAttributes(null);
+        }
+
+    }
+
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java
index b9c737057e670e1ed1d3938bbedabf588c48c737..f2cffdb68baf38fe5996a37d4cc3f2bebebbee73 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.attributes;
 
+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;
@@ -40,6 +41,8 @@ import com.oracle.truffle.r.runtime.data.RAttributeStorage;
 
 public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode {
 
+    @Child RemoveFixedAttributeNode recursive;
+
     protected RemoveFixedAttributeNode(String name) {
         super(name);
     }
@@ -89,7 +92,8 @@ public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode
     protected void removeAttrFromAttributable(RAttributable x,
                     @Cached("create()") BranchProfile attrNullProfile,
                     @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                    @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+                    @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                    @Cached("create()") BranchProfile emptyAttrProfile) {
         DynamicObject attributes;
         if (attrStorageProfile.profile(x instanceof RAttributeStorage)) {
             attributes = ((RAttributeStorage) x).getAttributes();
@@ -102,7 +106,18 @@ public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode
             return;
         }
 
-        removeAttrFallback(attributes);
+        if (recursive == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            recursive = insert(create(name));
+        }
+
+        recursive.execute(attributes);
+
+        if (attributes.isEmpty()) {
+            emptyAttrProfile.enter();
+            x.initAttributes(null);
+        }
+
     }
 
 }
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 8db25088fa1a830d58a8a2797c953d2052f2511a..c704588bb64b8d3b0a50369c98dbd9202fa57fe4 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
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.nodes.attributes;
 
 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.object.DynamicObject;
@@ -35,8 +36,8 @@ import com.oracle.truffle.r.nodes.function.opt.ShareObjectNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RIntVector;
@@ -305,6 +306,18 @@ public final class SpecialAttributesFunctions {
             }
         }
 
+        @Specialization(insertBefore = "setAttrInAttributable")
+        protected void setNamesInLanguage(RLanguage x, RStringVector newNames,
+                        @Cached("createBinaryProfile()") ConditionProfile pairListProfile) {
+            RPairList pl = x.getPairListInternal();
+            if (pairListProfile.profile(pl == null)) {
+                /* See getNames */
+                RContext.getRRuntimeASTAccess().setNames(x, newNames);
+            } else {
+                pl.setNames(newNames);
+            }
+        }
+
         @Specialization(insertBefore = "setAttrInAttributable")
         protected void resetDimNames(RAbstractContainer x, @SuppressWarnings("unused") RNull rnull,
                         @Cached("create()") RemoveNamesAttributeNode removeNamesAttrNode) {
@@ -349,6 +362,7 @@ public final class SpecialAttributesFunctions {
         }
 
         @Specialization(insertBefore = "setAttrInAttributable", guards = "!isRAbstractVector(x)")
+        @TruffleBoundary
         protected void setNamesInContainer(RAbstractContainer x, RStringVector newNames,
                         @Cached("createClassProfile()") ValueProfile contClassProfile) {
             RAbstractContainer xProfiled = contClassProfile.profile(x);
@@ -387,6 +401,40 @@ public final class SpecialAttributesFunctions {
             return (RStringVector) execute(x);
         }
 
+        @Specialization(insertBefore = "getAttrFromAttributable")
+        protected Object getScalarVectorNames(@SuppressWarnings("unused") RScalarVector x) {
+            return null;
+        }
+
+        @Specialization(insertBefore = "getAttrFromAttributable")
+        protected Object getPairListNames(RPairList x) {
+            return x.getNames();
+        }
+
+        @Specialization(insertBefore = "getAttrFromAttributable")
+        protected Object getSequenceVectorNames(@SuppressWarnings("unused") RSequence x) {
+            return null;
+        }
+
+        @Specialization(insertBefore = "getAttrFromAttributable")
+        protected Object getLanguageNames(RLanguage x,
+                        @Cached("createBinaryProfile()") ConditionProfile pairListProfile) {
+            RPairList pl = x.getPairListInternal();
+            if (pairListProfile.profile(pl == null)) {
+                /*
+                 * "names" for a language object is a special case, that is applicable to calls and
+                 * returns the names of the actual arguments, if any. E.g. f(x=1, 3) would return
+                 * c("", "x", ""). GnuR defines it as returning the "tag" values on the pairlist
+                 * that represents the call. Well, we don't have a pairlist, (we could get one by
+                 * serializing the expression), so we do it by AST walking.
+                 */
+                RStringVector names = RContext.getRRuntimeASTAccess().getNames(x);
+                return names;
+            } else {
+                return pl.getNames();
+            }
+        }
+
         @Specialization(insertBefore = "getAttrFromAttributable")
         protected Object getVectorNames(RAbstractVector x,
                         @Cached("create()") BranchProfile attrNullProfile,
@@ -409,10 +457,10 @@ public final class SpecialAttributesFunctions {
         }
 
         @Specialization(insertBefore = "getAttrFromAttributable", guards = "!isRAbstractVector(x)")
+        @TruffleBoundary
         protected Object getVectorNames(RAbstractContainer x,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
-                        @Cached("create()") RAttributeProfiles attrProfiles) {
-            return xTypeProfile.profile(x).getNames(attrProfiles);
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+            return xTypeProfile.profile(x).getNames();
         }
     }
 
@@ -694,6 +742,18 @@ public final class SpecialAttributesFunctions {
             removeDimNamesAttrNode.execute(x);
         }
 
+        @Specialization(insertBefore = "setAttrInAttributable")
+        protected void setDimNamesInLanguage(RLanguage x, RAbstractVector newDimNames,
+                        @Cached("createBinaryProfile()") ConditionProfile pairListProfile,
+                        @Cached("create()") BranchProfile attrNullProfile,
+                        @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                        @Cached("createClassProfile()") ValueProfile typeProfile,
+                        @Cached("create()") ShareObjectNode updateRefCountNode) {
+            RPairList pl = x.getPairListInternal();
+            RAttributable attr = pairListProfile.profile(pl == null) ? x : pl;
+            setAttrInAttributable(attr, newDimNames, attrNullProfile, attrStorageProfile, typeProfile, updateRefCountNode);
+        }
+
         @Specialization(insertBefore = "setAttrInAttributable")
         protected void setDimNamesInVector(RVector<?> x, RList newDimNames,
                         @Cached("create()") GetDimAttributeNode getDimNode,
@@ -763,6 +823,7 @@ public final class SpecialAttributesFunctions {
         }
 
         @Specialization(insertBefore = "setAttrInAttributable")
+        @TruffleBoundary
         protected void setDimNamesInContainer(RAbstractContainer x, RList dimNames, @Cached("createClassProfile()") ValueProfile contClassProfile) {
             RAbstractContainer xProfiled = contClassProfile.profile(x);
             xProfiled.setDimNames(dimNames);
@@ -801,6 +862,24 @@ public final class SpecialAttributesFunctions {
             return (RList) execute(x);
         }
 
+        @Specialization(insertBefore = "getAttrFromAttributable")
+        protected Object getVectorDimNames(@SuppressWarnings("unused") RPairList x) {
+            return null;
+        }
+
+        @Specialization(insertBefore = "getAttrFromAttributable")
+        protected Object getLanguageDimNames(RLanguage x,
+                        @Cached("createBinaryProfile()") ConditionProfile pairListProfile,
+                        @Cached("create()") BranchProfile attrNullProfile,
+                        @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
+                        @Cached("createBinaryProfile()") ConditionProfile nullRowNamesProfile) {
+            RPairList pl = x.getPairListInternal();
+            RAttributable attr = pairListProfile.profile(pl == null) ? x : pl;
+            Object res = super.getAttrFromAttributable(attr, attrNullProfile, attrStorageProfile, xTypeProfile);
+            return nullRowNamesProfile.profile(res == null) ? RNull.instance : res;
+        }
+
         @Specialization(insertBefore = "getAttrFromAttributable")
         protected Object getVectorDimNames(RAbstractVector x,
                         @Cached("create()") BranchProfile attrNullProfile,
@@ -810,10 +889,10 @@ public final class SpecialAttributesFunctions {
         }
 
         @Specialization(insertBefore = "getAttrFromAttributable", guards = "!isRAbstractVector(x)")
+        @TruffleBoundary
         protected Object getVectorDimNames(RAbstractContainer x,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
-                        @Cached("create()") RAttributeProfiles attrProfiles) {
-            return xTypeProfile.profile(x).getDimNames(attrProfiles);
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+            return xTypeProfile.profile(x).getDimNames();
         }
 
     }
@@ -844,6 +923,18 @@ public final class SpecialAttributesFunctions {
             removeRowNamesAttrNode.execute(x);
         }
 
+        @Specialization(insertBefore = "setAttrInAttributable")
+        protected void setRowNamesInLanguage(RLanguage x, RAbstractVector newRowNames,
+                        @Cached("createBinaryProfile()") ConditionProfile pairListProfile,
+                        @Cached("create()") BranchProfile attrNullProfile,
+                        @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                        @Cached("createClassProfile()") ValueProfile typeProfile,
+                        @Cached("create()") ShareObjectNode updateRefCountNode) {
+            RPairList pl = x.getPairListInternal();
+            RAttributable attr = pairListProfile.profile(pl == null) ? x : pl;
+            setAttrInAttributable(attr, newRowNames, attrNullProfile, attrStorageProfile, typeProfile, updateRefCountNode);
+        }
+
         @Specialization(insertBefore = "setAttrInAttributable")
         protected void setRowNamesInVector(RAbstractVector x, RAbstractVector newRowNames,
                         @Cached("create()") BranchProfile attrNullProfile,
@@ -860,6 +951,7 @@ public final class SpecialAttributesFunctions {
         }
 
         @Specialization(insertBefore = "setAttrInAttributable", guards = "!isRAbstractVector(x)")
+        @TruffleBoundary
         protected void setRowNamesInContainer(RAbstractContainer x, RAbstractVector rowNames, @Cached("createClassProfile()") ValueProfile contClassProfile) {
             RAbstractContainer xProfiled = contClassProfile.profile(x);
             xProfiled.setRowNames(rowNames);
@@ -904,25 +996,37 @@ public final class SpecialAttributesFunctions {
         }
 
         @Specialization(insertBefore = "getAttrFromAttributable")
-        protected Object getScalarVectorRowNames(@SuppressWarnings("unused") RSequence x) {
-            return RNull.class;
+        protected Object getSequenceRowNames(@SuppressWarnings("unused") RSequence x) {
+            return RNull.instance;
+        }
+
+        @Specialization(insertBefore = "getAttrFromAttributable")
+        protected Object getLanguageRowNames(RLanguage x,
+                        @Cached("createBinaryProfile()") ConditionProfile pairListProfile,
+                        @Cached("create()") BranchProfile attrNullProfile,
+                        @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
+                        @Cached("createBinaryProfile()") ConditionProfile nullRowNamesProfile,
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
+            RPairList pl = x.getPairListInternal();
+            RAttributable attr = pairListProfile.profile(pl == null) ? x : pl;
+            Object res = super.getAttrFromAttributable(attr, attrNullProfile, attrStorageProfile, xTypeProfile);
+            return nullRowNamesProfile.profile(res == null) ? RNull.instance : res;
         }
 
         @Specialization(insertBefore = "getAttrFromAttributable")
         protected Object getVectorRowNames(RAbstractVector x,
                         @Cached("create()") BranchProfile attrNullProfile,
                         @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
-                        @Cached("createBinaryProfile()") ConditionProfile nullRowNamesProfile) {
+                        @Cached("createBinaryProfile()") ConditionProfile nullRowNamesProfile,
+                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
             Object res = super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile);
             return nullRowNamesProfile.profile(res == null) ? RNull.instance : res;
         }
 
         @Specialization(insertBefore = "getAttrFromAttributable")
-        protected Object getVectorRowNames(RAbstractContainer x,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
-                        @Cached("create()") RAttributeProfiles attrProfiles) {
-            return xTypeProfile.profile(x).getRowNames(attrProfiles);
+        @TruffleBoundary
+        protected Object getVectorRowNames(RAbstractContainer x) {
+            return x.getRowNames();
         }
 
     }
@@ -974,7 +1078,7 @@ public final class SpecialAttributesFunctions {
                 updateRefCountNode.execute(classAttr);
             }
             if (nullClassProfile.profile(attrs != null && (classAttr == null || classAttr.getLength() == 0))) {
-                removeAttributeMapping(vector, attrs, removeClassAttrNode);
+                removeClassAttrNode.execute(vector);
             } else if (notNullClassProfile.profile(classAttr != null && classAttr.getLength() != 0)) {
                 for (int i = 0; i < classAttr.getLength(); i++) {
                     String attr = classAttr.getDataAt(i);
@@ -984,7 +1088,6 @@ public final class SpecialAttributesFunctions {
                         if (!initializeAttrs) {
                             super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile, updateRefCountNode);
                         }
-                        // setClassAttrNode.execute(attrs, classAttr);
                         if (vector.getElementClass() != RInteger.class) {
                             // N.B. there used to be conversion to integer under certain
                             // circumstances.
@@ -1006,22 +1109,9 @@ public final class SpecialAttributesFunctions {
         }
 
         @Specialization(insertBefore = "setAttrInAttributable", guards = "!isRAbstractVector(x)")
-        protected void handleAttributable(RAttributable x, @SuppressWarnings("unused") RNull classAttr) {
-            x.setClassAttr(null);
-        }
-
-        @Specialization(insertBefore = "setAttrInAttributable", guards = "!isRAbstractVector(x)")
-        protected void handleAttributable(RAttributable x, RStringVector classAttr) {
-            x.setClassAttr(classAttr);
-        }
-
-        private static void removeAttributeMapping(RAttributable x, DynamicObject attrs, RemoveFixedAttributeNode removeClassAttrNode) {
-            if (attrs != null) {
-                removeClassAttrNode.execute(attrs);
-                if (attrs.isEmpty()) {
-                    x.initAttributes(null);
-                }
-            }
+        protected void handleAttributable(RAttributable x, @SuppressWarnings("unused") RNull classAttr,
+                        @Cached("create()") RemoveClassAttributeNode removeClassNode) {
+            removeClassNode.execute(x);
         }
 
     }
@@ -1054,19 +1144,18 @@ public final class SpecialAttributesFunctions {
             return SpecialAttributesFunctionsFactory.GetClassAttributeNodeGen.create();
         }
 
-        @Specialization(insertBefore = "getAttrFromAttributable")
-        protected Object getVectorClass(RAbstractVector x,
-                        @Cached("create()") BranchProfile attrNullProfile,
-                        @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile) {
-            return super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile);
+        public final RStringVector getClassAttr(Object x) {
+            return (RStringVector) execute(x);
         }
 
-        @Specialization(insertBefore = "getAttrFromAttributable", guards = "!isRAbstractVector(x)")
-        protected Object getVectorClass(RAbstractContainer x,
-                        @Cached("createClassProfile()") ValueProfile xTypeProfile,
-                        @Cached("create()") RAttributeProfiles attrProfiles) {
-            return xTypeProfile.profile(x).getClassAttr(attrProfiles);
+        public final boolean isObject(Object x) {
+            return getClassAttr(x) != null ? true : false;
+        }
+
+        public final RStringVector getClassHierarchy(RAttributable x) {
+            Object v = execute(x);
+            RStringVector result = v instanceof RStringVector ? (RStringVector) v : x.getImplicitClass();
+            return result != null ? result : RDataFactory.createEmptyStringVector();
         }
 
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/package-info.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/package-info.java
index 5a5064daa93dc0ec7b843d10d725a50605b02680..9ef224784b2918f8e9635c26fd6d217e7668bae0 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/package-info.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/package-info.java
@@ -39,6 +39,8 @@
  * arbitrary attribute. If the first argument is an instance
  * {@link com.oracle.truffle.r.runtime.data.RAttributable}, the node initializes the object with the
  * empty attributes.
+ * <li>{@link com.oracle.truffle.r.nodes.attributes.RemoveAttributeNode}: removes an arbitrary
+ * attribute, if any.
  * </ul>
  *
  * <h3>Fixed attribute nodes</h3> The nodes in this group operate on the attribute that is specified
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java
index 385e36f70eba6ff3c170d8cb12447f3372604430..7dab79c0e30abdb9bbedfdb426db9dafc9e4fa36 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -24,7 +24,6 @@ package com.oracle.truffle.r.nodes.builtin;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
@@ -35,14 +34,12 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode;
  */
 public final class RList2EnvNode extends RBaseNode {
 
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
     @TruffleBoundary
     public REnvironment execute(RAbstractListVector list, REnvironment env) {
         if (list.getLength() == 0) {
             return env;
         }
-        RStringVector names = list.getNames(attrProfiles);
+        RStringVector names = list.getNames();
         if (names == null) {
             throw RError.error(this, RError.Message.LIST_NAMES_SAME_LENGTH);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java
index d7e65298d264c8ceb0b3c8f8d396a69b0df5f19e..6a7d5fa17632485aa4bf2f7d75f8284435146ab3 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -74,6 +74,10 @@ public final class RFactorNodes {
         private final ConditionProfile nonScalarLevels = ConditionProfile.createBinaryProfile();
         private final ConditionProfile stringVectorLevels = ConditionProfile.createBinaryProfile();
 
+        public static GetLevels create() {
+            return new GetLevels();
+        }
+
         /**
          * Returns the levels as a string vector. If the 'levels' attribute is not a string vector a
          * cast is done. May return null, if the 'levels' attribute is not present.
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/AsS4.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/AsS4.java
index c5c2e2f6cf6f847eb167d01dc2ffb58a5693eb50..9daa82af3e5143b1da79fad18d38b3804ba3ccfc 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/AsS4.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/AsS4.java
@@ -6,7 +6,7 @@
  * Copyright (c) 1995, 1996, 1997  Robert Gentleman and Ross Ihaka
  * Copyright (c) 1995-2014, The R Core Team
  * Copyright (c) 2002-2008, The R Foundation
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -16,11 +16,11 @@ import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
+import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetClassAttributeNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.data.RStringVector;
@@ -33,7 +33,7 @@ public abstract class AsS4 extends Node {
 
     private final BranchProfile shareable = BranchProfile.create();
     private final BranchProfile error = BranchProfile.create();
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+    private final GetClassAttributeNode getClassNode = GetClassAttributeNode.create();
 
     @Child private GetS4DataSlot getS4DataSlot;
 
@@ -62,7 +62,7 @@ public abstract class AsS4 extends Node {
                     return value;
                 } else if (complete == 1) {
                     error.enter();
-                    RStringVector classAttr = obj.getClassAttr(attrProfiles);
+                    RStringVector classAttr = getClassNode.getClassAttr(obj);
                     throw RError.error(this, RError.Message.CLASS_INVALID_S3, classAttr == null || classAttr.getLength() == 0 ? RRuntime.STRING_NA : classAttr.getDataAt(0));
                 } else {
                     return obj;
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 ccbd6106a60c14c2ae5b3e0a26a72fde87dc22c4..95fd29c2c776af28bdb963134a6b3b415ca3a22e 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
@@ -38,7 +38,6 @@ import com.oracle.truffle.r.nodes.primitive.UnaryMapNodeFactory.MapUnaryVectorIn
 import com.oracle.truffle.r.nodes.profile.VectorLengthProfile;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RScalarVector;
 import com.oracle.truffle.r.runtime.data.RShareable;
@@ -64,7 +63,6 @@ public final class UnaryMapNode extends RBaseNode {
     private final VectorLengthProfile operandLengthProfile = VectorLengthProfile.create();
     private final ConditionProfile operandIsNAProfile = ConditionProfile.createBinaryProfile();
     private final BranchProfile hasAttributesProfile;
-    private final RAttributeProfiles attrProfiles;
     private final ConditionProfile shareOperand;
 
     // compile-time optimization flags
@@ -85,7 +83,6 @@ public final class UnaryMapNode extends RBaseNode {
 
         // lazily create profiles only if needed to avoid unnecessary allocations
         this.shareOperand = operandVector ? ConditionProfile.createBinaryProfile() : null;
-        this.attrProfiles = mayContainMetadata ? RAttributeProfiles.create() : null;
         this.hasAttributesProfile = mayContainMetadata ? BranchProfile.create() : null;
     }
 
@@ -211,7 +208,7 @@ public final class UnaryMapNode extends RBaseNode {
     @TruffleBoundary
     private void copyAttributesInternal(RVector<?> result, RAbstractVector attributeSource) {
         result.copyRegAttributesFrom(attributeSource);
-        result.copyNamesFrom(attrProfiles, attributeSource);
+        result.copyNamesFrom(attributeSource);
     }
 
     @SuppressWarnings("unused")
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java
index 11fc0d9c9361611a2cf8e797fdf7282527963218..a1e52ad1f1ecc8bc4851017311d51e9009f3b226 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -26,6 +26,7 @@ import static com.oracle.truffle.r.runtime.RDispatch.OPS_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -33,7 +34,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.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -44,6 +44,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
@@ -53,7 +54,6 @@ public abstract class UnaryNotNode extends RBuiltinNode {
     private final NACheck na = NACheck.create();
     private final NAProfile naProfile = NAProfile.create();
     private final ConditionProfile zeroLengthProfile = ConditionProfile.createBinaryProfile();
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
     private static byte not(byte value) {
         return (value == RRuntime.LOGICAL_TRUE ? RRuntime.LOGICAL_FALSE : RRuntime.LOGICAL_TRUE);
@@ -129,7 +129,7 @@ public abstract class UnaryNotNode extends RBuiltinNode {
             }
         }
         RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA());
-        resultVector.copyNamesDimsDimNamesFrom(attrProfiles, vector, this);
+        copyNamesDimsDimNames(vector, resultVector);
         return resultVector;
     }
 
@@ -148,7 +148,7 @@ public abstract class UnaryNotNode extends RBuiltinNode {
             }
         }
         RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA());
-        resultVector.copyNamesDimsDimNamesFrom(attrProfiles, vector, this);
+        copyNamesDimsDimNames(vector, resultVector);
         return resultVector;
     }
 
@@ -167,10 +167,15 @@ public abstract class UnaryNotNode extends RBuiltinNode {
             }
         }
         RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA());
-        resultVector.copyNamesDimsDimNamesFrom(attrProfiles, vector, this);
+        copyNamesDimsDimNames(vector, resultVector);
         return resultVector;
     }
 
+    @TruffleBoundary
+    private void copyNamesDimsDimNames(RAbstractVector vector, RLogicalVector resultVector) {
+        resultVector.copyNamesDimsDimNamesFrom(vector, this);
+    }
+
     @Specialization
     protected RRawVector doRawVector(RRawVector vector) {
         int length = vector.getLength();
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 77b7024330594169c34bfebe20c65f3ceaddf35f..1e9616f6e8e2980452105f5d91536dd91390a54d 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -25,6 +25,7 @@ package com.oracle.truffle.r.runtime.ffi;
 import java.nio.charset.StandardCharsets;
 import java.util.function.Function;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
 import com.oracle.truffle.api.object.DynamicObject;
@@ -364,6 +365,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI {
     }
 
     @Override
+    @TruffleBoundary
     public void Rf_setAttrib(Object obj, Object name, Object val) {
         if (tracer != null) {
             tracer.Rf_setAttrib(obj, name, val);
@@ -379,7 +381,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI {
             }
             nameAsString = nameAsString.intern();
             if (val == RNull.instance) {
-                attrObj.removeAttr(nameAsString);
+                removeAttr(attrObj, nameAsString);
             } else if ("class" == nameAsString) {
                 attrObj.initAttributes().define(nameAsString, val);
             } else {
@@ -388,6 +390,11 @@ public class JavaUpCallsRFFI implements UpCallsRFFI {
         }
     }
 
+    @TruffleBoundary
+    private static void removeAttr(RAttributable a, String name) {
+        a.removeAttr(name);
+    }
+
     public static RStringVector getClassHr(Object v) {
         RStringVector result;
         if (v instanceof RAttributable) {
@@ -541,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) {
@@ -753,6 +765,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI {
     }
 
     @Override
+    @TruffleBoundary
     public int OBJECT(Object x) {
         if (tracer != null) {
             tracer.OBJECT(x);
@@ -1507,6 +1520,7 @@ public class JavaUpCallsRFFI implements UpCallsRFFI {
     }
 
     @Override
+    @TruffleBoundary
     public Object Rf_classgets(Object x, Object y) {
         if (tracer != null) {
             tracer.Rf_classgets(x, y);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
index 7b1f94e0f16223e3ace87561049a8e541501a391..9ea7f2f3880b01aa0a49b411257f50b9c50a5525 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -23,7 +23,6 @@ import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute;
 import com.oracle.truffle.r.runtime.data.RComplex;
@@ -61,8 +60,6 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor;
  */
 public class RDeparse {
 
-    private static final RAttributeProfiles DUMMY_ATTR_PROFILES = RAttributeProfiles.create();
-
     public static final int KEEPINTEGER = 1;
     public static final int QUOTEEXPRESSIONS = 2;
     public static final int SHOWATTRIBUTES = 4;
@@ -874,7 +871,7 @@ public class RDeparse {
         private DeparseVisitor appendListContents(RAbstractVector v) {
             int n = v.getLength();
             boolean lbreak = false;
-            Object names = v.getNames(DUMMY_ATTR_PROFILES);
+            Object names = v.getNames();
             RStringVector snames = names == RNull.instance ? null : (RStringVector) names;
             for (int i = 0; i < n; i++) {
                 if (i > 0) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java
index 6bba048cb6b84e38b5bd1f030abb5c25ea0924a0..fb962d532743cc97d68c4e90fd3bb4e985d0abd7 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java
@@ -309,13 +309,18 @@ public class RErrorHandling {
         } else if (i == 1) {
             Object[] data = new Object[]{"abort", RNull.instance};
             RList result = RDataFactory.createList(data);
-            result.setClassAttr(RESTART_CLASS);
+            setClassAttr(result);
             return result;
         } else {
             return RNull.instance;
         }
     }
 
+    @TruffleBoundary
+    private static void setClassAttr(RList result) {
+        result.setClassAttr(RESTART_CLASS);
+    }
+
     public static Object invokeRestart(RList restart, Object args) {
         ContextStateImpl errorHandlingState = getRErrorHandlingState();
         Object exit = restartExit(restart);
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 ea4b1ef78ecb089c201293265209f913f7c82dd5..babe770339419589c084e9006cdd0f1ed434b69e 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
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -804,6 +804,7 @@ public class RRuntime {
      * Returns {@code true} if the given object is R object and its class attribute contains given
      * class.
      */
+    @TruffleBoundary
     public static boolean hasRClass(Object obj, String rclassName) {
         return obj instanceof RAttributable && ((RAttributable) obj).hasClass(rclassName);
     }
@@ -867,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();
             }
@@ -880,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 {
@@ -895,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/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
index 156ab436c3abca2700e2169928fac1b40e075b29..a02451ec0ba66ab803163bf597c9c6b7284c5502 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
@@ -39,7 +39,6 @@ import com.oracle.truffle.r.runtime.conn.RConnection;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RAttributable;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RComplexVector;
@@ -846,6 +845,7 @@ public class RSerialize {
          * unusable, so we don't go to the trouble of converting the {@link RIntVector}
          * representation into an {@link RConnection}.
          */
+        @TruffleBoundary
         private static Object setAttributes(final Object object, Object attr) {
             RAttributable rAttributable = (RAttributable) object;
             RPairList pl = (RPairList) attr;
@@ -1371,11 +1371,10 @@ public class RSerialize {
             }
         }
 
-        private static final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
+        @TruffleBoundary
         private static boolean isObject(Object obj) {
             if (obj instanceof RAttributable) {
-                return ((RAttributable) obj).isObject(attrProfiles);
+                return ((RAttributable) obj).isObject();
             } else {
                 return false;
             }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java
index db3bbbbf036a6e8fa9768d26047bc02f4a035bc2..01fa26e6309fc3813856486d1178c7e193a2b66f 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -28,6 +28,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.runtime.context.RContext;
@@ -209,6 +210,7 @@ public class RSource {
         }
     }
 
+    @TruffleBoundary
     public static Object createSrcRef(SourceSection src) {
         if (src == null) {
             return RNull.instance;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java
index b5143138330b6b01525ea8eba44e9dd9b7adda0c..e52c909053bdcab09bc9948fc8ca76734223400e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2015, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2016, Oracle and/or its affiliates
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -17,6 +17,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.attribute.PosixFileAttributes;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -58,6 +59,7 @@ public class RSrcref {
         return createSrcfile(FileSystems.getDefault().getPath(Utils.tildeExpand(path)));
     }
 
+    @TruffleBoundary
     private static REnvironment createSrcfile(Path path) {
         // A srcref is an environment
         double mtime;
@@ -87,6 +89,7 @@ public class RSrcref {
         return createLloc(ss, createSrcfile(path));
     }
 
+    @TruffleBoundary
     public static RIntVector createLloc(SourceSection ss, REnvironment srcfile) {
         int[] llocData = new int[8];
         int startLine = ss.getStartLine();
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
index 751f209ca90f7dd5ac9bf099d255e6168cb33cb2..f47143a9ed80e0b390153fbfc51fe46f580b2639 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
@@ -472,6 +472,7 @@ public final class Utils {
         }
 
         @Override
+        @TruffleBoundary
         public Frame visitFrame(FrameInstance frameInstance) {
             Frame f = RArguments.unwrap(frameInstance.getFrame(FrameAccess.READ_ONLY, true));
             if (RArguments.isRFrame(f) && RArguments.getFunction(f) != null) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
index 2b36adaa26cf1df40d2f3a85bcb5c7b7174b2674..24ac4f6f07b995b77e842811c8a5c9531dc5e9de 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
@@ -272,6 +272,7 @@ public final class RContext extends ExecutionContext implements TruffleObject {
          * The result is an {@link RList} contain the value, plus an "error" attribute if the
          * evaluation resulted in an error.
          */
+        @TruffleBoundary
         private static RList createEvalResult(PolyglotEngine.Value resultValue) {
             Object result = resultValue.get();
             Object listResult = result;
@@ -292,6 +293,7 @@ public final class RContext extends ExecutionContext implements TruffleObject {
             return list;
         }
 
+        @TruffleBoundary
         public static RList createErrorResult(String errorMsg) {
             RList list = RDataFactory.createList(new Object[]{RRuntime.LOGICAL_NA});
             list.setAttr("error", errorMsg);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java
index 2fcc8fee9eb0465109998dde9517ad8123ffda69..661b24b02db8e595bb4454767d088448bb1aa9e9 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -24,6 +24,8 @@ package com.oracle.truffle.r.runtime.data;
 
 import java.util.Iterator;
 
+import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.env.REnvironment;
@@ -55,6 +57,7 @@ public interface RAttributable extends RTypedValue {
      * Returns the value of the {@code class} attribute or empty {@link RStringVector} if class
      * attribute is not set.
      */
+    @TruffleBoundary
     default RStringVector getClassHierarchy() {
         Object v = getAttr(RRuntime.CLASS_ATTR_KEY);
         RStringVector result = v instanceof RStringVector ? (RStringVector) v : getImplicitClass();
@@ -77,22 +80,11 @@ public interface RAttributable extends RTypedValue {
 
     RStringVector getImplicitClass();
 
-    /**
-     * Get the value of an attribute. Returns {@code null} if not set.
-     */
-    default Object getAttr(RAttributeProfiles profiles, String name) {
-        DynamicObject attributes = getAttributes();
-        if (profiles.attrNullProfile(attributes == null)) {
-            return null;
-        } else {
-            return attributes.get(name);
-        }
-    }
-
     /**
      * Get the value of an attribute. Returns {@code null} if not set.
      */
     default Object getAttr(String name) {
+        CompilerAsserts.neverPartOfCompilation();
         DynamicObject attr = getAttributes();
         return attr == null ? null : attr.get(name);
     }
@@ -102,6 +94,7 @@ public interface RAttributable extends RTypedValue {
      * generic; a class may need to override this to handle certain attributes specially.
      */
     default void setAttr(String name, Object value) {
+        CompilerAsserts.neverPartOfCompilation();
         DynamicObject attributes = getAttributes();
         if (attributes == null) {
             attributes = initAttributes();
@@ -109,27 +102,19 @@ public interface RAttributable extends RTypedValue {
         attributes.define(name, value);
     }
 
-    /**
-     * Remove the attribute {@code name}. No error if {@code name} is not an attribute. This is
-     * generic; a class may need to override this to handle certain attributes specially.
-     */
-    default void removeAttr(RAttributeProfiles profiles, String name) {
-        DynamicObject attributes = getAttributes();
-        if (profiles.attrNullProfile(attributes == null)) {
-            return;
-        } else {
-            attributes.delete(name);
-        }
-    }
-
     default void removeAttr(String name) {
+        CompilerAsserts.neverPartOfCompilation();
         DynamicObject attributes = getAttributes();
         if (attributes != null) {
             attributes.delete(name);
+            if (attributes.isEmpty()) {
+                initAttributes(null);
+            }
         }
     }
 
     default void removeAllAttributes() {
+        CompilerAsserts.neverPartOfCompilation();
         DynamicObject attributes = getAttributes();
         if (attributes != null) {
             RAttributesLayout.clear(attributes);
@@ -152,6 +137,7 @@ public interface RAttributable extends RTypedValue {
     }
 
     default RAttributable setClassAttr(RStringVector classAttr) {
+        CompilerAsserts.neverPartOfCompilation();
         if (classAttr == null && getAttributes() != null) {
             getAttributes().delete(RRuntime.CLASS_ATTR_KEY);
         } else {
@@ -160,10 +146,6 @@ public interface RAttributable extends RTypedValue {
         return this;
     }
 
-    default RStringVector getClassAttr(RAttributeProfiles profiles) {
-        return (RStringVector) getAttr(profiles, RRuntime.CLASS_ATTR_KEY);
-    }
-
     default RStringVector getClassAttr() {
         return (RStringVector) getAttr(RRuntime.CLASS_ATTR_KEY);
     }
@@ -172,10 +154,6 @@ public interface RAttributable extends RTypedValue {
      * Returns {@code true} if and only if the value has a {@code class} attribute added explicitly.
      * When {@code true}, it is possible to call {@link RAttributable#getClassHierarchy()}.
      */
-    default boolean isObject(RAttributeProfiles profiles) {
-        return getClassAttr(profiles) != null ? true : false;
-    }
-
     default boolean isObject() {
         return getClassAttr() != null ? true : false;
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributeProfiles.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributeProfiles.java
deleted file mode 100644
index 72ffa4fe471d2f6cf041c6b12ce1dccd8f08281b..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributeProfiles.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2015, 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.runtime.data;
-
-import com.oracle.truffle.api.profiles.ConditionProfile;
-
-public final class RAttributeProfiles {
-    private final ConditionProfile attrNullProfile = ConditionProfile.createBinaryProfile();
-    private final ConditionProfile attrNullNamesProfile = ConditionProfile.createBinaryProfile();
-
-    private RAttributeProfiles() {
-        // private constructor
-    }
-
-    public boolean attrNullProfile(boolean cond) {
-        return attrNullProfile.profile(cond);
-    }
-
-    public boolean attrNullNamesProfile(boolean cond) {
-        return attrNullNamesProfile.profile(cond);
-    }
-
-    public static RAttributeProfiles create() {
-        return new RAttributeProfiles();
-    }
-}
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..2b81e39bc395502480965538ff0a33044c90487e 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -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;
 
@@ -46,11 +47,13 @@ public class RExpression extends RListBase implements RAbstractVector {
     }
 
     @Override
+    @TruffleBoundary
     protected RExpression internalCopy() {
         return new RExpression(Arrays.copyOf(data, data.length), getDimensions(), null);
     }
 
     @Override
+    @TruffleBoundary
     protected RExpression internalDeepCopy() {
         // TOOD: only used for nested list updates, but still could be made faster (through a
         // separate AST node?)
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java
index 3d7371741262d164a0cdcfba4648e9c701d8d472..3d0746749a6a04225b2d39b7fd2d57a6f48afb92 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -39,14 +39,6 @@ public final class RFactor {
         return getLevelsImpl(factor.getAttr(RRuntime.LEVELS_ATTR_KEY));
     }
 
-    /**
-     * Helper method to get 'levels' of a factor with profile. However, all the invocations of this
-     * method should be replaced with FactorNodes.GetLevel in the future.
-     */
-    public static RVector<?> getLevels(RAttributeProfiles profile, RAbstractIntVector factor) {
-        return getLevelsImpl(factor.getAttr(profile, RRuntime.LEVELS_ATTR_KEY));
-    }
-
     private static RVector<?> getLevelsImpl(Object attr) {
         // convert scalar to RVector<?>if necessary
         return attr instanceof RVector ? (RVector<?>) attr : (RVector<?>) RRuntime.asAbstractVector(attr);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
index cd52a76a925b0dc067d7554f1c8ea060c24942f1..9166d94a99f94b95d74faaad099b036a21d300d1 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.runtime.data;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.CompilerDirectives.ValueType;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -179,7 +180,7 @@ public class RLanguage extends RSharingAttributeStorage implements RAbstractCont
     }
 
     @Override
-    public RStringVector getNames(RAttributeProfiles attrProfiles) {
+    public RStringVector getNames() {
         if (list == null) {
             /*
              * "names" for a language object is a special case, that is applicable to calls and
@@ -191,7 +192,7 @@ public class RLanguage extends RSharingAttributeStorage implements RAbstractCont
             RStringVector names = RContext.getRRuntimeASTAccess().getNames(this);
             return names;
         } else {
-            return list.getNames(attrProfiles);
+            return list.getNames();
         }
     }
 
@@ -201,14 +202,14 @@ public class RLanguage extends RSharingAttributeStorage implements RAbstractCont
             /* See getNames */
             RContext.getRRuntimeASTAccess().setNames(this, newNames);
         } else {
-            list.setNames(newNames);
+            setNamesOnPairList(newNames);
         }
     }
 
     @Override
-    public RList getDimNames(RAttributeProfiles attrProfiles) {
+    public RList getDimNames() {
         RAttributable attr = list == null ? this : list;
-        return (RList) attr.getAttr(attrProfiles, RRuntime.DIMNAMES_ATTR_KEY);
+        return (RList) attr.getAttr(RRuntime.DIMNAMES_ATTR_KEY);
     }
 
     @Override
@@ -218,9 +219,9 @@ public class RLanguage extends RSharingAttributeStorage implements RAbstractCont
     }
 
     @Override
-    public Object getRowNames(RAttributeProfiles attrProfiles) {
+    public Object getRowNames() {
         RAttributable attr = list == null ? this : list;
-        return attr.getAttr(attrProfiles, RRuntime.ROWNAMES_ATTR_KEY);
+        return attr.getAttr(RRuntime.ROWNAMES_ATTR_KEY);
     }
 
     @Override
@@ -249,6 +250,10 @@ public class RLanguage extends RSharingAttributeStorage implements RAbstractCont
         return String.format("RLanguage(rep=%s)", getRep());
     }
 
+    public final RPairList getPairListInternal() {
+        return this.list;
+    }
+
     public RPairList getPairList() {
         if (list == null) {
             Object obj = RNull.instance;
@@ -260,9 +265,14 @@ public class RLanguage extends RSharingAttributeStorage implements RAbstractCont
             RStringVector names = RContext.getRRuntimeASTAccess().getNames(this);
             list = (RPairList) obj;
             if (names != null) {
-                list.setNames(names);
+                setNamesOnPairList(names);
             }
         }
         return list;
     }
+
+    @TruffleBoundary
+    private void setNamesOnPairList(RStringVector names) {
+        list.setNames(names);
+    }
 }
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..f9082b3bb9646e1cb727e4929f8055883f2df52e 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -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/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
index 4b514edb83a7774ebb4e417fa35b4ab3373beb86..18f7592bcd264dbcb55bbe3891a909ce30e361c4 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -308,7 +308,7 @@ public class RPairList extends RSharingAttributeStorage implements RAbstractCont
     }
 
     @Override
-    public RStringVector getNames(RAttributeProfiles attrProfiles) {
+    public final RStringVector getNames() {
         int l = getLength();
         String[] data = new String[l];
         RPairList pl = this;
@@ -339,7 +339,7 @@ public class RPairList extends RSharingAttributeStorage implements RAbstractCont
     }
 
     @Override
-    public RList getDimNames(RAttributeProfiles attrProfiles) {
+    public RList getDimNames() {
         return null;
     }
 
@@ -348,11 +348,6 @@ public class RPairList extends RSharingAttributeStorage implements RAbstractCont
         throw RInternalError.unimplemented();
     }
 
-    @Override
-    public Object getRowNames(RAttributeProfiles attrProfiles) {
-        throw RInternalError.unimplemented();
-    }
-
     @Override
     public void setRowNames(RAbstractVector rowNames) {
         throw RInternalError.unimplemented();
@@ -364,7 +359,7 @@ public class RPairList extends RSharingAttributeStorage implements RAbstractCont
     }
 
     @Override
-    public boolean isObject(RAttributeProfiles attrProfiles) {
+    public final boolean isObject() {
         return false;
     }
 }
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 86a3aa0a7b7a3b4bdbb4031e1099b31e16f8f8a6..94892c2553c495a34f81ea4a6cbeffb7705f0dcc 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -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;
@@ -92,7 +93,7 @@ public abstract class RScalarVector extends RScalar implements RAbstractVector {
     }
 
     @Override
-    public RStringVector getNames(RAttributeProfiles attrProfiles) {
+    public RStringVector getNames() {
         return null;
     }
 
@@ -102,7 +103,7 @@ public abstract class RScalarVector extends RScalar implements RAbstractVector {
     }
 
     @Override
-    public RList getDimNames(RAttributeProfiles attrProfiles) {
+    public RList getDimNames() {
         return null;
     }
 
@@ -112,7 +113,7 @@ public abstract class RScalarVector extends RScalar implements RAbstractVector {
     }
 
     @Override
-    public Object getRowNames(RAttributeProfiles attrProfiles) {
+    public Object getRowNames() {
         return null;
     }
 
@@ -122,7 +123,7 @@ public abstract class RScalarVector extends RScalar implements RAbstractVector {
     }
 
     @Override
-    public boolean isObject(RAttributeProfiles attrProfiles) {
+    public final boolean isObject() {
         return false;
     }
 
@@ -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/RSequence.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSequence.java
index 3e9c0042f32d893a5d4f8e00aadbf00639b4786e..998e48a12650f315f77e61e3584f1972042aa867 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSequence.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSequence.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -104,7 +104,7 @@ public abstract class RSequence implements RAbstractVector {
     }
 
     @Override
-    public final RStringVector getNames(RAttributeProfiles attrProfiles) {
+    public final RStringVector getNames() {
         return null;
     }
 
@@ -115,7 +115,7 @@ public abstract class RSequence implements RAbstractVector {
     }
 
     @Override
-    public final RList getDimNames(RAttributeProfiles attrProfiles) {
+    public final RList getDimNames() {
         return null;
     }
 
@@ -126,7 +126,7 @@ public abstract class RSequence implements RAbstractVector {
     }
 
     @Override
-    public final Object getRowNames(RAttributeProfiles attrProfiles) {
+    public final Object getRowNames() {
         return RNull.instance;
     }
 
@@ -162,7 +162,7 @@ public abstract class RSequence implements RAbstractVector {
     }
 
     @Override
-    public final boolean isObject(RAttributeProfiles attrProfiles) {
+    public final boolean isObject() {
         return false;
     }
 
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 310bde8f45d7ac97bb6a82e9f6275a0cf11847a2..0acdfa456ccea7a5f58254b3acee4a93a649f5df 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -168,29 +168,11 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
         }
     }
 
-    @Override
-    public final RStringVector getNames(RAttributeProfiles attrProfiles) {
-        if (attrProfiles.attrNullProfile(attributes == null)) {
-            return null;
-        } else {
-            RStringVector names = getNamesFromAttrs();
-            if (attrProfiles.attrNullNamesProfile(names == null)) {
-                RList dimNames = getDimNames();
-                if (dimNames != null && dimNames.getLength() == 1) {
-                    return (RStringVector) dimNames.getDataAt(0);
-                } else {
-                    return null;
-                }
-            } else {
-                return names;
-            }
-        }
-    }
-
     /*
      * Version without profiles is used by RDeparse and for internal attribute copying (both are not
      * performance-critical)
      */
+    @Override
     public final RStringVector getNames() {
         RStringVector names = getNamesFromAttrs();
         if (names == null) {
@@ -206,8 +188,8 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
     }
 
     @TruffleBoundary
-    public final int getElementIndexByName(RAttributeProfiles attrProfiles, String name) {
-        if (getNames(attrProfiles) == null) {
+    public final int getElementIndexByName(String name) {
+        if (getNames() == null) {
             return -1;
         }
         RStringVector names = getNamesFromAttrs();
@@ -225,8 +207,8 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
      * -1.
      */
     @TruffleBoundary
-    public final int getElementIndexByNameInexact(RAttributeProfiles attrProfiles, String name) {
-        if (getNames(attrProfiles) == null) {
+    public final int getElementIndexByNameInexact(String name) {
+        if (getNames() == null) {
             return -1;
         }
         boolean oneMatch = false;
@@ -280,15 +262,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
         }
     }
 
-    @Override
-    public final Object getAttr(RAttributeProfiles attrProfiles, String name) {
-        if (attrProfiles.attrNullProfile(attributes == null)) {
-            return null;
-        } else {
-            return attributes.get(name);
-        }
-    }
-
     private void removeAttrInternal(String name) {
         if (name.equals(RRuntime.NAMES_ATTR_KEY)) {
             setNames(null);
@@ -311,15 +284,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
 
     }
 
-    @Override
-    public final void removeAttr(RAttributeProfiles attrProfiles, String name) {
-        if (attrProfiles.attrNullProfile(attributes == null)) {
-            return;
-        } else {
-            removeAttrInternal(name);
-        }
-    }
-
     @Override
     public final void removeAttr(String name) {
         if (attributes != null) {
@@ -372,10 +336,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
     }
 
     @Override
-    public final RList getDimNames(RAttributeProfiles attrProfiles) {
-        return getDimNames();
-    }
-
     public final RList getDimNames() {
         return getDimNamesFromAttrs();
     }
@@ -445,10 +405,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
     }
 
     @Override
-    public final Object getRowNames(RAttributeProfiles attrProfiles) {
-        return getRowNames();
-    }
-
     public final Object getRowNames() {
         Object rn = getRowNamesFromAttrs();
         return rn == null ? RNull.instance : rn;
@@ -532,6 +488,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
 
     @Override
     public RAbstractContainer setClassAttr(RStringVector classAttr) {
+        CompilerAsserts.neverPartOfCompilation();
         return setClassAttrInternal(this, classAttr);
     }
 
@@ -675,12 +632,17 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
         DynamicObject vecAttributes = vector.getAttributes();
         if (vecAttributes != null) {
             initAttributes(RAttributesLayout.copy(vecAttributes));
-            return this.setClassAttr((RStringVector) vecAttributes.get(RRuntime.CLASS_ATTR_KEY));
+            return copyClassAttr(vecAttributes);
         } else {
             return this;
         }
     }
 
+    @TruffleBoundary
+    private RAbstractContainer copyClassAttr(DynamicObject vecAttributes) {
+        return setClassAttr((RStringVector) vecAttributes.get(RRuntime.CLASS_ATTR_KEY));
+    }
+
     /*
      * Internal version without profiles used in a rare (and already slow) case of double-to-int
      * vector conversion when setting class attribute
@@ -689,13 +651,13 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
         DynamicObject vecAttributes = vector.getAttributes();
         if (vecAttributes != null) {
             initAttributes(RAttributesLayout.copy(vecAttributes));
-            return this.setClassAttr((RStringVector) vecAttributes.get(RRuntime.CLASS_ATTR_KEY));
+            return copyClassAttr(vecAttributes);
         } else {
             return this;
         }
     }
 
-    public final void copyNamesDimsDimNamesFrom(RAttributeProfiles attrProfiles, RAbstractVector vector, RBaseNode invokingNode) {
+    public final void copyNamesDimsDimNamesFrom(RAbstractVector vector, RBaseNode invokingNode) {
         // it's meant to be used on a "fresh" vector with only dimensions potentially set
         assert (!hasDimNames());
         assert (!hasDimNames());
@@ -704,17 +666,19 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
         // for some reason, names is copied first, then dims, then dimnames
         if (vector.getDimensions() == null || vector.getDimensions().length != 1) {
             // only assign name attribute if it's not represented as dimnames (as is the case for
-            // one-dimensional arrasy)
-            this.setNames(vector.getNames(attrProfiles), invokingNode);
+            // one-dimensional array)
+            this.setNames(vector.getNames(), invokingNode);
         }
         this.setDimensions(vector.getDimensions(), invokingNode);
-        this.setDimNames(vector.getDimNames(attrProfiles), invokingNode);
+        this.setDimNames(vector.getDimNames(), invokingNode);
     }
 
-    public final boolean copyNamesFrom(RAttributeProfiles attrProfiles, RAbstractVector vector) {
+    public final boolean copyNamesFrom(RAbstractVector vector) {
+        CompilerAsserts.neverPartOfCompilation();
+
         int[] dimensions = getDimensionsFromAttrs();
         if (dimensions == null) {
-            RStringVector vecNames = vector.getNames(attrProfiles);
+            RStringVector vecNames = vector.getNames();
             if (vecNames != null) {
                 this.setNames(vecNames);
                 return true;
@@ -722,8 +686,8 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
                 return false;
             }
         } else {
-            if (vector.getDimNames(attrProfiles) != null) {
-                this.setDimNames(vector.getDimNames(attrProfiles));
+            if (vector.getDimNames() != null) {
+                this.setDimNames(vector.getDimNames());
                 return true;
             } else {
                 return false;
@@ -802,11 +766,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement
         }
     }
 
-    @Override
-    public final boolean isObject(RAttributeProfiles attrProfiles) {
-        return this.getClassAttr(attrProfiles) != null ? true : false;
-    }
-
     // As shape of the vector may change at run-time we need to compute
     // class hierarchy on the fly.
     protected final RStringVector getClassHierarchyHelper(RStringVector implicitClassHeader) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java
index 1d75a18aa146d5ad1190a62f10bfa26af0c40fd9..bd3f40ac11731afc1c04da8fef21b95171ccb93f 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -22,7 +22,6 @@
  */
 package com.oracle.truffle.r.runtime.data.closures;
 
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RDouble;
 import com.oracle.truffle.r.runtime.data.RFactor;
@@ -120,10 +119,6 @@ public class RClosures {
 
     // Factor to vector
 
-    public static RAbstractVector createFactorToVector(RAbstractIntVector factor, boolean withNames, RAttributeProfiles attrProfiles) {
-        return createFactorToVector(factor, withNames, RFactor.getLevels(attrProfiles, factor));
-    }
-
     public static RAbstractVector createFactorToVector(RAbstractIntVector factor, boolean withNames, RVector<?> levels) {
         if (levels == null) {
             return new RFactorToStringVectorClosure(factor, null, withNames);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToComplexVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToComplexVectorClosure.java
index 680e2c5aebb22a6a30704d1d8b9349131b7d6187..5826cf4d5f8a060d6dd2153ee3dbb6f05462bd94 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToComplexVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToComplexVectorClosure.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -25,7 +25,6 @@ package com.oracle.truffle.r.runtime.data.closures;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
@@ -71,7 +70,7 @@ final class RFactorToComplexVectorClosure extends RToComplexVectorClosure implem
     }
 
     @Override
-    public RStringVector getNames(RAttributeProfiles attrProfiles) {
-        return withNames ? super.getNames(attrProfiles) : null;
+    public RStringVector getNames() {
+        return withNames ? super.getNames() : null;
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToDoubleVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToDoubleVectorClosure.java
index 45b41c2cfe2dc83860e11c908e1da96a3660f2ee..af9ed554947ed2e9c25e0a0fc493a48b9e97fb14 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToDoubleVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToDoubleVectorClosure.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -25,7 +25,6 @@ package com.oracle.truffle.r.runtime.data.closures;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
@@ -72,7 +71,7 @@ final class RFactorToDoubleVectorClosure extends RToDoubleVectorClosure implemen
     }
 
     @Override
-    public RStringVector getNames(RAttributeProfiles attrProfiles) {
-        return withNames ? super.getNames(attrProfiles) : null;
+    public RStringVector getNames() {
+        return withNames ? super.getNames() : null;
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToIntVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToIntVectorClosure.java
index 8e09817efcc8de283347149733a2c36effd09be5..ecec033a92626bdbdfe2ee54c57aa332778f3cfe 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToIntVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToIntVectorClosure.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -25,7 +25,6 @@ package com.oracle.truffle.r.runtime.data.closures;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
@@ -73,7 +72,7 @@ final class RFactorToIntVectorClosure extends RToIntVectorClosure implements RAb
     }
 
     @Override
-    public RStringVector getNames(RAttributeProfiles attrProfiles) {
-        return withNames ? super.getNames(attrProfiles) : null;
+    public RStringVector getNames() {
+        return withNames ? super.getNames() : null;
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToStringVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToStringVectorClosure.java
index d6223712ab2613a0364bbab38612b35aced8b340..91350bfa7865c8cd21a2a108f0888b7649da21f8 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToStringVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToStringVectorClosure.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -26,7 +26,6 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
@@ -80,7 +79,7 @@ public final class RFactorToStringVectorClosure extends RToStringVectorClosure i
     }
 
     @Override
-    public RStringVector getNames(RAttributeProfiles attrProfiles) {
-        return withNames ? super.getNames(attrProfiles) : null;
+    public RStringVector getNames() {
+        return withNames ? super.getNames() : null;
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToStringVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToStringVectorClosure.java
index 38d3cbeca01fc6ce77e782bd95ef49b6aef2fbf0..6db80a38ca6ed75d5ed8106df5c86f1f82307da4 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToStringVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToStringVectorClosure.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.runtime.data.closures;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RVector;
@@ -47,7 +48,17 @@ abstract class RToStringVectorClosure extends RToVectorClosure implements RAbstr
             String data = getDataAt(i);
             result[i] = data;
         }
-        return RDataFactory.createStringVector(result, vector.isComplete(), getDimensions(), getNames(null));
+        return RDataFactory.createStringVector(result, vector.isComplete(), getDimensionsMaterialized(), getNamesMaterialized());
+    }
+
+    @TruffleBoundary
+    private int[] getDimensionsMaterialized() {
+        return getDimensions();
+    }
+
+    @TruffleBoundary
+    private RStringVector getNamesMaterialized() {
+        return getNames();
     }
 
     @Override
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToVectorClosure.java
index 1e9b74ed898f2a8ed7f02bb69ae6ecb1c103c7de..1f17428efc272e49b1dad966bbd8602176b5841c 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToVectorClosure.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -24,7 +24,6 @@ package com.oracle.truffle.r.runtime.data.closures;
 
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.r.runtime.data.MemoryCopyTracer;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.data.RStringVector;
@@ -82,8 +81,8 @@ abstract class RToVectorClosure implements RAbstractVector {
     }
 
     @Override
-    public RStringVector getNames(RAttributeProfiles attrProfiles) {
-        return vector.getNames(attrProfiles);
+    public RStringVector getNames() {
+        return vector.getNames();
     }
 
     @Override
@@ -92,8 +91,8 @@ abstract class RToVectorClosure implements RAbstractVector {
     }
 
     @Override
-    public final RList getDimNames(RAttributeProfiles attrProfiles) {
-        return vector.getDimNames(attrProfiles);
+    public final RList getDimNames() {
+        return vector.getDimNames();
     }
 
     @Override
@@ -102,8 +101,8 @@ abstract class RToVectorClosure implements RAbstractVector {
     }
 
     @Override
-    public final Object getRowNames(RAttributeProfiles attrProfiles) {
-        return vector.getRowNames(attrProfiles);
+    public final Object getRowNames() {
+        return vector.getRowNames();
     }
 
     @Override
@@ -176,11 +175,6 @@ abstract class RToVectorClosure implements RAbstractVector {
         return vector.getImplicitClass();
     }
 
-    @Override
-    public final boolean isObject(RAttributeProfiles attrProfiles) {
-        return vector.isObject(attrProfiles);
-    }
-
     @Override
     public final RTypedValue getNonShared() {
         return vector.getNonShared();
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 2125cce5eeacdf0581e006a53de42b1ac2046631..a3001eaf5da0f4d603b89e626078bc2a917f2d84 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -22,8 +22,9 @@
  */
 package com.oracle.truffle.r.runtime.data.model;
 
+import com.oracle.truffle.api.CompilerAsserts;
+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.RList;
 import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.data.RStringVector;
@@ -64,15 +65,33 @@ public interface RAbstractContainer extends RAttributable, RTypedValue {
         return null;
     }
 
-    RStringVector getNames(RAttributeProfiles attrProfiles);
+    default RStringVector getNames() {
+        CompilerAsserts.neverPartOfCompilation();
+        return (RStringVector) getAttr(RRuntime.NAMES_ATTR_KEY);
+    }
 
-    void setNames(RStringVector newNames);
+    default void setNames(RStringVector newNames) {
+        CompilerAsserts.neverPartOfCompilation();
+        setAttr(RRuntime.NAMES_ATTR_KEY, newNames);
+    }
 
-    RList getDimNames(RAttributeProfiles attrProfiles);
+    default RList getDimNames() {
+        CompilerAsserts.neverPartOfCompilation();
+        return (RList) getAttr(RRuntime.DIMNAMES_ATTR_KEY);
+    }
 
-    void setDimNames(RList newDimNames);
+    default void setDimNames(RList newDimNames) {
+        CompilerAsserts.neverPartOfCompilation();
+        setAttr(RRuntime.DIMNAMES_ATTR_KEY, newDimNames);
+    }
 
-    Object getRowNames(RAttributeProfiles attrProfiles);
+    default Object getRowNames() {
+        CompilerAsserts.neverPartOfCompilation();
+        return getAttr(RRuntime.ROWNAMES_ATTR_KEY);
+    }
 
-    void setRowNames(RAbstractVector rowNames);
+    default void setRowNames(RAbstractVector rowNames) {
+        CompilerAsserts.neverPartOfCompilation();
+        setAttr(RRuntime.ROWNAMES_ATTR_KEY, rowNames);
+    }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java
index 2934601bc41ecfe0809d76ed53abbfab07893c66..48e0fcf60fc82ed3b4217fa0518840240f400507 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -40,7 +40,6 @@ import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.VirtualEvalFrame;
 import com.oracle.truffle.r.runtime.context.RContext;
-import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributeStorage;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -663,10 +662,10 @@ public abstract class REnvironment extends RAttributeStorage {
      * e.g. {@code substitute}.
      */
     @TruffleBoundary
-    public static REnvironment createFromList(RAttributeProfiles attrProfiles, RList list, REnvironment parent) {
+    public static REnvironment createFromList(RList list, REnvironment parent) {
         REnvironment result = RDataFactory.createNewEnv(null);
         RArguments.initializeEnclosingFrame(result.getFrame(), parent.getFrame());
-        RStringVector names = list.getNames(attrProfiles);
+        RStringVector names = list.getNames();
         for (int i = 0; i < list.getLength(); i++) {
             try {
                 result.put(names.getDataAt(i), list.getDataAt(i));
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
index a20cbe325d123a191d94fde8565660a08b49f96d..4e1bc8f75b7ac4927119d2a625a7c4bf5880faca 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
@@ -217,6 +217,7 @@ public class DLL {
         /**
          * Return array of values that can be plugged directly into an {@code RList}.
          */
+        @TruffleBoundary
         public RList toRList() {
             Object[] data = new Object[NAMES.getLength()];
             data[0] = name;
@@ -331,6 +332,7 @@ public class DLL {
         return tag.getName().equals(DLLInfo.DLL_INFO_REFERENCE);
     }
 
+    @TruffleBoundary
     public static RExternalPtr createExternalPtr(SymbolHandle value, RStringVector rClass, Object externalObject) {
         CompilerAsserts.neverPartOfCompilation(); // for interning
         RExternalPtr result = RDataFactory.createExternalPtr(value, externalObject, RDataFactory.createSymbolInterned(rClass.getDataAt(0)), RNull.instance);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java
index b3a6037cc7984b7723353c16950b94a6ba60b4a6..d4f9f6d33c68d82e1d813a62862225fe89da029e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.runtime.nodes;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.nodes.LoopNode;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.NodeVisitor;
@@ -244,11 +245,16 @@ public abstract class RBaseNode extends Node {
 
     protected static boolean isRFormula(Object value) {
         if (value instanceof RLanguage) {
-            return ((RAttributable) value).hasClass(RRuntime.FORMULA_CLASS);
+            return hasFormulaClass(value);
         }
         return false;
     }
 
+    @TruffleBoundary
+    private static boolean hasFormulaClass(Object value) {
+        return ((RAttributable) value).hasClass(RRuntime.FORMULA_CLASS);
+    }
+
     protected static boolean isRExpression(Object value) {
         return value instanceof RExpression;
     }
diff --git a/com.oracle.truffle.r.test.native/.project b/com.oracle.truffle.r.test.native/.project
deleted file mode 100644
index 05eaeba4243572c96c4c7c6fe3423a6df1ee03bd..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.test.native/.project
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>com.oracle.truffle.r.test.native</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-			<triggers>full,incremental,</triggers>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.cdt.core.cnature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-	</natures>
-</projectDescription>