From ba3a4eb7c031fb96f5344cf8a5e36adbaaa93bbb Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Wed, 15 Nov 2017 17:01:53 +0100
Subject: [PATCH] convert raw conversion in RFFI and Rf_copyMatrix to
 VectorAccess

---
 .../ffi/impl/common/JavaUpCallsRFFIImpl.java  | 155 +++---------------
 .../oracle/truffle/r/runtime/ffi/CRFFI.java   |  15 +-
 2 files changed, 35 insertions(+), 135 deletions(-)

diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
index d5efff6efc..cab4934525 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
@@ -90,16 +90,12 @@ import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.data.RUnboundValue;
-import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
-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.RAbstractListBaseVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.RandomIterator;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 import com.oracle.truffle.r.runtime.ffi.DLL;
@@ -860,138 +856,37 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     @Override
     @TruffleBoundary
     public void Rf_copyMatrix(Object t, Object s, int byRow) {
-        int tRows = RRuntime.nrows(t);
-        int tCols = RRuntime.ncols(t);
-        final Object sav = RRuntime.asAbstractVector(s);
-        ContainerItemCopier c;
-        if (sav instanceof RAbstractContainer) {
-            int sLen = ((RAbstractContainer) sav).getLength();
-            if (sav instanceof RAbstractIntVector) {
-                c = new ContainerItemCopier() {
-                    private final RAbstractIntVector sv = (RAbstractIntVector) sav;
-                    private final RAbstractIntVector tv = (RAbstractIntVector) t;
-                    private final Object tvStore = tv.getInternalStore();
-
-                    @Override
-                    public void copy(int sIdx, int tIdx) {
-                        tv.setDataAt(tvStore, tIdx, sv.getDataAt(sIdx));
-                    }
-                };
-            } else if (sav instanceof RAbstractDoubleVector) {
-                c = new ContainerItemCopier() {
-
-                    private final RAbstractDoubleVector sv = (RAbstractDoubleVector) sav;
-                    private final RAbstractDoubleVector tv = (RAbstractDoubleVector) t;
-                    private final Object tvStore = tv.getInternalStore();
-
-                    @Override
-                    public void copy(int sIdx, int tIdx) {
-                        tv.setDataAt(tvStore, tIdx, sv.getDataAt(sIdx));
-                    }
-                };
-            } else if (sav instanceof RAbstractLogicalVector) {
-                c = new ContainerItemCopier() {
-                    private final RAbstractLogicalVector sv = (RAbstractLogicalVector) sav;
-                    private final RAbstractLogicalVector tv = (RAbstractLogicalVector) t;
-                    private final Object tvStore = tv.getInternalStore();
-
-                    @Override
-                    public void copy(int sIdx, int tIdx) {
-                        tv.setDataAt(tvStore, tIdx, sv.getDataAt(sIdx));
-                    }
-                };
-            } else if (sav instanceof RAbstractComplexVector) {
-                c = new ContainerItemCopier() {
-                    private final RAbstractComplexVector sv = (RAbstractComplexVector) sav;
-                    private final RAbstractComplexVector tv = (RAbstractComplexVector) t;
-                    private final Object tvStore = tv.getInternalStore();
-
-                    @Override
-                    public void copy(int sIdx, int tIdx) {
-                        tv.setDataAt(tvStore, tIdx, sv.getDataAt(sIdx));
-                    }
-                };
-            } else if (sav instanceof RAbstractStringVector) {
-                c = new ContainerItemCopier() {
-                    private final RAbstractStringVector sv = (RAbstractStringVector) sav;
-                    private final RAbstractStringVector tv = (RAbstractStringVector) t;
-                    private final Object tvStore = tv.getInternalStore();
-
-                    @Override
-                    public void copy(int sIdx, int tIdx) {
-                        tv.setDataAt(tvStore, tIdx, sv.getDataAt(sIdx));
-                    }
-                };
-            } else if (sav instanceof RAbstractRawVector) {
-                c = new ContainerItemCopier() {
-                    private final RAbstractRawVector sv = (RAbstractRawVector) sav;
-                    private final RAbstractRawVector tv = (RAbstractRawVector) t;
-                    private final Object tvStore = tv.getInternalStore();
-
-                    @Override
-                    public void copy(int sIdx, int tIdx) {
-                        tv.setRawDataAt(tvStore, tIdx, sv.getRawDataAt(sIdx));
-                    }
-                };
-            } else if (sav instanceof RAbstractListBaseVector) {
-                c = new ContainerItemCopier() {
-                    private final RAbstractListBaseVector sv = (RAbstractListBaseVector) sav;
-                    private final RAbstractListBaseVector tv = (RAbstractListBaseVector) t;
-                    private final Object tvStore = tv.getInternalStore();
-
-                    @Override
-                    public void copy(int sIdx, int tIdx) {
-                        tv.setDataAt(tvStore, tIdx, sv.getDataAt(sIdx));
-                    }
-                };
-            } else {
-                throw unimplemented();
-            }
-            if (byRow != 0) {
-                int sIdx = 0;
-                for (int i = 0; i < tRows; i++) {
-                    int tIdx = i;
-                    for (int j = 0; j < tCols; j++) {
-                        c.copy(sIdx, tIdx);
-                        sIdx++;
-                        if (sIdx >= sLen) {
-                            sIdx -= sLen;
+        RAbstractVector target = guaranteeInstanceOf(t, RAbstractVector.class);
+        RAbstractVector source = guaranteeInstanceOf(RRuntime.asAbstractVector(s), RAbstractVector.class);
+
+        VectorAccess targetAccess = target.slowPathAccess();
+        VectorAccess sourceAccess = source.slowPathAccess();
+
+        try (SequentialIterator sourceIter = sourceAccess.access(source)) {
+            if (byRow != 0) { // copy by row
+                int tRows = RRuntime.nrows(target);
+                int tCols = RRuntime.ncols(target);
+                try (RandomIterator targetIter = targetAccess.randomAccess(target)) {
+                    for (int i = 0; i < tRows; i++) {
+                        int tIdx = i;
+                        for (int j = 0; j < tCols; j++) {
+                            sourceAccess.nextWithWrap(sourceIter);
+                            targetAccess.setFromSameType(targetIter, tIdx, sourceAccess, sourceIter);
+                            tIdx += tRows;
                         }
-                        tIdx += tRows;
                     }
                 }
-            } else { // Copy by column
-                int tLen = ((RAbstractContainer) t).getLength();
-                if (sLen >= tLen) {
-                    for (int i = 0; i < tLen; i++) {
-                        c.copy(i, i);
-                    }
-                } else { // Recycle needed
-                    int sIdx = 0;
-                    for (int i = 0; i < tLen; i++) {
-                        c.copy(sIdx, i);
-                        sIdx++;
-                        if (sIdx >= sLen) {
-                            sIdx -= sLen;
-                        }
+            } else { // copy by column
+                try (SequentialIterator targetIter = targetAccess.access(target)) {
+                    while (targetAccess.next(targetIter)) {
+                        sourceAccess.nextWithWrap(sourceIter);
+                        targetAccess.setFromSameType(targetIter, sourceAccess, sourceIter);
                     }
                 }
             }
-        } else { // source is non-RAbstractContainer
-            throw unimplemented();
         }
     }
 
-    /**
-     * Helper interface for {@link #Rf_copyMatrix(java.lang.Object, java.lang.Object, int)} that
-     * copies from source index in an (internally held) source container into target index in a
-     * target container.
-     */
-    interface ContainerItemCopier {
-
-        void copy(int sIdx, int tIdx);
-    }
-
     @Override
     @TruffleBoundary
     public Object R_tryEval(Object expr, Object env, int silent) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
index 1175bc95eb..b2b566a04b 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
@@ -56,6 +56,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
 import sun.misc.Unsafe;
@@ -390,12 +392,15 @@ final class RawWrapper extends TemporaryWrapper {
     @TruffleBoundary
     public long allocate() {
         RAbstractRawVector v = (RAbstractRawVector) vector;
-        int length = v.getLength();
-        long memory = UnsafeAdapter.UNSAFE.allocateMemory(length * Unsafe.ARRAY_BYTE_INDEX_SCALE);
-        for (int i = 0; i < length; i++) {
-            UnsafeAdapter.UNSAFE.putByte(memory + (i * Unsafe.ARRAY_BYTE_INDEX_SCALE), v.getRawDataAt(i));
+        VectorAccess access = v.slowPathAccess();
+        try (SequentialIterator iter = access.access(v)) {
+            int length = access.getLength(iter);
+            long memory = UnsafeAdapter.UNSAFE.allocateMemory(length * Unsafe.ARRAY_BYTE_INDEX_SCALE);
+            while (access.next(iter)) {
+                UnsafeAdapter.UNSAFE.putByte(memory + (iter.getIndex() * Unsafe.ARRAY_BYTE_INDEX_SCALE), access.getRaw(iter));
+            }
+            return memory;
         }
-        return memory;
     }
 
     @Override
-- 
GitLab