Search in sources :

Example 1 with EnumArrayLookup

use of com.oracle.svm.core.c.enums.EnumArrayLookup in project graal by oracle.

the class SizeAndSignednessVerifier method visitEnumInfo.

@Override
protected void visitEnumInfo(EnumInfo enumInfo) {
    super.visitEnumInfo(enumInfo);
    Map<Enum<?>, Long> javaToC = new HashMap<>();
    Map<Long, Enum<?>> cToJava = new HashMap<>();
    @SuppressWarnings("rawtypes") Class<? extends Enum> enumClass = null;
    long minLookupValue = Long.MAX_VALUE;
    long maxLookupValue = Long.MIN_VALUE;
    for (ElementInfo child : enumInfo.getChildren()) {
        if (child instanceof EnumConstantInfo) {
            EnumConstantInfo valueInfo = (EnumConstantInfo) child;
            long cValue = (Long) valueInfo.getValueInfo().getProperty();
            Enum<?> javaValue = valueInfo.getEnumValue();
            assert enumClass == null || enumClass == javaValue.getClass();
            enumClass = javaValue.getClass();
            assert javaToC.get(javaValue) == null;
            javaToC.put(javaValue, Long.valueOf(cValue));
            if (enumInfo.getNeedsLookup() && valueInfo.getIncludeInLookup()) {
                if (cToJava.get(cValue) != null) {
                    nativeLibs.addError("C value is not unique, so reverse lookup from C to Java is not possible: " + cToJava.get(cValue) + " and " + javaValue + " hava same C value " + cValue, valueInfo.getAnnotatedElement());
                }
                cToJava.put(cValue, javaValue);
                minLookupValue = Math.min(minLookupValue, cValue);
                maxLookupValue = Math.max(maxLookupValue, cValue);
            }
        }
    }
    long[] javaToCArray = new long[javaToC.size()];
    for (Map.Entry<Enum<?>, Long> entry : javaToC.entrySet()) {
        int idx = entry.getKey().ordinal();
        assert idx >= 0 && idx < javaToCArray.length && javaToCArray[idx] == 0 : "ordinal values are defined as unique and consecutive";
        javaToCArray[idx] = entry.getValue();
    }
    EnumRuntimeData runtimeData;
    if (cToJava.size() > 0) {
        assert minLookupValue <= maxLookupValue;
        long spread = maxLookupValue - minLookupValue;
        assert spread >= cToJava.size() - 1;
        /*
             * We have a choice between an array-based lookup and keeping the HashMap. Since HashMap
             * has a quite high memory footprint, an array is more compact even when most array
             * elements are null.
             */
        if (spread < cToJava.size() * 5L && spread >= 0 && spread < Integer.MAX_VALUE) {
            long offset = minLookupValue;
            Enum<?>[] cToJavaArray = (Enum[]) Array.newInstance(enumClass, (int) spread + 1);
            for (Map.Entry<Long, Enum<?>> entry : cToJava.entrySet()) {
                long idx = entry.getKey() - offset;
                assert idx >= 0 && idx < cToJavaArray.length;
                assert cToJavaArray[(int) idx] == null;
                cToJavaArray[(int) idx] = entry.getValue();
            }
            runtimeData = new EnumArrayLookup(javaToCArray, offset, cToJavaArray);
        } else {
            runtimeData = new EnumMapLookup(javaToCArray, cToJava);
        }
    } else {
        runtimeData = new EnumNoLookup(javaToCArray);
    }
    enumInfo.setRuntimeData(runtimeData);
}
Also used : EnumConstantInfo(com.oracle.svm.hosted.c.info.EnumConstantInfo) HashMap(java.util.HashMap) ElementInfo(com.oracle.svm.hosted.c.info.ElementInfo) EnumMapLookup(com.oracle.svm.core.c.enums.EnumMapLookup) EnumArrayLookup(com.oracle.svm.core.c.enums.EnumArrayLookup) EnumRuntimeData(com.oracle.svm.core.c.enums.EnumRuntimeData) EnumNoLookup(com.oracle.svm.core.c.enums.EnumNoLookup) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

EnumArrayLookup (com.oracle.svm.core.c.enums.EnumArrayLookup)1 EnumMapLookup (com.oracle.svm.core.c.enums.EnumMapLookup)1 EnumNoLookup (com.oracle.svm.core.c.enums.EnumNoLookup)1 EnumRuntimeData (com.oracle.svm.core.c.enums.EnumRuntimeData)1 ElementInfo (com.oracle.svm.hosted.c.info.ElementInfo)1 EnumConstantInfo (com.oracle.svm.hosted.c.info.EnumConstantInfo)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1