1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dalvik.annotation.optimization;
18 
19 import java.lang.annotation.ElementType;
20 import java.lang.annotation.Retention;
21 import java.lang.annotation.RetentionPolicy;
22 import java.lang.annotation.Target;
23 
24 /**
25  * An ART runtime built-in optimization for {@code native} methods to speed up JNI transitions:
26  * Methods that are annotated with {@literal @}{@code CriticalNative} use the fastest
27  * available JNI transitions from managed code to the native code and back.
28  * This annotation can be applied only to native methods that do not use managed
29  * objects (in parameters or return values, or as an implicit {@code this}).
30  *
31  * <p>
32  * The {@literal @}{@code CriticalNative} annotation changes the JNI transition ABI.
33  * The native implementation must exclude the {@code JNIEnv} and {@code jclass} parameters
34  * from its function signature.
35  * </p>
36  *
37  * <p>
38  * While executing a {@literal @}{@code CriticalNative} method, the garbage collection cannot
39  * suspend the thread for essential work and may become blocked. Use with caution. Do not use
40  * this annotation for long-running methods, including usually-fast, but generally unbounded,
41  * methods. In particular, the code should not perform significant I/O operations or acquire
42  * native locks that can be held for a long time. (Some logging or native allocations, which
43  * internally acquire native locks for a short time, are generally OK. However, as the cost
44  * of several such operations adds up, the {@literal @}{@code CriticalNative} performance gain
45  * can become insignificant and overshadowed by potential GC delays.)
46  * </p>
47  *
48  * <p>
49  * For performance critical methods that need this annotation, it is strongly recommended
50  * to explicitly register the method(s) with JNI {@code RegisterNatives} instead of relying
51  * on the built-in dynamic JNI linking.
52  * </p>
53  *
54  * <p>
55  * The {@literal @}{@code CriticalNative} optimization was implemented for system use since
56  * Android 8 and became CTS-tested public API in Android 14. Developers aiming for maximum
57  * compatibility should avoid calling {@literal @}{@code CriticalNative} methods on Android 13-.
58  * The optimization is likely to work also on Android 8-13 devices (after all, it was used
59  * in the system, albeit without the strong CTS guarantees), especially those that use
60  * unmodified versions of ART, such as Android 12+ devices with the official ART Module.
61  * The built-in dynamic JNI linking is working only in Android 12+, the explicit registration
62  * with JNI {@code RegisterNatives} is strictly required for running on Android versions 8-11.
63  * The annotation is ignored on Android 7-, so the ABI mismatch would lead to wrong argument
64  * marshalling and likely crashes.
65  * </p>
66  *
67  * <p>
68  * A similar annotation, {@literal @}{@link FastNative}, exists for methods that need fast
69  * transitions but absolutely need to use managed objects, whether as the implicit {@code this}
70  * for non-static methods, or method arguments, return values or to otherwise call back to
71  * managed code (say, static methods), or access managed heap objects (say, static fields).
72  * </p>
73  *
74  * <p>
75  * Performance of JNI transitions:
76  * <ul>
77  * <li>Regular JNI cost in nanoseconds: 115
78  * <li>Fast {@code (!)} JNI cost in nanoseconds: 60
79  * <li>{@literal @}{@link FastNative} cost in nanoseconds: 35
80  * <li>{@literal @}{@code CriticalNative} cost in nanoseconds: 25
81  * </ul>
82  * (Measured on angler-userdebug in 07/2016).
83  * </p>
84  *
85  * <p>
86  * <b>Deadlock Warning:</b> As a rule of thumb, any native locks acquired in a
87  * {@literal @}{@link CriticalNative} call (despite the above warning that this is an unbounded
88  * operation that can block GC for a long time) must be released before returning to managed code.
89  * </p>
90  *
91  * <p>
92  * Say some code does:
93  *
94  * <code>
95  * critical_native_call_to_grab_a_lock();
96  * does_some_java_work();
97  * critical_native_call_to_release_a_lock();
98  * </code>
99  *
100  * <p>
101  * This code can lead to deadlocks. Say thread 1 just finishes
102  * {@code critical_native_call_to_grab_a_lock()} and is in {@code does_some_java_work()}.
103  * GC kicks in and suspends thread 1. Thread 2 now is in
104  * {@code critical_native_call_to_grab_a_lock()} but is blocked on grabbing the
105  * native lock since it's held by thread 1. Now thread suspension can't finish
106  * since thread 2 can't be suspended since it's doing CriticalNative JNI.
107  * </p>
108  *
109  * <p>
110  * Normal natives don't have the issue since once it's executing in native code,
111  * it is considered suspended from the runtime's point of view.
112  * CriticalNative natives however don't do the state transition done by the normal natives.
113  * </p>
114  *
115  * <p>
116  * This annotation has no effect when used with non-native methods.
117  * </p>
118  *
119  * <p>
120  * The runtime shall throw a {@link java.lang.VerifyError} during verification if this annotation
121  * is present on a native method that is non-static, or contains object parameters, or returns an
122  * object.
123  * </p>
124  */
125 @Retention(RetentionPolicy.CLASS)  // Save memory, don't instantiate as an object at runtime.
126 @Target(ElementType.METHOD)
127 public @interface CriticalNative {}
128