1 /*
2  * Copyright (C) 2018 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  * Allow the implementation to eliminate object references that are no longer needed, just as it
26  * would eliminate other dead variables.
27  *
28  * The annotation applies to methods of the annotated class, and to methods declared in any inner
29  * class declared inside the annotated class. It does not apply to methods declared in subclasses
30  * or superclasses. It is ignored for interfaces.
31  *
32  * The annotation promises that the implementation of this class remains correct if objects are
33  * finalized, and java.lang.ref References are enqueued, as soon as the JLS allows them to be,
34  * i.e. after they are allowed to be marked as unreachable according to the JLS. Historically, the
35  * Android runtime has garbage collected objects later than the JLS would allow, by retaining
36  * objects references that are no longer needed. Some classes that implement finalize() or make
37  * use of java.lang.ref APIs may have grown to depend on this historic Android runtime behavior.
38  *
39  * For example, consider the method
40  *
41  * <pre> {@code
42  *   void m() {
43  *     long tmpNativePtr = this.nativePtrField;
44  *     foo(tmpNativePtr);
45  *   }}</pre>
46  *
47  * where foo() accesses the memory M referenced by {@code this.nativePtrField}.  Once {@code
48  * tmpNativePtr} is computed, this object itself is no longer needed, and may be unreachable by JLS
49  * rules.  This may cause this object to be finalized, and M to be deleted, while {@code foo()} is
50  * still running and accessing M.
51  *
52  * Historically, ART has avoided this by keeping "this" reachable until {@code m()} completes.
53  * (Class file and dex level tools may not always do the same.) With this annotation, the Android
54  * runtime may no longer retain the "this" reference, again making the erroneous early
55  * finalization possible.
56  *
57  * The above example code could be made safe to annotate with {@code DeadReferenceSafe} by either
58  * adding Reference.reachabilityFence(this) to the end of {@code m()} and similar methods, or
59  * (Android-only) by declaring nativePtrField with a {@code @ReachabilitySensitive} annotation.
60  *
61  * The annotation will normally be safe for classes that do not use or rely on finalization-like
62  * cleanup mechanisms. It is unlikely to be safe for classes that use {@code java.lang.ref} or
63  * finalization but never mention {@code reachabilityFence()} or {@code @ReachabilitySensitive}.
64  *
65  * When it is safe, this annotation might result in better performance because more memory can be
66  * reclaimed earlier by the garbage collector.
67  *
68  * Since this is technically safe for all classes that follow Java language rules, we expect this
69  * to eventually become the default. This annotation allows us to selectively enable dead
70  * reference elimination during the transition, and while the details of {@code
71  * @ReachabilitySensitive} (like its name) are in flux.
72  *
73  * @hide
74  */
75 @Retention(RetentionPolicy.RUNTIME)  // Let the GC or interpreter ask, if they need to.
76 @Target({ElementType.TYPE})
77 public @interface DeadReferenceSafe {}
78