xref: /aosp_15_r20/art/test/1915-get-set-local-current-thread/src/art/Test1915.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2017 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 art;
18 
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.Executable;
21 import java.lang.reflect.Method;
22 import java.nio.ByteBuffer;
23 import java.util.concurrent.Semaphore;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.function.Function;
29 import java.util.function.Predicate;
30 import java.util.function.Supplier;
31 import java.util.function.Consumer;
32 
33 public class Test1915 {
34     public static final int SET_VALUE = 1337;
35     public static final String TARGET_VAR = "TARGET";
36 
reportValue(Object val)37     public static void reportValue(Object val) {
38         System.out.println("\tValue is '" + val + "'");
39     }
40     public static interface ThrowRunnable {
run()41         public void run() throws Exception;
42     }
43 
IntMethod(ThrowRunnable safepoint)44     public static void IntMethod(ThrowRunnable safepoint) throws Exception {
45         int TARGET = 42;
46         safepoint.run();
47         reportValue(TARGET);
48     }
49 
run()50     public static void run() throws Exception {
51         Locals.EnableLocalVariableAccess();
52         final Method target = Test1915.class.getDeclaredMethod("IntMethod", ThrowRunnable.class);
53         // Get Variable.
54         System.out.println("GetLocalInt on current thread!");
55         IntMethod(() -> {
56             StackTrace.StackFrameData frame = FindStackFrame(target);
57             int depth = FindExpectedFrameDepth(frame);
58             int slot = FindSlot(frame);
59             int value = Locals.GetLocalVariableInt(Thread.currentThread(), depth, slot);
60             System.out.println("From GetLocalInt(), value is " + value);
61         });
62         // Set Variable.
63         System.out.println("SetLocalInt on current thread!");
64         IntMethod(() -> {
65             StackTrace.StackFrameData frame = FindStackFrame(target);
66             int depth = FindExpectedFrameDepth(frame);
67             int slot = FindSlot(frame);
68             Locals.SetLocalVariableInt(Thread.currentThread(), depth, slot, SET_VALUE);
69         });
70     }
71 
FindSlot(StackTrace.StackFrameData frame)72     public static int FindSlot(StackTrace.StackFrameData frame) throws Exception {
73         long loc = frame.current_location;
74         for (Locals.VariableDescription var : Locals.GetLocalVariableTable(frame.method)) {
75             if (var.start_location <= loc &&
76                     var.length + var.start_location > loc &&
77                     var.name.equals(TARGET_VAR)) {
78                 return var.slot;
79             }
80         }
81         throw new Error(
82                 "Unable to find variable " + TARGET_VAR + " in " + frame.method + " at loc " + loc);
83     }
84 
FindExpectedFrameDepth(StackTrace.StackFrameData frame)85     public static int FindExpectedFrameDepth(StackTrace.StackFrameData frame) throws Exception {
86         // Adjust the 'frame' depth since it is modified by:
87         // +1 for Get/SetLocalVariableInt in future.
88         // -1 for FindStackFrame
89         // -1 for GetStackTrace
90         // -1 for GetStackTraceNative
91         // ------------------------------
92         // -2
93         return frame.depth - 2;
94     }
95 
FindStackFrame(Method target)96     private static StackTrace.StackFrameData FindStackFrame(Method target) {
97         for (StackTrace.StackFrameData frame : StackTrace.GetStackTrace(Thread.currentThread())) {
98             if (frame.method.equals(target)) {
99                 return frame;
100             }
101         }
102         throw new Error("Unable to find stack frame in method " + target);
103     }
104 }
105 
106