Mercurial > hg > truffle
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; |