comparison src/share/vm/classfile/stackMapTable.cpp @ 6605:4ee06e614636

7116786: RFE: Detailed information on VerifyErrors Summary: Provide additional detail in VerifyError messages Reviewed-by: sspitsyn, acorn
author kamg
date Mon, 06 Aug 2012 15:54:45 -0400
parents 3449f5e02cc4
children aff11567504c
comparison
equal deleted inserted replaced
6604:c3c2141203e7 6605: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.
44 pre_frame, i == 0, max_locals, max_stack, 44 pre_frame, i == 0, max_locals, max_stack,
45 CHECK_VERIFY(pre_frame->verifier())); 45 CHECK_VERIFY(pre_frame->verifier()));
46 _frame_array[i] = frame; 46 _frame_array[i] = frame;
47 int offset = frame->offset(); 47 int offset = frame->offset();
48 if (offset >= code_len || code_data[offset] == 0) { 48 if (offset >= code_len || code_data[offset] == 0) {
49 frame->verifier()->verify_error("StackMapTable error: bad offset"); 49 frame->verifier()->verify_error(
50 ErrorContext::bad_stackmap(i, frame),
51 "StackMapTable error: bad offset");
50 return; 52 return;
51 } 53 }
52 pre_frame = frame; 54 pre_frame = frame;
53 } 55 }
54 } 56 }
66 return i; // frame with offset doesn't exist in the array 68 return i; // frame with offset doesn't exist in the array
67 } 69 }
68 70
69 bool StackMapTable::match_stackmap( 71 bool StackMapTable::match_stackmap(
70 StackMapFrame* frame, int32_t target, 72 StackMapFrame* frame, int32_t target,
71 bool match, bool update, TRAPS) const { 73 bool match, bool update, ErrorContext* ctx, TRAPS) const {
72 int index = get_index_from_offset(target); 74 int index = get_index_from_offset(target);
73 75 return match_stackmap(frame, target, index, match, update, ctx, THREAD);
74 return match_stackmap(
75 frame, target, index, match,
76 update, CHECK_VERIFY_(frame->verifier(), false));
77 } 76 }
78 77
79 // Match and/or update current_frame to the frame in stackmap table with 78 // Match and/or update current_frame to the frame in stackmap table with
80 // specified offset and frame index. Return true if the two frames match. 79 // specified offset and frame index. Return true if the two frames match.
81 // 80 //
86 // unconditional branch: false true 85 // unconditional branch: false true
87 // linear bytecode verification not following an 86 // linear bytecode verification not following an
88 // unconditional branch: true true 87 // unconditional branch: true true
89 bool StackMapTable::match_stackmap( 88 bool StackMapTable::match_stackmap(
90 StackMapFrame* frame, int32_t target, int32_t frame_index, 89 StackMapFrame* frame, int32_t target, int32_t frame_index,
91 bool match, bool update, TRAPS) const { 90 bool match, bool update, ErrorContext* ctx, TRAPS) const {
92 if (frame_index < 0 || frame_index >= _frame_count) { 91 if (frame_index < 0 || frame_index >= _frame_count) {
93 frame->verifier()->verify_error(frame->offset(), 92 *ctx = ErrorContext::missing_stackmap(frame->offset());
94 "Expecting a stackmap frame at branch target %d", target); 93 frame->verifier()->verify_error(
94 *ctx, "Expecting a stackmap frame at branch target %d", target);
95 return false; 95 return false;
96 } 96 }
97 97
98 StackMapFrame *stackmap_frame = _frame_array[frame_index];
98 bool result = true; 99 bool result = true;
99 StackMapFrame *stackmap_frame = _frame_array[frame_index];
100 if (match) { 100 if (match) {
101 // when checking handler target, match == true && update == false 101 // when checking handler target, match == true && update == false
102 bool is_exception_handler = !update; 102 bool is_exception_handler = !update;
103 // Has direct control flow from last instruction, need to match the two 103 // Has direct control flow from last instruction, need to match the two
104 // frames. 104 // frames.
105 result = frame->is_assignable_to( 105 result = frame->is_assignable_to(stackmap_frame, is_exception_handler,
106 stackmap_frame, is_exception_handler, 106 ctx, CHECK_VERIFY_(frame->verifier(), result));
107 CHECK_VERIFY_(frame->verifier(), false));
108 } 107 }
109 if (update) { 108 if (update) {
110 // Use the frame in stackmap table as current frame 109 // Use the frame in stackmap table as current frame
111 int lsize = stackmap_frame->locals_size(); 110 int lsize = stackmap_frame->locals_size();
112 int ssize = stackmap_frame->stack_size(); 111 int ssize = stackmap_frame->stack_size();
123 return result; 122 return result;
124 } 123 }
125 124
126 void StackMapTable::check_jump_target( 125 void StackMapTable::check_jump_target(
127 StackMapFrame* frame, int32_t target, TRAPS) const { 126 StackMapFrame* frame, int32_t target, TRAPS) const {
127 ErrorContext ctx;
128 bool match = match_stackmap( 128 bool match = match_stackmap(
129 frame, target, true, false, CHECK_VERIFY(frame->verifier())); 129 frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
130 if (!match || (target < 0 || target >= _code_length)) { 130 if (!match || (target < 0 || target >= _code_length)) {
131 frame->verifier()->verify_error(frame->offset(), 131 frame->verifier()->verify_error(ctx,
132 "Inconsistent stackmap frames at branch target %d", target); 132 "Inconsistent stackmap frames at branch target %d", target);
133 return; 133 return;
134 } 134 }
135 // check if uninitialized objects exist on backward branches 135 // check if uninitialized objects exist on backward branches
136 check_new_object(frame, target, CHECK_VERIFY(frame->verifier())); 136 check_new_object(frame, target, CHECK_VERIFY(frame->verifier()));
137 } 137 }
138 138
139 void StackMapTable::check_new_object( 139 void StackMapTable::check_new_object(
140 const StackMapFrame* frame, int32_t target, TRAPS) const { 140 const StackMapFrame* frame, int32_t target, TRAPS) const {
141 if (frame->offset() > target && frame->has_new_object()) { 141 if (frame->offset() > target && frame->has_new_object()) {
142 frame->verifier()->verify_error(frame->offset(), 142 frame->verifier()->verify_error(
143 "Uninitialized object exists on backward branch %d", target); 143 ErrorContext::bad_code(frame->offset()),
144 "Uninitialized object exists on backward branch %d", target);
144 return; 145 return;
145 } 146 }
146 } 147 }
147 148
148 #ifndef PRODUCT 149 void StackMapTable::print_on(outputStream* str) const {
149 150 str->indent().print_cr("StackMapTable: frame_count = %d", _frame_count);
150 void StackMapTable::print() const { 151 str->indent().print_cr("table = { ");
151 tty->print_cr("StackMapTable: frame_count = %d", _frame_count); 152 {
152 tty->print_cr("table = { "); 153 streamIndentor si(str);
153 for (int32_t i = 0; i < _frame_count; i++) { 154 for (int32_t i = 0; i < _frame_count; ++i) {
154 _frame_array[i]->print(); 155 _frame_array[i]->print_on(str);
155 } 156 }
156 tty->print_cr(" }"); 157 }
157 } 158 str->print_cr(" }");
158 159 }
159 #endif
160 160
161 int32_t StackMapReader::chop( 161 int32_t StackMapReader::chop(
162 VerificationType* locals, int32_t length, int32_t chops) { 162 VerificationType* locals, int32_t length, int32_t chops) {
163 if (locals == NULL) return -1; 163 if (locals == NULL) return -1;
164 int32_t pos = length - 1; 164 int32_t pos = length - 1;