Mercurial > hg > truffle
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()) { |