diff -r dfe27f03244a -r e9ff18c4ace7 src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Tue Jun 01 11:48:33 2010 -0700 +++ b/src/share/vm/classfile/verifier.cpp Wed Jun 02 22:45:42 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -257,6 +257,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 @@ -265,6 +268,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) { @@ -329,6 +338,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(); @@ -413,13 +425,13 @@ no_control_flow = false; break; case Bytecodes::_ldc : verify_ldc( - opcode, bcs.get_index(), ¤t_frame, + opcode, bcs.get_index_u1(), ¤t_frame, cp, bci, CHECK_VERIFY(this)); no_control_flow = false; break; case Bytecodes::_ldc_w : case Bytecodes::_ldc2_w : verify_ldc( - opcode, bcs.get_index_big(), ¤t_frame, + opcode, bcs.get_index_u2(), ¤t_frame, cp, bci, CHECK_VERIFY(this)); no_control_flow = false; break; case Bytecodes::_iload : @@ -1185,7 +1197,7 @@ no_control_flow = false; break; case Bytecodes::_new : { - index = bcs.get_index_big(); + index = bcs.get_index_u2(); verify_cp_class_type(index, cp, CHECK_VERIFY(this)); VerificationType new_class_type = cp_index_to_type(index, cp, CHECK_VERIFY(this)); @@ -1205,7 +1217,7 @@ no_control_flow = false; break; case Bytecodes::_anewarray : verify_anewarray( - bcs.get_index_big(), cp, ¤t_frame, CHECK_VERIFY(this)); + bcs.get_index_u2(), cp, ¤t_frame, CHECK_VERIFY(this)); no_control_flow = false; break; case Bytecodes::_arraylength : type = current_frame.pop_stack( @@ -1218,7 +1230,7 @@ no_control_flow = false; break; case Bytecodes::_checkcast : { - index = bcs.get_index_big(); + index = bcs.get_index_u2(); verify_cp_class_type(index, cp, CHECK_VERIFY(this)); current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); @@ -1228,7 +1240,7 @@ no_control_flow = false; break; } case Bytecodes::_instanceof : { - index = bcs.get_index_big(); + index = bcs.get_index_u2(); verify_cp_class_type(index, cp, CHECK_VERIFY(this)); current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); @@ -1243,7 +1255,7 @@ no_control_flow = false; break; case Bytecodes::_multianewarray : { - index = bcs.get_index_big(); + index = bcs.get_index_u2(); u2 dim = *(bcs.bcp()+3); verify_cp_class_type(index, cp, CHECK_VERIFY(this)); VerificationType new_array_type = @@ -1302,7 +1314,7 @@ while (!bcs.is_last_bytecode()) { if (bcs.raw_next() != Bytecodes::_illegal) { int bci = bcs.bci(); - if (bcs.code() == Bytecodes::_new) { + if (bcs.raw_code() == Bytecodes::_new) { code_data[bci] = NEW_OFFSET; } else { code_data[bci] = BYTECODE_OFFSET; @@ -1473,20 +1485,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(); @@ -1657,7 +1658,7 @@ int keys, delta; current_frame->pop_stack( VerificationType::integer_type(), CHECK_VERIFY(this)); - if (bcs->code() == Bytecodes::_tableswitch) { + if (bcs->raw_code() == Bytecodes::_tableswitch) { jint low = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize); jint high = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize); if (low > high) { @@ -1713,7 +1714,7 @@ StackMapFrame* current_frame, constantPoolHandle cp, TRAPS) { - u2 index = bcs->get_index_big(); + u2 index = bcs->get_index_u2(); verify_cp_type(index, cp, 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this)); // Get field name and signature @@ -1753,7 +1754,7 @@ &sig_stream, field_type, CHECK_VERIFY(this)); u2 bci = bcs->bci(); bool is_assignable; - switch (bcs->code()) { + switch (bcs->raw_code()) { case Bytecodes::_getstatic: { for (int i = 0; i < n; i++) { current_frame->push_stack(field_type[i], CHECK_VERIFY(this)); @@ -1873,7 +1874,7 @@ ref_class_type.name(), CHECK_VERIFY(this)); methodOop m = instanceKlass::cast(ref_klass)->uncached_lookup_method( vmSymbols::object_initializer_name(), - cp->signature_ref_at(bcs->get_index_big())); + cp->signature_ref_at(bcs->get_index_u2())); instanceKlassHandle mh(THREAD, m->method_holder()); if (m->is_protected() && !mh->is_same_class_package(_klass())) { bool assignable = current_type().is_assignable_from( @@ -1896,8 +1897,8 @@ bool *this_uninit, VerificationType return_type, constantPoolHandle cp, TRAPS) { // Make sure the constant pool item is the right type - u2 index = bcs->get_index_big(); - Bytecodes::Code opcode = bcs->code(); + u2 index = bcs->get_index_u2(); + Bytecodes::Code opcode = bcs->raw_code(); unsigned int types = (opcode == Bytecodes::_invokeinterface ? 1 << JVM_CONSTANT_InterfaceMethodref : opcode == Bytecodes::_invokedynamic