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