Merge
This commit is contained in:
commit
7f9acb7ba4
@ -1025,16 +1025,20 @@ public:
|
|||||||
|
|
||||||
static int skip_annotation_value(const u1*, int, int); // fwd decl
|
static int skip_annotation_value(const u1*, int, int); // fwd decl
|
||||||
|
|
||||||
|
// Safely increment index by val if does not pass limit
|
||||||
|
#define SAFE_ADD(index, limit, val) \
|
||||||
|
if (index >= limit - val) return limit; \
|
||||||
|
index += val;
|
||||||
|
|
||||||
// Skip an annotation. Return >=limit if there is any problem.
|
// Skip an annotation. Return >=limit if there is any problem.
|
||||||
static int skip_annotation(const u1* buffer, int limit, int index) {
|
static int skip_annotation(const u1* buffer, int limit, int index) {
|
||||||
assert(buffer != NULL, "invariant");
|
assert(buffer != NULL, "invariant");
|
||||||
// annotation := atype:u2 do(nmem:u2) {member:u2 value}
|
// annotation := atype:u2 do(nmem:u2) {member:u2 value}
|
||||||
// value := switch (tag:u1) { ... }
|
// value := switch (tag:u1) { ... }
|
||||||
index += 2; // skip atype
|
SAFE_ADD(index, limit, 4); // skip atype and read nmem
|
||||||
if ((index += 2) >= limit) return limit; // read nmem
|
|
||||||
int nmem = Bytes::get_Java_u2((address)buffer + index - 2);
|
int nmem = Bytes::get_Java_u2((address)buffer + index - 2);
|
||||||
while (--nmem >= 0 && index < limit) {
|
while (--nmem >= 0 && index < limit) {
|
||||||
index += 2; // skip member
|
SAFE_ADD(index, limit, 2); // skip member
|
||||||
index = skip_annotation_value(buffer, limit, index);
|
index = skip_annotation_value(buffer, limit, index);
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
@ -1052,7 +1056,7 @@ static int skip_annotation_value(const u1* buffer, int limit, int index) {
|
|||||||
// case @: annotation;
|
// case @: annotation;
|
||||||
// case s: s_con:u2;
|
// case s: s_con:u2;
|
||||||
// }
|
// }
|
||||||
if ((index += 1) >= limit) return limit; // read tag
|
SAFE_ADD(index, limit, 1); // read tag
|
||||||
const u1 tag = buffer[index - 1];
|
const u1 tag = buffer[index - 1];
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case 'B':
|
case 'B':
|
||||||
@ -1065,14 +1069,14 @@ static int skip_annotation_value(const u1* buffer, int limit, int index) {
|
|||||||
case 'J':
|
case 'J':
|
||||||
case 'c':
|
case 'c':
|
||||||
case 's':
|
case 's':
|
||||||
index += 2; // skip con or s_con
|
SAFE_ADD(index, limit, 2); // skip con or s_con
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
index += 4; // skip e_class, e_name
|
SAFE_ADD(index, limit, 4); // skip e_class, e_name
|
||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
{
|
{
|
||||||
if ((index += 2) >= limit) return limit; // read nval
|
SAFE_ADD(index, limit, 2); // read nval
|
||||||
int nval = Bytes::get_Java_u2((address)buffer + index - 2);
|
int nval = Bytes::get_Java_u2((address)buffer + index - 2);
|
||||||
while (--nval >= 0 && index < limit) {
|
while (--nval >= 0 && index < limit) {
|
||||||
index = skip_annotation_value(buffer, limit, index);
|
index = skip_annotation_value(buffer, limit, index);
|
||||||
@ -1101,8 +1105,8 @@ static void parse_annotations(const ConstantPool* const cp,
|
|||||||
assert(loader_data != NULL, "invariant");
|
assert(loader_data != NULL, "invariant");
|
||||||
|
|
||||||
// annotations := do(nann:u2) {annotation}
|
// annotations := do(nann:u2) {annotation}
|
||||||
int index = 0;
|
int index = 2; // read nann
|
||||||
if ((index += 2) >= limit) return; // read nann
|
if (index >= limit) return;
|
||||||
int nann = Bytes::get_Java_u2((address)buffer + index - 2);
|
int nann = Bytes::get_Java_u2((address)buffer + index - 2);
|
||||||
enum { // initial annotation layout
|
enum { // initial annotation layout
|
||||||
atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;'
|
atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;'
|
||||||
@ -1121,7 +1125,8 @@ static void parse_annotations(const ConstantPool* const cp,
|
|||||||
s_size = 9,
|
s_size = 9,
|
||||||
min_size = 6 // smallest possible size (zero members)
|
min_size = 6 // smallest possible size (zero members)
|
||||||
};
|
};
|
||||||
while ((--nann) >= 0 && (index - 2 + min_size <= limit)) {
|
// Cannot add min_size to index in case of overflow MAX_INT
|
||||||
|
while ((--nann) >= 0 && (index - 2 <= limit - min_size)) {
|
||||||
int index0 = index;
|
int index0 = index;
|
||||||
index = skip_annotation(buffer, limit, index);
|
index = skip_annotation(buffer, limit, index);
|
||||||
const u1* const abase = buffer + index0;
|
const u1* const abase = buffer + index0;
|
||||||
@ -1253,13 +1258,14 @@ void ClassFileParser::parse_field_attributes(const ClassFileStream* const cfs,
|
|||||||
runtime_visible_annotations_length = attribute_length;
|
runtime_visible_annotations_length = attribute_length;
|
||||||
runtime_visible_annotations = cfs->get_u1_buffer();
|
runtime_visible_annotations = cfs->get_u1_buffer();
|
||||||
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
||||||
|
cfs->guarantee_more(runtime_visible_annotations_length, CHECK);
|
||||||
parse_annotations(cp,
|
parse_annotations(cp,
|
||||||
runtime_visible_annotations,
|
runtime_visible_annotations,
|
||||||
runtime_visible_annotations_length,
|
runtime_visible_annotations_length,
|
||||||
parsed_annotations,
|
parsed_annotations,
|
||||||
_loader_data,
|
_loader_data,
|
||||||
CHECK);
|
CHECK);
|
||||||
cfs->skip_u1(runtime_visible_annotations_length, CHECK);
|
cfs->skip_u1_fast(runtime_visible_annotations_length);
|
||||||
} else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
|
} else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
|
||||||
if (runtime_invisible_annotations_exists) {
|
if (runtime_invisible_annotations_exists) {
|
||||||
classfile_parse_error(
|
classfile_parse_error(
|
||||||
@ -2574,13 +2580,14 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs,
|
|||||||
runtime_visible_annotations_length = method_attribute_length;
|
runtime_visible_annotations_length = method_attribute_length;
|
||||||
runtime_visible_annotations = cfs->get_u1_buffer();
|
runtime_visible_annotations = cfs->get_u1_buffer();
|
||||||
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
||||||
|
cfs->guarantee_more(runtime_visible_annotations_length, CHECK_NULL);
|
||||||
parse_annotations(cp,
|
parse_annotations(cp,
|
||||||
runtime_visible_annotations,
|
runtime_visible_annotations,
|
||||||
runtime_visible_annotations_length,
|
runtime_visible_annotations_length,
|
||||||
&parsed_annotations,
|
&parsed_annotations,
|
||||||
_loader_data,
|
_loader_data,
|
||||||
CHECK_NULL);
|
CHECK_NULL);
|
||||||
cfs->skip_u1(runtime_visible_annotations_length, CHECK_NULL);
|
cfs->skip_u1_fast(runtime_visible_annotations_length);
|
||||||
} else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
|
} else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
|
||||||
if (runtime_invisible_annotations_exists) {
|
if (runtime_invisible_annotations_exists) {
|
||||||
classfile_parse_error(
|
classfile_parse_error(
|
||||||
@ -3285,13 +3292,14 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
|
|||||||
runtime_visible_annotations_length = attribute_length;
|
runtime_visible_annotations_length = attribute_length;
|
||||||
runtime_visible_annotations = cfs->get_u1_buffer();
|
runtime_visible_annotations = cfs->get_u1_buffer();
|
||||||
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
||||||
|
cfs->guarantee_more(runtime_visible_annotations_length, CHECK);
|
||||||
parse_annotations(cp,
|
parse_annotations(cp,
|
||||||
runtime_visible_annotations,
|
runtime_visible_annotations,
|
||||||
runtime_visible_annotations_length,
|
runtime_visible_annotations_length,
|
||||||
parsed_annotations,
|
parsed_annotations,
|
||||||
_loader_data,
|
_loader_data,
|
||||||
CHECK);
|
CHECK);
|
||||||
cfs->skip_u1(runtime_visible_annotations_length, CHECK);
|
cfs->skip_u1_fast(runtime_visible_annotations_length);
|
||||||
} else if (tag == vmSymbols::tag_runtime_invisible_annotations()) {
|
} else if (tag == vmSymbols::tag_runtime_invisible_annotations()) {
|
||||||
if (runtime_invisible_annotations_exists) {
|
if (runtime_invisible_annotations_exists) {
|
||||||
classfile_parse_error(
|
classfile_parse_error(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -155,47 +155,8 @@ int StackMapFrame::is_assignable_to(
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StackMapFrame::has_flag_match_exception(
|
|
||||||
const StackMapFrame* target) const {
|
|
||||||
// We allow flags of {UninitThis} to assign to {} if-and-only-if the
|
|
||||||
// target frame does not depend upon the current type.
|
|
||||||
// This is slightly too strict, as we need only enforce that the
|
|
||||||
// slots that were initialized by the <init> (the things that were
|
|
||||||
// UninitializedThis before initialize_object() converted them) are unused.
|
|
||||||
// However we didn't save that information so we'll enforce this upon
|
|
||||||
// anything that might have been initialized. This is a rare situation
|
|
||||||
// and javac never generates code that would end up here, but some profilers
|
|
||||||
// (such as NetBeans) might, when adding exception handlers in <init>
|
|
||||||
// methods to cover the invokespecial instruction. See 7020118.
|
|
||||||
|
|
||||||
assert(max_locals() == target->max_locals() &&
|
|
||||||
stack_size() == target->stack_size(), "StackMap sizes must match");
|
|
||||||
|
|
||||||
VerificationType top = VerificationType::top_type();
|
|
||||||
VerificationType this_type = verifier()->current_type();
|
|
||||||
|
|
||||||
if (!flag_this_uninit() || target->flags() != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < target->locals_size(); ++i) {
|
|
||||||
if (locals()[i] == this_type && target->locals()[i] != top) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < target->stack_size(); ++i) {
|
|
||||||
if (stack()[i] == this_type && target->stack()[i] != top) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StackMapFrame::is_assignable_to(
|
bool StackMapFrame::is_assignable_to(
|
||||||
const StackMapFrame* target, bool is_exception_handler,
|
const StackMapFrame* target, ErrorContext* ctx, TRAPS) const {
|
||||||
ErrorContext* ctx, TRAPS) const {
|
|
||||||
if (_max_locals != target->max_locals()) {
|
if (_max_locals != target->max_locals()) {
|
||||||
*ctx = ErrorContext::locals_size_mismatch(
|
*ctx = ErrorContext::locals_size_mismatch(
|
||||||
_offset, (StackMapFrame*)this, (StackMapFrame*)target);
|
_offset, (StackMapFrame*)this, (StackMapFrame*)target);
|
||||||
@ -226,8 +187,7 @@ bool StackMapFrame::is_assignable_to(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_flags = (_flags | target->flags()) == target->flags();
|
if ((_flags | target->flags()) == target->flags()) {
|
||||||
if (match_flags || is_exception_handler && has_flag_match_exception(target)) {
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
*ctx = ErrorContext::bad_flags(target->offset(),
|
*ctx = ErrorContext::bad_flags(target->offset(),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -167,8 +167,7 @@ class StackMapFrame : public ResourceObj {
|
|||||||
|
|
||||||
// Return true if this stack map frame is assignable to target.
|
// Return true if this stack map frame is assignable to target.
|
||||||
bool is_assignable_to(
|
bool is_assignable_to(
|
||||||
const StackMapFrame* target, bool is_exception_handler,
|
const StackMapFrame* target, ErrorContext* ctx, TRAPS) const;
|
||||||
ErrorContext* ctx, TRAPS) const;
|
|
||||||
|
|
||||||
inline void set_mark() {
|
inline void set_mark() {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
@ -290,8 +289,6 @@ class StackMapFrame : public ResourceObj {
|
|||||||
int is_assignable_to(
|
int is_assignable_to(
|
||||||
VerificationType* src, VerificationType* target, int32_t len, TRAPS) const;
|
VerificationType* src, VerificationType* target, int32_t len, TRAPS) const;
|
||||||
|
|
||||||
bool has_flag_match_exception(const StackMapFrame* target) const;
|
|
||||||
|
|
||||||
TypeOrigin stack_top_ctx();
|
TypeOrigin stack_top_ctx();
|
||||||
|
|
||||||
void print_on(outputStream* str) const;
|
void print_on(outputStream* str) const;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -70,26 +70,25 @@ int StackMapTable::get_index_from_offset(int32_t offset) const {
|
|||||||
|
|
||||||
bool StackMapTable::match_stackmap(
|
bool StackMapTable::match_stackmap(
|
||||||
StackMapFrame* frame, int32_t target,
|
StackMapFrame* frame, int32_t target,
|
||||||
bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const {
|
bool match, bool update, ErrorContext* ctx, TRAPS) const {
|
||||||
int index = get_index_from_offset(target);
|
int index = get_index_from_offset(target);
|
||||||
return match_stackmap(frame, target, index, match, update, handler, ctx, THREAD);
|
return match_stackmap(frame, target, index, match, update, ctx, THREAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match and/or update current_frame to the frame in stackmap table with
|
// Match and/or update current_frame to the frame in stackmap table with
|
||||||
// specified offset and frame index. Return true if the two frames match.
|
// specified offset and frame index. Return true if the two frames match.
|
||||||
// handler is true if the frame in stackmap_table is for an exception handler.
|
|
||||||
//
|
//
|
||||||
// The values of match and update are: _match__update__handler
|
// The values of match and update are: _match__update
|
||||||
//
|
//
|
||||||
// checking a branch target: true false false
|
// checking a branch target: true false
|
||||||
// checking an exception handler: true false true
|
// checking an exception handler: true false
|
||||||
// linear bytecode verification following an
|
// linear bytecode verification following an
|
||||||
// unconditional branch: false true false
|
// unconditional branch: false true
|
||||||
// linear bytecode verification not following an
|
// linear bytecode verification not following an
|
||||||
// unconditional branch: true true false
|
// unconditional branch: true true
|
||||||
bool StackMapTable::match_stackmap(
|
bool StackMapTable::match_stackmap(
|
||||||
StackMapFrame* frame, int32_t target, int32_t frame_index,
|
StackMapFrame* frame, int32_t target, int32_t frame_index,
|
||||||
bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const {
|
bool match, bool update, ErrorContext* ctx, TRAPS) const {
|
||||||
if (frame_index < 0 || frame_index >= _frame_count) {
|
if (frame_index < 0 || frame_index >= _frame_count) {
|
||||||
*ctx = ErrorContext::missing_stackmap(frame->offset());
|
*ctx = ErrorContext::missing_stackmap(frame->offset());
|
||||||
frame->verifier()->verify_error(
|
frame->verifier()->verify_error(
|
||||||
@ -102,7 +101,7 @@ bool StackMapTable::match_stackmap(
|
|||||||
if (match) {
|
if (match) {
|
||||||
// Has direct control flow from last instruction, need to match the two
|
// Has direct control flow from last instruction, need to match the two
|
||||||
// frames.
|
// frames.
|
||||||
result = frame->is_assignable_to(stackmap_frame, handler,
|
result = frame->is_assignable_to(stackmap_frame,
|
||||||
ctx, CHECK_VERIFY_(frame->verifier(), result));
|
ctx, CHECK_VERIFY_(frame->verifier(), result));
|
||||||
}
|
}
|
||||||
if (update) {
|
if (update) {
|
||||||
@ -126,7 +125,7 @@ void StackMapTable::check_jump_target(
|
|||||||
StackMapFrame* frame, int32_t target, TRAPS) const {
|
StackMapFrame* frame, int32_t target, TRAPS) const {
|
||||||
ErrorContext ctx;
|
ErrorContext ctx;
|
||||||
bool match = match_stackmap(
|
bool match = match_stackmap(
|
||||||
frame, target, true, false, false, &ctx, CHECK_VERIFY(frame->verifier()));
|
frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
|
||||||
if (!match || (target < 0 || target >= _code_length)) {
|
if (!match || (target < 0 || target >= _code_length)) {
|
||||||
frame->verifier()->verify_error(ctx,
|
frame->verifier()->verify_error(ctx,
|
||||||
"Inconsistent stackmap frames at branch target %d", target);
|
"Inconsistent stackmap frames at branch target %d", target);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -60,12 +60,12 @@ class StackMapTable : public StackObj {
|
|||||||
// specified offset. Return true if the two frames match.
|
// specified offset. Return true if the two frames match.
|
||||||
bool match_stackmap(
|
bool match_stackmap(
|
||||||
StackMapFrame* current_frame, int32_t offset,
|
StackMapFrame* current_frame, int32_t offset,
|
||||||
bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const;
|
bool match, bool update, ErrorContext* ctx, TRAPS) const;
|
||||||
// Match and/or update current_frame to the frame in stackmap table with
|
// Match and/or update current_frame to the frame in stackmap table with
|
||||||
// specified offset and frame index. Return true if the two frames match.
|
// specified offset and frame index. Return true if the two frames match.
|
||||||
bool match_stackmap(
|
bool match_stackmap(
|
||||||
StackMapFrame* current_frame, int32_t offset, int32_t frame_index,
|
StackMapFrame* current_frame, int32_t offset, int32_t frame_index,
|
||||||
bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const;
|
bool match, bool update, ErrorContext* ctx, TRAPS) const;
|
||||||
|
|
||||||
// Check jump instructions. Make sure there are no uninitialized
|
// Check jump instructions. Make sure there are no uninitialized
|
||||||
// instances on backward branch.
|
// instances on backward branch.
|
||||||
|
@ -541,19 +541,13 @@ void ErrorContext::stackmap_details(outputStream* ss, const Method* method) cons
|
|||||||
stack_map_frame* sm_frame = sm_table->entries();
|
stack_map_frame* sm_frame = sm_table->entries();
|
||||||
streamIndentor si2(ss);
|
streamIndentor si2(ss);
|
||||||
int current_offset = -1;
|
int current_offset = -1;
|
||||||
// Subtract two from StackMapAttribute length because the length includes
|
address end_of_sm_table = (address)sm_table + method->stackmap_data()->length();
|
||||||
// two bytes for number of table entries.
|
|
||||||
size_t sm_table_space = method->stackmap_data()->length() - 2;
|
|
||||||
for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
|
for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
|
||||||
ss->indent();
|
ss->indent();
|
||||||
size_t sm_frame_size = sm_frame->size();
|
if (!sm_frame->verify((address)sm_frame, end_of_sm_table)) {
|
||||||
// If the size of the next stackmap exceeds the length of the entire
|
|
||||||
// stackmap table then print a truncated message and return.
|
|
||||||
if (sm_frame_size > sm_table_space) {
|
|
||||||
sm_frame->print_truncated(ss, current_offset);
|
sm_frame->print_truncated(ss, current_offset);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sm_table_space -= sm_frame_size;
|
|
||||||
sm_frame->print_on(ss, current_offset);
|
sm_frame->print_on(ss, current_offset);
|
||||||
ss->cr();
|
ss->cr();
|
||||||
current_offset += sm_frame->offset_delta();
|
current_offset += sm_frame->offset_delta();
|
||||||
@ -1863,7 +1857,7 @@ u2 ClassVerifier::verify_stackmap_table(u2 stackmap_index, u2 bci,
|
|||||||
// If matched, current_frame will be updated by this method.
|
// If matched, current_frame will be updated by this method.
|
||||||
bool matches = stackmap_table->match_stackmap(
|
bool matches = stackmap_table->match_stackmap(
|
||||||
current_frame, this_offset, stackmap_index,
|
current_frame, this_offset, stackmap_index,
|
||||||
!no_control_flow, true, false, &ctx, CHECK_VERIFY_(this, 0));
|
!no_control_flow, true, &ctx, CHECK_VERIFY_(this, 0));
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
// report type error
|
// report type error
|
||||||
verify_error(ctx, "Instruction type does not match stack map");
|
verify_error(ctx, "Instruction type does not match stack map");
|
||||||
@ -1913,7 +1907,7 @@ void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit,
|
|||||||
}
|
}
|
||||||
ErrorContext ctx;
|
ErrorContext ctx;
|
||||||
bool matches = stackmap_table->match_stackmap(
|
bool matches = stackmap_table->match_stackmap(
|
||||||
new_frame, handler_pc, true, false, true, &ctx, CHECK_VERIFY(this));
|
new_frame, handler_pc, true, false, &ctx, CHECK_VERIFY(this));
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
verify_error(ctx, "Stack map does not match the one at "
|
verify_error(ctx, "Stack map does not match the one at "
|
||||||
"exception handler %d", handler_pc);
|
"exception handler %d", handler_pc);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,7 +24,7 @@
|
|||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8075118
|
* @bug 8075118
|
||||||
* @summary Allow a ctor to call super() from a switch bytecode.
|
* @summary JVM stuck in infinite loop during verification
|
||||||
* @compile HandlerInTry.jasm
|
* @compile HandlerInTry.jasm
|
||||||
* @compile IsolatedHandlerInTry.jasm
|
* @compile IsolatedHandlerInTry.jasm
|
||||||
* @run main/othervm -Xverify:all LoadHandlerInTry
|
* @run main/othervm -Xverify:all LoadHandlerInTry
|
||||||
@ -70,9 +70,10 @@ public class LoadHandlerInTry {
|
|||||||
System.out.println("Regression test for bug 8075118");
|
System.out.println("Regression test for bug 8075118");
|
||||||
try {
|
try {
|
||||||
Class newClass = Class.forName("HandlerInTry");
|
Class newClass = Class.forName("HandlerInTry");
|
||||||
} catch (Exception e) {
|
throw new RuntimeException(
|
||||||
System.out.println("Failed: Exception was thrown: " + e.toString());
|
"Failed to throw VerifyError for HandlerInTry");
|
||||||
throw e;
|
} catch (java.lang.VerifyError e) {
|
||||||
|
System.out.println("Passed: VerifyError exception was thrown");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user