comparison src/share/vm/classfile/verifier.cpp @ 20242:d14a18794c90

8051012: Regression in verifier for <init> method call from inside of a branch Summary: Fix stackmap matching for branches. Reviewed-by: coleenp, lfoltan, acorn
author hseigel
date Sat, 02 Aug 2014 16:28:59 -0400
parents d22136881b85
children 92baebeb744b
comparison
equal deleted inserted replaced
20241:bcd72ab4d91f 20242:d14a18794c90
632 // Scan the byte code linearly from the start to the end 632 // Scan the byte code linearly from the start to the end
633 bool no_control_flow = false; // Set to true when there is no direct control 633 bool no_control_flow = false; // Set to true when there is no direct control
634 // flow from current instruction to the next 634 // flow from current instruction to the next
635 // instruction in sequence 635 // instruction in sequence
636 636
637 set_furthest_jump(0);
638
639 Bytecodes::Code opcode; 637 Bytecodes::Code opcode;
640 while (!bcs.is_last_bytecode()) { 638 while (!bcs.is_last_bytecode()) {
641 // Check for recursive re-verification before each bytecode. 639 // Check for recursive re-verification before each bytecode.
642 if (was_recursively_verified()) return; 640 if (was_recursively_verified()) return;
643 641
1792 // See if current stack map can be assigned to the frame in table. 1790 // See if current stack map can be assigned to the frame in table.
1793 // current_frame is the stackmap frame got from the last instruction. 1791 // current_frame is the stackmap frame got from the last instruction.
1794 // If matched, current_frame will be updated by this method. 1792 // If matched, current_frame will be updated by this method.
1795 bool matches = stackmap_table->match_stackmap( 1793 bool matches = stackmap_table->match_stackmap(
1796 current_frame, this_offset, stackmap_index, 1794 current_frame, this_offset, stackmap_index,
1797 !no_control_flow, true, &ctx, CHECK_VERIFY_(this, 0)); 1795 !no_control_flow, true, false, &ctx, CHECK_VERIFY_(this, 0));
1798 if (!matches) { 1796 if (!matches) {
1799 // report type error 1797 // report type error
1800 verify_error(ctx, "Instruction type does not match stack map"); 1798 verify_error(ctx, "Instruction type does not match stack map");
1801 return 0; 1799 return 0;
1802 } 1800 }
1839 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); 1837 VerificationType::reference_type(vmSymbols::java_lang_Throwable());
1840 new_frame->push_stack(throwable, CHECK_VERIFY(this)); 1838 new_frame->push_stack(throwable, CHECK_VERIFY(this));
1841 } 1839 }
1842 ErrorContext ctx; 1840 ErrorContext ctx;
1843 bool matches = stackmap_table->match_stackmap( 1841 bool matches = stackmap_table->match_stackmap(
1844 new_frame, handler_pc, true, false, &ctx, CHECK_VERIFY(this)); 1842 new_frame, handler_pc, true, false, true, &ctx, CHECK_VERIFY(this));
1845 if (!matches) { 1843 if (!matches) {
1846 verify_error(ctx, "Stack map does not match the one at " 1844 verify_error(ctx, "Stack map does not match the one at "
1847 "exception handler %d", handler_pc); 1845 "exception handler %d", handler_pc);
1848 return; 1846 return;
1849 } 1847 }
2250 TypeOrigin::implicit(current_type())), 2248 TypeOrigin::implicit(current_type())),
2251 "Bad <init> method call"); 2249 "Bad <init> method call");
2252 return; 2250 return;
2253 } 2251 }
2254 2252
2255 // Make sure that this call is not jumped over.
2256 if (bci < furthest_jump()) {
2257 verify_error(ErrorContext::bad_code(bci),
2258 "Bad <init> method call from inside of a branch");
2259 return;
2260 }
2261
2262 // Make sure that this call is not done from within a TRY block because 2253 // Make sure that this call is not done from within a TRY block because
2263 // that can result in returning an incomplete object. Simply checking 2254 // that can result in returning an incomplete object. Simply checking
2264 // (bci >= start_pc) also ensures that this call is not done after a TRY 2255 // (bci >= start_pc) also ensures that this call is not done after a TRY
2265 // block. That is also illegal because this call must be the first Java 2256 // block. That is also illegal because this call must be the first Java
2266 // statement in the constructor. 2257 // statement in the constructor.