src/share/vm/runtime/sharedRuntime.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8026478 Cdiff src/share/vm/runtime/sharedRuntime.cpp

src/share/vm/runtime/sharedRuntime.cpp

Print this page

        

*** 2220,2229 **** --- 2220,2249 ---- int index = hash_to_index(entry->hash()); add_entry(index, entry); } void free_entry(AdapterHandlerEntry* entry) { + AdapterFingerPrint* finger_print = entry->fingerprint(); + unsigned int hash = entry->fingerprint()->compute_hash(); + int index = hash_to_index(hash); + AdapterHandlerEntry* previous = NULL; + + // Loop over entries of the bucket and update linked list + for (AdapterHandlerEntry* e = bucket(index); e != NULL; e = e->next()) { + if (e->hash() == hash) { + if (finger_print->equals(e->fingerprint())) { + if (previous != NULL) { + previous->set_next(e->next()); + } else { + set_entry(index, e->next()); + } + } + } + previous = e; + } + + // Do the actual de-allocation entry->deallocate(); BasicHashtable<mtCode>::free_entry(entry); } // Find a entry with the same fingerprint if it exists
*** 2404,2456 **** // Lookup method signature's fingerprint entry = _adapters->lookup(total_args_passed, sig_bt); #ifdef ASSERT AdapterHandlerEntry* shared_entry = NULL; ! if (VerifyAdapterSharing && entry != NULL) { shared_entry = entry; entry = NULL; } #endif if (entry != NULL) { return entry; } // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); // Make a C heap allocated version of the fingerprint to store in the adapter fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); // Create I2C & C2I handlers - BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache if (buf != NULL) { CodeBuffer buffer(buf); short buffer_locs[20]; buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, sizeof(buffer_locs)/sizeof(relocInfo)); - MacroAssembler _masm(&buffer); entry = SharedRuntime::generate_i2c2i_adapters(&_masm, total_args_passed, comp_args_on_stack, sig_bt, regs, fingerprint); ! #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"); // 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); } } #endif B = AdapterBlob::create(&buffer); --- 2424,2485 ---- // Lookup method signature's fingerprint entry = _adapters->lookup(total_args_passed, sig_bt); #ifdef ASSERT AdapterHandlerEntry* shared_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) { + // Re-use generated adapter only if VM is booted (StubRoutines::code2() != NULL + // or VerifyAdapterCalls 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 int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); // Make a C heap allocated version of the fingerprint to store in the adapter fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); // Create I2C & C2I handlers BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache if (buf != NULL) { CodeBuffer buffer(buf); short buffer_locs[20]; buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, sizeof(buffer_locs)/sizeof(relocInfo)); + 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()), "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()); } } #endif B = AdapterBlob::create(&buffer);
*** 2528,2566 **** void AdapterHandlerEntry::deallocate() { 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 } #ifdef ASSERT // 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) { _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode); ! _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) { ! return false; ! } ! for (int i = 0; i < length; i++) { ! if (buffer[i] != _saved_code[i]) { return false; } ! } ! return true; } #endif // Create a native wrapper for this native method. The wrapper converts the --- 2557,2587 ---- void AdapterHandlerEntry::deallocate() { delete _fingerprint; #ifdef ASSERT if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode); #endif } #ifdef ASSERT // 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) { _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode); ! _saved_code_length = length; memcpy(_saved_code, buffer, length); } ! bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) { ! if (length != _saved_code_length) { return false; } ! ! return (memcmp(buffer, _saved_code, length) == 0) ? true : false; } #endif // Create a native wrapper for this native method. The wrapper converts the
src/share/vm/runtime/sharedRuntime.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File