Thu, 19 Dec 2013 06:09:16 +0100
8026478: -XX:+VerifyAdapterSharing is broken
Summary: Fix by considering all checks in StubRoutines
Reviewed-by: kvn, twisti
src/share/vm/runtime/sharedRuntime.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/runtime/sharedRuntime.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/runtime/sharedRuntime.cpp Tue Dec 17 08:31:06 2013 +0100 1.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp Thu Dec 19 06:09:16 2013 +0100 1.3 @@ -2400,7 +2400,7 @@ 1.4 ResourceMark rm; 1.5 1.6 NOT_PRODUCT(int insts_size); 1.7 - AdapterBlob* B = NULL; 1.8 + AdapterBlob* new_adapter = NULL; 1.9 AdapterHandlerEntry* entry = NULL; 1.10 AdapterFingerPrint* fingerprint = NULL; 1.11 { 1.12 @@ -2432,7 +2432,8 @@ 1.13 1.14 #ifdef ASSERT 1.15 AdapterHandlerEntry* shared_entry = NULL; 1.16 - if (VerifyAdapterSharing && entry != NULL) { 1.17 + // Start adapter sharing verification only after the VM is booted. 1.18 + if (VerifyAdapterSharing && (entry != NULL)) { 1.19 shared_entry = entry; 1.20 entry = NULL; 1.21 } 1.22 @@ -2448,41 +2449,44 @@ 1.23 // Make a C heap allocated version of the fingerprint to store in the adapter 1.24 fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); 1.25 1.26 + // StubRoutines::code2() is initialized after this function can be called. As a result, 1.27 + // VerifyAdapterCalls and VerifyAdapterSharing can fail if we re-use code that generated 1.28 + // prior to StubRoutines::code2() being set. Checks refer to checks generated in an I2C 1.29 + // stub that ensure that an I2C stub is called from an interpreter frame. 1.30 + bool contains_all_checks = StubRoutines::code2() != NULL; 1.31 + 1.32 // Create I2C & C2I handlers 1.33 - 1.34 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache 1.35 if (buf != NULL) { 1.36 CodeBuffer buffer(buf); 1.37 short buffer_locs[20]; 1.38 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, 1.39 sizeof(buffer_locs)/sizeof(relocInfo)); 1.40 + 1.41 MacroAssembler _masm(&buffer); 1.42 - 1.43 entry = SharedRuntime::generate_i2c2i_adapters(&_masm, 1.44 total_args_passed, 1.45 comp_args_on_stack, 1.46 sig_bt, 1.47 regs, 1.48 fingerprint); 1.49 - 1.50 #ifdef ASSERT 1.51 if (VerifyAdapterSharing) { 1.52 if (shared_entry != NULL) { 1.53 - assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt), 1.54 - "code must match"); 1.55 + assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size()), "code must match"); 1.56 // Release the one just created and return the original 1.57 _adapters->free_entry(entry); 1.58 return shared_entry; 1.59 } else { 1.60 - entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt); 1.61 + entry->save_code(buf->code_begin(), buffer.insts_size()); 1.62 } 1.63 } 1.64 #endif 1.65 1.66 - B = AdapterBlob::create(&buffer); 1.67 + new_adapter = AdapterBlob::create(&buffer); 1.68 NOT_PRODUCT(insts_size = buffer.insts_size()); 1.69 } 1.70 - if (B == NULL) { 1.71 + if (new_adapter == NULL) { 1.72 // CodeCache is full, disable compilation 1.73 // Ought to log this but compile log is only per compile thread 1.74 // and we're some non descript Java thread. 1.75 @@ -2490,7 +2494,7 @@ 1.76 CompileBroker::handle_full_code_cache(); 1.77 return NULL; // Out of CodeCache space 1.78 } 1.79 - entry->relocate(B->content_begin()); 1.80 + entry->relocate(new_adapter->content_begin()); 1.81 #ifndef PRODUCT 1.82 // debugging suppport 1.83 if (PrintAdapterHandlers || PrintStubCode) { 1.84 @@ -2509,22 +2513,25 @@ 1.85 } 1.86 } 1.87 #endif 1.88 - 1.89 - _adapters->add(entry); 1.90 + // Add the entry only if the entry contains all required checks (see sharedRuntime_xxx.cpp) 1.91 + // The checks are inserted only if -XX:+VerifyAdapterCalls is specified. 1.92 + if (contains_all_checks || !VerifyAdapterCalls) { 1.93 + _adapters->add(entry); 1.94 + } 1.95 } 1.96 // Outside of the lock 1.97 - if (B != NULL) { 1.98 + if (new_adapter != NULL) { 1.99 char blob_id[256]; 1.100 jio_snprintf(blob_id, 1.101 sizeof(blob_id), 1.102 "%s(%s)@" PTR_FORMAT, 1.103 - B->name(), 1.104 + new_adapter->name(), 1.105 fingerprint->as_string(), 1.106 - B->content_begin()); 1.107 - Forte::register_stub(blob_id, B->content_begin(), B->content_end()); 1.108 + new_adapter->content_begin()); 1.109 + Forte::register_stub(blob_id, new_adapter->content_begin(),new_adapter->content_end()); 1.110 1.111 if (JvmtiExport::should_post_dynamic_code_generated()) { 1.112 - JvmtiExport::post_dynamic_code_generated(blob_id, B->content_begin(), B->content_end()); 1.113 + JvmtiExport::post_dynamic_code_generated(blob_id, new_adapter->content_begin(), new_adapter->content_end()); 1.114 } 1.115 } 1.116 return entry; 1.117 @@ -2556,7 +2563,6 @@ 1.118 delete _fingerprint; 1.119 #ifdef ASSERT 1.120 if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode); 1.121 - if (_saved_sig) FREE_C_HEAP_ARRAY(Basictype, _saved_sig, mtCode); 1.122 #endif 1.123 } 1.124 1.125 @@ -2565,26 +2571,19 @@ 1.126 // Capture the code before relocation so that it can be compared 1.127 // against other versions. If the code is captured after relocation 1.128 // then relative instructions won't be equivalent. 1.129 -void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { 1.130 +void AdapterHandlerEntry::save_code(unsigned char* buffer, int length) { 1.131 _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode); 1.132 - _code_length = length; 1.133 + _saved_code_length = length; 1.134 memcpy(_saved_code, buffer, length); 1.135 - _total_args_passed = total_args_passed; 1.136 - _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed, mtCode); 1.137 - memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType)); 1.138 } 1.139 1.140 1.141 -bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { 1.142 - if (length != _code_length) { 1.143 +bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) { 1.144 + if (length != _saved_code_length) { 1.145 return false; 1.146 } 1.147 - for (int i = 0; i < length; i++) { 1.148 - if (buffer[i] != _saved_code[i]) { 1.149 - return false; 1.150 - } 1.151 - } 1.152 - return true; 1.153 + 1.154 + return (memcmp(buffer, _saved_code, length) == 0) ? true : false; 1.155 } 1.156 #endif 1.157
2.1 --- a/src/share/vm/runtime/sharedRuntime.hpp Tue Dec 17 08:31:06 2013 +0100 2.2 +++ b/src/share/vm/runtime/sharedRuntime.hpp Thu Dec 19 06:09:16 2013 +0100 2.3 @@ -612,9 +612,7 @@ 2.4 // Captures code and signature used to generate this adapter when 2.5 // verifing adapter equivalence. 2.6 unsigned char* _saved_code; 2.7 - int _code_length; 2.8 - BasicType* _saved_sig; 2.9 - int _total_args_passed; 2.10 + int _saved_code_length; 2.11 #endif 2.12 2.13 void init(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) { 2.14 @@ -624,9 +622,7 @@ 2.15 _c2i_unverified_entry = c2i_unverified_entry; 2.16 #ifdef ASSERT 2.17 _saved_code = NULL; 2.18 - _code_length = 0; 2.19 - _saved_sig = NULL; 2.20 - _total_args_passed = 0; 2.21 + _saved_code_length = 0; 2.22 #endif 2.23 } 2.24 2.25 @@ -639,7 +635,6 @@ 2.26 address get_i2c_entry() const { return _i2c_entry; } 2.27 address get_c2i_entry() const { return _c2i_entry; } 2.28 address get_c2i_unverified_entry() const { return _c2i_unverified_entry; } 2.29 - 2.30 address base_address(); 2.31 void relocate(address new_base); 2.32 2.33 @@ -651,8 +646,8 @@ 2.34 2.35 #ifdef ASSERT 2.36 // Used to verify that code generated for shared adapters is equivalent 2.37 - void save_code(unsigned char* code, int length, int total_args_passed, BasicType* sig_bt); 2.38 - bool compare_code(unsigned char* code, int length, int total_args_passed, BasicType* sig_bt); 2.39 + void save_code (unsigned char* code, int length); 2.40 + bool compare_code(unsigned char* code, int length); 2.41 #endif 2.42 2.43 //virtual void print_on(outputStream* st) const; DO NOT USE