use of org.graalvm.jniutils.JNI in project graal by oracle.
the class LibGraalUtil method checkToLibGraalCalls.
/*----------------- CHECKING ------------------*/
/**
* Checks that all {@code ToLibGraal}s are implemented and their HotSpot/libgraal ends points
* match.
*/
@Platforms(Platform.HOSTED_ONLY.class)
public static void checkToLibGraalCalls(Class<?> toLibGraalEntryPointsClass, Class<?> toLibGraalCallsClass, Class<? extends Annotation> annotationClass) throws InternalError {
try {
Method valueMethod = annotationClass.getDeclaredMethod("value");
Type t = valueMethod.getGenericReturnType();
check(t instanceof Class<?> && ((Class<?>) t).isEnum(), "Annotation value must be enum.");
@SuppressWarnings("unchecked") Set<? extends Enum<?>> unimplemented = EnumSet.allOf(((Class<?>) t).asSubclass(Enum.class));
for (Method libGraalMethod : toLibGraalEntryPointsClass.getDeclaredMethods()) {
Annotation call = libGraalMethod.getAnnotation(annotationClass);
if (call != null) {
check(Modifier.isStatic(libGraalMethod.getModifiers()), "Method annotated by %s must be static: %s", annotationClass, libGraalMethod);
CEntryPoint ep = libGraalMethod.getAnnotation(CEntryPoint.class);
check(ep != null, "Method annotated by %s must also be annotated by %s: %s", annotationClass, CEntryPoint.class, libGraalMethod);
String name = ep.name();
String prefix = "Java_" + toLibGraalCallsClass.getName().replace('.', '_') + '_';
check(name.startsWith(prefix), "Method must be a JNI entry point for a method in %s: %s", toLibGraalCallsClass, libGraalMethod);
name = name.substring(prefix.length());
Method hsMethod = findHSMethod(toLibGraalCallsClass, name, annotationClass);
Class<?>[] libGraalParameters = libGraalMethod.getParameterTypes();
Class<?>[] hsParameters = hsMethod.getParameterTypes();
check(hsParameters.length + 2 == libGraalParameters.length, "%s should have 2 more parameters than %s", libGraalMethod, hsMethod);
check(libGraalParameters.length >= 3, "Expect at least 3 parameters: %s", libGraalMethod);
check(libGraalParameters[0] == JNI.JNIEnv.class, "Parameter 0 must be of type %s: %s", JNI.JNIEnv.class, libGraalMethod);
check(libGraalParameters[1] == JNI.JClass.class, "Parameter 1 must be of type %s: %s", JNI.JClass.class, libGraalMethod);
check(libGraalParameters[2] == long.class, "Parameter 2 must be of type long: %s", libGraalMethod);
check(hsParameters[0] == long.class, "Parameter 0 must be of type long: %s", hsMethod);
for (int i = 3, j = 1; i < libGraalParameters.length; i++, j++) {
Class<?> libgraal = libGraalParameters[i];
Class<?> hs = hsParameters[j];
Class<?> hsExpect;
if (hs.isPrimitive()) {
hsExpect = libgraal;
} else {
if (libgraal == JNI.JString.class) {
hsExpect = String.class;
} else if (libgraal == JNI.JByteArray.class) {
hsExpect = byte[].class;
} else if (libgraal == JNI.JLongArray.class) {
hsExpect = long[].class;
} else if (libgraal == JNI.JObjectArray.class) {
hsExpect = Object[].class;
} else {
check(libgraal == JNI.JObject.class, "must be");
hsExpect = Object.class;
}
}
check(hsExpect.isAssignableFrom(hs), "HotSpot parameter %d (%s) incompatible with libgraal parameter %d (%s): %s", j, hs.getName(), i, libgraal.getName(), hsMethod);
}
unimplemented.remove(valueMethod.invoke(call));
}
}
check(unimplemented.isEmpty(), "Unimplemented libgraal calls: %s", unimplemented);
} catch (ReflectiveOperationException e) {
throw new InternalError(e);
}
}
use of org.graalvm.jniutils.JNI in project graal by oracle.
the class MBeanProxy method defineClassesInHotSpot.
/**
* Uses JNI to define the classes in HotSpot heap.
*/
private static void defineClassesInHotSpot(JNI.JNIEnv env) {
Pointer barrier = getDefineClassesStatePointer();
JNI.JObject classLoader = JNIUtil.getJVMCIClassLoader(env);
Runnable defineAction = () -> {
defineClassInHotSpot(env, classLoader, HS_CALLS_CLASS);
long entryPoints = defineClassInHotSpot(env, classLoader, HS_ENTRYPOINTS_CLASS).rawValue();
defineClassInHotSpot(env, classLoader, HS_BEAN_CLASS);
defineClassInHotSpot(env, classLoader, HS_BEAN_FACTORY_CLASS);
defineClassInHotSpot(env, classLoader, HS_PUSHBACK_ITER_CLASS);
defineClassInHotSpot(env, classLoader, HS_AGGREGATED_MEMORY_POOL_BEAN_CLASS);
fromLibGraalEntryPoints = JNIUtil.NewGlobalRef(env, WordFactory.pointer(entryPoints), "Class<" + HS_ENTRYPOINTS_CLASS.binaryName + ">");
};
Runnable loadAction = () -> {
long entryPoints = JNIUtil.findClass(env, classLoader, HS_ENTRYPOINTS_CLASS.binaryName, true).rawValue();
fromLibGraalEntryPoints = JNIUtil.NewGlobalRef(env, WordFactory.pointer(entryPoints), "Class<" + HS_ENTRYPOINTS_CLASS.binaryName + ">");
};
runGuarded(barrier, defineAction, loadAction);
}
use of org.graalvm.jniutils.JNI in project graal by oracle.
the class MBeanProxy method defineClassInHotSpot.
/**
* Defines a class in HotSpot heap using JNI.
*
* @param env the {@code JNIEnv}
* @param classLoader the class loader to define class in.
* @param classData the class to define in HotSpot
* @return the defined class
*/
private static JNI.JClass defineClassInHotSpot(JNI.JNIEnv env, JNI.JObject classLoader, ClassData classData) {
CCharPointer classDataPointer = UnmanagedMemory.malloc(classData.byteCode.length);
ByteBuffer buffer = CTypeConversion.asByteBuffer(classDataPointer, classData.byteCode.length);
buffer.put(classData.byteCode);
try (CTypeConversion.CCharPointerHolder className = CTypeConversion.toCString(classData.binaryName)) {
JNI.JClass definedClass = JNIUtil.DefineClass(env, className.get(), classLoader, classDataPointer, classData.byteCode.length);
return definedClass;
} finally {
UnmanagedMemory.free(classDataPointer);
// LinkageError is allowed, the class may be already defined
JNIExceptionWrapper.wrapAndThrowPendingJNIException(env, ExceptionHandler.allowExceptions(LinkageError.class));
}
}
use of org.graalvm.jniutils.JNI in project graal by oracle.
the class JMXToLibGraalEntryPoints method mapToRaw.
/**
* Encodes a {@link Map} of properties into JNI byte array using {@link OptionsEncoder}.
*/
private static JNI.JByteArray mapToRaw(JNI.JNIEnv env, Map<String, Object> map) {
byte[] serialized = OptionsEncoder.encode(map);
JNI.JByteArray res = JNIUtil.NewByteArray(env, serialized.length);
CCharPointer elems = JNIUtil.GetByteArrayElements(env, res, WordFactory.nullPointer());
try {
CTypeConversion.asByteBuffer(elems, serialized.length).put(serialized);
} finally {
JNIUtil.ReleaseByteArrayElements(env, res, elems, JNI.JArray.MODE_WRITE_RELEASE);
}
return res;
}
Aggregations