--- old/src/share/vm/runtime/sharedRuntime.cpp 2013-10-16 07:46:51.583736350 +0200 +++ new/src/share/vm/runtime/sharedRuntime.cpp 2013-10-16 07:46:51.379736354 +0200 @@ -2406,14 +2406,25 @@ #ifdef ASSERT AdapterHandlerEntry* shared_entry = NULL; - if (VerifyAdapterSharing && entry != NULL) { + // Start adapter sharing verification only after the VM is booted. + if (VerifyAdapterSharing && (entry != NULL) && entry->contains_all_checks()) { shared_entry = entry; entry = NULL; } #endif if (entry != NULL) { - return entry; + // Re-use generated adapter only if VM is booted (StubRoutines::code2() != NULL + // or VerifyAdapterCalls and VerifyAdapterSharing is false. The reason is that + // gen_i2c_adapter() generates code based on the existence of StubRoutines::code1() + // and StubRoutines::code2(). Since these fields can be initialized after adapters + // are generated, VerifyAdapterCalls potentially reports a false error and/or + // VerifyAdapterSharing will fail. + if (!entry->contains_all_checks()) { + _adapters->free_entry(entry); + } else { + return entry; + } } // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage @@ -2430,25 +2441,25 @@ short buffer_locs[20]; buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, sizeof(buffer_locs)/sizeof(relocInfo)); - MacroAssembler _masm(&buffer); + bool contains_all_checks = (StubRoutines::code2() != NULL) || !VerifyAdapterCalls; + MacroAssembler _masm(&buffer); entry = SharedRuntime::generate_i2c2i_adapters(&_masm, total_args_passed, comp_args_on_stack, sig_bt, regs, fingerprint); - + entry->set_contains_all_checks(contains_all_checks); #ifdef ASSERT if (VerifyAdapterSharing) { if (shared_entry != NULL) { - assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt), - "code must match"); + assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size()), "code must match"); // Release the one just created and return the original _adapters->free_entry(entry); return shared_entry; } else { - entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt); + entry->save_code(buf->code_begin(), buffer.insts_size()); } } #endif @@ -2530,7 +2541,6 @@ delete _fingerprint; #ifdef ASSERT if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode); - if (_saved_sig) FREE_C_HEAP_ARRAY(Basictype, _saved_sig, mtCode); #endif } @@ -2539,26 +2549,19 @@ // Capture the code before relocation so that it can be compared // against other versions. If the code is captured after relocation // then relative instructions won't be equivalent. -void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { +void AdapterHandlerEntry::save_code(unsigned char* buffer, int length) { _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode); - _code_length = length; + _saved_code_length = length; memcpy(_saved_code, buffer, length); - _total_args_passed = total_args_passed; - _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed, mtCode); - memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType)); } -bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { - if (length != _code_length) { +bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) { + if (length != _saved_code_length) { return false; } - for (int i = 0; i < length; i++) { - if (buffer[i] != _saved_code[i]) { - return false; - } - } - return true; + + return (memcmp(buffer, _saved_code, length) == 0) ? true : false; } #endif