comparison src/share/vm/classfile/stackMapTable.cpp @ 20242:d14a18794c90

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 aff11567504c
children c77d5db18942
comparison
equal deleted inserted replaced
20241:bcd72ab4d91f 20242:d14a18794c90
68 return i; // frame with offset doesn't exist in the array 68 return i; // frame with offset doesn't exist in the array
69 } 69 }
70 70
71 bool StackMapTable::match_stackmap( 71 bool StackMapTable::match_stackmap(
72 StackMapFrame* frame, int32_t target, 72 StackMapFrame* frame, int32_t target,
73 bool match, bool update, ErrorContext* ctx, TRAPS) const { 73 bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const {
74 int index = get_index_from_offset(target); 74 int index = get_index_from_offset(target);
75 return match_stackmap(frame, target, index, match, update, ctx, THREAD); 75 return match_stackmap(frame, target, index, match, update, handler, ctx, THREAD);
76 } 76 }
77 77
78 // 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
79 // 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.
80 // handler is true if the frame in stackmap_table is for an exception handler.
80 // 81 //
81 // The values of match and update are: _match__update_ 82 // The values of match and update are: _match__update__handler
82 // 83 //
83 // checking a branch target/exception handler: true false 84 // checking a branch target: true false false
85 // checking an exception handler: true false true
84 // linear bytecode verification following an 86 // linear bytecode verification following an
85 // unconditional branch: false true 87 // unconditional branch: false true false
86 // linear bytecode verification not following an 88 // linear bytecode verification not following an
87 // unconditional branch: true true 89 // unconditional branch: true true false
88 bool StackMapTable::match_stackmap( 90 bool StackMapTable::match_stackmap(
89 StackMapFrame* frame, int32_t target, int32_t frame_index, 91 StackMapFrame* frame, int32_t target, int32_t frame_index,
90 bool match, bool update, ErrorContext* ctx, TRAPS) const { 92 bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const {
91 if (frame_index < 0 || frame_index >= _frame_count) { 93 if (frame_index < 0 || frame_index >= _frame_count) {
92 *ctx = ErrorContext::missing_stackmap(frame->offset()); 94 *ctx = ErrorContext::missing_stackmap(frame->offset());
93 frame->verifier()->verify_error( 95 frame->verifier()->verify_error(
94 *ctx, "Expecting a stackmap frame at branch target %d", target); 96 *ctx, "Expecting a stackmap frame at branch target %d", target);
95 return false; 97 return false;
96 } 98 }
97 99
98 StackMapFrame *stackmap_frame = _frame_array[frame_index]; 100 StackMapFrame *stackmap_frame = _frame_array[frame_index];
99 bool result = true; 101 bool result = true;
100 if (match) { 102 if (match) {
101 // when checking handler target, match == true && update == false
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(stackmap_frame, is_exception_handler, 105 result = frame->is_assignable_to(stackmap_frame, handler,
106 ctx, CHECK_VERIFY_(frame->verifier(), result)); 106 ctx, CHECK_VERIFY_(frame->verifier(), result));
107 } 107 }
108 if (update) { 108 if (update) {
109 // Use the frame in stackmap table as current frame 109 // Use the frame in stackmap table as current frame
110 int lsize = stackmap_frame->locals_size(); 110 int lsize = stackmap_frame->locals_size();
124 124
125 void StackMapTable::check_jump_target( 125 void StackMapTable::check_jump_target(
126 StackMapFrame* frame, int32_t target, TRAPS) const { 126 StackMapFrame* frame, int32_t target, TRAPS) const {
127 ErrorContext ctx; 127 ErrorContext ctx;
128 bool match = match_stackmap( 128 bool match = match_stackmap(
129 frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier())); 129 frame, target, true, false, 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(ctx, 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 frame->verifier()->update_furthest_jump(target);
138 } 137 }
139 138
140 void StackMapTable::check_new_object( 139 void StackMapTable::check_new_object(
141 const StackMapFrame* frame, int32_t target, TRAPS) const { 140 const StackMapFrame* frame, int32_t target, TRAPS) const {
142 if (frame->offset() > target && frame->has_new_object()) { 141 if (frame->offset() > target && frame->has_new_object()) {