use of com.oracle.truffle.espresso.impl.ArrayKlass in project graal by oracle.
the class Target_sun_misc_Unsafe method arrayIndexScale.
/**
* Report the scale factor for addressing elements in the storage allocation of a given array
* class. However, arrays of "narrow" types will generally not work properly with accessors like
* {@link #getByte}, so the scale factor for such classes is reported as zero.
*
* @see #arrayBaseOffset
* @see #getInt
* @see #putInt
*/
@Substitution(hasReceiver = true, nameProvider = SharedUnsafeAppend0.class)
public static int arrayIndexScale(@SuppressWarnings("unused") @JavaType(Unsafe.class) StaticObject self, @JavaType(Class.class) StaticObject clazz, @Inject Meta meta) {
Unsafe unsafe = UnsafeAccess.getIfAllowed(meta);
Klass klass = clazz.getMirrorKlass();
assert klass.isArray();
if (((ArrayKlass) klass).getComponentType().isPrimitive()) {
Class<?> hostPrimitive = ((ArrayKlass) klass).getComponentType().getJavaKind().toJavaClass();
return unsafe.arrayIndexScale(Array.newInstance(hostPrimitive, 0).getClass());
} else {
// Just a reference type.
return unsafe.arrayIndexScale(Object[].class);
}
}
use of com.oracle.truffle.espresso.impl.ArrayKlass in project graal by oracle.
the class JDWPContextImpl method getTypeTag.
@Override
public byte getTypeTag(Object array) {
StaticObject staticObject = (StaticObject) array;
byte tag;
if (staticObject.isArray()) {
ArrayKlass arrayKlass = (ArrayKlass) staticObject.getKlass();
tag = arrayKlass.getComponentType().getJavaKind().toTagConstant();
if (arrayKlass.getDimension() > 1) {
tag = TagConstants.ARRAY;
} else if (tag == TagConstants.OBJECT) {
if (JAVA_LANG_STRING.equals(arrayKlass.getComponentType().getType().toString())) {
tag = TagConstants.STRING;
}
}
} else {
tag = staticObject.getKlass().getTagConstant();
// Object type, so check for String
if (tag == TagConstants.OBJECT) {
if (JAVA_LANG_STRING.equals(((StaticObject) array).getKlass().getType().toString())) {
tag = TagConstants.STRING;
}
}
}
return tag;
}
use of com.oracle.truffle.espresso.impl.ArrayKlass in project graal by oracle.
the class StaticObject method createClass.
public static StaticObject createClass(Klass klass) {
assert klass != null;
ObjectKlass guestClass = klass.getMeta().java_lang_Class;
StaticObject newObj = guestClass.getLinkedKlass().getShape(false).getFactory().create(guestClass);
newObj.initInstanceFields(guestClass);
klass.getMeta().java_lang_Class_classLoader.setObject(newObj, klass.getDefiningClassLoader());
if (klass.getContext().getJavaVersion().modulesEnabled()) {
newObj.setModule(klass);
}
if (klass.isArray() && klass.getMeta().java_lang_Class_componentType != null) {
klass.getMeta().java_lang_Class_componentType.setObject(newObj, ((ArrayKlass) klass).getComponentType().mirror());
}
// Will be overriden if necessary, but should be initialized to non-host null.
klass.getMeta().HIDDEN_PROTECTION_DOMAIN.setHiddenObject(newObj, StaticObject.NULL);
// Final hidden field assignment
klass.getMeta().HIDDEN_MIRROR_KLASS.setHiddenObject(newObj, klass);
return trackAllocation(klass, newObj);
}
use of com.oracle.truffle.espresso.impl.ArrayKlass in project graal by oracle.
the class Target_java_lang_System method doArrayCopy.
/*-
* Order of throws (see JCK api/java_lang/System/index.html#Arraycopy):
*
* A - NullPointerException
* if either src or dst is null.
* B - ArrayStoreException
* if an element in the src array could not be stored into the dest array because of:
* 1 - The src argument refers to an object that is not an array.
* 2 - The dst argument refers to an object that is not an array.
* 3 - The src argument and dst argument refer to arrays whose component types are
* different primitive types.
* 4 - The src argument refers to an array with a primitive component type and the
* dst argument refers to an array with a reference component type.
* 5 - The src argument refers to an array with a reference component type and the
* dst argument refers to an array with a primitive component type.
* C - IndexOutOfBoundsException
* if copying would cause access of data outside array bounds.
* D - ArrayStoreException
* if an element in the src array could not be stored into the dest array because of a type mismatch
*/
private static void doArrayCopy(@JavaType(Object.class) StaticObject src, int srcPos, @JavaType(Object.class) StaticObject dest, int destPos, int length, Meta meta, SubstitutionProfiler profiler) {
if (StaticObject.isNull(src) || StaticObject.isNull(dest)) {
throw throwNullPointerEx(meta, profiler);
}
if (src.isForeignObject() || dest.isForeignObject()) {
// TODO: handle foreign arrays efficiently.
profiler.profile(FOREIGN_PROFILE);
handleForeignArray(src.isForeignObject() ? src.rawForeignObject() : src, srcPos, dest.isForeignObject() ? dest.rawForeignObject() : dest, destPos, length, ((ArrayKlass) dest.getKlass()).getComponentType(), meta, profiler);
return;
}
// Mimics hotspot implementation.
/*
* First, check that both given objects are arrays. This is done before bypassing checks and
* bounds checks (see JCK api/java_lang/System/index.html#Arraycopy: System2015)
*/
profiler.profile(GUEST_PROFILE);
if (!src.isArray() || !dest.isArray()) {
throw throwArrayStoreEx(meta, profiler);
}
// If both arrays are the same, a lot of checks can be bypassed
if (src == dest) {
profiler.profile(SAME_ARRAY_PROFILE);
/*
* Let host VM's arrayCopy implementation handle bounds. Guest type checking is useless
* here due to both array being the same.
*/
System.arraycopy(src.unwrap(), srcPos, dest.unwrap(), destPos, length);
return;
}
profiler.profile(DIFF_ARRAY_PROFILE);
Klass destType = ((ArrayKlass) dest.getKlass()).getComponentType();
Klass srcType = ((ArrayKlass) src.getKlass()).getComponentType();
if (destType.isPrimitive() || srcType.isPrimitive()) {
// One of the two arrays is a primitive array.
profiler.profile(DIFF_PRIMITIVE_ARRAYS_PROFILE);
if (srcType != destType) {
throw throwArrayStoreEx(meta, profiler);
}
/*
* Let host VM's arrayCopy implementation handle bounds. Guest type checking is useless
* here due to one of the two arrays being primitives.
*/
System.arraycopy(src.unwrap(), srcPos, dest.unwrap(), destPos, length);
return;
}
// Both arrays are reference arrays.
profiler.profile(DIFF_REFERENCE_ARRAYS_PROFILE);
/*
* Perform bounds checks BEFORE checking for length == 0. (see JCK
* api/java_lang/System/index.html#Arraycopy: System1001)
*/
boundsCheck(meta, src.length(), srcPos, dest.length(), destPos, length, profiler);
if (length == 0) {
profiler.profile(ZERO_LENGTH_PROFILE);
// All checks have been done, we can take the shortcut.
return;
}
if (destType.isAssignableFrom(srcType)) {
// We have guarantee we can copy, as all elements in src conform to dest
// type.
profiler.profile(SUBTYPE_ARRAYS_PROFILE);
System.arraycopy(src.unwrap(), srcPos, dest.unwrap(), destPos, length);
return;
}
/*
* Slow path (manual copy) (/ex: copying an Object[] to a String[]) requires individual type
* checks. Should rarely happen ( < 1% of cases).
*
* Use cases:
*
* - System startup.
*
* - MethodHandle and CallSite linking.
*/
profiler.profile(UNRELATED_TYPE_ARRAYS_PROFILE);
StaticObject[] s = src.unwrap();
StaticObject[] d = dest.unwrap();
for (int i = 0; i < length; i++) {
StaticObject cpy = s[i + srcPos];
if (!StaticObject.isNull(cpy) && !destType.isAssignableFrom(cpy.getKlass())) {
throw throwArrayStoreEx(meta, profiler);
}
d[destPos + i] = cpy;
}
}
use of com.oracle.truffle.espresso.impl.ArrayKlass in project graal by oracle.
the class VM method cloneForeignArray.
private static StaticObject cloneForeignArray(StaticObject array, Meta meta, InteropLibrary interop, ToEspressoNode toEspressoNode, SubstitutionProfiler profiler, char exceptionBranch) {
assert array.isForeignObject();
assert array.isArray();
int length;
try {
long longLength = interop.getArraySize(array.rawForeignObject());
if (longLength > Integer.MAX_VALUE) {
profiler.profile(exceptionBranch);
throw meta.throwExceptionWithMessage(meta.java_lang_CloneNotSupportedException, "Cannot clone a foreign array whose length does not fit in int");
}
if (longLength < 0) {
profiler.profile(exceptionBranch);
throw meta.throwExceptionWithMessage(meta.java_lang_NegativeArraySizeException, "Cannot clone a foreign array with negative length");
}
length = (int) longLength;
} catch (UnsupportedMessageException e) {
profiler.profile(exceptionBranch);
throw meta.throwExceptionWithMessage(meta.java_lang_CloneNotSupportedException, "Cannot clone a non-array foreign object as an array");
}
ArrayKlass arrayKlass = (ArrayKlass) array.getKlass();
Klass componentType = arrayKlass.getComponentType();
if (componentType.isPrimitive()) {
try {
switch(componentType.getJavaKind()) {
case Boolean:
boolean[] booleanArray = new boolean[length];
for (int i = 0; i < length; ++i) {
Object foreignElement = readForeignArrayElement(array, i, interop, meta, profiler, exceptionBranch);
booleanArray[i] = (boolean) toEspressoNode.execute(foreignElement, componentType);
}
return StaticObject.createArray(arrayKlass, booleanArray);
case Byte:
byte[] byteArray = new byte[length];
for (int i = 0; i < length; ++i) {
Object foreignElement = readForeignArrayElement(array, i, interop, meta, profiler, exceptionBranch);
byteArray[i] = (byte) toEspressoNode.execute(foreignElement, componentType);
}
return StaticObject.createArray(arrayKlass, byteArray);
case Short:
short[] shortArray = new short[length];
for (int i = 0; i < length; ++i) {
Object foreignElement = readForeignArrayElement(array, i, interop, meta, profiler, exceptionBranch);
shortArray[i] = (short) toEspressoNode.execute(foreignElement, componentType);
}
return StaticObject.createArray(arrayKlass, shortArray);
case Char:
char[] charArray = new char[length];
for (int i = 0; i < length; ++i) {
Object foreignElement = readForeignArrayElement(array, i, interop, meta, profiler, exceptionBranch);
charArray[i] = (char) toEspressoNode.execute(foreignElement, componentType);
}
return StaticObject.createArray(arrayKlass, charArray);
case Int:
int[] intArray = new int[length];
for (int i = 0; i < length; ++i) {
Object foreignElement = readForeignArrayElement(array, i, interop, meta, profiler, exceptionBranch);
intArray[i] = (int) toEspressoNode.execute(foreignElement, componentType);
}
return StaticObject.createArray(arrayKlass, intArray);
case Float:
float[] floatArray = new float[length];
for (int i = 0; i < length; ++i) {
Object foreignElement = readForeignArrayElement(array, i, interop, meta, profiler, exceptionBranch);
floatArray[i] = (float) toEspressoNode.execute(foreignElement, componentType);
}
return StaticObject.createArray(arrayKlass, floatArray);
case Long:
long[] longArray = new long[length];
for (int i = 0; i < length; ++i) {
Object foreignElement = readForeignArrayElement(array, i, interop, meta, profiler, exceptionBranch);
longArray[i] = (long) toEspressoNode.execute(foreignElement, componentType);
}
return StaticObject.createArray(arrayKlass, longArray);
case Double:
double[] doubleArray = new double[length];
for (int i = 0; i < length; ++i) {
Object foreignElement = readForeignArrayElement(array, i, interop, meta, profiler, exceptionBranch);
doubleArray[i] = (double) toEspressoNode.execute(foreignElement, componentType);
}
return StaticObject.createArray(arrayKlass, doubleArray);
case Object:
case Void:
case ReturnAddress:
case Illegal:
CompilerDirectives.transferToInterpreter();
throw EspressoError.shouldNotReachHere("Unexpected primitive kind: " + componentType.getJavaKind());
}
} catch (UnsupportedTypeException e) {
profiler.profile(exceptionBranch);
throw meta.throwExceptionWithMessage(meta.java_lang_ClassCastException, "Cannot cast an element of a foreign array to the declared component type");
}
}
StaticObject[] newArray = new StaticObject[length];
for (int i = 0; i < length; ++i) {
Object foreignElement = readForeignArrayElement(array, i, interop, meta, profiler, exceptionBranch);
try {
newArray[i] = (StaticObject) toEspressoNode.execute(foreignElement, componentType);
} catch (UnsupportedTypeException e) {
profiler.profile(exceptionBranch);
throw meta.throwExceptionWithMessage(meta.java_lang_ClassCastException, "Cannot cast an element of a foreign array to the declared component type");
}
}
return StaticObject.createArray(arrayKlass, newArray);
}
Aggregations