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