/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package art; import java.util.ArrayList; import java.util.Arrays; public class Test904 { public static void run() throws Exception { // Use a list to ensure objects must be allocated. ArrayList l = new ArrayList<>(100); prefetchClassNames(); doTest(l); } // Pre-resolve class names so the strings don't have to be allocated as a side effect of // callback printing. private static void prefetchClassNames() { Object.class.getName(); Integer.class.getName(); Float.class.getName(); Short.class.getName(); Byte.class.getName(); Double.class.getName(); } public static void doTest(ArrayList l) throws Exception { // Disable the global registration from OnLoad, to get into a known state. enableAllocationTracking(null, false); // Enable actual logging callback. setupObjectAllocCallback(true); System.out.println(Arrays.toString(getTrackingEventMessages( new Thread[] { Thread.currentThread(), }))); enableAllocationTracking(null, true); l.add(new Object()); l.add(new Integer(1)); enableAllocationTracking(null, false); l.add(new Float(1.0f)); enableAllocationTracking(Thread.currentThread(), true); l.add(new Short((short)0)); enableAllocationTracking(Thread.currentThread(), false); l.add(new Byte((byte)0)); System.out.println(Arrays.toString(getTrackingEventMessages( new Thread[] { Thread.currentThread(), }))); System.out.println("Tracking on same thread"); Thread test_thread = testThread(l, true, true); l.add(new Byte((byte)0)); System.out.println(Arrays.toString(getTrackingEventMessages( new Thread[] { Thread.currentThread(), test_thread, }))); System.out.println("Tracking on same thread, not disabling tracking"); test_thread = testThread(l, true, false); System.out.println(Arrays.toString(getTrackingEventMessages( new Thread[] { Thread.currentThread(), test_thread, }))); System.out.println("Tracking on different thread"); test_thread = testThread(l, false, true); l.add(new Byte((byte)0)); // Disable actual logging callback and re-enable tracking, so we can keep the event enabled and // check that shutdown works correctly. setupObjectAllocCallback(false); System.out.println(Arrays.toString(getTrackingEventMessages( new Thread[] { Thread.currentThread(), test_thread, }))); enableAllocationTracking(null, true); } private static Thread testThread(final ArrayList l, final boolean sameThread, final boolean disableTracking) throws Exception { final SimpleBarrier startBarrier = new SimpleBarrier(1); final SimpleBarrier trackBarrier = new SimpleBarrier(1); final SimpleBarrier disableBarrier = new SimpleBarrier(1); final Thread thisThread = Thread.currentThread(); Thread t = new Thread() { public void run() { try { startBarrier.dec(); trackBarrier.waitFor(); } catch (Exception e) { e.printStackTrace(System.out); System.exit(1); } l.add(new Double(0.0)); if (disableTracking) { enableAllocationTracking(sameThread ? this : thisThread, false); } } }; t.start(); startBarrier.waitFor(); enableAllocationTracking(sameThread ? t : Thread.currentThread(), true); trackBarrier.dec(); t.join(); return t; } private static class SimpleBarrier { int count; public SimpleBarrier(int i) { count = i; } public synchronized void dec() throws Exception { count--; notifyAll(); } public synchronized void waitFor() throws Exception { while (count != 0) { wait(); } } } private static native void setupObjectAllocCallback(boolean enable); private static native void enableAllocationTracking(Thread thread, boolean enable); private static native String[] getTrackingEventMessages(Thread[] threads); }