# HG changeset patch # User jrose # Date 1274979247 25200 # Node ID de91a2f25c7e21b65265887528a70c6c0303242e # Parent f9a202dd8899ef5eaeb13d2eb344403dec79ca7b 6956164: nightly regressions from 6939207 Summary: Fix errors in 6939207. Reviewed-by: kvn diff -r f9a202dd8899 -r de91a2f25c7e src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Tue May 25 13:18:49 2010 -0700 +++ b/src/share/vm/classfile/verifier.cpp Thu May 27 09:54:07 2010 -0700 @@ -254,6 +254,9 @@ int num_methods = methods->length(); 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); if (m->is_native() || m->is_abstract()) { // If m is native or abstract, skip it. It is checked in class file @@ -262,6 +265,12 @@ } 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) { @@ -326,6 +335,9 @@ // instruction in sequence Bytecodes::Code opcode; while (!bcs.is_last_bytecode()) { + // Check for recursive re-verification before each bytecode. + if (was_recursively_verified()) return; + opcode = bcs.raw_next(); u2 bci = bcs.bci(); @@ -1470,20 +1482,9 @@ // 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 - // instead. Get the original index for the tag check - constantPoolCacheOop cache = cp->cache(); - if (cache != NULL && - ((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(); - } + // instead. Be sure we don't pick up such indices by accident. + // We must check was_recursively_verified() before we get here. + guarantee(cp->cache() == NULL, "not rewritten yet"); verify_cp_index(cp, index, CHECK_VERIFY(this)); unsigned int tag = cp->tag_at(index).value(); diff -r f9a202dd8899 -r de91a2f25c7e src/share/vm/classfile/verifier.hpp --- a/src/share/vm/classfile/verifier.hpp Tue May 25 13:18:49 2010 -0700 +++ b/src/share/vm/classfile/verifier.hpp Thu May 27 09:54:07 2010 -0700 @@ -158,6 +158,16 @@ methodHandle _method; // current method being verified 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: enum { BYTECODE_OFFSET = 1, diff -r f9a202dd8899 -r de91a2f25c7e src/share/vm/interpreter/bytecodeStream.hpp --- a/src/share/vm/interpreter/bytecodeStream.hpp Tue May 25 13:18:49 2010 -0700 +++ b/src/share/vm/interpreter/bytecodeStream.hpp Thu May 27 09:54:07 2010 -0700 @@ -212,5 +212,5 @@ return bytecode()->get_index_u2_cpcache(raw_code()); } int get_index_u4() const { assert_raw_stream(false); 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()); } }; diff -r f9a202dd8899 -r de91a2f25c7e src/share/vm/interpreter/bytecodes.cpp --- a/src/share/vm/interpreter/bytecodes.cpp Tue May 25 13:18:49 2010 -0700 +++ b/src/share/vm/interpreter/bytecodes.cpp Thu May 27 09:54:07 2010 -0700 @@ -86,6 +86,7 @@ return (len > 0 && len == (int)len) ? len : -1; } } + // Note: Length functions must return <=0 for invalid bytecodes. return 0; } diff -r f9a202dd8899 -r de91a2f25c7e src/share/vm/interpreter/bytecodes.hpp --- a/src/share/vm/interpreter/bytecodes.hpp Tue May 25 13:18:49 2010 -0700 +++ b/src/share/vm/interpreter/bytecodes.hpp Thu May 27 09:54:07 2010 -0700 @@ -353,8 +353,10 @@ static const char* name (Code code) { check(code); return _name [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 length_for (Code code) { check(code); return _lengths [code] & 0xF; } - static int wide_length_for(Code code) { check(code); return _lengths [code] >> 4; } + // Note: Length functions must return <=0 for invalid bytecodes. + // 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 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); }