@@ -127,6 +127,7 @@ bool StackMapTable::match_stackmap(
127127 frame->set_stack_size (ssize);
128128 frame->copy_stack (stackmap_frame);
129129 frame->set_flags (stackmap_frame->flags ());
130+ frame->set_assert_unset_fields (stackmap_frame->assert_unset_fields ());
130131 }
131132 return result;
132133}
@@ -157,11 +158,13 @@ void StackMapTable::print_on(outputStream* str) const {
157158StackMapReader::StackMapReader (ClassVerifier* v, StackMapStream* stream,
158159 char * code_data, int32_t code_len,
159160 StackMapFrame* init_frame,
160- u2 max_locals, u2 max_stack, TRAPS) :
161+ u2 max_locals, u2 max_stack,
162+ StackMapFrame::AssertUnsetFieldTable* initial_strict_fields, TRAPS) :
161163 _verifier(v), _stream(stream), _code_data(code_data),
162164 _code_length(code_len), _parsed_frame_count(0 ),
163165 _prev_frame(init_frame), _max_locals(max_locals),
164- _max_stack(max_stack), _first(true ) {
166+ _max_stack(max_stack), _assert_unset_fields_buffer(initial_strict_fields),
167+ _first(true ) {
165168 methodHandle m = v->method ();
166169 if (m->has_stackmap_table ()) {
167170 _cp = constantPoolHandle (THREAD, m->constants ());
@@ -245,6 +248,39 @@ StackMapFrame* StackMapReader::next_helper(TRAPS) {
245248 int offset;
246249 VerificationType* locals = nullptr ;
247250 u1 frame_type = _stream->get_u1 (CHECK_NULL);
251+ if (frame_type == ASSERT_UNSET_FIELDS) {
252+ u2 num_unset_fields = _stream->get_u2 (CHECK_NULL);
253+ StackMapFrame::AssertUnsetFieldTable* new_fields = new StackMapFrame::AssertUnsetFieldTable ();
254+
255+ for (u2 i = 0 ; i < num_unset_fields; i++) {
256+ u2 index = _stream->get_u2 (CHECK_NULL);
257+ Symbol* name = _cp->symbol_at (_cp->name_ref_index_at (index));
258+ Symbol* sig = _cp->symbol_at (_cp->signature_ref_index_at (index));
259+ NameAndSig tmp (name, sig);
260+
261+ if (!_prev_frame->assert_unset_fields ()->contains (tmp)) {
262+ ResourceMark rm (THREAD);
263+ log_info (verification)(" Field %s%s is not found among initial strict instance fields" , name->as_C_string (), sig->as_C_string ());
264+ StackMapFrame::print_strict_fields (_prev_frame->assert_unset_fields ());
265+ _prev_frame->verifier ()->verify_error (
266+ ErrorContext::bad_strict_fields (_prev_frame->offset (), _prev_frame),
267+ " Strict fields not a subset of initial strict instance fields" );
268+ } else {
269+ new_fields->put (tmp, false );
270+ }
271+ }
272+
273+ // Only modify strict instance fields the frame has uninitialized this
274+ if (_prev_frame->flag_this_uninit ()) {
275+ _assert_unset_fields_buffer = _prev_frame->merge_unset_fields (new_fields);
276+ } else if (new_fields->number_of_entries () > 0 ) {
277+ _prev_frame->verifier ()->verify_error (
278+ ErrorContext::bad_strict_fields (_prev_frame->offset (), _prev_frame),
279+ " Cannot have uninitialized strict fields after class initialization" );
280+ }
281+
282+ return nullptr ;
283+ }
248284 if (frame_type < 64 ) {
249285 // same_frame
250286 if (_first) {
@@ -260,7 +296,8 @@ StackMapFrame* StackMapReader::next_helper(TRAPS) {
260296 }
261297 frame = new StackMapFrame (
262298 offset, _prev_frame->flags (), _prev_frame->locals_size (), 0 ,
263- _max_locals, _max_stack, locals, nullptr , _verifier);
299+ _max_locals, _max_stack, locals, nullptr ,
300+ _assert_unset_fields_buffer, _verifier);
264301 if (_first && locals != nullptr ) {
265302 frame->copy_locals (_prev_frame);
266303 }
@@ -292,7 +329,8 @@ StackMapFrame* StackMapReader::next_helper(TRAPS) {
292329 stack_size, _max_stack, CHECK_VERIFY_ (_verifier, nullptr ));
293330 frame = new StackMapFrame (
294331 offset, _prev_frame->flags (), _prev_frame->locals_size (), stack_size,
295- _max_locals, _max_stack, locals, stack, _verifier);
332+ _max_locals, _max_stack, locals, stack,
333+ _assert_unset_fields_buffer, _verifier);
296334 if (_first && locals != nullptr ) {
297335 frame->copy_locals (_prev_frame);
298336 }
@@ -302,7 +340,7 @@ StackMapFrame* StackMapReader::next_helper(TRAPS) {
302340
303341 u2 offset_delta = _stream->get_u2 (CHECK_NULL);
304342
305- if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED ) {
343+ if (frame_type < ASSERT_UNSET_FIELDS ) {
306344 // reserved frame types
307345 _stream->stackmap_format_error (
308346 " reserved frame type" , CHECK_VERIFY_ (_verifier, nullptr ));
@@ -333,7 +371,8 @@ StackMapFrame* StackMapReader::next_helper(TRAPS) {
333371 stack_size, _max_stack, CHECK_VERIFY_ (_verifier, nullptr ));
334372 frame = new StackMapFrame (
335373 offset, _prev_frame->flags (), _prev_frame->locals_size (), stack_size,
336- _max_locals, _max_stack, locals, stack, _verifier);
374+ _max_locals, _max_stack, locals, stack,
375+ _assert_unset_fields_buffer, _verifier);
337376 if (_first && locals != nullptr ) {
338377 frame->copy_locals (_prev_frame);
339378 }
@@ -375,7 +414,8 @@ StackMapFrame* StackMapReader::next_helper(TRAPS) {
375414 }
376415 frame = new StackMapFrame (
377416 offset, flags, new_length, 0 , _max_locals, _max_stack,
378- locals, nullptr , _verifier);
417+ locals, nullptr ,
418+ _assert_unset_fields_buffer, _verifier);
379419 if (_first && locals != nullptr ) {
380420 frame->copy_locals (_prev_frame);
381421 }
@@ -409,7 +449,8 @@ StackMapFrame* StackMapReader::next_helper(TRAPS) {
409449 }
410450 frame = new StackMapFrame (
411451 offset, flags, real_length, 0 , _max_locals,
412- _max_stack, locals, nullptr , _verifier);
452+ _max_stack, locals, nullptr ,
453+ _assert_unset_fields_buffer, _verifier);
413454 _first = false ;
414455 return frame;
415456 }
@@ -457,7 +498,8 @@ StackMapFrame* StackMapReader::next_helper(TRAPS) {
457498 }
458499 frame = new StackMapFrame (
459500 offset, flags, real_locals_size, real_stack_size,
460- _max_locals, _max_stack, locals, stack, _verifier);
501+ _max_locals, _max_stack, locals, stack,
502+ _assert_unset_fields_buffer, _verifier);
461503 _first = false ;
462504 return frame;
463505 }
0 commit comments