Mercurial > hg > graal-compiler
comparison src/share/vm/classfile/verifier.cpp @ 20740:7c9925f21c25 jdk8u20-b31
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 | d6fcbd1e1075 |
children | 7ebfc4557ca5 |
comparison
equal
deleted
inserted
replaced
18045:f06c7b654d63 | 20740:7c9925f21c25 |
---|---|
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. |