Mercurial > hg > openjdk > jdk6 > hotspot
changeset 4084:8af48ff040c9
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 | Mon, 19 Jan 2015 05:28:21 +0000 |
parents | 1c7abe33c11f |
children | c9b5ffda6970 |
files | src/share/vm/classfile/stackMapTable.cpp src/share/vm/classfile/stackMapTable.hpp src/share/vm/classfile/verifier.cpp src/share/vm/classfile/verifier.hpp |
diffstat | 4 files changed, 16 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/classfile/stackMapTable.cpp Thu Nov 06 04:57:28 2014 -0800 +++ b/src/share/vm/classfile/stackMapTable.cpp Mon Jan 19 05:28:21 2015 +0000 @@ -68,27 +68,29 @@ bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, - bool match, bool update, TRAPS) const { + bool match, bool update, bool handler, TRAPS) const { int index = get_index_from_offset(target); return match_stackmap( frame, target, index, match, - update, CHECK_VERIFY_(frame->verifier(), false)); + update, handler, CHECK_VERIFY_(frame->verifier(), false)); } // Match and/or update current_frame to the frame in stackmap table with // specified offset and frame index. Return true if the two frames match. +// handler is true if the frame in stackmap_table is for an exception handler. // -// The values of match and update are: _match__update_ +// The values of match and update are: _match__update__handler // -// checking a branch target/exception handler: true false +// checking a branch target: true false false +// checking an exception handler: true false true // linear bytecode verification following an -// unconditional branch: false true +// unconditional branch: false true false // linear bytecode verification not following an -// unconditional branch: true true +// unconditional branch: true true false bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, int32_t frame_index, - bool match, bool update, TRAPS) const { + bool match, bool update, bool handler, TRAPS) const { if (frame_index < 0 || frame_index >= _frame_count) { frame->verifier()->verify_error(frame->offset(), "Expecting a stackmap frame at branch target %d", target); @@ -98,12 +100,10 @@ bool result = true; StackMapFrame *stackmap_frame = _frame_array[frame_index]; if (match) { - // when checking handler target, match == true && update == false - bool is_exception_handler = !update; // Has direct control flow from last instruction, need to match the two // frames. result = frame->is_assignable_to( - stackmap_frame, is_exception_handler, + stackmap_frame, handler, CHECK_VERIFY_(frame->verifier(), false)); } if (update) { @@ -126,7 +126,7 @@ void StackMapTable::check_jump_target( StackMapFrame* frame, int32_t target, TRAPS) const { bool match = match_stackmap( - frame, target, true, false, CHECK_VERIFY(frame->verifier())); + frame, target, true, false, false, CHECK_VERIFY(frame->verifier())); if (!match || (target < 0 || target >= _code_length)) { frame->verifier()->verify_error(frame->offset(), "Inconsistent stackmap frames at branch target %d", target); @@ -134,7 +134,6 @@ } // check if uninitialized objects exist on backward branches check_new_object(frame, target, CHECK_VERIFY(frame->verifier())); - frame->verifier()->update_furthest_jump(target); } void StackMapTable::check_new_object(
--- a/src/share/vm/classfile/stackMapTable.hpp Thu Nov 06 04:57:28 2014 -0800 +++ b/src/share/vm/classfile/stackMapTable.hpp Mon Jan 19 05:28:21 2015 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,12 +73,12 @@ // specified offset. Return true if the two frames match. bool match_stackmap( StackMapFrame* current_frame, int32_t offset, - bool match, bool update, TRAPS) const; + bool match, bool update, bool handler, TRAPS) const; // Match and/or update current_frame to the frame in stackmap table with // specified offset and frame index. Return true if the two frames match. bool match_stackmap( StackMapFrame* current_frame, int32_t offset, int32_t frame_index, - bool match, bool update, TRAPS) const; + bool match, bool update, bool handler, TRAPS) const; // Check jump instructions. Make sure there are no uninitialized // instances on backward branch.
--- a/src/share/vm/classfile/verifier.cpp Thu Nov 06 04:57:28 2014 -0800 +++ b/src/share/vm/classfile/verifier.cpp Mon Jan 19 05:28:21 2015 +0000 @@ -379,8 +379,6 @@ // flow from current instruction to the next // instruction in sequence - set_furthest_jump(0); - Bytecodes::Code opcode; while (!bcs.is_last_bytecode()) { // Check for recursive re-verification before each bytecode. @@ -1455,7 +1453,7 @@ // If matched, current_frame will be updated by this method. bool match = stackmap_table->match_stackmap( current_frame, this_offset, stackmap_index, - !no_control_flow, true, CHECK_VERIFY_(this, 0)); + !no_control_flow, true, false, CHECK_VERIFY_(this, 0)); if (!match) { // report type error verify_error(bci, "Instruction type does not match stack map"); @@ -1499,7 +1497,7 @@ new_frame->push_stack(throwable, CHECK_VERIFY(this)); } bool match = stackmap_table->match_stackmap( - new_frame, handler_pc, true, false, CHECK_VERIFY(this)); + new_frame, handler_pc, true, false, true, CHECK_VERIFY(this)); if (!match) { verify_error(bci, "Stack map does not match the one at exception handler %d", @@ -1895,12 +1893,6 @@ return; } - // Make sure that this call is not jumped over. - if (bci < furthest_jump()) { - verify_error(bci, "Bad <init> method call from inside of a branch"); - return; - } - // Make sure that this call is not done from within a TRY block because // that can result in returning an incomplete object. Simply checking // (bci >= start_pc) also ensures that this call is not done after a TRY
--- a/src/share/vm/classfile/verifier.hpp Thu Nov 06 04:57:28 2014 -0800 +++ b/src/share/vm/classfile/verifier.hpp Mon Jan 19 05:28:21 2015 +0000 @@ -97,9 +97,6 @@ size_t _message_buffer_len; GrowableArray<Symbol*>* _symbols; // keep a list of symbols created - // Used to detect illegal jumps over calls to super() nd this() in ctors. - int32_t _furthest_jump; - void verify_method(methodHandle method, TRAPS); char* generate_code_data(methodHandle m, u4 code_length, TRAPS); void verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS); @@ -236,18 +233,6 @@ static bool _verify_verbose; // for debugging - // Keep track of the furthest branch done in a method to make sure that - // there are no branches over calls to super() or this() from inside of - // a constructor. - int32_t furthest_jump() { return _furthest_jump; } - - void set_furthest_jump(int32_t target) { - _furthest_jump = target; - } - - void update_furthest_jump(int32_t target) { - if (target > _furthest_jump) _furthest_jump = target; - } }; inline int ClassVerifier::change_sig_to_verificationType(