Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/sourcetools/com.ibm.jpp.preprocessor/com/ibm/jpp/om/JitAttributes.java
6004 views
1
/*******************************************************************************
2
* Copyright (c) 1999, 2020 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
package com.ibm.jpp.om;
23
24
import java.io.File;
25
import java.io.FileOutputStream;
26
import java.io.IOException;
27
import java.io.PrintWriter;
28
import java.util.HashMap;
29
import java.util.Map;
30
31
/**
32
* Format of JCL annotations:
33
* [ATTR <Type> <Signature>]
34
* where Type is one of:
35
* SkipNullChecks
36
* SkipBoundChecks
37
* SkipCheckCasts
38
* SkipDivChecks
39
* SkipArrayStoreChecks
40
* SkipChecksOnArrayCopies
41
* SkipZeroInitializationOnNewarrays
42
*
43
* These Types are always applied to a method. Signature must be of the
44
* form com_ibm_oti_Foo.blah(II)V.
45
*
46
* or [ATTR Recognized <Signature>]
47
*
48
* The given method is a "recognized" method (used for special,
49
* non-generalizable optimizations).
50
*
51
* or [ATTR <Type> <Arg> <FQN/Signature>]
52
* where Type is one of:
53
* Trusted
54
* Untrusted
55
*
56
* Trusted means arguments will not escape the methods. The Trusted
57
* attribute may be applied to either a method or a class. If it is
58
* applied to a method, Signature must be the same form as above. If it
59
* is applied to a class, use the fully qualified class name, like
60
* java_lang_Object. Untrusted can only be used for methods, and is used
61
* to indicate exceptions to Trusted classes.
62
*
63
* For Trusted and Untrusted, Arg is an integer indicating for which
64
* argument(s) the attribute applies. -1 means all arguments. The number
65
* must be formatted such that it can be converted to a Java int using
66
* Integer.parseInt().
67
*
68
* eg.
69
* [ATTR Trusted -1 com_ibm_oti_Foo]
70
* All arguments of all methods in com.ibm.oti.Foo will not escape.
71
*
72
* [ATTR Trusted 2 com_ibm_oti_Foo]
73
* The third argument of all methods in the class will not escape.
74
*
75
* [ATTR Trusted -1 com_ibm_oti_Foo]
76
* [ATTR Untrusted -1 com_ibm_oti_Foo.blah()V]
77
* All arguments of all methods will not escape, except blah(), where
78
* all arguments will escape.
79
*
80
* [ATTR Trusted 0 com_bim_oti_Foo.blah()V]
81
* The first argument of blah() will not escape.
82
*
83
*/
84
public class JitAttributes {
85
86
static Map<String, Integer> recognizedMethods;
87
88
static {
89
/* This set of methods should be synchronized with the
90
* "enum RecognizedMethod" in codegen_common/Symbol.hpp.
91
* ie., the contents and order should be the same.
92
*/
93
String[] methods = {
94
"unknownMethod",
95
"java_lang_Double_doubleToLongBits",
96
"java_lang_Double_longBitsToDouble",
97
"java_lang_Float_floatToIntBits",
98
"java_lang_Float_intBitsToFloat",
99
"java_lang_Object_getClass",
100
"java_lang_Object_hashCodeImpl",
101
"java_lang_String_hashCode",
102
"java_lang_System_arraycopy",
103
"java_lang_System_currentTimeMillis",
104
"java_lang_Thread_currentThread",
105
"java_lang_Throwable_fillInStackTrace",
106
"java_lang_Throwable_printStackTrace",
107
"java_util_HashtableHashEnumerator_hasMoreElements",
108
"com_ibm_oti_vm_VM_callerClass",
109
"com_ibm_oti_vm_VM_callerClassLoader" };
110
recognizedMethods = new HashMap<>();
111
for (int i = 0; i < methods.length; i++) {
112
recognizedMethods.put(methods[i], Integer.valueOf(i));
113
}
114
}
115
116
AttributesMap map = new AttributesMap();
117
118
public void skipNullChecksFor(String method) {
119
checkMethod(method);
120
map.getOrAdd(method).skipNullChecks = true;
121
}
122
123
public void skipBoundChecksFor(String method) {
124
checkMethod(method);
125
map.getOrAdd(method).skipBoundChecks = true;
126
}
127
128
public void skipCheckCastsFor(String method) {
129
checkMethod(method);
130
map.getOrAdd(method).skipCheckCasts = true;
131
}
132
133
public void skipDivChecksFor(String method) {
134
checkMethod(method);
135
map.getOrAdd(method).skipDivChecks = true;
136
}
137
138
public void skipArrayStoreChecksFor(String method) {
139
checkMethod(method);
140
map.getOrAdd(method).skipArrayStoreChecks = true;
141
}
142
143
public void skipChecksOnArrayCopiesFor(String method) {
144
checkMethod(method);
145
map.getOrAdd(method).skipChecksOnArrayCopies = true;
146
}
147
148
public void skipZeroInitializationOnNewarraysFor(String method) {
149
checkMethod(method);
150
map.getOrAdd(method).skipZeroInitializationOnNewarrays = true;
151
}
152
153
public void addTrustedMethodOrClass(String name, int argNum) {
154
if (argNum < -1 || argNum >= 100) {
155
throw new PreprocessorException("Argument must be between -1 and 99 inclusive");
156
}
157
Attributes attr = map.getOrAdd(name);
158
attr.trusted = true;
159
attr.argNum = argNum;
160
}
161
162
public void addUntrustedMethod(String method, int argNum) {
163
checkMethod(method);
164
if (argNum < -1 || argNum >= 100) {
165
throw new PreprocessorException("Argument must be between -1 and 99 inclusive");
166
}
167
Attributes attr = map.getOrAdd(method);
168
attr.untrusted = true;
169
attr.argNum = argNum;
170
}
171
172
public void addRecognizedMethod(String method) {
173
checkMethod(method);
174
175
/* Convert from com_ibm_oti_Foo.blah() to com_ibm_oti_Foo_blah, to match
176
* the format of the enum values.
177
*/
178
StringBuffer chopped = new StringBuffer(method.substring(0, method.indexOf("(")));
179
chopped.setCharAt(method.indexOf("."), '_');
180
181
Integer integer = recognizedMethods.get(chopped.toString());
182
if (integer == null) {
183
throw new PreprocessorException(method + " is not a recognized method");
184
}
185
int value = integer.intValue();
186
if (value < 0 || value >= 100) {
187
throw new PreprocessorException("Not expecting recognizedMethodId < 0 or >= 100");
188
}
189
Attributes attr = map.getOrAdd(method);
190
attr.recognized = true;
191
attr.recognizedMethodId = value;
192
}
193
194
public void write(String filename) throws IOException {
195
if (map.size() == 0) {
196
return;
197
}
198
File outputFile = new File(filename);
199
outputFile.mkdirs();
200
try (FileOutputStream stream = new FileOutputStream(filename);
201
PrintWriter out = new PrintWriter(stream)) {
202
out.print(map.toString());
203
}
204
}
205
206
private static void checkMethod(String method) {
207
boolean valid = true;
208
int dot = method.indexOf('.');
209
210
// if the first char is the dot, or there is more
211
// than one dot, it's not a valid method name
212
if (dot == 0 || method.indexOf('.', dot + 1) > 0) {
213
valid = false;
214
} else {
215
// ensure that there is both a left bracket and a right
216
// bracket, and that they appear in the right order.
217
int left = method.indexOf('(', dot + 1);
218
if (left == -1) {
219
valid = false;
220
} else {
221
int right = method.indexOf(')', left + 1);
222
if (right == -1) {
223
valid = false;
224
}
225
}
226
}
227
228
if (!valid) {
229
throw new PreprocessorException(method + " does not appear to be a valid method name.");
230
}
231
}
232
}
233
234
class Attributes {
235
String name;
236
237
boolean skipNullChecks = false;
238
boolean skipBoundChecks = false;
239
boolean skipCheckCasts = false;
240
boolean skipDivChecks = false;
241
boolean skipArrayStoreChecks = false;
242
boolean skipChecksOnArrayCopies = false;
243
boolean skipZeroInitializationOnNewarrays = false;
244
245
boolean trusted = false;
246
boolean untrusted = false;
247
int argNum;
248
boolean recognized = false;
249
int recognizedMethodId;
250
251
@Override
252
public String toString() {
253
StringBuffer ret = new StringBuffer();
254
255
if (trusted) {
256
if (argNum == -1) {
257
ret.append("T");
258
} else {
259
ret.append("t");
260
if (argNum < 10) {
261
ret.append("0");
262
}
263
ret.append(argNum);
264
}
265
} else if (untrusted) {
266
if (argNum == -1) {
267
ret.append("U");
268
} else {
269
ret.append("u");
270
if (argNum < 10) {
271
ret.append("0");
272
}
273
ret.append(argNum);
274
}
275
}
276
/* These attributes are only for methods */
277
if (name.indexOf(".") != -1) {
278
if (recognized) {
279
ret.append("r");
280
if (recognizedMethodId < 10) {
281
ret.append("0");
282
}
283
ret.append(recognizedMethodId);
284
}
285
ret.append(skipNullChecks ? "y" : "n");
286
ret.append(skipBoundChecks ? "y" : "n");
287
ret.append(skipCheckCasts ? "y" : "n");
288
ret.append(skipDivChecks ? "y" : "n");
289
ret.append(skipArrayStoreChecks ? "y" : "n");
290
ret.append(skipChecksOnArrayCopies ? "y" : "n");
291
ret.append(skipZeroInitializationOnNewarrays ? "y" : "n");
292
}
293
294
return ret.toString();
295
}
296
}
297
298
class AttributesMap extends HashMap<String, Attributes> {
299
300
/**
301
* serialVersionUID
302
*/
303
private static final long serialVersionUID = 3257003276233683256L;
304
305
public Attributes getOrAdd(String name) {
306
Attributes attr = get(name);
307
if (attr == null) {
308
attr = new Attributes();
309
attr.name = name;
310
put(name, attr);
311
}
312
return attr;
313
}
314
315
@Override
316
public String toString() {
317
StringBuffer ret = new StringBuffer();
318
319
for (Attributes next : values()) {
320
ret.append(next.name);
321
ret.append("\n");
322
ret.append(next.toString());
323
ret.append("\n");
324
}
325
326
return ret.toString();
327
}
328
329
}
330
331