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);
}
Aggregations