Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/jdk/jfr/event/oldobject/OldObjects.java
44021 views
1
/*
2
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
package jdk.jfr.event.oldobject;
24
25
import java.io.IOException;
26
import java.util.List;
27
import java.util.function.Predicate;
28
29
import jdk.jfr.Recording;
30
import jdk.jfr.consumer.RecordedClass;
31
import jdk.jfr.consumer.RecordedEvent;
32
import jdk.jfr.consumer.RecordedFrame;
33
import jdk.jfr.consumer.RecordedMethod;
34
import jdk.jfr.consumer.RecordedObject;
35
import jdk.jfr.consumer.RecordedStackTrace;
36
import jdk.test.lib.jfr.Events;
37
38
/**
39
* Utility class to perform Old Object provocation/detection and
40
* stack trace/object verification for the Old Object Sample JFR event
41
*/
42
final public class OldObjects {
43
44
public static final int MIN_SIZE = 99901; // prime number
45
public final static int LEAK_CONTEXT = 100; // length of chain assiociated with the object sample
46
public final static int ROOT_CONTEXT = 100; // length of chain assoicated with the root
47
public final static int MAX_CHAIN_LENGTH = LEAK_CONTEXT + ROOT_CONTEXT; // the VM should not construct chains longer than this
48
49
private static String[] getFrames(String expectedFrame) {
50
if (expectedFrame != null) {
51
return new String[] { expectedFrame };
52
} else {
53
return null;
54
}
55
}
56
57
/**
58
*
59
* @param r
60
* A recording
61
* @param expectedFrame
62
* A frame that must be found on the stack. Null if no check is required.
63
* @param fieldType
64
* The object type (of the field). Null if no check is required.
65
* @param fieldName
66
* The field name. Null if no check is required.
67
* @param referrerType
68
* The class name. Null if no check is required.
69
* @param minDuration
70
* The minimum duration of the event, -1 if not applicable.
71
* @return The count of matching events
72
* @throws IOException
73
*/
74
public static long countMatchingEvents(Recording r, String expectedFrame, Class<?> fieldType, String fieldName, Class<?> referrerType, long minDuration) throws IOException {
75
return countMatchingEvents(r, getFrames(expectedFrame), fieldType, fieldName, referrerType, minDuration);
76
}
77
78
/**
79
* Gets the OldObjectSample events from the provided recording through a dump
80
* and counts how many events matches the provided parameters.
81
*
82
* @param r
83
* A recording
84
* @param expectedStack
85
* Some frames that must be found on the stack. Null if no check is required.
86
* @param fieldType
87
* The object type (of the field). Null if no check is required.
88
* @param fieldName
89
* The field name. Null if no check is required.
90
* @param referrerType
91
* The class name. Null if no check is required.
92
* @param minDuration
93
* The minimum duration of the event, -1 if not applicable.
94
* @return The count of matching events
95
* @throws IOException
96
*/
97
public static long countMatchingEvents(Recording r, String[] expectedStack, Class<?> fieldType, String fieldName, Class<?> referrerType, long minDuration) throws IOException {
98
return countMatchingEvents(Events.fromRecording(r), fieldType, fieldName, referrerType, minDuration, expectedStack);
99
}
100
101
/**
102
*
103
* @param events
104
* A list of RecordedEvent.
105
* @param expectedFrame
106
* A frame that must be found on the stack. Null if no check is required.
107
* @param fieldType
108
* The object type (of the field). Null if no check is required.
109
* @param fieldName
110
* The field name. Null if no check is required.
111
* @param referrerType
112
* The class name. Null if no check is required.
113
* @param minDuration
114
* The minimum duration of the event, -1 if not applicable.
115
* @return The count of matching events
116
* @throws IOException
117
*/
118
public static long countMatchingEvents(List<RecordedEvent> events, String expectedFrame, Class<?> fieldType, String fieldName, Class<?> referrerType, long minDuration) throws IOException {
119
return countMatchingEvents(events, fieldType, fieldName, referrerType, minDuration, getFrames(expectedFrame));
120
}
121
122
/**
123
*
124
* @param events
125
* The list of events to find matching events in
126
* @param expectedStack
127
* Some frames that must be found on the stack. Null if no check is required.
128
* @param fieldType
129
* The object type (of the field). Null if no check is required.
130
* @param fieldName
131
* The field name. Null if no check is required.
132
* @param referrerType
133
* The class name. Null if no check is required.
134
* @param minDuration
135
* The minimum duration of the event, -1 if not applicable.
136
* @return The count of matching events
137
* @throws IOException
138
*/
139
public static long countMatchingEvents(List<RecordedEvent> events, Class<?> fieldType, String fieldName, Class<?> referrerType, long minDuration, String... expectedStack) throws IOException {
140
String currentThread = Thread.currentThread().getName();
141
return events.stream()
142
.filter(hasJavaThread(currentThread))
143
.filter(fieldIsType(fieldType))
144
.filter(hasFieldName(fieldName))
145
.filter(isReferrerType(referrerType))
146
.filter(durationAtLeast(minDuration))
147
.filter(hasStackTrace(expectedStack))
148
.count();
149
}
150
151
private static Predicate<RecordedEvent> hasJavaThread(String expectedThread) {
152
if (expectedThread != null) {
153
return e -> e.getThread() != null && expectedThread.equals(e.getThread().getJavaName());
154
} else {
155
return e -> true;
156
}
157
}
158
159
private static Predicate<RecordedEvent> hasStackTrace(String[] expectedStack) {
160
if (expectedStack != null) {
161
return e -> matchingStackTrace(e.getStackTrace(), expectedStack);
162
} else {
163
return e -> true;
164
}
165
}
166
167
private static Predicate<RecordedEvent> fieldIsType(Class<?> fieldType) {
168
if (fieldType != null) {
169
return e -> e.hasField("object.type") && ((RecordedClass) e.getValue("object.type")).getName().equals(fieldType.getName());
170
} else {
171
return e -> true;
172
}
173
}
174
175
private static Predicate<RecordedEvent> hasFieldName(String fieldName) {
176
if (fieldName != null) {
177
return e -> {
178
RecordedObject referrer = e.getValue("object.referrer");
179
return referrer != null ? referrer.hasField("field.name") && referrer.getValue("field.name").equals(fieldName) : false;
180
};
181
} else {
182
return e -> true;
183
}
184
}
185
186
private static Predicate<RecordedEvent> isReferrerType(Class<?> referrerType) {
187
if (referrerType != null) {
188
return e -> {
189
RecordedObject referrer = e.getValue("object.referrer");
190
return referrer != null ? referrer.hasField("object.type") &&
191
((RecordedClass) referrer.getValue("object.type")).getName().equals(referrerType.getName()) : false;
192
};
193
} else {
194
return e -> true;
195
}
196
}
197
198
private static Predicate<RecordedEvent> durationAtLeast(long minDurationMs) {
199
if (minDurationMs > 0) {
200
return e -> e.getDuration().toMillis() >= minDurationMs;
201
} else {
202
return e -> true;
203
}
204
}
205
206
public static boolean matchingReferrerClass(RecordedEvent event, String className) {
207
RecordedObject referrer = event.getValue("object.referrer");
208
if (referrer != null) {
209
if (!referrer.hasField("object.type")) {
210
return false;
211
}
212
213
String reportedClass = ((RecordedClass) referrer.getValue("object.type")).getName();
214
if (reportedClass.equals(className)) {
215
return true;
216
}
217
}
218
return false;
219
}
220
221
public static String getReferrerFieldName(RecordedEvent event) {
222
RecordedObject referrer = event.getValue("object.referrer");
223
return referrer != null && referrer.hasField("field.name") ? referrer.getValue("field.name") : null;
224
}
225
226
public static boolean matchingStackTrace(RecordedStackTrace stack, String[] expectedStack) {
227
if (stack == null) {
228
return false;
229
}
230
231
List<RecordedFrame> frames = stack.getFrames();
232
int pos = findFramePos(frames, expectedStack[0]);
233
234
if (pos == -1) {
235
return false;
236
}
237
238
for (String expectedFrame : expectedStack) {
239
RecordedFrame f = frames.get(pos++);
240
String frame = frameToString(f);
241
242
if (!frame.contains(expectedFrame)) {
243
return false;
244
}
245
}
246
return true;
247
}
248
249
private static int findFramePos(List<RecordedFrame> frames, String frame) {
250
int pos = 0;
251
for (RecordedFrame f : frames) {
252
if (frameToString(f).contains(frame)) {
253
return pos;
254
}
255
pos++;
256
}
257
return -1;
258
}
259
260
private static String frameToString(RecordedFrame f) {
261
RecordedMethod m = f.getMethod();
262
String methodName = m.getName();
263
String className = m.getType().getName();
264
return className + "." + methodName;
265
}
266
267
public static void validateReferenceChainLimit(RecordedEvent e, int maxLength) {
268
int length = 0;
269
RecordedObject object = e.getValue("object");
270
while (object != null) {
271
++length;
272
RecordedObject referrer = object.getValue("referrer");
273
object = referrer != null ? referrer.getValue("object") : null;
274
}
275
if (length > maxLength) {
276
throw new RuntimeException("Reference chain max length not respected. Found a chain of length " + length);
277
}
278
}
279
}
280
281