Search in sources :

Example 1 with ArrayKlass

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);
    }
}
Also used : Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) Unsafe(sun.misc.Unsafe) TruffleObject(com.oracle.truffle.api.interop.TruffleObject) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject)

Example 2 with ArrayKlass

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;
}
Also used : ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass)

Example 3 with ArrayKlass

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);
}
Also used : ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass)

Example 4 with ArrayKlass

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;
    }
}
Also used : Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass)

Example 5 with ArrayKlass

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);
}
Also used : ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) NoSafepoint(com.oracle.truffle.espresso.jni.NoSafepoint) Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) UnsupportedMessageException(com.oracle.truffle.api.interop.UnsupportedMessageException) UnsupportedTypeException(com.oracle.truffle.api.interop.UnsupportedTypeException) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) TruffleObject(com.oracle.truffle.api.interop.TruffleObject)

Aggregations

ArrayKlass (com.oracle.truffle.espresso.impl.ArrayKlass)7 ObjectKlass (com.oracle.truffle.espresso.impl.ObjectKlass)5 Klass (com.oracle.truffle.espresso.impl.Klass)4 StaticObject (com.oracle.truffle.espresso.runtime.StaticObject)4 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)3 Unsafe (sun.misc.Unsafe)2 TruffleSafepoint (com.oracle.truffle.api.TruffleSafepoint)1 UnsupportedMessageException (com.oracle.truffle.api.interop.UnsupportedMessageException)1 UnsupportedTypeException (com.oracle.truffle.api.interop.UnsupportedTypeException)1 ExplodeLoop (com.oracle.truffle.api.nodes.ExplodeLoop)1 NoSafepoint (com.oracle.truffle.espresso.jni.NoSafepoint)1