Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/classfile/stackMapFrame.cpp
32285 views
1
/*
2
* Copyright (c) 2003, 2016, 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
*/
24
25
#include "precompiled.hpp"
26
#include "classfile/stackMapFrame.hpp"
27
#include "classfile/verifier.hpp"
28
#include "memory/resourceArea.hpp"
29
#include "oops/oop.inline.hpp"
30
#include "oops/symbol.hpp"
31
#include "runtime/handles.inline.hpp"
32
#include "utilities/globalDefinitions.hpp"
33
34
StackMapFrame::StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* v) :
35
_offset(0), _locals_size(0), _stack_size(0),
36
_stack_mark(0), _flags(0), _max_locals(max_locals),
37
_max_stack(max_stack), _verifier(v) {
38
Thread* thr = v->thread();
39
_locals = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_locals);
40
_stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_stack);
41
int32_t i;
42
for(i = 0; i < max_locals; i++) {
43
_locals[i] = VerificationType::bogus_type();
44
}
45
for(i = 0; i < max_stack; i++) {
46
_stack[i] = VerificationType::bogus_type();
47
}
48
}
49
50
StackMapFrame* StackMapFrame::frame_in_exception_handler(u1 flags) {
51
Thread* thr = _verifier->thread();
52
VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, 1);
53
StackMapFrame* frame = new StackMapFrame(_offset, flags, _locals_size, 0, _max_locals, _max_stack, _locals, stack, _verifier);
54
return frame;
55
}
56
57
void StackMapFrame::initialize_object(
58
VerificationType old_object, VerificationType new_object) {
59
int32_t i;
60
for (i = 0; i < _max_locals; i++) {
61
if (_locals[i].equals(old_object)) {
62
_locals[i] = new_object;
63
}
64
}
65
for (i = 0; i < _stack_size; i++) {
66
if (_stack[i].equals(old_object)) {
67
_stack[i] = new_object;
68
}
69
}
70
if (old_object == VerificationType::uninitialized_this_type()) {
71
// "this" has been initialized - reset flags
72
_flags = 0;
73
}
74
}
75
76
VerificationType StackMapFrame::set_locals_from_arg(
77
const methodHandle m, VerificationType thisKlass, TRAPS) {
78
SignatureStream ss(m->signature());
79
int init_local_num = 0;
80
if (!m->is_static()) {
81
init_local_num++;
82
// add one extra argument for instance method
83
if (m->name() == vmSymbols::object_initializer_name() &&
84
thisKlass.name() != vmSymbols::java_lang_Object()) {
85
_locals[0] = VerificationType::uninitialized_this_type();
86
_flags |= FLAG_THIS_UNINIT;
87
} else {
88
_locals[0] = thisKlass;
89
}
90
}
91
92
// local num may be greater than size of parameters because long/double occupies two slots
93
while(!ss.at_return_type()) {
94
init_local_num += _verifier->change_sig_to_verificationType(
95
&ss, &_locals[init_local_num],
96
CHECK_VERIFY_(verifier(), VerificationType::bogus_type()));
97
ss.next();
98
}
99
_locals_size = init_local_num;
100
101
switch (ss.type()) {
102
case T_OBJECT:
103
case T_ARRAY:
104
{
105
Symbol* sig = ss.as_symbol(CHECK_(VerificationType::bogus_type()));
106
// Create another symbol to save as signature stream unreferences
107
// this symbol.
108
Symbol* sig_copy =
109
verifier()->create_temporary_symbol(sig, 0, sig->utf8_length(),
110
CHECK_(VerificationType::bogus_type()));
111
assert(sig_copy == sig, "symbols don't match");
112
return VerificationType::reference_type(sig_copy);
113
}
114
case T_INT: return VerificationType::integer_type();
115
case T_BYTE: return VerificationType::byte_type();
116
case T_CHAR: return VerificationType::char_type();
117
case T_SHORT: return VerificationType::short_type();
118
case T_BOOLEAN: return VerificationType::boolean_type();
119
case T_FLOAT: return VerificationType::float_type();
120
case T_DOUBLE: return VerificationType::double_type();
121
case T_LONG: return VerificationType::long_type();
122
case T_VOID: return VerificationType::bogus_type();
123
default:
124
ShouldNotReachHere();
125
}
126
return VerificationType::bogus_type();
127
}
128
129
void StackMapFrame::copy_locals(const StackMapFrame* src) {
130
int32_t len = src->locals_size() < _locals_size ?
131
src->locals_size() : _locals_size;
132
for (int32_t i = 0; i < len; i++) {
133
_locals[i] = src->locals()[i];
134
}
135
}
136
137
void StackMapFrame::copy_stack(const StackMapFrame* src) {
138
int32_t len = src->stack_size() < _stack_size ?
139
src->stack_size() : _stack_size;
140
for (int32_t i = 0; i < len; i++) {
141
_stack[i] = src->stack()[i];
142
}
143
}
144
145
// Returns the location of the first mismatch, or 'len' if there are no
146
// mismatches
147
int StackMapFrame::is_assignable_to(
148
VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
149
int32_t i = 0;
150
for (i = 0; i < len; i++) {
151
if (!to[i].is_assignable_from(from[i], verifier(), false, THREAD)) {
152
break;
153
}
154
}
155
return i;
156
}
157
158
bool StackMapFrame::is_assignable_to(
159
const StackMapFrame* target, ErrorContext* ctx, TRAPS) const {
160
if (_max_locals != target->max_locals()) {
161
*ctx = ErrorContext::locals_size_mismatch(
162
_offset, (StackMapFrame*)this, (StackMapFrame*)target);
163
return false;
164
}
165
if (_stack_size != target->stack_size()) {
166
*ctx = ErrorContext::stack_size_mismatch(
167
_offset, (StackMapFrame*)this, (StackMapFrame*)target);
168
return false;
169
}
170
// Only need to compare type elements up to target->locals() or target->stack().
171
// The remaining type elements in this state can be ignored because they are
172
// assignable to bogus type.
173
int mismatch_loc;
174
mismatch_loc = is_assignable_to(
175
_locals, target->locals(), target->locals_size(), THREAD);
176
if (mismatch_loc != target->locals_size()) {
177
*ctx = ErrorContext::bad_type(target->offset(),
178
TypeOrigin::local(mismatch_loc, (StackMapFrame*)this),
179
TypeOrigin::sm_local(mismatch_loc, (StackMapFrame*)target));
180
return false;
181
}
182
mismatch_loc = is_assignable_to(_stack, target->stack(), _stack_size, THREAD);
183
if (mismatch_loc != _stack_size) {
184
*ctx = ErrorContext::bad_type(target->offset(),
185
TypeOrigin::stack(mismatch_loc, (StackMapFrame*)this),
186
TypeOrigin::sm_stack(mismatch_loc, (StackMapFrame*)target));
187
return false;
188
}
189
190
if ((_flags | target->flags()) == target->flags()) {
191
return true;
192
} else {
193
*ctx = ErrorContext::bad_flags(target->offset(),
194
(StackMapFrame*)this, (StackMapFrame*)target);
195
return false;
196
}
197
}
198
199
VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {
200
if (_stack_size <= 0) {
201
verifier()->verify_error(
202
ErrorContext::stack_underflow(_offset, this),
203
"Operand stack underflow");
204
return VerificationType::bogus_type();
205
}
206
VerificationType top = _stack[--_stack_size];
207
bool subtype = type.is_assignable_from(
208
top, verifier(), false, CHECK_(VerificationType::bogus_type()));
209
if (!subtype) {
210
verifier()->verify_error(
211
ErrorContext::bad_type(_offset, stack_top_ctx(),
212
TypeOrigin::implicit(type)),
213
"Bad type on operand stack");
214
return VerificationType::bogus_type();
215
}
216
return top;
217
}
218
219
VerificationType StackMapFrame::get_local(
220
int32_t index, VerificationType type, TRAPS) {
221
if (index >= _max_locals) {
222
verifier()->verify_error(
223
ErrorContext::bad_local_index(_offset, index),
224
"Local variable table overflow");
225
return VerificationType::bogus_type();
226
}
227
bool subtype = type.is_assignable_from(_locals[index],
228
verifier(), false, CHECK_(VerificationType::bogus_type()));
229
if (!subtype) {
230
verifier()->verify_error(
231
ErrorContext::bad_type(_offset,
232
TypeOrigin::local(index, this),
233
TypeOrigin::implicit(type)),
234
"Bad local variable type");
235
return VerificationType::bogus_type();
236
}
237
if(index >= _locals_size) { _locals_size = index + 1; }
238
return _locals[index];
239
}
240
241
void StackMapFrame::get_local_2(
242
int32_t index, VerificationType type1, VerificationType type2, TRAPS) {
243
assert(type1.is_long() || type1.is_double(), "must be long/double");
244
assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
245
if (index >= _locals_size - 1) {
246
verifier()->verify_error(
247
ErrorContext::bad_local_index(_offset, index),
248
"get long/double overflows locals");
249
return;
250
}
251
bool subtype = type1.is_assignable_from(_locals[index], verifier(), false, CHECK);
252
if (!subtype) {
253
verifier()->verify_error(
254
ErrorContext::bad_type(_offset,
255
TypeOrigin::local(index, this), TypeOrigin::implicit(type1)),
256
"Bad local variable type");
257
} else {
258
subtype = type2.is_assignable_from(_locals[index + 1], verifier(), false, CHECK);
259
if (!subtype) {
260
/* Unreachable? All local store routines convert a split long or double
261
* into a TOP during the store. So we should never end up seeing an
262
* orphaned half. */
263
verifier()->verify_error(
264
ErrorContext::bad_type(_offset,
265
TypeOrigin::local(index + 1, this), TypeOrigin::implicit(type2)),
266
"Bad local variable type");
267
}
268
}
269
}
270
271
void StackMapFrame::set_local(int32_t index, VerificationType type, TRAPS) {
272
assert(!type.is_check(), "Must be a real type");
273
if (index >= _max_locals) {
274
verifier()->verify_error(
275
ErrorContext::bad_local_index(_offset, index),
276
"Local variable table overflow");
277
return;
278
}
279
// If type at index is double or long, set the next location to be unusable
280
if (_locals[index].is_double() || _locals[index].is_long()) {
281
assert((index + 1) < _locals_size, "Local variable table overflow");
282
_locals[index + 1] = VerificationType::bogus_type();
283
}
284
// If type at index is double_2 or long_2, set the previous location to be unusable
285
if (_locals[index].is_double2() || _locals[index].is_long2()) {
286
assert(index >= 1, "Local variable table underflow");
287
_locals[index - 1] = VerificationType::bogus_type();
288
}
289
_locals[index] = type;
290
if (index >= _locals_size) {
291
#ifdef ASSERT
292
for (int i=_locals_size; i<index; i++) {
293
assert(_locals[i] == VerificationType::bogus_type(),
294
"holes must be bogus type");
295
}
296
#endif
297
_locals_size = index + 1;
298
}
299
}
300
301
void StackMapFrame::set_local_2(
302
int32_t index, VerificationType type1, VerificationType type2, TRAPS) {
303
assert(type1.is_long() || type1.is_double(), "must be long/double");
304
assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
305
if (index >= _max_locals - 1) {
306
verifier()->verify_error(
307
ErrorContext::bad_local_index(_offset, index),
308
"Local variable table overflow");
309
return;
310
}
311
// If type at index+1 is double or long, set the next location to be unusable
312
if (_locals[index+1].is_double() || _locals[index+1].is_long()) {
313
assert((index + 2) < _locals_size, "Local variable table overflow");
314
_locals[index + 2] = VerificationType::bogus_type();
315
}
316
// If type at index is double_2 or long_2, set the previous location to be unusable
317
if (_locals[index].is_double2() || _locals[index].is_long2()) {
318
assert(index >= 1, "Local variable table underflow");
319
_locals[index - 1] = VerificationType::bogus_type();
320
}
321
_locals[index] = type1;
322
_locals[index+1] = type2;
323
if (index >= _locals_size - 1) {
324
#ifdef ASSERT
325
for (int i=_locals_size; i<index; i++) {
326
assert(_locals[i] == VerificationType::bogus_type(),
327
"holes must be bogus type");
328
}
329
#endif
330
_locals_size = index + 2;
331
}
332
}
333
334
TypeOrigin StackMapFrame::stack_top_ctx() {
335
return TypeOrigin::stack(_stack_size, this);
336
}
337
338
void StackMapFrame::print_on(outputStream* str) const {
339
str->indent().print_cr("bci: @%d", _offset);
340
str->indent().print_cr("flags: {%s }",
341
flag_this_uninit() ? " flagThisUninit" : "");
342
str->indent().print("locals: {");
343
for (int32_t i = 0; i < _locals_size; ++i) {
344
str->print(" ");
345
_locals[i].print_on(str);
346
if (i != _locals_size - 1) {
347
str->print(",");
348
}
349
}
350
str->print_cr(" }");
351
str->indent().print("stack: {");
352
for (int32_t j = 0; j < _stack_size; ++j) {
353
str->print(" ");
354
_stack[j].print_on(str);
355
if (j != _stack_size - 1) {
356
str->print(",");
357
}
358
}
359
str->print_cr(" }");
360
}
361
362