xref: /aosp_15_r20/art/test/916-obsolete-jit/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker 
18*795d594fSAndroid Build Coastguard Worker import art.Redefinition;
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker import java.util.function.Consumer;
21*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method;
22*795d594fSAndroid Build Coastguard Worker import java.util.Base64;
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker public class Main {
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker     // import java.util.function.Consumer;
27*795d594fSAndroid Build Coastguard Worker     //
28*795d594fSAndroid Build Coastguard Worker     // class Transform {
29*795d594fSAndroid Build Coastguard Worker     //     private void Start(Consumer<String> reporter) {
30*795d594fSAndroid Build Coastguard Worker     //         reporter.accept("Hello - private - Transformed");
31*795d594fSAndroid Build Coastguard Worker     //     }
32*795d594fSAndroid Build Coastguard Worker     //
33*795d594fSAndroid Build Coastguard Worker     //     private void Finish(Consumer<String> reporter) {
34*795d594fSAndroid Build Coastguard Worker     //        reporter.accept("Goodbye - private - Transformed");
35*795d594fSAndroid Build Coastguard Worker     //     }
36*795d594fSAndroid Build Coastguard Worker     //
37*795d594fSAndroid Build Coastguard Worker     //     public void sayHi(Runnable r, Consumer<String> reporter) {
38*795d594fSAndroid Build Coastguard Worker     //         reporter.accept("pre Start private method call - Transformed");
39*795d594fSAndroid Build Coastguard Worker     //         Start(reporter);
40*795d594fSAndroid Build Coastguard Worker     //         reporter.accept("post Start private method call - Transformed");
41*795d594fSAndroid Build Coastguard Worker     //         r.run();
42*795d594fSAndroid Build Coastguard Worker     //         reporter.accept("pre Finish private method call - Transformed");
43*795d594fSAndroid Build Coastguard Worker     //         Finish(reporter);
44*795d594fSAndroid Build Coastguard Worker     //         reporter.accept("post Finish private method call - Transformed");
45*795d594fSAndroid Build Coastguard Worker     //     }
46*795d594fSAndroid Build Coastguard Worker     // }
47*795d594fSAndroid Build Coastguard Worker     private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
48*795d594fSAndroid Build Coastguard Worker             "yv66vgAAADQAMAoADQAcCAAdCwAeAB8IACAIACEKAAwAIggAIwsAJAAlCAAmCgAMACcIACgHACkH" +
49*795d594fSAndroid Build Coastguard Worker             "ACoBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAFU3RhcnQBACAoTGph" +
50*795d594fSAndroid Build Coastguard Worker             "dmEvdXRpbC9mdW5jdGlvbi9Db25zdW1lcjspVgEACVNpZ25hdHVyZQEANChMamF2YS91dGlsL2Z1" +
51*795d594fSAndroid Build Coastguard Worker             "bmN0aW9uL0NvbnN1bWVyPExqYXZhL2xhbmcvU3RyaW5nOz47KVYBAAZGaW5pc2gBAAVzYXlIaQEA" +
52*795d594fSAndroid Build Coastguard Worker             "NChMamF2YS9sYW5nL1J1bm5hYmxlO0xqYXZhL3V0aWwvZnVuY3Rpb24vQ29uc3VtZXI7KVYBAEgo" +
53*795d594fSAndroid Build Coastguard Worker             "TGphdmEvbGFuZy9SdW5uYWJsZTtMamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVyPExqYXZhL2xh" +
54*795d594fSAndroid Build Coastguard Worker             "bmcvU3RyaW5nOz47KVYBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAA4ADwEAHUhlbGxv" +
55*795d594fSAndroid Build Coastguard Worker             "IC0gcHJpdmF0ZSAtIFRyYW5zZm9ybWVkBwArDAAsAC0BAB9Hb29kYnllIC0gcHJpdmF0ZSAtIFRy" +
56*795d594fSAndroid Build Coastguard Worker             "YW5zZm9ybWVkAQArcHJlIFN0YXJ0IHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAwA" +
57*795d594fSAndroid Build Coastguard Worker             "EgATAQAscG9zdCBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQHAC4MAC8A" +
58*795d594fSAndroid Build Coastguard Worker             "DwEALHByZSBGaW5pc2ggcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAAWABMBAC1w" +
59*795d594fSAndroid Build Coastguard Worker             "b3N0IEZpbmlzaCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQBAAlUcmFuc2Zvcm0B" +
60*795d594fSAndroid Build Coastguard Worker             "ABBqYXZhL2xhbmcvT2JqZWN0AQAbamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVyAQAGYWNjZXB0" +
61*795d594fSAndroid Build Coastguard Worker             "AQAVKExqYXZhL2xhbmcvT2JqZWN0OylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuACAADAAN" +
62*795d594fSAndroid Build Coastguard Worker             "AAAAAAAEAAAADgAPAAEAEAAAAB0AAQABAAAABSq3AAGxAAAAAQARAAAABgABAAAAEwACABIAEwAC" +
63*795d594fSAndroid Build Coastguard Worker             "ABAAAAAlAAIAAgAAAAkrEgK5AAMCALEAAAABABEAAAAKAAIAAAAVAAgAFgAUAAAAAgAVAAIAFgAT" +
64*795d594fSAndroid Build Coastguard Worker             "AAIAEAAAACUAAgACAAAACSsSBLkAAwIAsQAAAAEAEQAAAAoAAgAAABkACAAaABQAAAACABUAAQAX" +
65*795d594fSAndroid Build Coastguard Worker             "ABgAAgAQAAAAZQACAAMAAAAxLBIFuQADAgAqLLcABiwSB7kAAwIAK7kACAEALBIJuQADAgAqLLcA" +
66*795d594fSAndroid Build Coastguard Worker             "CiwSC7kAAwIAsQAAAAEAEQAAACIACAAAAB0ACAAeAA0AHwAVACAAGwAhACMAIgAoACMAMAAkABQA" +
67*795d594fSAndroid Build Coastguard Worker             "AAACABkAAQAaAAAAAgAb");
68*795d594fSAndroid Build Coastguard Worker     private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
69*795d594fSAndroid Build Coastguard Worker             "ZGV4CjAzNQBc8wr9PcHqnOR61m+0kimXTSddVMToJPuYBQAAcAAAAHhWNBIAAAAAAAAAAOAEAAAc" +
70*795d594fSAndroid Build Coastguard Worker             "AAAAcAAAAAYAAADgAAAABAAAAPgAAAAAAAAAAAAAAAcAAAAoAQAAAQAAAGABAAAYBAAAgAEAAHoC" +
71*795d594fSAndroid Build Coastguard Worker             "AAB9AgAAgAIAAIgCAACOAgAAlgIAALcCAADWAgAA4wIAAAIDAAAWAwAALAMAAEADAABeAwAAfQMA" +
72*795d594fSAndroid Build Coastguard Worker             "AIQDAACUAwAAlwMAAJsDAACgAwAAqAMAALwDAADrAwAAGQQAAEcEAAB0BAAAeQQAAIAEAAAHAAAA" +
73*795d594fSAndroid Build Coastguard Worker             "CAAAAAkAAAAKAAAADQAAABAAAAAQAAAABQAAAAAAAAARAAAABQAAAGQCAAASAAAABQAAAGwCAAAR" +
74*795d594fSAndroid Build Coastguard Worker             "AAAABQAAAHQCAAAAAAAAAgAAAAAAAwAEAAAAAAADAA4AAAAAAAIAGgAAAAIAAAACAAAAAwAAABkA" +
75*795d594fSAndroid Build Coastguard Worker             "AAAEAAEAEwAAAAAAAAAAAAAAAgAAAAAAAAAPAAAAPAIAAMoEAAAAAAAAAQAAAKgEAAABAAAAuAQA" +
76*795d594fSAndroid Build Coastguard Worker             "AAEAAQABAAAAhwQAAAQAAABwEAQAAAAOAAMAAgACAAAAjAQAAAcAAAAbAAUAAAByIAYAAgAOAAAA" +
77*795d594fSAndroid Build Coastguard Worker             "AwACAAIAAACTBAAABwAAABsABgAAAHIgBgACAA4AAAAEAAMAAgAAAJoEAAAiAAAAGwAYAAAAciAG" +
78*795d594fSAndroid Build Coastguard Worker             "AAMAcCACADEAGwAWAAAAciAGAAMAchAFAAIAGwAXAAAAciAGAAMAcCABADEAGwAVAAAAciAGAAMA" +
79*795d594fSAndroid Build Coastguard Worker             "DgAAAAAAAAAAAAMAAAAAAAAAAQAAAIABAAACAAAAgAEAAAMAAACIAQAAAQAAAAIAAAACAAAAAwAE" +
80*795d594fSAndroid Build Coastguard Worker             "AAEAAAAEAAEoAAE8AAY8aW5pdD4ABD47KVYABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBU" +
81*795d594fSAndroid Build Coastguard Worker             "cmFuc2Zvcm1lZAAdSGVsbG8gLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQAC0xUcmFuc2Zvcm07AB1M" +
82*795d594fSAndroid Build Coastguard Worker             "ZGFsdmlrL2Fubm90YXRpb24vU2lnbmF0dXJlOwASTGphdmEvbGFuZy9PYmplY3Q7ABRMamF2YS9s" +
83*795d594fSAndroid Build Coastguard Worker             "YW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABxMamF2YS91dGlsL2Z1bmN0aW9uL0Nv" +
84*795d594fSAndroid Build Coastguard Worker             "bnN1bWVyAB1MamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVyOwAFU3RhcnQADlRyYW5zZm9ybS5q" +
85*795d594fSAndroid Build Coastguard Worker             "YXZhAAFWAAJWTAADVkxMAAZhY2NlcHQAEmVtaXR0ZXI6IGphY2stNC4xOQAtcG9zdCBGaW5pc2gg" +
86*795d594fSAndroid Build Coastguard Worker             "cHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkACxwb3N0IFN0YXJ0IHByaXZhdGUgbWV0" +
87*795d594fSAndroid Build Coastguard Worker             "aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAscHJlIEZpbmlzaCBwcml2YXRlIG1ldGhvZCBjYWxsIC0g" +
88*795d594fSAndroid Build Coastguard Worker             "VHJhbnNmb3JtZWQAK3ByZSBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQA" +
89*795d594fSAndroid Build Coastguard Worker             "A3J1bgAFc2F5SGkABXZhbHVlABMABw4AGQEABw5pABUBAAcOaQAdAgAABw5pPGk8aTxpAAIBARsc" +
90*795d594fSAndroid Build Coastguard Worker             "BRcAFwwXARcLFwMCAQEbHAYXABcKFwwXARcLFwMAAAMBAICABJADAQKoAwECyAMDAegDDwAAAAAA" +
91*795d594fSAndroid Build Coastguard Worker             "AAABAAAAAAAAAAEAAAAcAAAAcAAAAAIAAAAGAAAA4AAAAAMAAAAEAAAA+AAAAAUAAAAHAAAAKAEA" +
92*795d594fSAndroid Build Coastguard Worker             "AAYAAAABAAAAYAEAAAMQAAACAAAAgAEAAAEgAAAEAAAAkAEAAAYgAAABAAAAPAIAAAEQAAADAAAA" +
93*795d594fSAndroid Build Coastguard Worker             "ZAIAAAIgAAAcAAAAegIAAAMgAAAEAAAAhwQAAAQgAAACAAAAqAQAAAAgAAABAAAAygQAAAAQAAAB" +
94*795d594fSAndroid Build Coastguard Worker             "AAAA4AQAAA==");
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker     // A class that we can use to keep track of the output of this test.
97*795d594fSAndroid Build Coastguard Worker     private static class TestWatcher implements Consumer<String> {
98*795d594fSAndroid Build Coastguard Worker         private StringBuilder sb;
TestWatcher()99*795d594fSAndroid Build Coastguard Worker         public TestWatcher() {
100*795d594fSAndroid Build Coastguard Worker             sb = new StringBuilder();
101*795d594fSAndroid Build Coastguard Worker         }
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker         @Override
accept(String s)104*795d594fSAndroid Build Coastguard Worker         public void accept(String s) {
105*795d594fSAndroid Build Coastguard Worker             sb.append(s);
106*795d594fSAndroid Build Coastguard Worker             sb.append('\n');
107*795d594fSAndroid Build Coastguard Worker         }
108*795d594fSAndroid Build Coastguard Worker 
getOutput()109*795d594fSAndroid Build Coastguard Worker         public String getOutput() {
110*795d594fSAndroid Build Coastguard Worker             return sb.toString();
111*795d594fSAndroid Build Coastguard Worker         }
112*795d594fSAndroid Build Coastguard Worker 
clear()113*795d594fSAndroid Build Coastguard Worker         public void clear() {
114*795d594fSAndroid Build Coastguard Worker             sb = new StringBuilder();
115*795d594fSAndroid Build Coastguard Worker         }
116*795d594fSAndroid Build Coastguard Worker     }
117*795d594fSAndroid Build Coastguard Worker 
main(String[] args)118*795d594fSAndroid Build Coastguard Worker     public static void main(String[] args) {
119*795d594fSAndroid Build Coastguard Worker         doTest(new Transform(), new TestWatcher());
120*795d594fSAndroid Build Coastguard Worker     }
121*795d594fSAndroid Build Coastguard Worker 
122*795d594fSAndroid Build Coastguard Worker     private static boolean interpreting = true;
123*795d594fSAndroid Build Coastguard Worker     private static boolean retry = false;
124*795d594fSAndroid Build Coastguard Worker 
doTest(Transform t, TestWatcher w)125*795d594fSAndroid Build Coastguard Worker     public static void doTest(Transform t, TestWatcher w) {
126*795d594fSAndroid Build Coastguard Worker         // Get the methods that need to be optimized.
127*795d594fSAndroid Build Coastguard Worker         Method say_hi_method;
128*795d594fSAndroid Build Coastguard Worker         // Figure out if we can even JIT at all.
129*795d594fSAndroid Build Coastguard Worker         final boolean has_jit = hasJit();
130*795d594fSAndroid Build Coastguard Worker         try {
131*795d594fSAndroid Build Coastguard Worker             say_hi_method = Transform.class.getDeclaredMethod(
132*795d594fSAndroid Build Coastguard Worker                     "sayHi", Runnable.class, Consumer.class);
133*795d594fSAndroid Build Coastguard Worker         } catch (Exception e) {
134*795d594fSAndroid Build Coastguard Worker             System.out.println("Unable to find methods!");
135*795d594fSAndroid Build Coastguard Worker             e.printStackTrace(System.out);
136*795d594fSAndroid Build Coastguard Worker             return;
137*795d594fSAndroid Build Coastguard Worker         }
138*795d594fSAndroid Build Coastguard Worker         // Makes sure the stack is the way we want it for the test and does the redefinition.
139*795d594fSAndroid Build Coastguard Worker         // It will set the retry boolean to true if the stack does not have a JIT-compiled
140*795d594fSAndroid Build Coastguard Worker         // sayHi entry. This can only happen if the method gets GC'd.
141*795d594fSAndroid Build Coastguard Worker         Runnable do_redefinition = () -> {
142*795d594fSAndroid Build Coastguard Worker             if (has_jit && Main.isInterpretedFunction(say_hi_method, true)) {
143*795d594fSAndroid Build Coastguard Worker                 // Try again. We are not running the right jitted methods/cannot redefine them now.
144*795d594fSAndroid Build Coastguard Worker                 retry = true;
145*795d594fSAndroid Build Coastguard Worker             } else {
146*795d594fSAndroid Build Coastguard Worker                 // Actually do the redefinition. The stack looks good.
147*795d594fSAndroid Build Coastguard Worker                 retry = false;
148*795d594fSAndroid Build Coastguard Worker                 w.accept("transforming calling function");
149*795d594fSAndroid Build Coastguard Worker                 Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
150*795d594fSAndroid Build Coastguard Worker             }
151*795d594fSAndroid Build Coastguard Worker         };
152*795d594fSAndroid Build Coastguard Worker         // This just prints something out to show we are running the Runnable.
153*795d594fSAndroid Build Coastguard Worker         Runnable say_nothing = () -> { w.accept("Not doing anything here"); };
154*795d594fSAndroid Build Coastguard Worker         do {
155*795d594fSAndroid Build Coastguard Worker             // Run ensureJitCompiled here since it might get GCd
156*795d594fSAndroid Build Coastguard Worker             ensureJitCompiled(Transform.class, "sayHi");
157*795d594fSAndroid Build Coastguard Worker             // Clear output.
158*795d594fSAndroid Build Coastguard Worker             w.clear();
159*795d594fSAndroid Build Coastguard Worker             // Try and redefine.
160*795d594fSAndroid Build Coastguard Worker             t.sayHi(say_nothing, w);
161*795d594fSAndroid Build Coastguard Worker             t.sayHi(do_redefinition, w);
162*795d594fSAndroid Build Coastguard Worker             t.sayHi(say_nothing, w);
163*795d594fSAndroid Build Coastguard Worker         } while (retry);
164*795d594fSAndroid Build Coastguard Worker         // Print output of last run.
165*795d594fSAndroid Build Coastguard Worker         System.out.print(w.getOutput());
166*795d594fSAndroid Build Coastguard Worker     }
167*795d594fSAndroid Build Coastguard Worker 
hasJit()168*795d594fSAndroid Build Coastguard Worker     private static native boolean hasJit();
169*795d594fSAndroid Build Coastguard Worker 
isInterpretedFunction(Method m, boolean require_deoptimizable)170*795d594fSAndroid Build Coastguard Worker     private static native boolean isInterpretedFunction(Method m, boolean require_deoptimizable);
171*795d594fSAndroid Build Coastguard Worker 
ensureJitCompiled(Class c, String name)172*795d594fSAndroid Build Coastguard Worker     private static native void ensureJitCompiled(Class c, String name);
173*795d594fSAndroid Build Coastguard Worker }
174