From 10549938dd8a8412edfcbdf30290109d6f253720 Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Thu, 7 Dec 2017 10:13:30 +0100
Subject: [PATCH] Add generic "fallback" specializations for caching
 specializations in Replace/ExtractVectorNode

---
 .../access/vector/ExtractVectorNode.java      | 41 +++++++++++++++----
 .../access/vector/ReplaceVectorNode.java      | 14 ++++++-
 2 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java
index 54338db024..16eff7b81b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java
@@ -108,7 +108,7 @@ public abstract class ExtractVectorNode extends RBaseNode {
     protected abstract Object execute(Object vector, Object[] positions, Object exact, Object dropDimensions);
 
     @Specialization(guards = {"cached != null", "cached.isSupported(vector, positions)"}, limit = "3")
-    protected Object doExtractSameDimensions(RAbstractVector vector, Object[] positions, Object exact, Object dropDimensions,  //
+    protected Object doRecursive(RAbstractVector vector, Object[] positions, Object exact, Object dropDimensions,  //
                     @Cached("createRecursiveCache(vector, positions)") RecursiveExtractSubscriptNode cached) {
         return cached.apply(vector, positions, exact, dropDimensions);
     }
@@ -148,11 +148,15 @@ public abstract class ExtractVectorNode extends RBaseNode {
         return new CachedExtractVectorNode(node.getMode(), vector, positions, (RTypedValue) exact, (RTypedValue) dropDimensions, node.recursive);
     }
 
-    @Specialization(replaces = "doExtractDefaultCached", guards = {"!isForeignObject(vector)"})
+    @Specialization(replaces = {"doExtractDefaultCached", "doRecursive"}, guards = {"!isForeignObject(vector)"})
     @TruffleBoundary
     protected Object doExtractDefaultGeneric(RAbstractContainer vector, Object[] positions, Object exact, Object dropDimensions,  //
-                    @Cached("new(createDefaultCache(getThis(), vector, positions, exact, dropDimensions))") GenericVectorExtractNode generic) {
-        return generic.get(this, vector, positions, exact, dropDimensions).apply(vector, positions, null, exact, dropDimensions);
+                    @Cached("create()") GenericVectorExtractNode generic) {
+        if (isRecursiveSubscript(vector, positions)) {
+            return generic.getRecursive(vector, positions).apply(vector, positions, exact, dropDimensions);
+        } else {
+            return generic.get(this, vector, positions, exact, dropDimensions).apply(vector, positions, null, exact, dropDimensions);
+        }
     }
 
     @Specialization
@@ -231,15 +235,24 @@ public abstract class ExtractVectorNode extends RBaseNode {
     protected static final class GenericVectorExtractNode extends TruffleBoundaryNode {
 
         @Child private CachedExtractVectorNode cached;
+        @Child private RecursiveExtractSubscriptNode cachedRecursive;
+
+        public static GenericVectorExtractNode create() {
+            return new GenericVectorExtractNode();
+        }
 
-        public GenericVectorExtractNode(CachedExtractVectorNode cachedOperation) {
-            this.cached = insert(cachedOperation);
+        public RecursiveExtractSubscriptNode getRecursive(RAbstractContainer vector, Object[] positions) {
+            CompilerAsserts.neverPartOfCompilation();
+            if (cachedRecursive == null || !cachedRecursive.isSupported(vector, positions)) {
+                cachedRecursive = insert(RecursiveExtractSubscriptNode.create((RAbstractListVector) vector, positions[0]));
+            }
+            return cachedRecursive;
         }
 
         public CachedExtractVectorNode get(ExtractVectorNode node, RAbstractContainer vector, Object[] positions, Object exact, Object dropDimensions) {
             CompilerAsserts.neverPartOfCompilation();
-            if (!cached.isSupported(vector, positions, exact, dropDimensions)) {
-                cached = cached.replace(createDefaultCache(node, vector, positions, exact, dropDimensions));
+            if (cached == null || !cached.isSupported(vector, positions, exact, dropDimensions)) {
+                cached = insert(createDefaultCache(node, vector, positions, exact, dropDimensions));
             }
             return cached;
         }
@@ -299,6 +312,18 @@ public abstract class ExtractVectorNode extends RBaseNode {
         }
     }
 
+    @Specialization(guards = {"isForeignObject(object)", "!positionsByVector(positions)"}, replaces = "accessField")
+    protected Object accessFieldGeneric(TruffleObject object, Object[] positions, @SuppressWarnings("unused") Object exact, @SuppressWarnings("unused") Object dropDimensions,
+                    @Cached("READ.createNode()") Node foreignRead,
+                    @Cached("KEY_INFO.createNode()") Node keyInfoNode,
+                    @Cached("HAS_SIZE.createNode()") Node hasSizeNode,
+                    @Cached("create()") CastStringNode castNode,
+                    @Cached("createFirstString()") FirstStringNode firstString,
+                    @Cached("createClassProfile()") ValueProfile positionProfile,
+                    @Cached("create()") Foreign2R foreign2RNode) {
+        return accessField(object, positions, exact, dropDimensions, foreignRead, keyInfoNode, hasSizeNode, positions.length, castNode, firstString, positionProfile, foreign2RNode);
+    }
+
     public static Object read(RBaseNode caller, Object positions, Node foreignRead, Node keyInfoNode, Node hasSizeNode, TruffleObject object, FirstStringNode firstString, CastStringNode castNode)
                     throws RError, InteropException {
         Object pos = positions;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java
index 9d78ec1485..093cee2ae2 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java
@@ -235,7 +235,7 @@ public abstract class ReplaceVectorNode extends RBaseNode {
         return new GenericVectorReplaceNode();
     }
 
-    @Specialization(replaces = "doReplaceCached", guards = "!isForeignObject(vector)")
+    @Specialization(replaces = {"doReplaceCached", "doRecursive"}, guards = "!isForeignObject(vector)")
     @TruffleBoundary
     protected Object doReplaceDefaultGeneric(RAbstractVector vector, Object[] positions, Object value,  //
                     @Cached("createGeneric()") GenericVectorReplaceNode generic) {
@@ -295,6 +295,18 @@ public abstract class ReplaceVectorNode extends RBaseNode {
         }
     }
 
+    @Specialization(guards = {"isForeignObject(object)"}, replaces = "accessField")
+    protected Object accessFieldGeneric(TruffleObject object, Object[] positions, Object value,
+                    @Cached("WRITE.createNode()") Node foreignWrite,
+                    @Cached("READ.createNode()") Node foreignRead,
+                    @Cached("KEY_INFO.createNode()") Node keyInfoNode,
+                    @Cached("HAS_SIZE.createNode()") Node hasSizeNode,
+                    @Cached("create()") CastStringNode castNode,
+                    @Cached("createFirstString()") FirstStringNode firstString,
+                    @Cached("create()") R2Foreign r2Foreign) {
+        return accessField(object, positions, value, foreignWrite, foreignRead, keyInfoNode, hasSizeNode, positions.length, castNode, firstString, r2Foreign);
+    }
+
     private void write(Object position, Node foreignWrite, Node keyInfoNode, Node hasSizeNode, TruffleObject object, Object writtenValue, FirstStringNode firstString, CastStringNode castNode,
                     R2Foreign r2Foreign)
                     throws InteropException, RError {
-- 
GitLab