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.util.Arrays; 20 import java.lang.reflect.Executable; 21 import java.lang.reflect.Method; 22 import java.util.concurrent.Semaphore; 23 24 public class Test1941 { 25 public static final boolean PRINT_CNT = false; 26 public static long CNT = 0; 27 public static final long MAX_ITERS = 100_000; 28 29 // Method with multiple paths we can break on. fib(long f)30 public static long fib(long f) { 31 if (f < 0) { 32 throw new IllegalArgumentException("Bad argument f < 0: f = " + f); 33 } else if (f == 0) { 34 return 0; 35 } else if (f == 1) { 36 return 1; 37 } else { 38 return fib(f - 1) + fib(f - 2); 39 } 40 } 41 notifySingleStep(Thread thr, Executable e, long loc)42 public static void notifySingleStep(Thread thr, Executable e, long loc) { 43 // Don't bother actually doing anything. 44 } 45 LoopAllocFreeEnv(Semaphore sem, Semaphore delay)46 public static void LoopAllocFreeEnv(Semaphore sem, Semaphore delay) { 47 sem.release(); 48 try { 49 delay.acquire(); 50 } catch (Exception e) { 51 throw new Error("exception occurred!", e); 52 } 53 while (!Thread.interrupted() && CNT < MAX_ITERS) { 54 CNT++; 55 long env = AllocEnv(); 56 FreeEnv(env); 57 Thread.yield(); 58 } 59 } 60 AllocEnv()61 public static native long AllocEnv(); FreeEnv(long env)62 public static native void FreeEnv(long env); 63 setTracingOn(Thread thr, boolean enable)64 public static native void setTracingOn(Thread thr, boolean enable); 65 run()66 public static void run() throws Exception { 67 final Semaphore sem = new Semaphore(0); 68 final Semaphore delay = new Semaphore(0); 69 Thread thr = new Thread(() -> { LoopAllocFreeEnv(sem, delay); }, "LoopNative"); 70 thr.start(); 71 // Make sure the other thread is actually started. 72 sem.acquire(); 73 Trace.enableSingleStepTracing(Test1941.class, 74 Test1941.class.getDeclaredMethod( 75 "notifySingleStep", Thread.class, Executable.class, Long.TYPE), 76 thr); 77 setTracingOn(Thread.currentThread(), true); 78 // Don't let the other thread start actually running until we've started 79 // tracing this thread too in order to ensure that the (formerly) racy 80 // behavior can happen. 81 delay.release(); 82 83 System.out.println("fib(20) is " + fib(20)); 84 85 thr.interrupt(); 86 thr.join(); 87 setTracingOn(Thread.currentThread(), false); 88 Trace.disableTracing(null); 89 if (PRINT_CNT) { 90 System.out.println("Number of envs created/destroyed: " + CNT); 91 } 92 } 93 } 94