< prev index next > src/hotspot/share/classfile/stackMapTable.cpp
Print this page
frame->set_locals_size(lsize);
frame->copy_locals(stackmap_frame);
frame->set_stack_size(ssize);
frame->copy_stack(stackmap_frame);
frame->set_flags(stackmap_frame->flags());
+ frame->set_assert_unset_fields(stackmap_frame->assert_unset_fields());
}
return result;
}
void StackMapTable::check_jump_target(
}
StackMapReader::StackMapReader(ClassVerifier* v, StackMapStream* stream,
char* code_data, int32_t code_len,
StackMapFrame* init_frame,
! u2 max_locals, u2 max_stack, TRAPS) :
_verifier(v), _stream(stream), _code_data(code_data),
_code_length(code_len), _parsed_frame_count(0),
_prev_frame(init_frame), _max_locals(max_locals),
! _max_stack(max_stack), _first(true) {
methodHandle m = v->method();
if (m->has_stackmap_table()) {
_cp = constantPoolHandle(THREAD, m->constants());
_frame_count = _stream->get_u2(CHECK);
} else {
}
StackMapReader::StackMapReader(ClassVerifier* v, StackMapStream* stream,
char* code_data, int32_t code_len,
StackMapFrame* init_frame,
! u2 max_locals, u2 max_stack,
+ StackMapFrame::AssertUnsetFieldTable* initial_strict_fields, TRAPS) :
_verifier(v), _stream(stream), _code_data(code_data),
_code_length(code_len), _parsed_frame_count(0),
_prev_frame(init_frame), _max_locals(max_locals),
! _max_stack(max_stack), _assert_unset_fields_buffer(initial_strict_fields),
+ _first(true) {
methodHandle m = v->method();
if (m->has_stackmap_table()) {
_cp = constantPoolHandle(THREAD, m->constants());
_frame_count = _stream->get_u2(CHECK);
} else {
(!_cp->tag_at(class_index).is_klass() &&
!_cp->tag_at(class_index).is_unresolved_klass())) {
_stream->stackmap_format_error("bad class index", THREAD);
return VerificationType::bogus_type();
}
! return VerificationType::reference_type(_cp->klass_name_at(class_index));
}
if (tag == ITEM_UninitializedThis) {
if (flags != nullptr) {
*flags |= FLAG_THIS_UNINIT;
}
(!_cp->tag_at(class_index).is_klass() &&
!_cp->tag_at(class_index).is_unresolved_klass())) {
_stream->stackmap_format_error("bad class index", THREAD);
return VerificationType::bogus_type();
}
! Symbol* klass_name = _cp->klass_name_at(class_index);
+ return VerificationType::reference_type(klass_name);
}
if (tag == ITEM_UninitializedThis) {
if (flags != nullptr) {
*flags |= FLAG_THIS_UNINIT;
}
StackMapFrame* StackMapReader::next_helper(TRAPS) {
StackMapFrame* frame;
int offset;
VerificationType* locals = nullptr;
u1 frame_type = _stream->get_u1(CHECK_NULL);
+ if (frame_type == ASSERT_UNSET_FIELDS) {
+ u2 num_unset_fields = _stream->get_u2(CHECK_NULL);
+ StackMapFrame::AssertUnsetFieldTable* new_fields = new StackMapFrame::AssertUnsetFieldTable();
+
+ for (u2 i = 0; i < num_unset_fields; i++) {
+ u2 index = _stream->get_u2(CHECK_NULL);
+ Symbol* name = _cp->symbol_at(_cp->name_ref_index_at(index));
+ Symbol* sig = _cp->symbol_at(_cp->signature_ref_index_at(index));
+ NameAndSig tmp(name, sig);
+
+ if (!_prev_frame->assert_unset_fields()->contains(tmp)) {
+ ResourceMark rm(THREAD);
+ log_info(verification)("Field %s%s is not found among initial strict instance fields", name->as_C_string(), sig->as_C_string());
+ StackMapFrame::print_strict_fields(_prev_frame->assert_unset_fields());
+ _prev_frame->verifier()->verify_error(
+ ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
+ "Strict fields not a subset of initial strict instance fields: %s:%s", name->as_C_string(), sig->as_C_string());
+ } else {
+ new_fields->put(tmp, false);
+ }
+ }
+
+ // Only modify strict instance fields the frame has uninitialized this
+ if (_prev_frame->flag_this_uninit()) {
+ _assert_unset_fields_buffer = _prev_frame->merge_unset_fields(new_fields);
+ } else if (new_fields->number_of_entries() > 0) {
+ _prev_frame->verifier()->verify_error(
+ ErrorContext::bad_strict_fields(_prev_frame->offset(), _prev_frame),
+ "Cannot have uninitialized strict fields after class initialization");
+ }
+
+ return nullptr;
+ }
if (frame_type < 64) {
// same_frame
if (_first) {
offset = frame_type;
// Can't share the locals array since that is updated by the verifier.
offset = _prev_frame->offset() + frame_type + 1;
locals = _prev_frame->locals();
}
frame = new StackMapFrame(
offset, _prev_frame->flags(), _prev_frame->locals_size(), 0,
! _max_locals, _max_stack, locals, nullptr, _verifier);
if (_first && locals != nullptr) {
frame->copy_locals(_prev_frame);
}
_first = false;
return frame;
offset = _prev_frame->offset() + frame_type + 1;
locals = _prev_frame->locals();
}
frame = new StackMapFrame(
offset, _prev_frame->flags(), _prev_frame->locals_size(), 0,
! _max_locals, _max_stack, locals, nullptr,
+ _assert_unset_fields_buffer, _verifier);
if (_first && locals != nullptr) {
frame->copy_locals(_prev_frame);
}
_first = false;
return frame;
}
check_verification_type_array_size(
stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
frame = new StackMapFrame(
offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
! _max_locals, _max_stack, locals, stack, _verifier);
if (_first && locals != nullptr) {
frame->copy_locals(_prev_frame);
}
_first = false;
return frame;
}
u2 offset_delta = _stream->get_u2(CHECK_NULL);
! if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
// reserved frame types
_stream->stackmap_format_error(
"reserved frame type", CHECK_VERIFY_(_verifier, nullptr));
}
}
check_verification_type_array_size(
stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
frame = new StackMapFrame(
offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
! _max_locals, _max_stack, locals, stack,
+ _assert_unset_fields_buffer, _verifier);
if (_first && locals != nullptr) {
frame->copy_locals(_prev_frame);
}
_first = false;
return frame;
}
u2 offset_delta = _stream->get_u2(CHECK_NULL);
! if (frame_type < ASSERT_UNSET_FIELDS) {
// reserved frame types
_stream->stackmap_format_error(
"reserved frame type", CHECK_VERIFY_(_verifier, nullptr));
}
}
check_verification_type_array_size(
stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
frame = new StackMapFrame(
offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
! _max_locals, _max_stack, locals, stack, _verifier);
if (_first && locals != nullptr) {
frame->copy_locals(_prev_frame);
}
_first = false;
return frame;
}
check_verification_type_array_size(
stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr));
frame = new StackMapFrame(
offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size,
! _max_locals, _max_stack, locals, stack,
+ _assert_unset_fields_buffer, _verifier);
if (_first && locals != nullptr) {
frame->copy_locals(_prev_frame);
}
_first = false;
return frame;
} else {
offset = _prev_frame->offset() + offset_delta + 1;
}
frame = new StackMapFrame(
offset, flags, new_length, 0, _max_locals, _max_stack,
! locals, nullptr, _verifier);
if (_first && locals != nullptr) {
frame->copy_locals(_prev_frame);
}
_first = false;
return frame;
} else {
offset = _prev_frame->offset() + offset_delta + 1;
}
frame = new StackMapFrame(
offset, flags, new_length, 0, _max_locals, _max_stack,
! locals, nullptr,
+ _assert_unset_fields_buffer, _verifier);
if (_first && locals != nullptr) {
frame->copy_locals(_prev_frame);
}
_first = false;
return frame;
} else {
offset = _prev_frame->offset() + offset_delta + 1;
}
frame = new StackMapFrame(
offset, flags, real_length, 0, _max_locals,
! _max_stack, locals, nullptr, _verifier);
_first = false;
return frame;
}
if (frame_type == FULL) {
// full_frame
} else {
offset = _prev_frame->offset() + offset_delta + 1;
}
frame = new StackMapFrame(
offset, flags, real_length, 0, _max_locals,
! _max_stack, locals, nullptr,
+ _assert_unset_fields_buffer, _verifier);
_first = false;
return frame;
}
if (frame_type == FULL) {
// full_frame
} else {
offset = _prev_frame->offset() + offset_delta + 1;
}
frame = new StackMapFrame(
offset, flags, real_locals_size, real_stack_size,
! _max_locals, _max_stack, locals, stack, _verifier);
_first = false;
return frame;
}
_stream->stackmap_format_error(
} else {
offset = _prev_frame->offset() + offset_delta + 1;
}
frame = new StackMapFrame(
offset, flags, real_locals_size, real_stack_size,
! _max_locals, _max_stack, locals, stack,
+ _assert_unset_fields_buffer, _verifier);
_first = false;
return frame;
}
_stream->stackmap_format_error(
< prev index next >