Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/com/sun/tools/javap/StackMapWriter.java
38899 views
1
/*
2
* Copyright (c) 2009, 2013, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.tools.javap;
27
28
import java.util.Arrays;
29
import java.util.HashMap;
30
import java.util.Map;
31
32
import com.sun.tools.classfile.AccessFlags;
33
import com.sun.tools.classfile.Attribute;
34
import com.sun.tools.classfile.Code_attribute;
35
import com.sun.tools.classfile.ConstantPool;
36
import com.sun.tools.classfile.ConstantPoolException;
37
import com.sun.tools.classfile.Descriptor;
38
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
39
import com.sun.tools.classfile.Instruction;
40
import com.sun.tools.classfile.Method;
41
import com.sun.tools.classfile.StackMapTable_attribute;
42
import com.sun.tools.classfile.StackMapTable_attribute.*;
43
44
import static com.sun.tools.classfile.StackMapTable_attribute.verification_type_info.*;
45
46
/**
47
* Annotate instructions with stack map.
48
*
49
* <p><b>This is NOT part of any supported API.
50
* If you write code that depends on this, you do so at your own risk.
51
* This code and its internal interfaces are subject to change or
52
* deletion without notice.</b>
53
*/
54
public class StackMapWriter extends InstructionDetailWriter {
55
static StackMapWriter instance(Context context) {
56
StackMapWriter instance = context.get(StackMapWriter.class);
57
if (instance == null)
58
instance = new StackMapWriter(context);
59
return instance;
60
}
61
62
protected StackMapWriter(Context context) {
63
super(context);
64
context.put(StackMapWriter.class, this);
65
classWriter = ClassWriter.instance(context);
66
}
67
68
public void reset(Code_attribute attr) {
69
setStackMap((StackMapTable_attribute) attr.attributes.get(Attribute.StackMapTable));
70
}
71
72
void setStackMap(StackMapTable_attribute attr) {
73
if (attr == null) {
74
map = null;
75
return;
76
}
77
78
Method m = classWriter.getMethod();
79
Descriptor d = m.descriptor;
80
String[] args;
81
try {
82
ConstantPool cp = classWriter.getClassFile().constant_pool;
83
String argString = d.getParameterTypes(cp);
84
args = argString.substring(1, argString.length() - 1).split("[, ]+");
85
} catch (ConstantPoolException e) {
86
return;
87
} catch (InvalidDescriptor e) {
88
return;
89
}
90
boolean isStatic = m.access_flags.is(AccessFlags.ACC_STATIC);
91
92
verification_type_info[] initialLocals = new verification_type_info[(isStatic ? 0 : 1) + args.length];
93
if (!isStatic)
94
initialLocals[0] = new CustomVerificationTypeInfo("this");
95
for (int i = 0; i < args.length; i++) {
96
initialLocals[(isStatic ? 0 : 1) + i] =
97
new CustomVerificationTypeInfo(args[i].replace(".", "/"));
98
}
99
100
map = new HashMap<Integer, StackMap>();
101
StackMapBuilder builder = new StackMapBuilder();
102
103
// using -1 as the pc for the initial frame effectively compensates for
104
// the difference in behavior for the first stack map frame (where the
105
// pc offset is just offset_delta) compared to subsequent frames (where
106
// the pc offset is always offset_delta+1).
107
int pc = -1;
108
109
map.put(pc, new StackMap(initialLocals, empty));
110
111
for (int i = 0; i < attr.entries.length; i++)
112
pc = attr.entries[i].accept(builder, pc);
113
}
114
115
public void writeInitialDetails() {
116
writeDetails(-1);
117
}
118
119
public void writeDetails(Instruction instr) {
120
writeDetails(instr.getPC());
121
}
122
123
private void writeDetails(int pc) {
124
if (map == null)
125
return;
126
127
StackMap m = map.get(pc);
128
if (m != null) {
129
print("StackMap locals: ", m.locals);
130
print("StackMap stack: ", m.stack);
131
}
132
133
}
134
135
void print(String label, verification_type_info[] entries) {
136
print(label);
137
for (int i = 0; i < entries.length; i++) {
138
print(" ");
139
print(entries[i]);
140
}
141
println();
142
}
143
144
void print(verification_type_info entry) {
145
if (entry == null) {
146
print("ERROR");
147
return;
148
}
149
150
switch (entry.tag) {
151
case -1:
152
print(((CustomVerificationTypeInfo) entry).text);
153
break;
154
155
case ITEM_Top:
156
print("top");
157
break;
158
159
case ITEM_Integer:
160
print("int");
161
break;
162
163
case ITEM_Float:
164
print("float");
165
break;
166
167
case ITEM_Long:
168
print("long");
169
break;
170
171
case ITEM_Double:
172
print("double");
173
break;
174
175
case ITEM_Null:
176
print("null");
177
break;
178
179
case ITEM_UninitializedThis:
180
print("uninit_this");
181
break;
182
183
case ITEM_Object:
184
try {
185
ConstantPool cp = classWriter.getClassFile().constant_pool;
186
ConstantPool.CONSTANT_Class_info class_info = cp.getClassInfo(((Object_variable_info) entry).cpool_index);
187
print(cp.getUTF8Value(class_info.name_index));
188
} catch (ConstantPoolException e) {
189
print("??");
190
}
191
break;
192
193
case ITEM_Uninitialized:
194
print(((Uninitialized_variable_info) entry).offset);
195
break;
196
}
197
198
}
199
200
private Map<Integer, StackMap> map;
201
private ClassWriter classWriter;
202
203
class StackMapBuilder
204
implements StackMapTable_attribute.stack_map_frame.Visitor<Integer, Integer> {
205
206
public Integer visit_same_frame(same_frame frame, Integer pc) {
207
int new_pc = pc + frame.getOffsetDelta() + 1;
208
StackMap m = map.get(pc);
209
assert (m != null);
210
map.put(new_pc, m);
211
return new_pc;
212
}
213
214
public Integer visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame frame, Integer pc) {
215
int new_pc = pc + frame.getOffsetDelta() + 1;
216
StackMap prev = map.get(pc);
217
assert (prev != null);
218
StackMap m = new StackMap(prev.locals, frame.stack);
219
map.put(new_pc, m);
220
return new_pc;
221
}
222
223
public Integer visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended frame, Integer pc) {
224
int new_pc = pc + frame.getOffsetDelta() + 1;
225
StackMap prev = map.get(pc);
226
assert (prev != null);
227
StackMap m = new StackMap(prev.locals, frame.stack);
228
map.put(new_pc, m);
229
return new_pc;
230
}
231
232
public Integer visit_chop_frame(chop_frame frame, Integer pc) {
233
int new_pc = pc + frame.getOffsetDelta() + 1;
234
StackMap prev = map.get(pc);
235
assert (prev != null);
236
int k = 251 - frame.frame_type;
237
verification_type_info[] new_locals = Arrays.copyOf(prev.locals, prev.locals.length - k);
238
StackMap m = new StackMap(new_locals, empty);
239
map.put(new_pc, m);
240
return new_pc;
241
}
242
243
public Integer visit_same_frame_extended(same_frame_extended frame, Integer pc) {
244
int new_pc = pc + frame.getOffsetDelta();
245
StackMap m = map.get(pc);
246
assert (m != null);
247
map.put(new_pc, m);
248
return new_pc;
249
}
250
251
public Integer visit_append_frame(append_frame frame, Integer pc) {
252
int new_pc = pc + frame.getOffsetDelta() + 1;
253
StackMap prev = map.get(pc);
254
assert (prev != null);
255
verification_type_info[] new_locals = new verification_type_info[prev.locals.length + frame.locals.length];
256
System.arraycopy(prev.locals, 0, new_locals, 0, prev.locals.length);
257
System.arraycopy(frame.locals, 0, new_locals, prev.locals.length, frame.locals.length);
258
StackMap m = new StackMap(new_locals, empty);
259
map.put(new_pc, m);
260
return new_pc;
261
}
262
263
public Integer visit_full_frame(full_frame frame, Integer pc) {
264
int new_pc = pc + frame.getOffsetDelta() + 1;
265
StackMap m = new StackMap(frame.locals, frame.stack);
266
map.put(new_pc, m);
267
return new_pc;
268
}
269
270
}
271
272
static class StackMap {
273
StackMap(verification_type_info[] locals, verification_type_info[] stack) {
274
this.locals = locals;
275
this.stack = stack;
276
}
277
278
private final verification_type_info[] locals;
279
private final verification_type_info[] stack;
280
}
281
282
static class CustomVerificationTypeInfo extends verification_type_info {
283
public CustomVerificationTypeInfo(String text) {
284
super(-1);
285
this.text = text;
286
}
287
private String text;
288
}
289
290
private final verification_type_info[] empty = { };
291
}
292
293