Skip to content

Commit

Permalink
Update code documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
peter-hofer committed Jul 11, 2022
1 parent 9d279ca commit 0e0a4a2
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public static JNIAccessFeature singleton() {
return ImageSingletons.lookup(JNIAccessFeature.class);
}

/** A group of wrappers for the same target signature, but different JNI call variants. */
static final class JNIJavaCallVariantWrapperGroup {
static final JNIJavaCallVariantWrapperGroup NONE = new JNIJavaCallVariantWrapperGroup(null, null, null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.util.Arrays;
import java.util.List;

import org.graalvm.nativeimage.c.function.CFunctionPointer;
import org.graalvm.nativeimage.hosted.Feature;

import com.oracle.svm.core.jni.JNIRuntimeAccess;
Expand All @@ -47,21 +46,27 @@
* </p>
*
* <p>
* Native-to-Java call wrappers are generated as follows:
* Native-to-Java call wrappers are generated by {@link JNIAccessFeature} as follows:
* <ol>
* <li>{@link JNIAccessFeature} creates a {@link JNIJavaCallWrapperMethod} for each method that is
* callable from JNI, associates it with its corresponding {@link JNIAccessibleMethod}, and
* registers it as an entry point. The method provides a graph that performs the Java method
* invocation from native code and that is visible to the analysis.</li>
* <li>Because all {@link JNIJavaCallWrapperMethod call wrappers} are entry points, the call
* wrappers and any code that is reachable through them is compiled.</li>
* <li>Before compilation, a {@link CFunctionPointer} is created for each call wrapper that is
* eventually filled with the call wrapper's final entry point address.</li>
* <li>Looking up a Java method via JNI finds its {@link JNIAccessibleMethod}, reads its call
* wrapper's entry address from the {@link CFunctionPointer}, and returns it as the jmethodID. The
* JNI functions for calling methods, named
* {@code Call[Static?][ReturnType]Method(env, obj, jmethodID)} only perform a jump to the provided
* jmethodID argument, and the call wrapper code takes over execution.</li>
* <li>A {@link JNICallTrampolineMethod} exists for each way how a Java method can be invoked
* (regular--including static--, and nonvirtual) and variant of passing arguments via JNI (varargs,
* array, va_list), and implements the JNI {@code Call{Static,Nonvirtual}?<ReturnKind>Method{V,A}?}
* functions, e.g. {@code CallIntMethod} or {@code CallNonvirtualObjectMethodA}. These trampolines
* dispatch to the {@link JNIJavaCallVariantWrapperMethod} corresponding to the call.</li>
* <li>{@link JNIJavaCallVariantWrapperMethod}s are generated so that for each method which can be
* called via JNI and for each call variant, there exists a wrapper method which is compatible with
* the called method's signature. Each wrapper method extracts its arguments according to its call
* variant and passes them to a {@link JNIJavaCallWrapperMethod}.</li>
* <li>A {@link JNIJavaCallWrapperMethod} for a specific signature resolves object handles in its
* arguments (if any) and calls the specific Java method either by dynamic dispatch via an object's
* vtable or via a function pointer for static or nonvirtual calls.<br/>
* Separating call-variant wrappers and call wrappers significantly reduces code size because
* call-variant wrappers can be made to be compatible to more different signatures than call
* wrappers could, and each target signature requires providing three to six (for nonvirtual calls)
* compatible call variant wrappers.</li>
* <li>All dispatching is done via a {@code jmethodID}, which native code passes to the JNI call
* functions and which is actually a reference to a {@link JNIAccessibleMethod} object containing
* the function pointers for the wrapper methods and the target method and the vtable index.</li>
* </ol>
* </p>
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Signature;

/**
* Generated code for taking arguments according to a specific signature and {@link CallVariant} and
* passing them on to a {@link JNIJavaCallWrapperMethod} which does the actual Java call. This
* method also enters the isolate and catches any exception.
*/
public class JNIJavaCallVariantWrapperMethod extends EntryPointCallStubMethod {
public enum CallVariant {
VARARGS,
Expand Down

0 comments on commit 0e0a4a2

Please sign in to comment.