From 1f6c4afd3619bbba7a4754df2e375123b33ea407 Mon Sep 17 00:00:00 2001
From: Florian Angerer <florian.angerer@oracle.com>
Date: Mon, 21 Aug 2017 19:31:57 +0200
Subject: [PATCH] Using RClosures to reduce unnecessary allocations in
 DoubleCastNode.

---
 .../truffle/r/nodes/unary/CastBaseNode.java     |  2 +-
 .../r/nodes/unary/CastDoubleBaseNode.java       |  3 +++
 .../truffle/r/nodes/unary/CastDoubleNode.java   | 17 ++++++++++++++---
 .../data/closures/RToDoubleVectorClosure.java   |  2 +-
 .../runtime/data/closures/RToVectorClosure.java |  9 ++++-----
 .../truffle/r/runtime/ops/na/NAProfile.java     |  4 ++++
 6 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java
index d94c36c1dc..cd8529b1b1 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java
@@ -121,7 +121,7 @@ public abstract class CastBaseNode extends CastNode {
         }
     }
 
-    protected void preserveDimensionNames(RAbstractContainer operand, RVector<?> ret) {
+    protected void preserveDimensionNames(RAbstractContainer operand, RAbstractContainer ret) {
         if (preserveDimensions()) {
             RList dimNames = getDimNamesNode.getDimNames(operand);
             if (hasDimNamesProfile.profile(dimNames != null)) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java
index 9abeb67a8d..24744b62d9 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java
@@ -25,6 +25,7 @@ package com.oracle.truffle.r.nodes.unary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.function.opt.IsNonSharedNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
@@ -40,6 +41,8 @@ public abstract class CastDoubleBaseNode extends CastBaseNode {
     protected final NACheck naCheck = NACheck.create();
     protected final NAProfile naProfile = NAProfile.create();
 
+    @Child protected IsNonSharedNode reuseNonShared = IsNonSharedNode.create();
+
     protected CastDoubleBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
         super(preserveNames, preserveDimensions, preserveAttributes);
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
index f0e17bb98d..a8a6668720 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
@@ -33,6 +33,7 @@ import com.oracle.truffle.api.profiles.BranchProfile;
 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.RComplex;
 import com.oracle.truffle.r.runtime.data.RComplexVector;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -42,6 +43,7 @@ import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RRawVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
+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.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
@@ -92,12 +94,18 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
     }
 
     @Specialization
-    protected RDoubleVector doIntVector(RAbstractIntVector operand) {
+    protected RAbstractDoubleVector doIntVector(RAbstractIntVector operand) {
+        if (reuseNonShared.execute(operand)) {
+            return (RAbstractDoubleVector) operand.castSafe(RType.Double, naProfile.getConditionProfile());
+        }
         return createResultVector(operand, index -> naCheck.convertIntToDouble(operand.getDataAt(index)));
     }
 
     @Specialization
-    protected RDoubleVector doLogicalVectorDims(RAbstractLogicalVector operand) {
+    protected RAbstractDoubleVector doLogicalVectorDims(RAbstractLogicalVector operand) {
+        if (reuseNonShared.execute(operand)) {
+            return (RAbstractDoubleVector) operand.castSafe(RType.Double, naProfile.getConditionProfile());
+        }
         return createResultVector(operand, index -> naCheck.convertLogicalToDouble(operand.getDataAt(index)));
     }
 
@@ -157,7 +165,10 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
     }
 
     @Specialization
-    protected RDoubleVector doRawVector(RRawVector operand) {
+    protected RAbstractDoubleVector doRawVector(RRawVector operand) {
+        if (reuseNonShared.execute(operand)) {
+            return (RAbstractDoubleVector) operand.castSafe(RType.Double, naProfile.getConditionProfile());
+        }
         return createResultVector(operand, index -> RRuntime.raw2double(operand.getDataAt(index)));
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToDoubleVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToDoubleVectorClosure.java
index 435498a961..cd5aa24729 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToDoubleVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToDoubleVectorClosure.java
@@ -47,7 +47,7 @@ abstract class RToDoubleVectorClosure extends RToVectorClosure implements RAbstr
             double data = getDataAt(i);
             result[i] = data;
         }
-        return RDataFactory.createDoubleVector(result, getVector().isComplete());
+        return RDataFactory.createDoubleVector(result, getVector().isComplete(), getVector().getDimensions(), getVector().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 9d00bf9472..d2ff0cb3a9 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
@@ -23,7 +23,6 @@
 package com.oracle.truffle.r.runtime.data.closures;
 
 import com.oracle.truffle.api.object.DynamicObject;
-import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
@@ -122,22 +121,22 @@ abstract class RToVectorClosure implements RAbstractVector {
 
     @Override
     public final RAbstractVector copy() {
-        throw RInternalError.shouldNotReachHere();
+        return materialize().copy();
     }
 
     @Override
     public final RVector<?> copyResized(int size, boolean fillNA) {
-        throw RInternalError.shouldNotReachHere();
+        return materialize().copyResized(size, fillNA);
     }
 
     @Override
     public final RVector<?> copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
-        throw RInternalError.shouldNotReachHere();
+        return materialize().copyResizedWithDimensions(newDimensions, fillNA);
     }
 
     @Override
     public final RAbstractVector copyDropAttributes() {
-        throw RInternalError.shouldNotReachHere();
+        return materialize().copyDropAttributes();
     }
 
     @Override
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/na/NAProfile.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/na/NAProfile.java
index 9369eff3db..36d1acc29d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/na/NAProfile.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/na/NAProfile.java
@@ -58,6 +58,10 @@ public final class NAProfile {
         return profile.profile(RRuntime.isNA(value));
     }
 
+    public ConditionProfile getConditionProfile() {
+        return profile;
+    }
+
     public void ifNa(double value, Runnable runnable) {
         if (isNA(value)) {
             runnable.run();
-- 
GitLab