src/share/vm/classfile/stackMapFrame.cpp

changeset 3992
4ee06e614636
parent 2759
3449f5e02cc4
child 6824
2373a1f4987c
child 6960
b2daaf70fab2
equal deleted inserted replaced
3991:c3c2141203e7 3992:4ee06e614636
1 /* 1 /*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
30 #include "oops/symbol.hpp" 30 #include "oops/symbol.hpp"
31 #include "runtime/handles.inline.hpp" 31 #include "runtime/handles.inline.hpp"
32 #include "utilities/globalDefinitions.hpp" 32 #include "utilities/globalDefinitions.hpp"
33 33
34 StackMapFrame::StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* v) : 34 StackMapFrame::StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* v) :
35 _offset(0), _locals_size(0), _stack_size(0), _flags(0), 35 _offset(0), _locals_size(0), _stack_size(0),
36 _max_locals(max_locals), _max_stack(max_stack), 36 _stack_mark(0), _flags(0), _max_locals(max_locals),
37 _verifier(v) { 37 _max_stack(max_stack), _verifier(v) {
38 Thread* thr = v->thread(); 38 Thread* thr = v->thread();
39 _locals = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_locals); 39 _locals = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_locals);
40 _stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_stack); 40 _stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_stack);
41 int32_t i; 41 int32_t i;
42 for(i = 0; i < max_locals; i++) { 42 for(i = 0; i < max_locals; i++) {
155 for (int32_t i = 0; i < len; i++) { 155 for (int32_t i = 0; i < len; i++) {
156 _stack[i] = src->stack()[i]; 156 _stack[i] = src->stack()[i];
157 } 157 }
158 } 158 }
159 159
160 160 // Returns the location of the first mismatch, or 'len' if there are no
161 bool StackMapFrame::is_assignable_to( 161 // mismatches
162 int StackMapFrame::is_assignable_to(
162 VerificationType* from, VerificationType* to, int32_t len, TRAPS) const { 163 VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
163 for (int32_t i = 0; i < len; i++) { 164 int32_t i = 0;
164 bool subtype = to[i].is_assignable_from( 165 for (i = 0; i < len; i++) {
165 from[i], verifier(), THREAD); 166 if (!to[i].is_assignable_from(from[i], verifier(), THREAD)) {
166 if (!subtype) { 167 break;
167 return false; 168 }
168 } 169 }
169 } 170 return i;
170 return true;
171 } 171 }
172 172
173 bool StackMapFrame::has_flag_match_exception( 173 bool StackMapFrame::has_flag_match_exception(
174 const StackMapFrame* target) const { 174 const StackMapFrame* target) const {
175 // We allow flags of {UninitThis} to assign to {} if-and-only-if the 175 // We allow flags of {UninitThis} to assign to {} if-and-only-if the
207 207
208 return true; 208 return true;
209 } 209 }
210 210
211 bool StackMapFrame::is_assignable_to( 211 bool StackMapFrame::is_assignable_to(
212 const StackMapFrame* target, bool is_exception_handler, TRAPS) const { 212 const StackMapFrame* target, bool is_exception_handler,
213 if (_max_locals != target->max_locals() || 213 ErrorContext* ctx, TRAPS) const {
214 _stack_size != target->stack_size()) { 214 if (_max_locals != target->max_locals()) {
215 *ctx = ErrorContext::locals_size_mismatch(
216 _offset, (StackMapFrame*)this, (StackMapFrame*)target);
217 return false;
218 }
219 if (_stack_size != target->stack_size()) {
220 *ctx = ErrorContext::stack_size_mismatch(
221 _offset, (StackMapFrame*)this, (StackMapFrame*)target);
215 return false; 222 return false;
216 } 223 }
217 // Only need to compare type elements up to target->locals() or target->stack(). 224 // Only need to compare type elements up to target->locals() or target->stack().
218 // The remaining type elements in this state can be ignored because they are 225 // The remaining type elements in this state can be ignored because they are
219 // assignable to bogus type. 226 // assignable to bogus type.
220 bool match_locals = is_assignable_to( 227 int mismatch_loc;
221 _locals, target->locals(), target->locals_size(), CHECK_false); 228 mismatch_loc = is_assignable_to(
222 bool match_stack = is_assignable_to( 229 _locals, target->locals(), target->locals_size(), THREAD);
223 _stack, target->stack(), _stack_size, CHECK_false); 230 if (mismatch_loc != target->locals_size()) {
231 *ctx = ErrorContext::bad_type(target->offset(),
232 TypeOrigin::local(mismatch_loc, (StackMapFrame*)this),
233 TypeOrigin::sm_local(mismatch_loc, (StackMapFrame*)target));
234 return false;
235 }
236 mismatch_loc = is_assignable_to(_stack, target->stack(), _stack_size, THREAD);
237 if (mismatch_loc != _stack_size) {
238 *ctx = ErrorContext::bad_type(target->offset(),
239 TypeOrigin::stack(mismatch_loc, (StackMapFrame*)this),
240 TypeOrigin::sm_stack(mismatch_loc, (StackMapFrame*)target));
241 return false;
242 }
243
224 bool match_flags = (_flags | target->flags()) == target->flags(); 244 bool match_flags = (_flags | target->flags()) == target->flags();
225 245 if (match_flags || is_exception_handler && has_flag_match_exception(target)) {
226 return match_locals && match_stack && 246 return true;
227 (match_flags || (is_exception_handler && has_flag_match_exception(target))); 247 } else {
248 *ctx = ErrorContext::bad_flags(target->offset(),
249 (StackMapFrame*)this, (StackMapFrame*)target);
250 return false;
251 }
228 } 252 }
229 253
230 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) { 254 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {
231 if (_stack_size <= 0) { 255 if (_stack_size <= 0) {
232 verifier()->verify_error(_offset, "Operand stack underflow"); 256 verifier()->verify_error(
257 ErrorContext::stack_underflow(_offset, this),
258 "Operand stack underflow");
233 return VerificationType::bogus_type(); 259 return VerificationType::bogus_type();
234 } 260 }
235 VerificationType top = _stack[--_stack_size]; 261 VerificationType top = _stack[--_stack_size];
236 bool subtype = type.is_assignable_from( 262 bool subtype = type.is_assignable_from(
237 top, verifier(), CHECK_(VerificationType::bogus_type())); 263 top, verifier(), CHECK_(VerificationType::bogus_type()));
238 if (!subtype) { 264 if (!subtype) {
239 verifier()->verify_error(_offset, "Bad type on operand stack"); 265 verifier()->verify_error(
266 ErrorContext::bad_type(_offset, stack_top_ctx(),
267 TypeOrigin::implicit(type)),
268 "Bad type on operand stack");
240 return VerificationType::bogus_type(); 269 return VerificationType::bogus_type();
241 } 270 }
242 NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
243 return top; 271 return top;
244 } 272 }
245 273
246 VerificationType StackMapFrame::get_local( 274 VerificationType StackMapFrame::get_local(
247 int32_t index, VerificationType type, TRAPS) { 275 int32_t index, VerificationType type, TRAPS) {
248 if (index >= _max_locals) { 276 if (index >= _max_locals) {
249 verifier()->verify_error(_offset, "Local variable table overflow"); 277 verifier()->verify_error(
278 ErrorContext::bad_local_index(_offset, index),
279 "Local variable table overflow");
250 return VerificationType::bogus_type(); 280 return VerificationType::bogus_type();
251 } 281 }
252 bool subtype = type.is_assignable_from(_locals[index], 282 bool subtype = type.is_assignable_from(_locals[index],
253 verifier(), CHECK_(VerificationType::bogus_type())); 283 verifier(), CHECK_(VerificationType::bogus_type()));
254 if (!subtype) { 284 if (!subtype) {
255 verifier()->verify_error(_offset, "Bad local variable type"); 285 verifier()->verify_error(
286 ErrorContext::bad_type(_offset,
287 TypeOrigin::local(index, this),
288 TypeOrigin::implicit(type)),
289 "Bad local variable type");
256 return VerificationType::bogus_type(); 290 return VerificationType::bogus_type();
257 } 291 }
258 if(index >= _locals_size) { _locals_size = index + 1; } 292 if(index >= _locals_size) { _locals_size = index + 1; }
259 return _locals[index]; 293 return _locals[index];
260 } 294 }
262 void StackMapFrame::get_local_2( 296 void StackMapFrame::get_local_2(
263 int32_t index, VerificationType type1, VerificationType type2, TRAPS) { 297 int32_t index, VerificationType type1, VerificationType type2, TRAPS) {
264 assert(type1.is_long() || type1.is_double(), "must be long/double"); 298 assert(type1.is_long() || type1.is_double(), "must be long/double");
265 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); 299 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
266 if (index >= _locals_size - 1) { 300 if (index >= _locals_size - 1) {
267 verifier()->verify_error(_offset, "get long/double overflows locals"); 301 verifier()->verify_error(
302 ErrorContext::bad_local_index(_offset, index),
303 "get long/double overflows locals");
268 return; 304 return;
269 } 305 }
270 bool subtype1 = type1.is_assignable_from( 306 bool subtype = type1.is_assignable_from(_locals[index], verifier(), CHECK);
271 _locals[index], verifier(), CHECK); 307 if (!subtype) {
272 bool subtype2 = type2.is_assignable_from( 308 verifier()->verify_error(
273 _locals[index+1], verifier(), CHECK); 309 ErrorContext::bad_type(_offset,
274 if (!subtype1 || !subtype2) { 310 TypeOrigin::local(index, this), TypeOrigin::implicit(type1)),
275 verifier()->verify_error(_offset, "Bad local variable type"); 311 "Bad local variable type");
276 return; 312 } else {
313 subtype = type2.is_assignable_from(_locals[index + 1], verifier(), CHECK);
314 if (!subtype) {
315 /* Unreachable? All local store routines convert a split long or double
316 * into a TOP during the store. So we should never end up seeing an
317 * orphaned half. */
318 verifier()->verify_error(
319 ErrorContext::bad_type(_offset,
320 TypeOrigin::local(index + 1, this), TypeOrigin::implicit(type2)),
321 "Bad local variable type");
322 }
277 } 323 }
278 } 324 }
279 325
280 void StackMapFrame::set_local(int32_t index, VerificationType type, TRAPS) { 326 void StackMapFrame::set_local(int32_t index, VerificationType type, TRAPS) {
281 assert(!type.is_check(), "Must be a real type"); 327 assert(!type.is_check(), "Must be a real type");
282 if (index >= _max_locals) { 328 if (index >= _max_locals) {
283 verifier()->verify_error("Local variable table overflow", _offset); 329 verifier()->verify_error(
330 ErrorContext::bad_local_index(_offset, index),
331 "Local variable table overflow");
284 return; 332 return;
285 } 333 }
286 // If type at index is double or long, set the next location to be unusable 334 // If type at index is double or long, set the next location to be unusable
287 if (_locals[index].is_double() || _locals[index].is_long()) { 335 if (_locals[index].is_double() || _locals[index].is_long()) {
288 assert((index + 1) < _locals_size, "Local variable table overflow"); 336 assert((index + 1) < _locals_size, "Local variable table overflow");
308 void StackMapFrame::set_local_2( 356 void StackMapFrame::set_local_2(
309 int32_t index, VerificationType type1, VerificationType type2, TRAPS) { 357 int32_t index, VerificationType type1, VerificationType type2, TRAPS) {
310 assert(type1.is_long() || type1.is_double(), "must be long/double"); 358 assert(type1.is_long() || type1.is_double(), "must be long/double");
311 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2"); 359 assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
312 if (index >= _max_locals - 1) { 360 if (index >= _max_locals - 1) {
313 verifier()->verify_error("Local variable table overflow", _offset); 361 verifier()->verify_error(
362 ErrorContext::bad_local_index(_offset, index),
363 "Local variable table overflow");
314 return; 364 return;
315 } 365 }
316 // If type at index+1 is double or long, set the next location to be unusable 366 // If type at index+1 is double or long, set the next location to be unusable
317 if (_locals[index+1].is_double() || _locals[index+1].is_long()) { 367 if (_locals[index+1].is_double() || _locals[index+1].is_long()) {
318 assert((index + 2) < _locals_size, "Local variable table overflow"); 368 assert((index + 2) < _locals_size, "Local variable table overflow");
334 #endif 384 #endif
335 _locals_size = index + 2; 385 _locals_size = index + 2;
336 } 386 }
337 } 387 }
338 388
339 #ifndef PRODUCT 389 TypeOrigin StackMapFrame::stack_top_ctx() {
340 390 return TypeOrigin::stack(_stack_size, this);
341 void StackMapFrame::print() const { 391 }
342 tty->print_cr("stackmap_frame[%d]:", _offset); 392
343 tty->print_cr("flags = 0x%x", _flags); 393 void StackMapFrame::print_on(outputStream* str) const {
344 tty->print("locals[%d] = { ", _locals_size); 394 str->indent().print_cr("bci: @%d", _offset);
345 for (int32_t i = 0; i < _locals_size; i++) { 395 str->indent().print_cr("flags: {%s }",
346 _locals[i].print_on(tty); 396 flag_this_uninit() ? " flagThisUninit" : "");
347 } 397 str->indent().print("locals: {");
348 tty->print_cr(" }"); 398 for (int32_t i = 0; i < _locals_size; ++i) {
349 tty->print("stack[%d] = { ", _stack_size); 399 str->print(" ");
350 for (int32_t j = 0; j < _stack_size; j++) { 400 _locals[i].print_on(str);
351 _stack[j].print_on(tty); 401 if (i != _locals_size - 1) {
352 } 402 str->print(",");
353 tty->print_cr(" }"); 403 }
354 } 404 }
355 405 str->print_cr(" }");
356 #endif 406 str->indent().print("stack: {");
407 for (int32_t j = 0; j < _stack_size; ++j) {
408 str->print(" ");
409 _stack[j].print_on(str);
410 if (j != _stack_size - 1) {
411 str->print(",");
412 }
413 }
414 str->print_cr(" }");
415 }

mercurial