• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 package android.jvmti.cts;
15 
16 import static org.junit.Assert.assertEquals;
17 import static org.junit.Assert.assertTrue;
18 
19 import java.util.ArrayList;
20 import org.junit.Before;
21 import org.junit.Test;
22 
23 import art.Main;
24 
25 /**
26  * Check tracking-related functionality.
27  */
28 public class JvmtiTrackingTest extends JvmtiTestBase {
29 
30     @Before
setUp()31     public void setUp() throws Exception {
32         prefetchClassNames();
33     }
34 
35     // Pre-resolve class names so the strings don't have to be allocated as a side effect of
36     // callback printing.
37     @SuppressWarnings("ReturnValueIgnored")
prefetchClassNames()38     private static void prefetchClassNames() {
39         Object.class.getName();
40         Integer.class.getName();
41         Float.class.getName();
42         Short.class.getName();
43         Byte.class.getName();
44         Double.class.getName();
45     }
46 
47     private ArrayList<Object> l = new ArrayList<>(100);
48 
49     @Test
testTracking()50     public void testTracking() throws Exception {
51         // Disable the global registration from OnLoad, to get into a known state.
52         enableAllocationTracking(null, false);
53 
54         assertEquals(null, getAndResetAllocationTrackingString());
55 
56         // Enable actual logging callback.
57         setupObjectAllocCallback(true);
58 
59         enableAllocationTracking(null, true);
60 
61         l.add(new Object());
62         l.add(new Integer(1));
63 
64         enableAllocationTracking(null, false);
65 
66         String trackingString = getAndResetAllocationTrackingString();
67         String object_line = "ObjectAllocated type java.lang.Object/java.lang.Object size 8#";
68         String integer_line = "ObjectAllocated type java.lang.Integer/java.lang.Integer size 16#";
69         assertTrue("does not contain " + object_line, trackingString.contains(object_line));
70         assertTrue("does not contain " + integer_line, trackingString.contains(integer_line));
71 
72         l.add(new Float(1.0f));
73 
74         assertEquals(null, getAndResetAllocationTrackingString());
75 
76         enableAllocationTracking(Thread.currentThread(), true);
77 
78         l.add(new Short((short) 0));
79 
80         enableAllocationTracking(Thread.currentThread(), false);
81 
82         assertEquals("ObjectAllocated type java.lang.Short/java.lang.Short size 16#",
83                 getAndResetAllocationTrackingString());
84 
85         l.add(new Byte((byte) 0));
86 
87         assertEquals(null, getAndResetAllocationTrackingString());
88 
89         testThread(l, true, true);
90 
91         l.add(new Byte((byte) 0));
92 
93         assertEquals("ObjectAllocated type java.lang.Double/java.lang.Double size 16#",
94                 getAndResetAllocationTrackingString());
95 
96         testThread(l, true, false);
97 
98         assertEquals("ObjectAllocated type java.lang.Double/java.lang.Double size 16#",
99                 getAndResetAllocationTrackingString());
100 
101         System.out.println("Tracking on different thread");
102 
103         testThread(l, false, true);
104 
105         l.add(new Byte((byte) 0));
106 
107         // Disable actual logging callback and re-enable tracking, so we can keep the event enabled
108         // and
109         // check that shutdown works correctly.
110         setupObjectAllocCallback(false);
111         enableAllocationTracking(null, true);
112 
113         assertEquals(null, getAndResetAllocationTrackingString());
114     }
115 
testThread(final ArrayList<Object> l, final boolean sameThread, final boolean disableTracking)116     private static void testThread(final ArrayList<Object> l, final boolean sameThread,
117             final boolean disableTracking) throws Exception {
118         final SimpleBarrier startBarrier = new SimpleBarrier(1);
119         final SimpleBarrier trackBarrier = new SimpleBarrier(1);
120 
121         final Thread thisThread = Thread.currentThread();
122 
123         Thread t = new Thread() {
124             @Override
125             public void run() {
126                 try {
127                     startBarrier.dec();
128                     trackBarrier.waitFor();
129                 } catch (Exception e) {
130                     e.printStackTrace(System.out);
131                     System.exit(1);
132                 }
133 
134                 l.add(new Double(0.0));
135 
136                 if (disableTracking) {
137                     enableAllocationTracking(sameThread ? this : thisThread, false);
138                 }
139             }
140         };
141 
142         t.start();
143         startBarrier.waitFor();
144         enableAllocationTracking(sameThread ? t : Thread.currentThread(), true);
145         trackBarrier.dec();
146 
147         t.join();
148     }
149 
150     // Our own little barrier, to avoid behind-the-scenes allocations.
151     private static class SimpleBarrier {
152         int count;
153 
SimpleBarrier(int i)154         public SimpleBarrier(int i) {
155             count = i;
156         }
157 
dec()158         public synchronized void dec() throws Exception {
159             count--;
160             notifyAll();
161         }
162 
waitFor()163         public synchronized void waitFor() throws Exception {
164             while (count != 0) {
165                 wait();
166             }
167         }
168     }
169 
setupObjectAllocCallback(boolean enable)170     private static native void setupObjectAllocCallback(boolean enable);
171 
enableAllocationTracking(Thread thread, boolean enable)172     private static native void enableAllocationTracking(Thread thread, boolean enable);
173 
getAndResetAllocationTrackingString()174     private static native String getAndResetAllocationTrackingString();
175 }
176