From 08469690cad0edb0630a5ac90d3619fdf1619d2d Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Fri, 25 Aug 2017 11:44:13 +0200 Subject: [PATCH] Nodes for operations on vectors in c.o.t.r.runtime.data --- .../r/runtime/data/NativeDataAccess.java | 43 ++- .../truffle/r/runtime/data/RIntVector.java | 1 - .../r/runtime/data/RLogicalVector.java | 1 - .../truffle/r/runtime/data/RRawVector.java | 1 - .../truffle/r/runtime/data/RStringVector.java | 1 + .../truffle/r/runtime/data/RVector.java | 8 +- .../data/closures/RToVectorClosure.java | 4 +- .../data/model/RAbstractContainer.java | 9 +- .../r/runtime/data/nodes/GetDataAt.java | 333 +++++++++++++++++ .../r/runtime/data/nodes/GetDataCopy.java | 96 +++++ .../r/runtime/data/nodes/GetDataStore.java | 68 ++++ .../r/runtime/data/nodes/GetReadonlyData.java | 77 ++++ .../r/runtime/data/nodes/ReadAccessor.java | 184 +++++++++ .../r/runtime/data/nodes/SetDataAt.java | 218 +++++++++++ .../data/nodes/VectorAccessAdapter.java | 37 ++ .../r/runtime/data/nodes/VectorIterator.java | 348 ++++++++++++++++++ .../runtime/data/nodes/VectorReadAccess.java | 152 ++++++++ .../runtime/data/nodes/VectorWriteAccess.java | 118 ++++++ 18 files changed, 1682 insertions(+), 17 deletions(-) create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataAt.java create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataCopy.java create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataStore.java create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetReadonlyData.java create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/ReadAccessor.java create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/SetDataAt.java create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorAccessAdapter.java create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorReadAccess.java create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorWriteAccess.java diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java index 9c6878788b..2b31a68422 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java @@ -104,7 +104,8 @@ public final class NativeDataAccess { */ private long dataAddress; /** - * Length of the native data array. E.g. for CHARSXP this is not just the length of the Java String. + * Length of the native data array. E.g. for CHARSXP this is not just the length of the Java + * String. */ private long length; @@ -121,9 +122,11 @@ public final class NativeDataAccess { void allocateNative(String source) { assert dataAddress == 0; - byte[] bytes = source.getBytes(StandardCharsets.UTF_8); + byte[] bytes = source.getBytes(StandardCharsets.US_ASCII); dataAddress = UnsafeAdapter.UNSAFE.allocateMemory(bytes.length + 1); - UnsafeAdapter.UNSAFE.copyMemory(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, dataAddress, bytes.length + 1); + UnsafeAdapter.UNSAFE.copyMemory(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, dataAddress, bytes.length); + UnsafeAdapter.UNSAFE.putByte(dataAddress + bytes.length, (byte) 0); // C strings + // terminator this.length = bytes.length + 1; } @@ -235,6 +238,14 @@ public final class NativeDataAccess { return UnsafeAdapter.UNSAFE.getByte(address + index * Unsafe.ARRAY_BYTE_INDEX_SCALE); } + public static RComplex getComplexNativeMirrorData(Object nativeMirror, int index) { + long address = ((NativeMirror) nativeMirror).dataAddress; + assert address != 0; + assert index < ((NativeMirror) nativeMirror).length; + return RComplex.valueOf(UnsafeAdapter.UNSAFE.getDouble(address + index * 2 * Unsafe.ARRAY_DOUBLE_INDEX_SCALE), + UnsafeAdapter.UNSAFE.getDouble(address + (index * 2 + 1) * Unsafe.ARRAY_DOUBLE_INDEX_SCALE)); + } + public static void setNativeMirrorData(Object nativeMirror, int index, double value) { long address = ((NativeMirror) nativeMirror).dataAddress; assert address != 0; @@ -242,6 +253,27 @@ public final class NativeDataAccess { UnsafeAdapter.UNSAFE.putDouble(address + index * Unsafe.ARRAY_DOUBLE_INDEX_SCALE, value); } + public static void setNativeMirrorData(Object nativeMirror, int index, byte value) { + long address = ((NativeMirror) nativeMirror).dataAddress; + assert address != 0; + assert index < ((NativeMirror) nativeMirror).length; + UnsafeAdapter.UNSAFE.putByte(address + index * Unsafe.ARRAY_BYTE_INDEX_SCALE, value); + } + + public static void setNativeMirrorData(Object nativeMirror, int index, int value) { + long address = ((NativeMirror) nativeMirror).dataAddress; + assert address != 0; + assert index < ((NativeMirror) nativeMirror).length; + UnsafeAdapter.UNSAFE.putInt(address + index * Unsafe.ARRAY_INT_INDEX_SCALE, value); + } + + public static void setNativeMirrorLogicalData(Object nativeMirror, int index, byte logical) { + long address = ((NativeMirror) nativeMirror).dataAddress; + assert address != 0; + assert index < ((NativeMirror) nativeMirror).length; + UnsafeAdapter.UNSAFE.putInt(address + index * Unsafe.ARRAY_INT_INDEX_SCALE, RRuntime.logical2int(logical)); + } + public static double[] copyDoubleNativeData(Object mirrorObj) { NativeMirror mirror = (NativeMirror) mirrorObj; long address = mirror.dataAddress; @@ -386,10 +418,7 @@ public final class NativeDataAccess { if (noComplexNative.isValid() || data != null) { return RComplex.valueOf(data[index * 2], data[index * 2 + 1]); } else { - long address = ((NativeMirror) vector.getNativeMirror()).dataAddress; - assert address != 0; - return RComplex.valueOf(UnsafeAdapter.UNSAFE.getDouble(address + index * 2 * Unsafe.ARRAY_DOUBLE_INDEX_SCALE), - UnsafeAdapter.UNSAFE.getDouble(address + (index * 2 + 1) * Unsafe.ARRAY_DOUBLE_INDEX_SCALE)); + return getComplexNativeMirrorData(vector.getNativeMirror(), index); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java index 93d5547fc5..f52c7cb614 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java @@ -79,7 +79,6 @@ public final class RIntVector extends RVector<int[]> implements RAbstractIntVect @Override public int[] getInternalStore() { - assert data != null; return data; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLogicalVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLogicalVector.java index 8d87a76756..1d5bcca090 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLogicalVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLogicalVector.java @@ -86,7 +86,6 @@ public final class RLogicalVector extends RVector<byte[]> implements RAbstractLo @Override public byte[] getInternalStore() { - assert data != null; return data; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRawVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRawVector.java index 1bd4e1e70c..58025d7eb7 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRawVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRawVector.java @@ -84,7 +84,6 @@ public final class RRawVector extends RVector<byte[]> implements RAbstractRawVec @Override public byte[] getInternalStore() { - assert data != null; return data; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringVector.java index b0e42cf3ac..4a0374063a 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringVector.java @@ -68,6 +68,7 @@ public final class RStringVector extends RVector<String[]> implements RAbstractS @Override public String[] getInternalStore() { + assert data != null : "support for native memory backed vectors is not complete"; return data; } 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 27ad924f7b..f13b35c636 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 @@ -39,7 +39,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; 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.data.nodes.VectorToArray; +import com.oracle.truffle.r.runtime.data.nodes.GetReadonlyData; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.ops.na.NACheck; @@ -88,7 +88,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement /** * Returns the internal data Java array for read only purposes only or {@code null} if the * vector has been materialized to native mirror and it does not hold managed data anymore. This - * method is for only very specific purposes especially of {@link VectorToArray}. + * method is for only very specific purposes especially of {@link GetReadonlyData}. * * @return vector data */ @@ -106,9 +106,9 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement /** * Returns data for read-only purposes. The result may or may not be copy of the internal data. * This is a slow path operation for vector types that may have a native mirror, use - * {@link VectorToArray} node for fast path in such cases. + * {@link GetReadonlyData} node for fast path in such cases. * - * @see VectorToArray + * @see GetReadonlyData * @see RObject#getNativeMirror() * @return vector data */ 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 2f0146bee3..e8c5104485 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 @@ -49,8 +49,8 @@ abstract class RToVectorClosure implements RAbstractVector { } @Override - public Void getInternalStore() { - return null; + public EmptyInternalStore getInternalStore() { + return EmptyInternalStore.INSTANCE; } @Override 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 928229bfae..0a2bd4c3d4 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 @@ -68,7 +68,7 @@ public interface RAbstractContainer extends RAttributable, RTypedValue { * beneficial when in loop. */ default Object getInternalStore() { - return null; + return EmptyInternalStore.INSTANCE; } default RStringVector getNames() { @@ -100,4 +100,11 @@ public interface RAbstractContainer extends RAttributable, RTypedValue { CompilerAsserts.neverPartOfCompilation(); setAttr(RRuntime.ROWNAMES_ATTR_KEY, rowNames); } + + final class EmptyInternalStore { + private EmptyInternalStore() { + } + + public static EmptyInternalStore INSTANCE = new EmptyInternalStore(); + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataAt.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataAt.java new file mode 100644 index 0000000000..1c4c4d158b --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataAt.java @@ -0,0 +1,333 @@ +/* + * 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.runtime.data.nodes; + +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RComplexVector; +import com.oracle.truffle.r.runtime.data.RDoubleSequence; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RIntSequence; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RLogicalVector; +import com.oracle.truffle.r.runtime.data.RRawVector; +import com.oracle.truffle.r.runtime.data.RStringVector; +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.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.GetDataAtFactory.DoubleNodeGen; +import com.oracle.truffle.r.runtime.data.nodes.GetDataAtFactory.IntNodeGen; + +/** + * Contains nodes implementing fast-path versions of e.g. + * {@link RAbstractIntVector#getDataAt(Object, int)}. The first parameter 'store' should be + * retrieved for given vector using {@link GetDataStore} node. Store object must be used only for + * accessing the data of the vector for which it was created. The reason for having a store object + * is to avoid field load (field of the RVector object) on every data access. + */ +public abstract class GetDataAt extends Node { + + public abstract Object getAsObject(RAbstractVector vector, Object store, int index); + + @ImportStatic(NativeDataAccess.class) + public abstract static class Int extends GetDataAt { + + public static Int create() { + return IntNodeGen.create(); + } + + @Override + public Object getAsObject(RAbstractVector vector, Object store, int index) { + return get((RAbstractIntVector) vector, store, index); + } + + public final int get(RAbstractIntVector vector, Object store, int index) { + return execute(vector, store, index); + } + + public abstract int execute(RAbstractIntVector vector, Object store, int index); + + protected int doRVector(RIntVector vector, int[] store, int index) { + return store[index]; + } + + @Specialization(guards = "isNativeMirror(store)") + protected int doRVector(RIntVector vector, Object store, int index) { + return NativeDataAccess.getIntNativeMirrorData(store, index); + } + + @Specialization + protected int doSequence(RIntSequence sequence, Object store, int index) { + return sequence.getStart() + index * sequence.getStride(); + } + + // This accounts for other vector types, like closures + @Specialization(guards = {"isGenericVector(vector)", "cachedClass == vector.getClass()"}) + protected int doDoubleClosure(RAbstractIntVector vector, Object store, int index, + @Cached("vector.getClass()") Class<? extends RAbstractIntVector> cachedClass) { + return cachedClass.cast(vector).getDataAt(store, index); + } + + @Fallback + protected int doDoubleClosure(RAbstractIntVector vector, Object store, int index) { + return vector.getDataAt(store, index); + } + + protected static boolean isGenericVector(RAbstractIntVector vector) { + return !(vector instanceof RIntVector) && !(vector instanceof RIntSequence); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class Double extends GetDataAt { + + public static Double create() { + return DoubleNodeGen.create(); + } + + @Override + public Object getAsObject(RAbstractVector vector, Object store, int index) { + return get((RAbstractDoubleVector) vector, store, index); + } + + public final double get(RAbstractDoubleVector vector, Object store, int index) { + return execute(vector, store, index); + } + + public abstract double execute(RAbstractDoubleVector vector, Object store, int index); + + @Specialization(guards = "isNativeMirror(store)") + protected double doRVector(RDoubleVector vector, Object store, int index) { + return NativeDataAccess.getDoubleNativeMirrorData(store, index); + } + + @Specialization + protected double doRVector(RDoubleVector vector, double[] store, int index) { + return store[index]; + } + + @Specialization + protected double doSequence(RDoubleSequence sequence, Object store, int index) { + return sequence.getStart() + index * sequence.getStride(); + } + + @Specialization(guards = {"isGenericVector(vector)", "cachedClass == vector.getClass()"}, limit = "3") + protected double doDoubleClosure(RAbstractDoubleVector vector, Object store, int index, + @Cached("vector.getClass()") Class<?> cachedClass) { + return ((RAbstractDoubleVector) cachedClass.cast(vector)).getDataAt(store, index); + } + + @Fallback + protected double doDoubleClosure(RAbstractDoubleVector vector, Object store, int index) { + return vector.getDataAt(store, index); + } + + protected static boolean isGenericVector(RAbstractDoubleVector vector) { + return !(vector instanceof RDoubleVector) && !(vector instanceof RDoubleSequence); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class Logical extends GetDataAt { + + public static Logical create() { + return GetDataAtFactory.LogicalNodeGen.create(); + } + + @Override + public Object getAsObject(RAbstractVector vector, Object store, int index) { + return get((RAbstractLogicalVector) vector, store, index); + } + + public final byte get(RAbstractLogicalVector vector, Object store, int index) { + return execute(vector, store, index); + } + + public abstract byte execute(RAbstractLogicalVector vector, Object store, int index); + + protected byte doRVector(RLogicalVector vector, byte[] store, int index) { + return store[index]; + } + + @Specialization(guards = "isNativeMirror(store)") + protected byte doRVector(RLogicalVector vector, Object store, int index) { + return NativeDataAccess.getLogicalNativeMirrorData(store, index); + } + + // This accounts for other vector types, like closures + @Specialization(guards = {"isGenericVector(vector)", "cachedClass == vector.getClass()"}) + protected byte doDoubleClosure(RAbstractLogicalVector vector, Object store, int index, + @Cached("vector.getClass()") Class<? extends RAbstractLogicalVector> cachedClass) { + return cachedClass.cast(vector).getDataAt(store, index); + } + + @Fallback + protected byte doDoubleClosure(RAbstractLogicalVector vector, Object store, int index) { + return vector.getDataAt(store, index); + } + + protected static boolean isGenericVector(RAbstractLogicalVector vector) { + return !(vector instanceof RLogicalVector); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class Raw extends GetDataAt { + + public static Raw create() { + return GetDataAtFactory.RawNodeGen.create(); + } + + @Override + public Object getAsObject(RAbstractVector vector, Object store, int index) { + return get((RAbstractRawVector) vector, store, index); + } + + public final byte get(RAbstractRawVector vector, Object store, int index) { + return execute(vector, store, index); + } + + public abstract byte execute(RAbstractRawVector vector, Object store, int index); + + protected byte doRVector(RRawVector vector, byte[] store, int index) { + return store[index]; + } + + @Specialization(guards = "isNativeMirror(store)") + protected byte doRVector(RRawVector vector, Object store, int index) { + return NativeDataAccess.getRawNativeMirrorData(store, index); + } + + // This accounts for other vector types, like closures + @Specialization(guards = {"isGenericVector(vector)", "cachedClass == vector.getClass()"}) + protected byte doDoubleClosure(RAbstractRawVector vector, Object store, int index, + @Cached("vector.getClass()") Class<? extends RAbstractRawVector> cachedClass) { + return cachedClass.cast(vector).getRawDataAt(store, index); + } + + @Fallback + protected byte doDoubleClosure(RAbstractRawVector vector, Object store, int index) { + return vector.getRawDataAt(store, index); + } + + protected static boolean isGenericVector(RAbstractRawVector vector) { + return !(vector instanceof RRawVector); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class Complex extends GetDataAt { + + public static Complex create() { + return GetDataAtFactory.ComplexNodeGen.create(); + } + + @Override + public Object getAsObject(RAbstractVector vector, Object store, int index) { + return get((RAbstractComplexVector) vector, store, index); + } + + public final RComplex get(RAbstractComplexVector vector, Object store, int index) { + return execute(vector, store, index); + } + + public abstract RComplex execute(RAbstractComplexVector vector, Object store, int index); + + protected RComplex doRVector(RComplexVector vector, double[] store, int index) { + return RComplex.valueOf(store[index * 2], store[index * 2 + 1]); + } + + @Specialization(guards = "isNativeMirror(store)") + protected RComplex doRVector(RComplexVector vector, Object store, int index) { + throw RInternalError.unimplemented(); + } + + @Specialization(guards = {"isGenericVector(vector)", "cachedClass == vector.getClass()"}) + protected RComplex doDoubleClosure(RAbstractComplexVector vector, Object store, int index, + @Cached("vector.getClass()") Class<? extends RAbstractComplexVector> cachedClass) { + return cachedClass.cast(vector).getDataAt(store, index); + } + + @Fallback + protected RComplex doDoubleClosure(RAbstractComplexVector vector, Object store, int index) { + return vector.getDataAt(store, index); + } + + protected static boolean isGenericVector(RAbstractComplexVector vector) { + return !(vector instanceof RComplexVector); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class String extends GetDataAt { + + public static String create() { + return GetDataAtFactory.StringNodeGen.create(); + } + + @Override + public Object getAsObject(RAbstractVector vector, Object store, int index) { + return get((RAbstractStringVector) vector, store, index); + } + + public final java.lang.String get(RAbstractStringVector vector, Object store, int index) { + return execute(vector, store, index); + } + + public abstract java.lang.String execute(RAbstractStringVector vector, Object store, int index); + + protected java.lang.String doRVector(RStringVector vector, java.lang.String[] store, int index) { + return store[index]; + } + + @Specialization(guards = "isNativeMirror(store)") + protected java.lang.String doRVector(RStringVector vector, Object store, int index) { + throw RInternalError.unimplemented(); + } + + @Specialization(guards = {"isGenericVector(vector)", "cachedClass == vector.getClass()"}) + protected java.lang.String doDoubleClosure(RAbstractStringVector vector, Object store, int index, + @Cached("vector.getClass()") Class<? extends RAbstractStringVector> cachedClass) { + return cachedClass.cast(vector).getDataAt(store, index); + } + + @Fallback + protected java.lang.String doDoubleClosure(RAbstractStringVector vector, Object store, int index) { + return vector.getDataAt(store, index); + } + + protected static boolean isGenericVector(RAbstractStringVector vector) { + return !(vector instanceof RStringVector); + } + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataCopy.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataCopy.java new file mode 100644 index 0000000000..f5b86c65dd --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataCopy.java @@ -0,0 +1,96 @@ +/* + * 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.runtime.data.nodes; + +import java.util.Arrays; + +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.data.nodes.GetDataCopyFactory.DoubleNodeGen; +import com.oracle.truffle.r.runtime.data.nodes.GetDataCopyFactory.StringNodeGen; + +/** + * Nodes contained in this class materialize given vector into an array of corresponding type. The + * array is always a copy of the original data and can be modified freely. + * + * @see RVector#getDataCopy() + */ +public abstract class GetDataCopy { + + public abstract static class Double extends Node { + public abstract double[] execute(RAbstractDoubleVector vector); + + public static Double create() { + return DoubleNodeGen.create(); + } + + @Specialization(guards = "!vec.hasNativeMemoryData()") + protected double[] doManagedRVector(RDoubleVector vec) { + double[] data = vec.getInternalManagedData(); + return Arrays.copyOf(data, data.length); + } + + @Specialization(guards = "vec.hasNativeMemoryData()") + protected double[] doNativeDataRVector(RDoubleVector vec) { + return NativeDataAccess.copyDoubleNativeData(vec.getNativeMirror()); + } + + @Fallback + protected double[] doOthers(RAbstractDoubleVector vec) { + int len = vec.getLength(); + double[] result = new double[len]; + Object store = vec.getInternalStore(); + for (int i = 0; i < len; i++) { + result[i] = vec.getDataAt(store, i); + } + return result; + } + } + + public abstract static class String extends Node { + public abstract java.lang.String[] execute(RAbstractStringVector vector); + + public static String create() { + return StringNodeGen.create(); + } + + @Specialization(guards = "vec.hasNativeMemoryData()") + protected java.lang.String[] doManagedRVector(RStringVector vec) { + throw RInternalError.unimplemented("string vectors backed by native memory"); + } + + @Specialization(guards = "!vec.hasNativeMemoryData()") + protected java.lang.String[] doNativeDataRVector(RStringVector vec) { + java.lang.String[] data = vec.getInternalManagedData(); + return Arrays.copyOf(data, data.length); + } + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataStore.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataStore.java new file mode 100644 index 0000000000..d3587b1ed9 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetDataStore.java @@ -0,0 +1,68 @@ +/* + * 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.runtime.data.nodes; + +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; + +public abstract class GetDataStore extends Node { + + protected static final int CACHE_LIMIT = 6; + + public static GetDataStore create() { + return GetDataStoreNodeGen.create(); + } + + public abstract Object execute(RAbstractVector vector); + + @Specialization(guards = "vector.hasNativeMemoryData()") + protected Object doNative(RVector<?> vector) { + return vector.getNativeMirror(); + } + + @Specialization(guards = {"noNativeMemoryData(vector)", "vector.getClass() == vectorClass"}, limit = "CACHE_LIMIT") + protected Object doGeneric(RAbstractVector vector, + @Cached("vector.getClass()") Class<? extends RAbstractVector> vectorClass, + @Cached("getStoreClass(vector)") Class<?> storeClass) { + Object store = vectorClass.cast(vector).getInternalStore(); + assert store.getClass() == storeClass : "every concrete implementation of RAbstractVector#getInternalStore() must always return a store object of the same type."; + return storeClass.cast(store); + } + + @Fallback + protected Object doFallback(RAbstractVector vector) { + return vector.getInternalStore(); + } + + protected static boolean noNativeMemoryData(RAbstractVector vector) { + return !(vector instanceof RVector<?>) || !((RVector) vector).hasNativeMemoryData(); + } + + protected static Class<?> getStoreClass(RAbstractVector vector) { + return vector.getInternalStore().getClass(); + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetReadonlyData.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetReadonlyData.java new file mode 100644 index 0000000000..a30faf79fd --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/GetReadonlyData.java @@ -0,0 +1,77 @@ +/* + * 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.runtime.data.nodes; + +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RVector; + +/** + * Nodes contained in this class return an array that is either directly backing the vector data, or + * copy of it if the data is not internally represented as contiguous Java array. The result must + * not be modified, as it may result in different behaviour depending on the concrete vector + * implementation. + * + * @see RVector#getDataCopy() + */ +public class GetReadonlyData { + + public abstract static class Double extends Node { + public abstract double[] execute(RDoubleVector vector); + + @Specialization(guards = "!vec.hasNativeMemoryData()") + protected double[] doManagedRVector(RDoubleVector vec) { + return vec.getInternalManagedData(); + } + + @Specialization(guards = "vec.hasNativeMemoryData()") + protected double[] doNativeDataRVector(RDoubleVector vec) { + return NativeDataAccess.copyDoubleNativeData(vec.getNativeMirror()); + } + + public static Double create() { + return GetReadonlyDataFactory.DoubleNodeGen.create(); + } + } + + public abstract static class Int extends Node { + public abstract int[] execute(RIntVector vector); + + @Specialization(guards = "!vec.hasNativeMemoryData()") + protected int[] doManagedRVector(RIntVector vec) { + return vec.getInternalManagedData(); + } + + @Specialization(guards = "vec.hasNativeMemoryData()") + protected int[] doNativeDataRVector(RIntVector vec) { + return NativeDataAccess.copyIntNativeData(vec.getNativeMirror()); + } + + public static Int create() { + return GetReadonlyDataFactory.IntNodeGen.create(); + } + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/ReadAccessor.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/ReadAccessor.java new file mode 100644 index 0000000000..997488a9de --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/ReadAccessor.java @@ -0,0 +1,184 @@ +/* + * 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.runtime.data.nodes; + +import com.oracle.truffle.r.runtime.data.RComplex; +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.RAbstractLogicalVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; + +/** + * Convenience classes that wraps {@link VectorReadAccess} node, the vector and its store so that + * those data can be passed around as a single paramter. + */ +public abstract class ReadAccessor { + private ReadAccessor() { + } + + public static final class Int extends ReadAccessor { + private final RAbstractIntVector vector; + private final VectorReadAccess.Int readAccess; + private final Object store; + + public Int(RAbstractIntVector vector, VectorReadAccess.Int readAccess) { + this.vector = vector; + this.readAccess = readAccess; + store = readAccess.getDataStore(vector); + } + + public int getDataAt(int index) { + return readAccess.getDataAt(vector, store, index); + } + + public Object getStore() { + return store; + } + + public RAbstractIntVector getVector() { + return vector; + } + } + + public static final class Double extends ReadAccessor { + private final RAbstractDoubleVector vector; + private final VectorReadAccess.Double readAccess; + private final Object store; + + public Double(RAbstractDoubleVector vector, VectorReadAccess.Double readAccess) { + this.vector = vector; + this.readAccess = readAccess; + store = readAccess.getDataStore(vector); + } + + public double getDataAt(int index) { + return readAccess.getDataAt(vector, store, index); + } + + public Object getStore() { + return store; + } + + public RAbstractDoubleVector getVector() { + return vector; + } + } + + public static final class Logical extends ReadAccessor { + private final RAbstractLogicalVector vector; + private final VectorReadAccess.Logical readAccess; + private final Object store; + + public Logical(RAbstractLogicalVector vector, VectorReadAccess.Logical readAccess) { + this.vector = vector; + this.readAccess = readAccess; + store = readAccess.getDataStore(vector); + } + + public byte getDataAt(int index) { + return readAccess.getDataAt(vector, store, index); + } + + public Object getStore() { + return store; + } + + public RAbstractLogicalVector getVector() { + return vector; + } + } + + public static final class Raw extends ReadAccessor { + private final RAbstractRawVector vector; + private final VectorReadAccess.Raw readAccess; + private final Object store; + + public Raw(RAbstractRawVector vector, VectorReadAccess.Raw readAccess) { + this.vector = vector; + this.readAccess = readAccess; + store = readAccess.getDataStore(vector); + } + + public byte getDataAt(int index) { + return readAccess.getDataAt(vector, store, index); + } + + public Object getStore() { + return store; + } + + public RAbstractRawVector getVector() { + return vector; + } + } + + public static final class Complex extends ReadAccessor { + private final RAbstractComplexVector vector; + private final VectorReadAccess.Complex readAccess; + private final Object store; + + public Complex(RAbstractComplexVector vector, VectorReadAccess.Complex readAccess) { + this.vector = vector; + this.readAccess = readAccess; + store = readAccess.getDataStore(vector); + } + + public RComplex getDataAt(int index) { + return readAccess.getDataAt(vector, store, index); + } + + public Object getStore() { + return store; + } + + public RAbstractComplexVector getVector() { + return vector; + } + } + + public static final class String extends ReadAccessor { + private final RAbstractStringVector vector; + private final VectorReadAccess.String readAccess; + private final Object store; + + public String(RAbstractStringVector vector, VectorReadAccess.String readAccess) { + this.vector = vector; + this.readAccess = readAccess; + store = readAccess.getDataStore(vector); + } + + public java.lang.String getDataAt(int index) { + return readAccess.getDataAt(vector, store, index); + } + + public Object getStore() { + return store; + } + + public RAbstractStringVector getVector() { + return vector; + } + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/SetDataAt.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/SetDataAt.java new file mode 100644 index 0000000000..46f7a849bc --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/SetDataAt.java @@ -0,0 +1,218 @@ +/* + * 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.runtime.data.nodes; + +import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RComplexVector; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RLogicalVector; +import com.oracle.truffle.r.runtime.data.RRawVector; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RVector; + +public abstract class SetDataAt extends Node { + + public abstract void setDataAtAsObject(RVector<?> vector, Object store, int index, Object value); + + @ImportStatic(NativeDataAccess.class) + public abstract static class Double extends SetDataAt { + + @Override + public final void setDataAtAsObject(RVector<?> vector, Object store, int index, Object value) { + setDataAt((RDoubleVector) vector, store, index, (double) value); + } + + public final void setDataAt(RDoubleVector vector, Object store, int index, double value) { + execute(vector, store, index, value); + } + + public abstract void execute(RDoubleVector vector, Object store, int index, double value); + + @Specialization(guards = "!isNativeMirror(store)") + protected void doManagedRVector(RDoubleVector vec, Object store, int index, double value) { + ((double[]) store)[index] = value; + } + + @Specialization(guards = "isNativeMirror(store)") + protected void doNativeDataRVector(RDoubleVector vec, Object store, int index, double value) { + NativeDataAccess.setNativeMirrorData(store, index, value); + } + + public static Double create() { + return SetDataAtFactory.DoubleNodeGen.create(); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class Int extends SetDataAt { + + @Override + public final void setDataAtAsObject(RVector<?> vector, Object store, int index, Object value) { + setDataAt((RIntVector) vector, store, index, (int) value); + } + + public final void setDataAt(RIntVector vector, Object store, int index, int value) { + execute(vector, store, index, value); + } + + public abstract void execute(RIntVector vector, Object store, int index, int value); + + @Specialization(guards = "!isNativeMirror(store)") + protected void doManagedRVector(RIntVector vec, Object store, int index, int value) { + ((int[]) store)[index] = value; + } + + @Specialization(guards = "isNativeMirror(store)") + protected void doNativeDataRVector(RIntVector vec, Object store, int index, int value) { + NativeDataAccess.setNativeMirrorData(store, index, value); + } + + public static Int create() { + return SetDataAtFactory.IntNodeGen.create(); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class Logical extends SetDataAt { + + @Override + public final void setDataAtAsObject(RVector<?> vector, Object store, int index, Object value) { + setDataAt((RLogicalVector) vector, store, index, (byte) value); + } + + public final void setDataAt(RLogicalVector vector, Object store, int index, byte value) { + execute(vector, store, index, value); + } + + public abstract void execute(RLogicalVector vector, Object store, int index, byte value); + + @Specialization(guards = "!isNativeMirror(store)") + protected void doManagedRVector(RLogicalVector vec, Object store, int index, byte value) { + ((byte[]) store)[index] = value; + } + + @Specialization(guards = "isNativeMirror(store)") + protected void doNativeDataRVector(RLogicalVector vec, Object store, int index, byte value) { + NativeDataAccess.setNativeMirrorData(store, index, value); + } + + public static Logical create() { + return SetDataAtFactory.LogicalNodeGen.create(); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class Raw extends SetDataAt { + + @Override + public final void setDataAtAsObject(RVector<?> vector, Object store, int index, Object value) { + setDataAt((RRawVector) vector, store, index, (byte) value); + } + + public final void setDataAt(RRawVector vector, Object store, int index, byte value) { + execute(vector, store, index, value); + } + + public abstract void execute(RRawVector vector, Object store, int index, byte value); + + @Specialization(guards = "!isNativeMirror(store)") + protected void doManagedRVector(RRawVector vec, Object store, int index, byte value) { + ((byte[]) store)[index] = value; + } + + @Specialization(guards = "isNativeMirror(store)") + protected void doNativeDataRVector(RRawVector vec, Object store, int index, byte value) { + NativeDataAccess.setNativeMirrorData(store, index, value); + } + + public static Raw create() { + return SetDataAtFactory.RawNodeGen.create(); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class Complex extends SetDataAt { + + @Override + public final void setDataAtAsObject(RVector<?> vector, Object store, int index, Object value) { + setDataAt((RComplexVector) vector, store, index, (RComplex) value); + } + + public final void setDataAt(RComplexVector vector, Object store, int index, RComplex value) { + execute(vector, store, index, value); + } + + public abstract void execute(RComplexVector vector, Object store, int index, RComplex value); + + @Specialization(guards = "!isNativeMirror(storeObj)") + protected void doManagedRVector(RComplexVector vec, Object storeObj, int index, RComplex value) { + double[] store = (double[]) storeObj; + store[index * 2] = value.getRealPart(); + store[index * 2 + 1] = value.getImaginaryPart(); + } + + @Specialization(guards = "isNativeMirror(store)") + protected void doNativeDataRVector(RComplexVector vec, Object store, int index, RComplex value) { + throw RInternalError.unimplemented(); + } + + public static Complex create() { + return SetDataAtFactory.ComplexNodeGen.create(); + } + } + + @ImportStatic(NativeDataAccess.class) + public abstract static class String extends SetDataAt { + + @Override + public final void setDataAtAsObject(RVector<?> vector, Object store, int index, Object value) { + setDataAt((RStringVector) vector, store, index, (java.lang.String) value); + } + + public final void setDataAt(RStringVector vector, Object store, int index, java.lang.String value) { + execute(vector, store, index, value); + } + + public abstract void execute(RStringVector vector, Object store, int index, java.lang.String value); + + @Specialization(guards = "!isNativeMirror(store)") + protected void doManagedRVector(RStringVector vec, Object store, int index, java.lang.String value) { + ((java.lang.String[]) store)[index] = value; + } + + @Specialization(guards = "isNativeMirror(store)") + protected void doNativeDataRVector(RStringVector vec, Object store, int index, java.lang.String value) { + throw RInternalError.unimplemented(); + } + + public static String create() { + return SetDataAtFactory.StringNodeGen.create(); + } + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorAccessAdapter.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorAccessAdapter.java new file mode 100644 index 0000000000..c42c45e40b --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorAccessAdapter.java @@ -0,0 +1,37 @@ +/* + * 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.runtime.data.nodes; + +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; + +/** + * Factors out common code. + */ +abstract class VectorAccessAdapter extends Node { + @Child private GetDataStore getDataStoreNode = GetDataStoreNodeGen.create(); + + public Object getDataStore(RAbstractVector vector) { + return getDataStoreNode.execute(vector); + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java new file mode 100644 index 0000000000..d87792ed94 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorIterator.java @@ -0,0 +1,348 @@ +/* + * 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.runtime.data.nodes; + +import com.oracle.truffle.api.CompilerDirectives.ValueType; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.Utils; +import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RComplexVector; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RLogicalVector; +import com.oracle.truffle.r.runtime.data.RRawVector; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RVector; +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.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.VectorIterator.IteratorData; + +abstract class VectorIteratorNodeAdapter extends Node { + public static boolean hasNoNativeMemoryData(RAbstractVector vector) { + return !(vector instanceof RVector) || !((RVector) vector).hasNativeMemoryData(); + } + + public static boolean isRVector(RAbstractVector vector) { + return vector instanceof RVector; + } +} + +abstract class GetIteratorNode extends VectorIteratorNodeAdapter { + public abstract IteratorData<?> execute(RAbstractVector vector); + + @Specialization(guards = "vector.hasNativeMemoryData()") + protected IteratorData<?> nativeMirrorIterator(RVector<?> vector) { + return new IteratorData<>(vector.getNativeMirror(), vector.getLength()); + } + + @Specialization(guards = {"hasNoNativeMemoryData(vector)", "vectorClass == vector.getClass()"}) + protected IteratorData<?> generic(RAbstractVector vector, + @Cached("vector.getClass()") Class<? extends RAbstractVector> vectorClass) { + RAbstractVector profiledVec = vectorClass.cast(vector); + return new IteratorData<>(profiledVec.getInternalStore(), vector.getLength()); + } + + @Fallback + protected IteratorData<?> generic(RAbstractVector vector) { + return new IteratorData<>(vector.getInternalStore(), vector.getLength()); + } +} + +abstract class HasNextNode extends VectorIteratorNodeAdapter { + public abstract boolean execute(RAbstractVector vector, IteratorData<?> iterator); + + @Specialization(guards = "!iter.hasNativeMirror()") + protected boolean intVector(RIntVector vector, IteratorData<?> iter) { + return iter.index < ((int[]) iter.store).length; + } + + @Specialization(guards = "!iter.hasNativeMirror()") + protected boolean doubleVector(RDoubleVector vector, IteratorData<?> iter) { + return iter.index < ((double[]) iter.store).length; + } + + @Specialization(guards = "!iter.hasNativeMirror()") + protected boolean logicalVector(RLogicalVector vector, IteratorData<?> iter) { + return iter.index < ((byte[]) iter.store).length; + } + + @Specialization(guards = "!iter.hasNativeMirror()") + protected boolean rawVector(RRawVector vector, IteratorData<?> iter) { + return iter.index < ((byte[]) iter.store).length; + } + + @Specialization(guards = "!iter.hasNativeMirror()") + protected boolean stringVector(RStringVector vector, IteratorData<?> iter) { + return iter.index < ((String[]) iter.store).length; + } + + @Specialization(guards = {"!isRVector(vector)", "vectorClass == vector.getClass()"}) + protected boolean generic(RAbstractVector vector, IteratorData<?> iter, + @Cached("vector.getClass()") Class<? extends RAbstractVector> vectorClass) { + RAbstractVector profiledVec = vectorClass.cast(vector); + return iter.index < profiledVec.getLength(); + } + + @Fallback + protected boolean generic(RAbstractVector vector, IteratorData<?> iter) { + return iter.index < vector.getLength(); + } +} + +abstract class GetNextNode extends VectorIteratorNodeAdapter { + public abstract Object execute(RAbstractVector vector, IteratorData<?> iterator); + + @Specialization(guards = "!iter.hasNativeMirror()") + protected int intVector(RIntVector vector, IteratorData<?> iter) { + return ((int[]) iter.store)[iter.index]; + } + + @Specialization(guards = "!iter.hasNativeMirror()") + protected double doubleVector(RDoubleVector vector, IteratorData<?> iter) { + return ((double[]) iter.store)[iter.index]; + } + + @Specialization(guards = "!iter.hasNativeMirror()") + protected byte logicalVector(RLogicalVector vector, IteratorData<?> iter) { + return ((byte[]) iter.store)[iter.index]; + } + + @Specialization(guards = "!iter.hasNativeMirror()") + protected RComplex doComplexVector(RComplexVector vector, IteratorData<?> iter) { + double[] arr = (double[]) iter.store; + return RComplex.valueOf(arr[iter.index * 2], arr[iter.index * 2 + 1]); + } + + @Specialization(guards = "!iter.hasNativeMirror()") + protected byte doRawVector(RRawVector vector, IteratorData<?> iter) { + return ((byte[]) iter.store)[iter.index]; + } + + @Specialization(guards = "!iter.hasNativeMirror()") + protected String doStringVector(RStringVector vector, IteratorData<?> iter) { + return ((String[]) iter.store)[iter.index]; + } + + @Specialization(guards = "iter.hasNativeMirror()") + protected int intVectorNative(RIntVector vector, IteratorData<?> iter) { + return NativeDataAccess.getIntNativeMirrorData(iter.store, iter.index); + } + + @Specialization(guards = "iter.hasNativeMirror()") + protected double doubleVectorNative(RDoubleVector vector, IteratorData<?> iter) { + return NativeDataAccess.getDoubleNativeMirrorData(iter.store, iter.index); + } + + @Specialization(guards = "iter.hasNativeMirror()") + protected byte logicalVectorNative(RLogicalVector vector, IteratorData<?> iter) { + return NativeDataAccess.getLogicalNativeMirrorData(iter.store, iter.index); + } + + @Specialization(guards = "iter.hasNativeMirror()") + protected byte doubleVectorNative(RRawVector vector, IteratorData<?> iter) { + return NativeDataAccess.getRawNativeMirrorData(iter.store, iter.index); + } + + @Specialization(guards = "iter.hasNativeMirror()") + protected RComplex complexVectorNative(RComplexVector vector, IteratorData<?> iter) { + return NativeDataAccess.getComplexNativeMirrorData(iter.store, iter.index); + } + + @Specialization(guards = "iter.hasNativeMirror()") + protected byte stringVectorNative(RStringVector vector, IteratorData<?> iter) { + throw RInternalError.unimplemented("string vectors backed by native memory"); + } + + @Specialization(guards = "!isRVector(vector)") + protected int intVectorGeneric(RAbstractIntVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Int getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization(guards = "!isRVector(vector)") + protected double doubleVectorGeneric(RAbstractDoubleVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Double getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization(guards = "!isRVector(vector)") + protected String stringVectorGeneric(RAbstractStringVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.String getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization(guards = "!isRVector(vector)") + protected byte rawVectorGeneric(RAbstractRawVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Raw getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization(guards = "!isRVector(vector)") + protected byte logicalVectorGeneric(RAbstractLogicalVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Logical getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } + + @Specialization(guards = "!isRVector(vector)") + protected RComplex complexVectorGeneric(RAbstractComplexVector vector, IteratorData<?> iter, + @Cached("create()") GetDataAt.Complex getDataAtNode) { + return getDataAtNode.get(vector, iter.store, iter.index); + } +} + +// Checkstyle: stop final class check +// Note: the VectorIterator cannot be final, it has inner subclasses, which probably confuses check +// style + +/** + * This node wraps 3 nodes needed to sequentially iterate a given vector and provides convenience + * methods to invoke those nodes: {@link #init(RAbstractVector)}, + * {@link #next(RAbstractVector, Object)} and {@link #hasNext(RAbstractVector, Object)}. + * + * To construct use factory methods from type specialized inner classes, e.g. {@link Int#create()}, + * or generic version if the iterated vector could be of any type {@link Generic#create()}. + * + * Iterator can wrap around, i.e. once the iteration ends, it starts again from the first element. + */ +public abstract class VectorIterator<T> extends Node { + + // Note: it could be worth adding a LoopConditionProfile, however, it must be shared between + // getIteratorNode and getNextNode + + @Child private GetIteratorNode getIteratorNode = GetIteratorNodeGen.create(); + @Child private HasNextNode hasNextNode; + @Child private GetNextNode getNextNode = GetNextNodeGen.create(); + private final boolean wrapAround; + + private VectorIterator(boolean wrapAround) { + this.wrapAround = wrapAround; + if (!wrapAround) { + hasNextNode = HasNextNodeGen.create(); + } + } + + @SuppressWarnings("unchecked") + public Object init(RAbstractVector vector) { + return (IteratorData<T>) getIteratorNode.execute(vector); + } + + public boolean hasNext(RAbstractVector vector, Object iterator) { + assert !wrapAround : "wrap-around iteration does not support hasNext"; + return hasNextNode.execute(vector, (IteratorData<?>) iterator); + } + + @SuppressWarnings("unchecked") + public T next(RAbstractVector vector, Object iterator) { + IteratorData<T> it = (IteratorData<T>) iterator; + assert it.index < it.length; + Object result = getNextNode.execute(vector, it); + if (wrapAround) { + it.index = Utils.incMod(it.index, it.length); + } else { + it.index++; + } + return (T) result; + } + + public static final class Generic extends VectorIterator<Object> { + + private Generic(boolean wrapAround) { + super(wrapAround); + } + + public static Generic create() { + return new Generic(false); + } + + public static Generic createWrapAround() { + return new Generic(true); + } + } + + public static final class Int extends VectorIterator<Integer> { + + public Int(boolean wrapAround) { + super(wrapAround); + } + + public static Int create() { + return new Int(false); + } + } + + public static final class Double extends VectorIterator<java.lang.Double> { + public Double(boolean wrapAround) { + super(wrapAround); + } + + public static Double create() { + return new Double(false); + } + } + + public static final class Logical extends VectorIterator<Byte> { + public Logical(boolean wrapAround) { + super(wrapAround); + } + + public static Logical create() { + return new Logical(false); + } + } + + public static final class Raw extends VectorIterator<Byte> { + public Raw(boolean wrapAround) { + super(wrapAround); + } + + public static Raw create() { + return new Raw(false); + } + } + + @ValueType + public static final class IteratorData<StoreT> { + public int index = 0; + public final StoreT store; + public final int length; + + public IteratorData(StoreT store, int length) { + this.store = store; + this.length = length; + } + + public boolean hasNativeMirror() { + return NativeDataAccess.isNativeMirror(store); + } + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorReadAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorReadAccess.java new file mode 100644 index 0000000000..f4d70cdf22 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorReadAccess.java @@ -0,0 +1,152 @@ +/* + * 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.runtime.data.nodes; + +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.r.runtime.data.RComplex; +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.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; + +/** + * Contains nodes that encapsulate {@link GetDataStore} and one of the nodes from {@link GetDataAt} + * as these are often used together. These are convenience wrappers to be used e.g. for a @Cached + * parameter. + */ +public abstract class VectorReadAccess extends VectorAccessAdapter { + + public abstract Object getDataAtAsObject(RAbstractVector vector, Object store, int index); + + @NodeInfo(cost = NodeCost.NONE) + public static final class Double extends VectorReadAccess { + @Child private GetDataAt.Double getDataAtNode = GetDataAt.Double.create(); + + public double getDataAt(RAbstractDoubleVector vec, Object store, int index) { + return getDataAtNode.get(vec, store, index); + } + + @Override + public Object getDataAtAsObject(RAbstractVector vector, Object store, int index) { + return getDataAt((RAbstractDoubleVector) vector, store, index); + } + + public static Double create() { + return new Double(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class Int extends VectorReadAccess { + @Child private GetDataAt.Int getDataAtNode = GetDataAt.Int.create(); + + public int getDataAt(RAbstractIntVector vec, Object store, int index) { + return getDataAtNode.get(vec, store, index); + } + + @Override + public Object getDataAtAsObject(RAbstractVector vector, Object store, int index) { + return getDataAt((RAbstractIntVector) vector, store, index); + } + + public static Int create() { + return new Int(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class Logical extends VectorReadAccess { + @Child private GetDataAt.Logical getDataAtNode = GetDataAt.Logical.create(); + + public byte getDataAt(RAbstractLogicalVector vec, Object store, int index) { + return getDataAtNode.get(vec, store, index); + } + + @Override + public Object getDataAtAsObject(RAbstractVector vector, Object store, int index) { + return getDataAt((RAbstractLogicalVector) vector, store, index); + } + + public static Logical create() { + return new Logical(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class Complex extends VectorReadAccess { + @Child private GetDataAt.Complex getDataAtNode = GetDataAt.Complex.create(); + + public RComplex getDataAt(RAbstractComplexVector vec, Object store, int index) { + return getDataAtNode.get(vec, store, index); + } + + @Override + public Object getDataAtAsObject(RAbstractVector vector, Object store, int index) { + return getDataAt((RAbstractComplexVector) vector, store, index); + } + + public static Complex create() { + return new Complex(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class String extends VectorReadAccess { + @Child private GetDataAt.String getDataAtNode = GetDataAt.String.create(); + + public java.lang.String getDataAt(RAbstractStringVector vec, Object store, int index) { + return getDataAtNode.get(vec, store, index); + } + + @Override + public Object getDataAtAsObject(RAbstractVector vector, Object store, int index) { + return getDataAt((RAbstractStringVector) vector, store, index); + } + + public static String create() { + return new String(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class Raw extends VectorReadAccess { + @Child private GetDataAt.Raw getDataAtNode = GetDataAt.Raw.create(); + + public byte getDataAt(RAbstractRawVector vec, Object store, int index) { + return getDataAtNode.get(vec, store, index); + } + + @Override + public Object getDataAtAsObject(RAbstractVector vector, Object store, int index) { + return getDataAt((RAbstractRawVector) vector, store, index); + } + + public static Raw create() { + return new Raw(); + } + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorWriteAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorWriteAccess.java new file mode 100644 index 0000000000..8c8af33639 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/VectorWriteAccess.java @@ -0,0 +1,118 @@ +/* + * 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.runtime.data.nodes; + +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RComplexVector; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RLogicalVector; +import com.oracle.truffle.r.runtime.data.RRawVector; +import com.oracle.truffle.r.runtime.data.RStringVector; + +/** + * Contains nodes that encapsulate {@link GetDataStore} and one of the nodes from {@link SetDataAt} + * as these are often used together. These are convenience wrappers to be used e.g. for a @Cached + * parameter. + */ +public abstract class VectorWriteAccess { + @NodeInfo(cost = NodeCost.NONE) + public static final class Double extends VectorAccessAdapter { + @Child private SetDataAt.Double setDataAtNode = SetDataAt.Double.create(); + + public void setDataAt(RDoubleVector vector, Object store, int index, double value) { + setDataAtNode.setDataAt(vector, store, index, value); + } + + public static Double create() { + return new Double(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class Int extends VectorAccessAdapter { + @Child private SetDataAt.Int setDataAtNode = SetDataAt.Int.create(); + + public void setDataAt(RIntVector vector, Object store, int index, int value) { + setDataAtNode.setDataAt(vector, store, index, value); + } + + public static Int create() { + return new Int(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class Logical extends VectorAccessAdapter { + @Child private SetDataAt.Logical setDataAtNode = SetDataAt.Logical.create(); + + public void setDataAt(RLogicalVector vector, Object store, int index, byte value) { + setDataAtNode.setDataAt(vector, store, index, value); + } + + public static Logical create() { + return new Logical(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class Raw extends VectorAccessAdapter { + @Child private SetDataAt.Raw setDataAtNode = SetDataAt.Raw.create(); + + public void setDataAt(RRawVector vector, Object store, int index, byte value) { + setDataAtNode.setDataAt(vector, store, index, value); + } + + public static Raw create() { + return new Raw(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class String extends VectorAccessAdapter { + @Child private SetDataAt.String setDataAtNode = SetDataAt.String.create(); + + public void setDataAt(RStringVector vector, Object store, int index, java.lang.String value) { + setDataAtNode.setDataAt(vector, store, index, value); + } + + public static String create() { + return new String(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + public static final class Complex extends VectorAccessAdapter { + @Child private SetDataAt.Complex setDataAtNode = SetDataAt.Complex.create(); + + public void setDataAt(RComplexVector vector, Object store, int index, RComplex value) { + setDataAtNode.setDataAt(vector, store, index, value); + } + + public static Complex create() { + return new Complex(); + } + } +} -- GitLab