mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
6956164: nightly regressions from 6939207
Fix errors in 6939207. Reviewed-by: kvn
This commit is contained in:
parent
66b26ccfb4
commit
05b4f2e796
5 changed files with 31 additions and 17 deletions
|
@ -254,6 +254,9 @@ void ClassVerifier::verify_class(TRAPS) {
|
||||||
int num_methods = methods->length();
|
int num_methods = methods->length();
|
||||||
|
|
||||||
for (int index = 0; index < num_methods; index++) {
|
for (int index = 0; index < num_methods; index++) {
|
||||||
|
// Check for recursive re-verification before each method.
|
||||||
|
if (was_recursively_verified()) return;
|
||||||
|
|
||||||
methodOop m = (methodOop)methods->obj_at(index);
|
methodOop m = (methodOop)methods->obj_at(index);
|
||||||
if (m->is_native() || m->is_abstract()) {
|
if (m->is_native() || m->is_abstract()) {
|
||||||
// If m is native or abstract, skip it. It is checked in class file
|
// If m is native or abstract, skip it. It is checked in class file
|
||||||
|
@ -262,6 +265,12 @@ void ClassVerifier::verify_class(TRAPS) {
|
||||||
}
|
}
|
||||||
verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this));
|
verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_verify_verbose || TraceClassInitialization) {
|
||||||
|
if (was_recursively_verified())
|
||||||
|
tty->print_cr("Recursive verification detected for: %s",
|
||||||
|
_klass->external_name());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassVerifier::verify_method(methodHandle m, TRAPS) {
|
void ClassVerifier::verify_method(methodHandle m, TRAPS) {
|
||||||
|
@ -326,6 +335,9 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) {
|
||||||
// instruction in sequence
|
// instruction in sequence
|
||||||
Bytecodes::Code opcode;
|
Bytecodes::Code opcode;
|
||||||
while (!bcs.is_last_bytecode()) {
|
while (!bcs.is_last_bytecode()) {
|
||||||
|
// Check for recursive re-verification before each bytecode.
|
||||||
|
if (was_recursively_verified()) return;
|
||||||
|
|
||||||
opcode = bcs.raw_next();
|
opcode = bcs.raw_next();
|
||||||
u2 bci = bcs.bci();
|
u2 bci = bcs.bci();
|
||||||
|
|
||||||
|
@ -1470,20 +1482,9 @@ void ClassVerifier::verify_cp_type(
|
||||||
|
|
||||||
// In some situations, bytecode rewriting may occur while we're verifying.
|
// In some situations, bytecode rewriting may occur while we're verifying.
|
||||||
// In this case, a constant pool cache exists and some indices refer to that
|
// In this case, a constant pool cache exists and some indices refer to that
|
||||||
// instead. Get the original index for the tag check
|
// instead. Be sure we don't pick up such indices by accident.
|
||||||
constantPoolCacheOop cache = cp->cache();
|
// We must check was_recursively_verified() before we get here.
|
||||||
if (cache != NULL &&
|
guarantee(cp->cache() == NULL, "not rewritten yet");
|
||||||
((types == (1 << JVM_CONSTANT_InterfaceMethodref)) ||
|
|
||||||
(types == (1 << JVM_CONSTANT_Methodref)) ||
|
|
||||||
(types == (1 << JVM_CONSTANT_Fieldref)))) {
|
|
||||||
int native_index = index;
|
|
||||||
if (Bytes::is_Java_byte_ordering_different()) {
|
|
||||||
native_index = Bytes::swap_u2(index);
|
|
||||||
}
|
|
||||||
assert((native_index >= 0) && (native_index < cache->length()),
|
|
||||||
"Must be a legal index into the cp cache");
|
|
||||||
index = cache->entry_at(native_index)->constant_pool_index();
|
|
||||||
}
|
|
||||||
|
|
||||||
verify_cp_index(cp, index, CHECK_VERIFY(this));
|
verify_cp_index(cp, index, CHECK_VERIFY(this));
|
||||||
unsigned int tag = cp->tag_at(index).value();
|
unsigned int tag = cp->tag_at(index).value();
|
||||||
|
|
|
@ -158,6 +158,16 @@ class ClassVerifier : public StackObj {
|
||||||
methodHandle _method; // current method being verified
|
methodHandle _method; // current method being verified
|
||||||
VerificationType _this_type; // the verification type of the current class
|
VerificationType _this_type; // the verification type of the current class
|
||||||
|
|
||||||
|
// Some recursive calls from the verifier to the name resolver
|
||||||
|
// can cause the current class to be re-verified and rewritten.
|
||||||
|
// If this happens, the original verification should not continue,
|
||||||
|
// because constant pool indexes will have changed.
|
||||||
|
// The rewriter is preceded by the verifier. If the verifier throws
|
||||||
|
// an error, rewriting is prevented. Also, rewriting always precedes
|
||||||
|
// bytecode execution or compilation. Thus, is_rewritten implies
|
||||||
|
// that a class has been verified and prepared for execution.
|
||||||
|
bool was_recursively_verified() { return _klass->is_rewritten(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
BYTECODE_OFFSET = 1,
|
BYTECODE_OFFSET = 1,
|
||||||
|
|
|
@ -212,5 +212,5 @@ class BytecodeStream: public BaseBytecodeStream {
|
||||||
return bytecode()->get_index_u2_cpcache(raw_code()); }
|
return bytecode()->get_index_u2_cpcache(raw_code()); }
|
||||||
int get_index_u4() const { assert_raw_stream(false);
|
int get_index_u4() const { assert_raw_stream(false);
|
||||||
return bytecode()->get_index_u4(raw_code()); }
|
return bytecode()->get_index_u4(raw_code()); }
|
||||||
int has_index_u4() const { return bytecode()->get_index_u4(raw_code()); }
|
bool has_index_u4() const { return bytecode()->has_index_u4(raw_code()); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,6 +86,7 @@ int Bytecodes::special_length_at(address bcp, address end) {
|
||||||
return (len > 0 && len == (int)len) ? len : -1;
|
return (len > 0 && len == (int)len) ? len : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Note: Length functions must return <=0 for invalid bytecodes.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -353,8 +353,10 @@ class Bytecodes: AllStatic {
|
||||||
static const char* name (Code code) { check(code); return _name [code]; }
|
static const char* name (Code code) { check(code); return _name [code]; }
|
||||||
static BasicType result_type (Code code) { check(code); return _result_type [code]; }
|
static BasicType result_type (Code code) { check(code); return _result_type [code]; }
|
||||||
static int depth (Code code) { check(code); return _depth [code]; }
|
static int depth (Code code) { check(code); return _depth [code]; }
|
||||||
static int length_for (Code code) { check(code); return _lengths [code] & 0xF; }
|
// Note: Length functions must return <=0 for invalid bytecodes.
|
||||||
static int wide_length_for(Code code) { check(code); return _lengths [code] >> 4; }
|
// Calling check(code) in length functions would throw an unwanted assert.
|
||||||
|
static int length_for (Code code) { /*no check*/ return _lengths [code] & 0xF; }
|
||||||
|
static int wide_length_for(Code code) { /*no check*/ return _lengths [code] >> 4; }
|
||||||
static bool can_trap (Code code) { check(code); return has_all_flags(code, _bc_can_trap, false); }
|
static bool can_trap (Code code) { check(code); return has_all_flags(code, _bc_can_trap, false); }
|
||||||
static Code java_code (Code code) { check(code); return _java_code [code]; }
|
static Code java_code (Code code) { check(code); return _java_code [code]; }
|
||||||
static bool can_rewrite (Code code) { check(code); return has_all_flags(code, _bc_can_rewrite, false); }
|
static bool can_rewrite (Code code) { check(code); return has_all_flags(code, _bc_can_rewrite, false); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue