Skip to content
Snippets Groups Projects
Commit 08469690 authored by stepan's avatar stepan
Browse files

Nodes for operations on vectors in c.o.t.r.runtime.data

parent 17320f82
No related branches found
No related tags found
No related merge requests found
Showing
with 1682 additions and 17 deletions
...@@ -104,7 +104,8 @@ public final class NativeDataAccess { ...@@ -104,7 +104,8 @@ public final class NativeDataAccess {
*/ */
private long dataAddress; 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; private long length;
...@@ -121,9 +122,11 @@ public final class NativeDataAccess { ...@@ -121,9 +122,11 @@ public final class NativeDataAccess {
void allocateNative(String source) { void allocateNative(String source) {
assert dataAddress == 0; assert dataAddress == 0;
byte[] bytes = source.getBytes(StandardCharsets.UTF_8); byte[] bytes = source.getBytes(StandardCharsets.US_ASCII);
dataAddress = UnsafeAdapter.UNSAFE.allocateMemory(bytes.length + 1); 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; this.length = bytes.length + 1;
} }
...@@ -235,6 +238,14 @@ public final class NativeDataAccess { ...@@ -235,6 +238,14 @@ public final class NativeDataAccess {
return UnsafeAdapter.UNSAFE.getByte(address + index * Unsafe.ARRAY_BYTE_INDEX_SCALE); 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) { public static void setNativeMirrorData(Object nativeMirror, int index, double value) {
long address = ((NativeMirror) nativeMirror).dataAddress; long address = ((NativeMirror) nativeMirror).dataAddress;
assert address != 0; assert address != 0;
...@@ -242,6 +253,27 @@ public final class NativeDataAccess { ...@@ -242,6 +253,27 @@ public final class NativeDataAccess {
UnsafeAdapter.UNSAFE.putDouble(address + index * Unsafe.ARRAY_DOUBLE_INDEX_SCALE, value); 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) { public static double[] copyDoubleNativeData(Object mirrorObj) {
NativeMirror mirror = (NativeMirror) mirrorObj; NativeMirror mirror = (NativeMirror) mirrorObj;
long address = mirror.dataAddress; long address = mirror.dataAddress;
...@@ -386,10 +418,7 @@ public final class NativeDataAccess { ...@@ -386,10 +418,7 @@ public final class NativeDataAccess {
if (noComplexNative.isValid() || data != null) { if (noComplexNative.isValid() || data != null) {
return RComplex.valueOf(data[index * 2], data[index * 2 + 1]); return RComplex.valueOf(data[index * 2], data[index * 2 + 1]);
} else { } else {
long address = ((NativeMirror) vector.getNativeMirror()).dataAddress; return getComplexNativeMirrorData(vector.getNativeMirror(), index);
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));
} }
} }
......
...@@ -79,7 +79,6 @@ public final class RIntVector extends RVector<int[]> implements RAbstractIntVect ...@@ -79,7 +79,6 @@ public final class RIntVector extends RVector<int[]> implements RAbstractIntVect
@Override @Override
public int[] getInternalStore() { public int[] getInternalStore() {
assert data != null;
return data; return data;
} }
......
...@@ -86,7 +86,6 @@ public final class RLogicalVector extends RVector<byte[]> implements RAbstractLo ...@@ -86,7 +86,6 @@ public final class RLogicalVector extends RVector<byte[]> implements RAbstractLo
@Override @Override
public byte[] getInternalStore() { public byte[] getInternalStore() {
assert data != null;
return data; return data;
} }
......
...@@ -84,7 +84,6 @@ public final class RRawVector extends RVector<byte[]> implements RAbstractRawVec ...@@ -84,7 +84,6 @@ public final class RRawVector extends RVector<byte[]> implements RAbstractRawVec
@Override @Override
public byte[] getInternalStore() { public byte[] getInternalStore() {
assert data != null;
return data; return data;
} }
......
...@@ -68,6 +68,7 @@ public final class RStringVector extends RVector<String[]> implements RAbstractS ...@@ -68,6 +68,7 @@ public final class RStringVector extends RVector<String[]> implements RAbstractS
@Override @Override
public String[] getInternalStore() { public String[] getInternalStore() {
assert data != null : "support for native memory backed vectors is not complete";
return data; return data;
} }
......
...@@ -39,7 +39,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; ...@@ -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.RAbstractIntVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; 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.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.nodes.RBaseNode;
import com.oracle.truffle.r.runtime.ops.na.NACheck; import com.oracle.truffle.r.runtime.ops.na.NACheck;
...@@ -88,7 +88,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement ...@@ -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 * 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 * 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 * @return vector data
*/ */
...@@ -106,9 +106,9 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement ...@@ -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. * 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 * 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() * @see RObject#getNativeMirror()
* @return vector data * @return vector data
*/ */
......
...@@ -49,8 +49,8 @@ abstract class RToVectorClosure implements RAbstractVector { ...@@ -49,8 +49,8 @@ abstract class RToVectorClosure implements RAbstractVector {
} }
@Override @Override
public Void getInternalStore() { public EmptyInternalStore getInternalStore() {
return null; return EmptyInternalStore.INSTANCE;
} }
@Override @Override
......
...@@ -68,7 +68,7 @@ public interface RAbstractContainer extends RAttributable, RTypedValue { ...@@ -68,7 +68,7 @@ public interface RAbstractContainer extends RAttributable, RTypedValue {
* beneficial when in loop. * beneficial when in loop.
*/ */
default Object getInternalStore() { default Object getInternalStore() {
return null; return EmptyInternalStore.INSTANCE;
} }
default RStringVector getNames() { default RStringVector getNames() {
...@@ -100,4 +100,11 @@ public interface RAbstractContainer extends RAttributable, RTypedValue { ...@@ -100,4 +100,11 @@ public interface RAbstractContainer extends RAttributable, RTypedValue {
CompilerAsserts.neverPartOfCompilation(); CompilerAsserts.neverPartOfCompilation();
setAttr(RRuntime.ROWNAMES_ATTR_KEY, rowNames); setAttr(RRuntime.ROWNAMES_ATTR_KEY, rowNames);
} }
final class EmptyInternalStore {
private EmptyInternalStore() {
}
public static EmptyInternalStore INSTANCE = new EmptyInternalStore();
}
} }
/*
* 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);
}
}
}
/*
* 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);
}
}
}
/*
* 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();
}
}
/*
* 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();
}
}
}
/*
* 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;
}
}
}
/*
* 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();
}
}
}
/*
* 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);
}
}
/*
* 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);
}
}
}
/*
* 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();
}
}
}
/*
* 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();
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment