< prev index next >

src/hotspot/share/classfile/stackMapTable.cpp

Print this page

110   bool result = true;
111   if (match) {
112     // Has direct control flow from last instruction, need to match the two
113     // frames.
114     result = frame->is_assignable_to(stackmap_frame,
115         ctx, CHECK_VERIFY_(frame->verifier(), result));
116   }
117   if (update) {
118     // Use the frame in stackmap table as current frame
119     int lsize = stackmap_frame->locals_size();
120     int ssize = stackmap_frame->stack_size();
121     if (frame->locals_size() > lsize || frame->stack_size() > ssize) {
122       // Make sure unused type array items are all _bogus_type.
123       frame->reset();
124     }
125     frame->set_locals_size(lsize);
126     frame->copy_locals(stackmap_frame);
127     frame->set_stack_size(ssize);
128     frame->copy_stack(stackmap_frame);
129     frame->set_flags(stackmap_frame->flags());

130   }
131   return result;
132 }
133 
134 void StackMapTable::check_jump_target(
135     StackMapFrame* frame, int bci, int offset, TRAPS) const {
136   ErrorContext ctx;
137   // Jump targets must be within the method and the method size is limited. See JVMS 4.11
138   int min_offset = -1 * max_method_code_size;
139   if (offset < min_offset || offset > max_method_code_size) {
140     frame->verifier()->verify_error(ErrorContext::bad_stackmap(bci, frame),
141         "Illegal target of jump or branch (bci %d + offset %d)", bci, offset);
142     return;
143   }
144   int target = bci + offset;
145   bool match = match_stackmap(
146     frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
147   if (!match || (target < 0 || target >= _code_length)) {
148     frame->verifier()->verify_error(ctx,
149         "Inconsistent stackmap frames at branch target %d", target);
150   }
151 }
152 
153 void StackMapTable::print_on(outputStream* str) const {
154   str->print_cr("StackMapTable: frame_count = %d", _frame_count);
155   str->print_cr("table = {");
156   {
157     StreamIndentor si(str, 2);
158     for (int32_t i = 0; i < _frame_count; ++i) {
159       _frame_array->at(i)->print_on(str);
160     }
161   }
162   str->print_cr(" }");
163 }
164 
165 StackMapReader::StackMapReader(ClassVerifier* v, StackMapStream* stream,
166                                char* code_data, int32_t code_len,
167                                StackMapFrame* init_frame,
168                                u2 max_locals, u2 max_stack, TRAPS) :

169                                   _verifier(v), _stream(stream), _code_data(code_data),
170                                   _code_length(code_len), _parsed_frame_count(0),
171                                   _prev_frame(init_frame), _max_locals(max_locals),
172                                   _max_stack(max_stack), _first(true) {

173   methodHandle m = v->method();
174   if (m->has_stackmap_table()) {
175     _cp = constantPoolHandle(THREAD, m->constants());
176     _frame_count = _stream->get_u2(CHECK);
177   } else {
178     // There's no stackmap table present. Frame count and size are 0.
179     _frame_count = 0;
180   }
181 }
182 
183 int32_t StackMapReader::chop(
184     VerificationType* locals, int32_t length, int32_t chops) {
185   if (locals == nullptr) return -1;
186   int32_t pos = length - 1;
187   for (int32_t i=0; i<chops; i++) {
188     if (locals[pos].is_category2_2nd()) {
189       pos -= 2;
190     } else {
191       pos --;
192     }

194   }
195   return pos+1;
196 }
197 
198 #define CHECK_NT CHECK_(VerificationType::bogus_type())
199 
200 VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) {
201   u1 tag = _stream->get_u1(CHECK_NT);
202   if (tag < (u1)ITEM_UninitializedThis) {
203     return VerificationType::from_tag(tag);
204   }
205   if (tag == ITEM_Object) {
206     u2 class_index = _stream->get_u2(CHECK_NT);
207     int nconstants = _cp->length();
208     if ((class_index <= 0 || class_index >= nconstants) ||
209         (!_cp->tag_at(class_index).is_klass() &&
210          !_cp->tag_at(class_index).is_unresolved_klass())) {
211       _stream->stackmap_format_error("bad class index", THREAD);
212       return VerificationType::bogus_type();
213     }
214     return VerificationType::reference_type(_cp->klass_name_at(class_index));

215   }
216   if (tag == ITEM_UninitializedThis) {
217     if (flags != nullptr) {
218       *flags |= FLAG_THIS_UNINIT;
219     }
220     return VerificationType::uninitialized_this_type();
221   }
222   if (tag == ITEM_Uninitialized) {
223     u2 offset = _stream->get_u2(CHECK_NT);
224     if (offset >= _code_length ||
225         _code_data[offset] != ClassVerifier::NEW_OFFSET) {
226       _verifier->class_format_error(
227         "StackMapTable format error: bad offset for Uninitialized");
228       return VerificationType::bogus_type();
229     }
230     return VerificationType::uninitialized_type(offset);
231   }
232   _stream->stackmap_format_error("bad verification type", THREAD);
233   return VerificationType::bogus_type();
234 }
235 
236 StackMapFrame* StackMapReader::next(TRAPS) {
237   _parsed_frame_count++;
238   check_size(CHECK_NULL);
239   StackMapFrame* frame = next_helper(CHECK_VERIFY_(_verifier, nullptr));
240   if (frame != nullptr) {
241     check_offset(frame);
242     if (frame->verifier()->has_error()) {
243       return nullptr;
244     }
245     _prev_frame = frame;
246   }
247   return frame;
248 }
249 
250 StackMapFrame* StackMapReader::next_helper(TRAPS) {
251   StackMapFrame* frame;
252   int offset;
253   VerificationType* locals = nullptr;
254   u1 frame_type = _stream->get_u1(CHECK_NULL);

























































255   if (frame_type <= SAME_FRAME_END) {
256     // same_frame
257     if (_first) {
258       offset = frame_type;
259       // Can't share the locals array since that is updated by the verifier.
260       if (_prev_frame->locals_size() > 0) {
261         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
262           THREAD, VerificationType, _prev_frame->locals_size());
263       }
264     } else {
265       offset = _prev_frame->offset() + frame_type + 1;
266       locals = _prev_frame->locals();
267     }
268     frame = new StackMapFrame(
269       offset, _prev_frame->flags(), _prev_frame->locals_size(), 0,
270       _max_locals, _max_stack, locals, nullptr, _verifier);

271     if (_first && locals != nullptr) {
272       frame->copy_locals(_prev_frame);
273     }
274     _first = false;
275     return frame;
276   }
277   if (frame_type <= SAME_LOCALS_1_STACK_ITEM_FRAME_END) {
278     // same_locals_1_stack_item_frame
279     if (_first) {
280       offset = frame_type - SAME_LOCALS_1_STACK_ITEM_FRAME_START;
281       // Can't share the locals array since that is updated by the verifier.
282       if (_prev_frame->locals_size() > 0) {
283         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
284           THREAD, VerificationType, _prev_frame->locals_size());
285       }
286     } else {
287       offset = _prev_frame->offset() + frame_type - (SAME_LOCALS_1_STACK_ITEM_FRAME_START - 1);
288       locals = _prev_frame->locals();
289     }
290     VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(
291       THREAD, VerificationType, 2);
292     u2 stack_size = 1;
293     stack[0] = parse_verification_type(nullptr, CHECK_VERIFY_(_verifier, nullptr));
294     if (stack[0].is_category2()) {
295       stack[1] = stack[0].to_category2_2nd();
296       stack_size = 2;
297     }
298     check_verification_type_array_size(
299       stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
300     frame = new StackMapFrame(
301       offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
302       _max_locals, _max_stack, locals, stack, _verifier);

303     if (_first && locals != nullptr) {
304       frame->copy_locals(_prev_frame);
305     }
306     _first = false;
307     return frame;
308   }
309 
310   u2 offset_delta = _stream->get_u2(CHECK_NULL);
311 
312   if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
313     // reserved frame types
314     _stream->stackmap_format_error(
315       "reserved frame type", CHECK_VERIFY_(_verifier, nullptr));
316   }
317 
318   if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
319     // same_locals_1_stack_item_frame_extended
320     if (_first) {
321       offset = offset_delta;
322       // Can't share the locals array since that is updated by the verifier.
323       if (_prev_frame->locals_size() > 0) {
324         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
325           THREAD, VerificationType, _prev_frame->locals_size());
326       }
327     } else {
328       offset = _prev_frame->offset() + offset_delta + 1;
329       locals = _prev_frame->locals();
330     }
331     VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(
332       THREAD, VerificationType, 2);
333     u2 stack_size = 1;
334     stack[0] = parse_verification_type(nullptr, CHECK_VERIFY_(_verifier, nullptr));
335     if (stack[0].is_category2()) {
336       stack[1] = stack[0].to_category2_2nd();
337       stack_size = 2;
338     }
339     check_verification_type_array_size(
340       stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
341     frame = new StackMapFrame(
342       offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
343       _max_locals, _max_stack, locals, stack, _verifier);

344     if (_first && locals != nullptr) {
345       frame->copy_locals(_prev_frame);
346     }
347     _first = false;
348     return frame;
349   }
350 
351   if (frame_type <= SAME_FRAME_EXTENDED) {
352     // chop_frame or same_frame_extended
353     locals = _prev_frame->locals();
354     int length = _prev_frame->locals_size();
355     int chops = SAME_FRAME_EXTENDED - frame_type;
356     int new_length = length;
357     u1 flags = _prev_frame->flags();
358     assert(chops == 0 || (frame_type >= CHOP_FRAME_START && frame_type <= CHOP_FRAME_END), "should be");
359     if (chops != 0) {
360       new_length = chop(locals, length, chops);
361       check_verification_type_array_size(
362         new_length, _max_locals, CHECK_VERIFY_(_verifier, nullptr));
363       // Recompute flags since uninitializedThis could have been chopped.

366         if (locals[i].is_uninitialized_this()) {
367           flags |= FLAG_THIS_UNINIT;
368           break;
369         }
370       }
371     }
372     if (_first) {
373       offset = offset_delta;
374       // Can't share the locals array since that is updated by the verifier.
375       if (new_length > 0) {
376         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
377           THREAD, VerificationType, new_length);
378       } else {
379         locals = nullptr;
380       }
381     } else {
382       offset = _prev_frame->offset() + offset_delta + 1;
383     }
384     frame = new StackMapFrame(
385       offset, flags, new_length, 0, _max_locals, _max_stack,
386       locals, nullptr, _verifier);

387     if (_first && locals != nullptr) {
388       frame->copy_locals(_prev_frame);
389     }
390     _first = false;
391     return frame;
392   } else if (frame_type <= APPEND_FRAME_END) {
393     // append_frame
394     assert(frame_type >= APPEND_FRAME_START && frame_type <= APPEND_FRAME_END, "should be");
395     int appends = frame_type - APPEND_FRAME_START + 1;
396     int real_length = _prev_frame->locals_size();
397     int new_length = real_length + appends*2;
398     locals = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, VerificationType, new_length);
399     VerificationType* pre_locals = _prev_frame->locals();
400     for (int i = 0; i < _prev_frame->locals_size(); i++) {
401       locals[i] = pre_locals[i];
402     }
403     u1 flags = _prev_frame->flags();
404     for (int i = 0; i < appends; i++) {
405       locals[real_length] = parse_verification_type(&flags, CHECK_NULL);
406       if (locals[real_length].is_category2()) {
407         locals[real_length + 1] = locals[real_length].to_category2_2nd();
408         ++real_length;
409       }
410       ++real_length;
411     }
412     check_verification_type_array_size(
413       real_length, _max_locals, CHECK_VERIFY_(_verifier, nullptr));
414     if (_first) {
415       offset = offset_delta;
416     } else {
417       offset = _prev_frame->offset() + offset_delta + 1;
418     }
419     frame = new StackMapFrame(
420       offset, flags, real_length, 0, _max_locals,
421       _max_stack, locals, nullptr, _verifier);

