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.io.PrintWriter; 20 import java.io.StringWriter; 21 import java.util.concurrent.Semaphore; 22 import java.util.Arrays; 23 import java.lang.reflect.Executable; 24 import java.lang.reflect.Method; 25 import java.util.List; 26 import java.util.Set; 27 import java.util.ArrayList; 28 import java.util.HashSet; 29 import java.util.function.IntUnaryOperator; 30 import java.util.function.Function; 31 32 public class Test1925 { handleFramePop(Executable m, boolean exception, long location)33 public static void handleFramePop(Executable m, boolean exception, long location) { 34 System.out.println( 35 m + " pop. Line=" + Breakpoint.locationToLine(m, location) + " exception:" + exception); 36 } 37 recurTimesA(int times, Runnable safepoint)38 public static void recurTimesA(int times, Runnable safepoint) { 39 if (times == 0) { 40 safepoint.run(); 41 return; 42 } 43 recurTimesB(times - 1, safepoint); 44 } 45 recurTimesB(int times, Runnable safepoint)46 public static void recurTimesB(int times, Runnable safepoint) { 47 if (times == 0) { 48 safepoint.run(); 49 return; 50 } 51 recurTimesC(times - 1, safepoint); 52 } 53 recurTimesC(int times, Runnable safepoint)54 public static void recurTimesC(int times, Runnable safepoint) { 55 if (times == 0) { 56 safepoint.run(); 57 return; 58 } 59 recurTimesD(times - 1, safepoint); 60 } 61 recurTimesD(int times, Runnable safepoint)62 public static void recurTimesD(int times, Runnable safepoint) { 63 if (times == 0) { 64 safepoint.run(); 65 return; 66 } 67 recurTimesE(times - 1, safepoint); 68 } 69 recurTimesE(int times, Runnable safepoint)70 public static void recurTimesE(int times, Runnable safepoint) { 71 if (times == 0) { 72 safepoint.run(); 73 return; 74 } 75 recurTimesF(times - 1, safepoint); 76 } 77 recurTimesF(int times, Runnable safepoint)78 public static void recurTimesF(int times, Runnable safepoint) { 79 if (times == 0) { 80 safepoint.run(); 81 return; 82 } 83 recurTimesG(times - 1, safepoint); 84 } 85 recurTimesG(int times, Runnable safepoint)86 public static void recurTimesG(int times, Runnable safepoint) { 87 if (times == 0) { 88 safepoint.run(); 89 return; 90 } 91 recurTimesH(times - 1, safepoint); 92 } 93 recurTimesH(int times, Runnable safepoint)94 public static void recurTimesH(int times, Runnable safepoint) { 95 if (times == 0) { 96 safepoint.run(); 97 return; 98 } 99 recurTimesI(times - 1, safepoint); 100 } 101 recurTimesI(int times, Runnable safepoint)102 public static void recurTimesI(int times, Runnable safepoint) { 103 if (times == 0) { 104 safepoint.run(); 105 return; 106 } 107 recurTimesJ(times - 1, safepoint); 108 } 109 recurTimesJ(int times, Runnable safepoint)110 public static void recurTimesJ(int times, Runnable safepoint) { 111 if (times == 0) { 112 safepoint.run(); 113 return; 114 } 115 recurTimesK(times - 1, safepoint); 116 } 117 118 public static class RecursionError extends Error { RecursionError(String s)119 public RecursionError(String s) { super(s); } 120 } recurTimesK(int times, Runnable safepoint)121 public static void recurTimesK(int times, Runnable safepoint) { 122 if (times == 0) { 123 safepoint.run(); 124 return; 125 } 126 safepoint.run(); 127 throw new RecursionError("Unable recur further. Still " + times + " outstanding!"); 128 } 129 doRecurTestWith(final int times, int watch_frame)130 public static void doRecurTestWith(final int times, int watch_frame) throws Exception { 131 final String target_method_name_start = "recurTimes"; 132 final Runnable safepoint = () -> { 133 StackTrace.StackFrameData target_frame = null; 134 int cnt = 0; 135 for (StackTrace.StackFrameData frame : StackTrace.GetStackTrace(Thread.currentThread())) { 136 if (frame.method.getName().startsWith(target_method_name_start)) { 137 if (times - cnt == watch_frame) { 138 target_frame = frame; 139 break; 140 } else { 141 cnt++; 142 } 143 } 144 } 145 try { 146 FramePop.notifyFramePop(null, target_frame.depth); 147 } catch (Exception e) { 148 throw new Error("Unexpected error in notifyFramePop!", e); 149 } 150 }; 151 try { 152 recurTimesA(times, safepoint); 153 System.out.println("Ran recurTimes(" + times + ") without errors!"); 154 } catch (Throwable e) { 155 System.out.println("Caught exception " + e + " while running recurTimes(" + times + ")"); 156 } 157 } 158 run()159 public static void run() throws Exception { 160 FramePop.enableFramePopEvent( 161 Test1925.class, 162 Test1925.class.getDeclaredMethod( 163 "handleFramePop", Executable.class, Boolean.TYPE, Long.TYPE), 164 null); 165 doRecurTestWith(10, 5); 166 doRecurTestWith(100, 95); 167 } 168 } 169