< prev index next >

src/share/vm/classfile/stackMapTable.cpp

Print this page
rev 4136 : 7116786: RFE: Detailed information on VerifyErrors
Summary: Provide additional detail in VerifyError messages
Reviewed-by: sspitsyn, acorn

*** 1,7 **** /* ! * Copyright (c) 2003, 2011, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2003, 2012, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 44,54 **** pre_frame, i == 0, max_locals, max_stack, CHECK_VERIFY(pre_frame->verifier())); _frame_array[i] = frame; int offset = frame->offset(); if (offset >= code_len || code_data[offset] == 0) { ! frame->verifier()->verify_error("StackMapTable error: bad offset"); return; } pre_frame = frame; } } --- 44,56 ---- pre_frame, i == 0, max_locals, max_stack, CHECK_VERIFY(pre_frame->verifier())); _frame_array[i] = frame; int offset = frame->offset(); if (offset >= code_len || code_data[offset] == 0) { ! frame->verifier()->verify_error( ! ErrorContext::bad_stackmap(i, frame), ! "StackMapTable error: bad offset"); return; } pre_frame = frame; } }
*** 66,81 **** return i; // frame with offset doesn't exist in the array } bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, ! bool match, bool update, bool handler, TRAPS) const { int index = get_index_from_offset(target); ! ! return match_stackmap( ! frame, target, index, match, ! 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. --- 68,80 ---- return i; // frame with offset doesn't exist in the array } bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, ! bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { int index = get_index_from_offset(target); ! return match_stackmap(frame, target, index, match, update, handler, ctx, THREAD); } // 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.
*** 88,112 **** // unconditional branch: false true false // linear bytecode verification not following an // unconditional branch: true true false bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, int32_t frame_index, ! 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); return false; } - bool result = true; StackMapFrame *stackmap_frame = _frame_array[frame_index]; if (match) { // Has direct control flow from last instruction, need to match the two // frames. ! result = frame->is_assignable_to( ! stackmap_frame, handler, ! CHECK_VERIFY_(frame->verifier(), false)); } if (update) { // Use the frame in stackmap table as current frame int lsize = stackmap_frame->locals_size(); int ssize = stackmap_frame->stack_size(); --- 87,111 ---- // unconditional branch: false true false // linear bytecode verification not following an // unconditional branch: true true false bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, int32_t frame_index, ! bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { if (frame_index < 0 || frame_index >= _frame_count) { ! *ctx = ErrorContext::missing_stackmap(frame->offset()); ! frame->verifier()->verify_error( ! *ctx, "Expecting a stackmap frame at branch target %d", target); return false; } StackMapFrame *stackmap_frame = _frame_array[frame_index]; + bool result = true; if (match) { // Has direct control flow from last instruction, need to match the two // frames. ! result = frame->is_assignable_to(stackmap_frame, handler, ! ctx, CHECK_VERIFY_(frame->verifier(), result)); } if (update) { // Use the frame in stackmap table as current frame int lsize = stackmap_frame->locals_size(); int ssize = stackmap_frame->stack_size();
*** 123,165 **** return result; } void StackMapTable::check_jump_target( StackMapFrame* frame, int32_t target, TRAPS) const { bool match = match_stackmap( ! 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); return; } // check if uninitialized objects exist on backward branches check_new_object(frame, target, CHECK_VERIFY(frame->verifier())); } void StackMapTable::check_new_object( const StackMapFrame* frame, int32_t target, TRAPS) const { if (frame->offset() > target && frame->has_new_object()) { ! frame->verifier()->verify_error(frame->offset(), "Uninitialized object exists on backward branch %d", target); return; } } ! #ifndef PRODUCT ! ! void StackMapTable::print() const { ! tty->print_cr("StackMapTable: frame_count = %d", _frame_count); ! tty->print_cr("table = { "); ! for (int32_t i = 0; i < _frame_count; i++) { ! _frame_array[i]->print(); } ! tty->print_cr(" }"); } - #endif - int32_t StackMapReader::chop( VerificationType* locals, int32_t length, int32_t chops) { if (locals == NULL) return -1; int32_t pos = length - 1; for (int32_t i=0; i<chops; i++) { --- 122,165 ---- return result; } void StackMapTable::check_jump_target( StackMapFrame* frame, int32_t target, TRAPS) const { + ErrorContext ctx; bool match = match_stackmap( ! frame, target, true, false, false, &ctx, CHECK_VERIFY(frame->verifier())); if (!match || (target < 0 || target >= _code_length)) { ! frame->verifier()->verify_error(ctx, "Inconsistent stackmap frames at branch target %d", target); return; } // check if uninitialized objects exist on backward branches check_new_object(frame, target, CHECK_VERIFY(frame->verifier())); } void StackMapTable::check_new_object( const StackMapFrame* frame, int32_t target, TRAPS) const { if (frame->offset() > target && frame->has_new_object()) { ! frame->verifier()->verify_error( ! ErrorContext::bad_code(frame->offset()), "Uninitialized object exists on backward branch %d", target); return; } } ! void StackMapTable::print_on(outputStream* str) const { ! str->indent().print_cr("StackMapTable: frame_count = %d", _frame_count); ! str->indent().print_cr("table = { "); ! { ! streamIndentor si(str); ! for (int32_t i = 0; i < _frame_count; ++i) { ! _frame_array[i]->print_on(str); ! } } ! str->print_cr(" }"); } int32_t StackMapReader::chop( VerificationType* locals, int32_t length, int32_t chops) { if (locals == NULL) return -1; int32_t pos = length - 1; for (int32_t i=0; i<chops; i++) {
< prev index next >