422     _first = false;
423     return frame;
424   }
425   if (frame_type == FULL_FRAME) {
426     // full_frame
427     u1 flags = 0;
428     u2 locals_size = _stream->get_u2(CHECK_NULL);
429     int real_locals_size = 0;
430     if (locals_size > 0) {
431       locals = NEW_RESOURCE_ARRAY_IN_THREAD(
432         THREAD, VerificationType, locals_size*2);
433     }
434     for (int i = 0; i < locals_size; i++) {
435       locals[real_locals_size] = parse_verification_type(&flags, CHECK_NULL);
436       if (locals[real_locals_size].is_category2()) {
437         locals[real_locals_size + 1] =
438           locals[real_locals_size].to_category2_2nd();
439         ++real_locals_size;
440       }
441       ++real_locals_size;

449       stack = NEW_RESOURCE_ARRAY_IN_THREAD(
450         THREAD, VerificationType, stack_size*2);
451     }
452     for (int i = 0; i < stack_size; i++) {
453       stack[real_stack_size] = parse_verification_type(nullptr, CHECK_NULL);
454       if (stack[real_stack_size].is_category2()) {
455         stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd();
456         ++real_stack_size;
457       }
458       ++real_stack_size;
459     }
460     check_verification_type_array_size(
461       real_stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
462     if (_first) {
463       offset = offset_delta;
464     } else {
465       offset = _prev_frame->offset() + offset_delta + 1;
466     }
467     frame = new StackMapFrame(
468       offset, flags, real_locals_size, real_stack_size,
469       _max_locals, _max_stack, locals, stack, _verifier);

470     _first = false;
471     return frame;
472   }
473 
474   _stream->stackmap_format_error(
475     "reserved frame type", CHECK_VERIFY_(_prev_frame->verifier(), nullptr));
476   return nullptr;
477 }

110   bool result = true;
111   if (match) {
112     // Has direct control flow from last instruction, need to match the two
113     // frames.
114     result = frame->is_assignable_to(stackmap_frame,
115         ctx, CHECK_VERIFY_(frame->verifier(), result));
116   }
117   if (update) {
118     // Use the frame in stackmap table as current frame
119     int lsize = stackmap_frame->locals_size();
120     int ssize = stackmap_frame->stack_size();
121     if (frame->locals_size() > lsize || frame->stack_size() > ssize) {
122       // Make sure unused type array items are all _bogus_type.
123       frame->reset();
124     }
125     frame->set_locals_size(lsize);
126     frame->copy_locals(stackmap_frame);
127     frame->set_stack_size(ssize);
128     frame->copy_stack(stackmap_frame);
129     frame->set_flags(stackmap_frame->flags());
130     frame->set_assert_unset_fields(stackmap_frame->assert_unset_fields());
131   }
132   return result;
133 }
134 
135 void StackMapTable::check_jump_target(
136     StackMapFrame* frame, int bci, int offset, TRAPS) const {
137   ErrorContext ctx;
138   // Jump targets must be within the method and the method size is limited. See JVMS 4.11
139   int min_offset = -1 * max_method_code_size;
140   if (offset < min_offset || offset > max_method_code_size) {
141     frame->verifier()->verify_error(ErrorContext::bad_stackmap(bci, frame),
142         "Illegal target of jump or branch (bci %d + offset %d)", bci, offset);
143     return;
144   }
145   int target = bci + offset;
146   bool match = match_stackmap(
147     frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
148   if (!match || (target < 0 || target >= _code_length)) {
149     frame->verifier()->verify_error(ctx,
150         "Inconsistent stackmap frames at branch target %d", target);
151   }
152 }
153 
154 void StackMapTable::print_on(outputStream* str) const {
155   str->print_cr("StackMapTable: frame_count = %d", _frame_count);
156   str->print_cr("table = {");
157   {
158     StreamIndentor si(str, 2);
159     for (int32_t i = 0; i < _frame_count; ++i) {
160       _frame_array->at(i)->print_on(str);
161     }
162   }
163   str->print_cr(" }");
164 }
165 
166 StackMapReader::StackMapReader(ClassVerifier* v, StackMapStream* stream,
167                                char* code_data, int32_t code_len,
168                                StackMapFrame* init_frame,
169                                u2 max_locals, u2 max_stack,
170                                StackMapFrame::AssertUnsetFieldTable* initial_strict_fields, TRAPS) :
171                                   _verifier(v), _stream(stream), _code_data(code_data),
172                                   _code_length(code_len), _parsed_frame_count(0),
173                                   _prev_frame(init_frame), _max_locals(max_locals),
174                                   _max_stack(max_stack), _assert_unset_fields_buffer(initial_strict_fields),
175                                   _first(true) {
176   methodHandle m = v->method();
177   if (m->has_stackmap_table()) {
178     _cp = constantPoolHandle(THREAD, m->constants());
179     _frame_count = _stream->get_u2(CHECK);
180   } else {
181     // There's no stackmap table present. Frame count and size are 0.
182     _frame_count = 0;
183   }
184 }
185 
186 int32_t StackMapReader::chop(
187     VerificationType* locals, int32_t length, int32_t chops) {
188   if (locals == nullptr) return -1;
189   int32_t pos = length - 1;
190   for (int32_t i=0; i<chops; i++) {
191     if (locals[pos].is_category2_2nd()) {
192       pos -= 2;
193     } else {
194       pos --;
195     }

197   }
198   return pos+1;
199 }
200 
201 #define CHECK_NT CHECK_(VerificationType::bogus_type())
202 
203 VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) {
204   u1 tag = _stream->get_u1(CHECK_NT);
205   if (tag < (u1)ITEM_UninitializedThis) {
206     return VerificationType::from_tag(tag);
207   }
208   if (tag == ITEM_Object) {
209     u2 class_index = _stream->get_u2(CHECK_NT);
210     int nconstants = _cp->length();
211     if ((class_index <= 0 || class_index >= nconstants) ||
212         (!_cp->tag_at(class_index).is_klass() &&
213          !_cp->tag_at(class_index).is_unresolved_klass())) {
214       _stream->stackmap_format_error("bad class index", THREAD);
215       return VerificationType::bogus_type();
216     }
217     Symbol* klass_name = _cp->klass_name_at(class_index);
218     return VerificationType::reference_type(klass_name);
219   }
220   if (tag == ITEM_UninitializedThis) {
221     if (flags != nullptr) {
222       *flags |= FLAG_THIS_UNINIT;
223     }
224     return VerificationType::uninitialized_this_type();
225   }
226   if (tag == ITEM_Uninitialized) {
227     u2 offset = _stream->get_u2(CHECK_NT);
228     if (offset >= _code_length ||
229         _code_data[offset] != ClassVerifier::NEW_OFFSET) {
230       _verifier->class_format_error(
231         "StackMapTable format error: bad offset for Uninitialized");
232       return VerificationType::bogus_type();
233     }
234     return VerificationType::uninitialized_type(offset);
235   }
236   _stream->stackmap_format_error("bad verification type", THREAD);
237   return VerificationType::bogus_type();
238 }
239 
240 StackMapFrame* StackMapReader::next(TRAPS) {
241   _parsed_frame_count++;
242   check_size(CHECK_NULL);
243   StackMapFrame* frame = next_helper(CHECK_VERIFY_(_verifier, nullptr));
244   if (frame != nullptr) {
245     check_offset(frame);
246     if (frame->verifier()->has_error()) {
247       return nullptr;
248     }
249     _prev_frame = frame;
250   }
251   return frame;
252 }
253 
254 StackMapFrame* StackMapReader::next_helper(TRAPS) {
255   StackMapFrame* frame;
256   int offset;
257   VerificationType* locals = nullptr;
258   u1 frame_type = _stream->get_u1(CHECK_NULL);
259   if (frame_type == EARLY_LARVAL) {
260     u2 num_unset_fields = _stream->get_u2(CHECK_NULL);
261     StackMapFrame::AssertUnsetFieldTable* new_fields = new StackMapFrame::AssertUnsetFieldTable();
262 
263     for (u2 i = 0; i < num_unset_fields; i++) {
264       u2 index = _stream->get_u2(CHECK_NULL);
265 
266       if (!_cp->is_within_bounds(index) || !_cp->tag_at(index).is_name_and_type()) {
267         _prev_frame->verifier()->verify_error(
268           ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
269           "Invalid constant pool index in early larval frame: %d", index);
270         return nullptr;
271       }
272 
273       Symbol* name = _cp->symbol_at(_cp->name_ref_index_at(index));
274       Symbol* sig = _cp->symbol_at(_cp->signature_ref_index_at(index));
275       NameAndSig tmp(name, sig);
276 
277       if (!_prev_frame->assert_unset_fields()->contains(tmp)) {
278         log_info(verification)("NameAndType %s%s(CP index: %d) is not found among initial strict instance fields", name->as_C_string(), sig->as_C_string(), index);
279         StackMapFrame::print_strict_fields(_prev_frame->assert_unset_fields());
280         _prev_frame->verifier()->verify_error(
281             ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
282             "Strict fields not a subset of initial strict instance fields: %s:%s", name->as_C_string(), sig->as_C_string());
283         return nullptr;
284       } else {
285         new_fields->put(tmp, false);
286       }
287     }
288 
289     // Only modify strict instance fields the frame has uninitialized this
290     if (_prev_frame->flag_this_uninit()) {
291       _assert_unset_fields_buffer = _prev_frame->merge_unset_fields(new_fields);
292     } else if (new_fields->number_of_entries() > 0) {
293       _prev_frame->verifier()->verify_error(
294         ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
295         "Cannot have uninitialized strict fields after class initialization");
296       return nullptr;
297     }
298 
299     // Continue reading frame data
300     if (at_end()) {
301       _prev_frame->verifier()->verify_error(
302         ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
303         "Early larval frame must be followed by a base frame");
304       return nullptr;
305     }
306 
307     frame_type = _stream->get_u1(CHECK_NULL);
308     if (frame_type == EARLY_LARVAL) {
309       _prev_frame->verifier()->verify_error(
310         ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
311         "Early larval frame must be followed by a base frame");
312       return nullptr;
313     }
314   }
315 
316   if (frame_type <= SAME_FRAME_END) {
317     // same_frame
318     if (_first) {
319       offset = frame_type;
320       // Can't share the locals array since that is updated by the verifier.
321       if (_prev_frame->locals_size() > 0) {
322         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
323           THREAD, VerificationType, _prev_frame->locals_size());
324       }
325     } else {
326       offset = _prev_frame->offset() + frame_type + 1;
327       locals = _prev_frame->locals();
328     }
329     frame = new StackMapFrame(
330       offset, _prev_frame->flags(), _prev_frame->locals_size(), 0,
331       _max_locals, _max_stack, locals, nullptr,
332       _assert_unset_fields_buffer, _verifier);
333     if (_first && locals != nullptr) {
334       frame->copy_locals(_prev_frame);
335     }
336     _first = false;
337     return frame;
338   }
339   if (frame_type <= SAME_LOCALS_1_STACK_ITEM_FRAME_END) {
340     // same_locals_1_stack_item_frame
341     if (_first) {
342       offset = frame_type - SAME_LOCALS_1_STACK_ITEM_FRAME_START;
343       // Can't share the locals array since that is updated by the verifier.
344       if (_prev_frame->locals_size() > 0) {
345         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
346           THREAD, VerificationType, _prev_frame->locals_size());
347       }
348     } else {
349       offset = _prev_frame->offset() + frame_type - (SAME_LOCALS_1_STACK_ITEM_FRAME_START - 1);
350       locals = _prev_frame->locals();
351     }
352     VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(
353       THREAD, VerificationType, 2);
354     u2 stack_size = 1;
355     stack[0] = parse_verification_type(nullptr, CHECK_VERIFY_(_verifier, nullptr));
356     if (stack[0].is_category2()) {
357       stack[1] = stack[0].to_category2_2nd();
358       stack_size = 2;
359     }
360     check_verification_type_array_size(
361       stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
362     frame = new StackMapFrame(
363       offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
364       _max_locals, _max_stack, locals, stack,
365       _assert_unset_fields_buffer, _verifier);
366     if (_first && locals != nullptr) {
367       frame->copy_locals(_prev_frame);
368     }
369     _first = false;
370     return frame;
371   }
372 
373   u2 offset_delta = _stream->get_u2(CHECK_NULL);
374 
375   if (frame_type < EARLY_LARVAL) {
376     // reserved frame types
377     _stream->stackmap_format_error(
378       "reserved frame type", CHECK_VERIFY_(_verifier, nullptr));
379   }
380 
381   if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
382     // same_locals_1_stack_item_frame_extended
383     if (_first) {
384       offset = offset_delta;
385       // Can't share the locals array since that is updated by the verifier.
386       if (_prev_frame->locals_size() > 0) {
387         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
388           THREAD, VerificationType, _prev_frame->locals_size());
389       }
390     } else {
391       offset = _prev_frame->offset() + offset_delta + 1;
392       locals = _prev_frame->locals();
393     }
394     VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD(
395       THREAD, VerificationType, 2);
396     u2 stack_size = 1;
397     stack[0] = parse_verification_type(nullptr, CHECK_VERIFY_(_verifier, nullptr));
398     if (stack[0].is_category2()) {
399       stack[1] = stack[0].to_category2_2nd();
400       stack_size = 2;
401     }
402     check_verification_type_array_size(
403       stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
404     frame = new StackMapFrame(
405       offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
406       _max_locals, _max_stack, locals, stack,
407       _assert_unset_fields_buffer, _verifier);
408     if (_first && locals != nullptr) {
409       frame->copy_locals(_prev_frame);
410     }
411     _first = false;
412     return frame;
413   }
414 
415   if (frame_type <= SAME_FRAME_EXTENDED) {
416     // chop_frame or same_frame_extended
417     locals = _prev_frame->locals();
418     int length = _prev_frame->locals_size();
419     int chops = SAME_FRAME_EXTENDED - frame_type;
420     int new_length = length;
421     u1 flags = _prev_frame->flags();
422     assert(chops == 0 || (frame_type >= CHOP_FRAME_START && frame_type <= CHOP_FRAME_END), "should be");
423     if (chops != 0) {
424       new_length = chop(locals, length, chops);
425       check_verification_type_array_size(
426         new_length, _max_locals, CHECK_VERIFY_(_verifier, nullptr));
427       // Recompute flags since uninitializedThis could have been chopped.

430         if (locals[i].is_uninitialized_this()) {
431           flags |= FLAG_THIS_UNINIT;
432           break;
433         }
434       }
435     }
436     if (_first) {
437       offset = offset_delta;
438       // Can't share the locals array since that is updated by the verifier.
439       if (new_length > 0) {
440         locals = NEW_RESOURCE_ARRAY_IN_THREAD(
441           THREAD, VerificationType, new_length);
442       } else {
443         locals = nullptr;
444       }
445     } else {
446       offset = _prev_frame->offset() + offset_delta + 1;
447     }
448     frame = new StackMapFrame(
449       offset, flags, new_length, 0, _max_locals, _max_stack,
450       locals, nullptr,
451       _assert_unset_fields_buffer, _verifier);
452     if (_first && locals != nullptr) {
453       frame->copy_locals(_prev_frame);
454     }
455     _first = false;
456     return frame;
457   } else if (frame_type <= APPEND_FRAME_END) {
458     // append_frame
459     assert(frame_type >= APPEND_FRAME_START && frame_type <= APPEND_FRAME_END, "should be");
460     int appends = frame_type - APPEND_FRAME_START + 1;
461     int real_length = _prev_frame->locals_size();
462     int new_length = real_length + appends*2;
463     locals = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, VerificationType, new_length);
464     VerificationType* pre_locals = _prev_frame->locals();
465     for (int i = 0; i < _prev_frame->locals_size(); i++) {
466       locals[i] = pre_locals[i];
467     }
468     u1 flags = _prev_frame->flags();
469     for (int i = 0; i < appends; i++) {
470       locals[real_length] = parse_verification_type(&flags, CHECK_NULL);
471       if (locals[real_length].is_category2()) {
472         locals[real_length + 1] = locals[real_length].to_category2_2nd();
473         ++real_length;
474       }
475       ++real_length;
476     }
477     check_verification_type_array_size(
478       real_length, _max_locals, CHECK_VERIFY_(_verifier, nullptr));
479     if (_first) {
480       offset = offset_delta;
481     } else {
482       offset = _prev_frame->offset() + offset_delta + 1;
483     }
484     frame = new StackMapFrame(
485       offset, flags, real_length, 0, _max_locals,
486       _max_stack, locals, nullptr,
487       _assert_unset_fields_buffer, _verifier);
488     _first = false;
489     return frame;
490   }
491   if (frame_type == FULL_FRAME) {
492     // full_frame
493     u1 flags = 0;
494     u2 locals_size = _stream->get_u2(CHECK_NULL);
495     int real_locals_size = 0;
496     if (locals_size > 0) {
497       locals = NEW_RESOURCE_ARRAY_IN_THREAD(
498         THREAD, VerificationType, locals_size*2);
499     }
500     for (int i = 0; i < locals_size; i++) {
501       locals[real_locals_size] = parse_verification_type(&flags, CHECK_NULL);
502       if (locals[real_locals_size].is_category2()) {
503         locals[real_locals_size + 1] =
504           locals[real_locals_size].to_category2_2nd();
505         ++real_locals_size;
506       }
507       ++real_locals_size;

515       stack = NEW_RESOURCE_ARRAY_IN_THREAD(
516         THREAD, VerificationType, stack_size*2);
517     }
518     for (int i = 0; i < stack_size; i++) {
519       stack[real_stack_size] = parse_verification_type(nullptr, CHECK_NULL);
520       if (stack[real_stack_size].is_category2()) {
521         stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd();
522         ++real_stack_size;
523       }
524       ++real_stack_size;
525     }
526     check_verification_type_array_size(
527       real_stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
528     if (_first) {
529       offset = offset_delta;
530     } else {
531       offset = _prev_frame->offset() + offset_delta + 1;
532     }
533     frame = new StackMapFrame(
534       offset, flags, real_locals_size, real_stack_size,
535       _max_locals, _max_stack, locals, stack,
536       _assert_unset_fields_buffer, _verifier);
537     _first = false;
538     return frame;
539   }
540 
541   _stream->stackmap_format_error(
542     "reserved frame type", CHECK_VERIFY_(_prev_frame->verifier(), nullptr));
543   return nullptr;
544 }
< prev index next >