1.1 --- a/src/share/vm/runtime/sharedRuntime.cpp Mon Feb 01 16:49:49 2010 -0800 1.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp Wed Feb 03 12:28:30 2010 -0800 1.3 @@ -1806,55 +1806,78 @@ 1.4 class AdapterFingerPrint : public CHeapObj { 1.5 private: 1.6 union { 1.7 - signed char _compact[12]; 1.8 - int _compact_int[3]; 1.9 - intptr_t* _fingerprint; 1.10 + int _compact[3]; 1.11 + int* _fingerprint; 1.12 } _value; 1.13 - int _length; // A negative length indicates that _value._fingerprint is the array. 1.14 - // Otherwise it's in the compact form. 1.15 + int _length; // A negative length indicates the fingerprint is in the compact form, 1.16 + // Otherwise _value._fingerprint is the array. 1.17 1.18 - public: 1.19 - AdapterFingerPrint(int total_args_passed, VMRegPair* regs) { 1.20 - assert(sizeof(_value._compact) == sizeof(_value._compact_int), "must match"); 1.21 - _length = total_args_passed * 2; 1.22 - if (_length < (int)sizeof(_value._compact)) { 1.23 - _value._compact_int[0] = _value._compact_int[1] = _value._compact_int[2] = 0; 1.24 - // Storing the signature encoded as signed chars hits about 98% 1.25 - // of the time. 1.26 - signed char* ptr = _value._compact; 1.27 - int o = 0; 1.28 - for (int i = 0; i < total_args_passed; i++) { 1.29 - VMRegPair pair = regs[i]; 1.30 - intptr_t v1 = pair.first()->value(); 1.31 - intptr_t v2 = pair.second()->value(); 1.32 - if (v1 == (signed char) v1 && 1.33 - v2 == (signed char) v2) { 1.34 - _value._compact[o++] = v1; 1.35 - _value._compact[o++] = v2; 1.36 - } else { 1.37 - goto big; 1.38 + // Remap BasicTypes that are handled equivalently by the adapters. 1.39 + // These are correct for the current system but someday it might be 1.40 + // necessary to make this mapping platform dependent. 1.41 + static BasicType adapter_encoding(BasicType in) { 1.42 + assert((~0xf & in) == 0, "must fit in 4 bits"); 1.43 + switch(in) { 1.44 + case T_BOOLEAN: 1.45 + case T_BYTE: 1.46 + case T_SHORT: 1.47 + case T_CHAR: 1.48 + // There are all promoted to T_INT in the calling convention 1.49 + return T_INT; 1.50 + 1.51 + case T_OBJECT: 1.52 + case T_ARRAY: 1.53 + if (!TaggedStackInterpreter) { 1.54 +#ifdef _LP64 1.55 + return T_LONG; 1.56 +#else 1.57 + return T_INT; 1.58 +#endif 1.59 } 1.60 - } 1.61 - _length = -_length; 1.62 - return; 1.63 - } 1.64 - big: 1.65 - _value._fingerprint = NEW_C_HEAP_ARRAY(intptr_t, _length); 1.66 - int o = 0; 1.67 - for (int i = 0; i < total_args_passed; i++) { 1.68 - VMRegPair pair = regs[i]; 1.69 - intptr_t v1 = pair.first()->value(); 1.70 - intptr_t v2 = pair.second()->value(); 1.71 - _value._fingerprint[o++] = v1; 1.72 - _value._fingerprint[o++] = v2; 1.73 + return T_OBJECT; 1.74 + 1.75 + case T_INT: 1.76 + case T_LONG: 1.77 + case T_FLOAT: 1.78 + case T_DOUBLE: 1.79 + case T_VOID: 1.80 + return in; 1.81 + 1.82 + default: 1.83 + ShouldNotReachHere(); 1.84 + return T_CONFLICT; 1.85 } 1.86 } 1.87 1.88 - AdapterFingerPrint(AdapterFingerPrint* orig) { 1.89 - _length = orig->_length; 1.90 - _value = orig->_value; 1.91 - // take ownership of any storage by destroying the length 1.92 - orig->_length = 0; 1.93 + public: 1.94 + AdapterFingerPrint(int total_args_passed, BasicType* sig_bt) { 1.95 + // The fingerprint is based on the BasicType signature encoded 1.96 + // into an array of ints with four entries per int. 1.97 + int* ptr; 1.98 + int len = (total_args_passed + 3) >> 2; 1.99 + if (len <= (int)(sizeof(_value._compact) / sizeof(int))) { 1.100 + _value._compact[0] = _value._compact[1] = _value._compact[2] = 0; 1.101 + // Storing the signature encoded as signed chars hits about 98% 1.102 + // of the time. 1.103 + _length = -len; 1.104 + ptr = _value._compact; 1.105 + } else { 1.106 + _length = len; 1.107 + _value._fingerprint = NEW_C_HEAP_ARRAY(int, _length); 1.108 + ptr = _value._fingerprint; 1.109 + } 1.110 + 1.111 + // Now pack the BasicTypes with 4 per int 1.112 + int sig_index = 0; 1.113 + for (int index = 0; index < len; index++) { 1.114 + int value = 0; 1.115 + for (int byte = 0; byte < 4; byte++) { 1.116 + if (sig_index < total_args_passed) { 1.117 + value = (value << 4) | adapter_encoding(sig_bt[sig_index++]); 1.118 + } 1.119 + } 1.120 + ptr[index] = value; 1.121 + } 1.122 } 1.123 1.124 ~AdapterFingerPrint() { 1.125 @@ -1863,11 +1886,7 @@ 1.126 } 1.127 } 1.128 1.129 - AdapterFingerPrint* allocate() { 1.130 - return new AdapterFingerPrint(this); 1.131 - } 1.132 - 1.133 - intptr_t value(int index) { 1.134 + int value(int index) { 1.135 if (_length < 0) { 1.136 return _value._compact[index]; 1.137 } 1.138 @@ -1883,9 +1902,9 @@ 1.139 } 1.140 1.141 unsigned int compute_hash() { 1.142 - intptr_t hash = 0; 1.143 + int hash = 0; 1.144 for (int i = 0; i < length(); i++) { 1.145 - intptr_t v = value(i); 1.146 + int v = value(i); 1.147 hash = (hash << 8) ^ v ^ (hash >> 5); 1.148 } 1.149 return (unsigned int)hash; 1.150 @@ -1904,9 +1923,9 @@ 1.151 return false; 1.152 } 1.153 if (_length < 0) { 1.154 - return _value._compact_int[0] == other->_value._compact_int[0] && 1.155 - _value._compact_int[1] == other->_value._compact_int[1] && 1.156 - _value._compact_int[2] == other->_value._compact_int[2]; 1.157 + return _value._compact[0] == other->_value._compact[0] && 1.158 + _value._compact[1] == other->_value._compact[1] && 1.159 + _value._compact[2] == other->_value._compact[2]; 1.160 } else { 1.161 for (int i = 0; i < _length; i++) { 1.162 if (_value._fingerprint[i] != other->_value._fingerprint[i]) { 1.163 @@ -1954,10 +1973,15 @@ 1.164 add_entry(index, entry); 1.165 } 1.166 1.167 + void free_entry(AdapterHandlerEntry* entry) { 1.168 + entry->deallocate(); 1.169 + BasicHashtable::free_entry(entry); 1.170 + } 1.171 + 1.172 // Find a entry with the same fingerprint if it exists 1.173 - AdapterHandlerEntry* lookup(int total_args_passed, VMRegPair* regs) { 1.174 + AdapterHandlerEntry* lookup(int total_args_passed, BasicType* sig_bt) { 1.175 debug_only(_lookups++); 1.176 - AdapterFingerPrint fp(total_args_passed, regs); 1.177 + AdapterFingerPrint fp(total_args_passed, sig_bt); 1.178 unsigned int hash = fp.compute_hash(); 1.179 int index = hash_to_index(hash); 1.180 for (AdapterHandlerEntry* e = bucket(index); e != NULL; e = e->next()) { 1.181 @@ -2129,17 +2153,26 @@ 1.182 } 1.183 assert(i == total_args_passed, ""); 1.184 1.185 - // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage 1.186 - int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); 1.187 + // Lookup method signature's fingerprint 1.188 + entry = _adapters->lookup(total_args_passed, sig_bt); 1.189 1.190 - // Lookup method signature's fingerprint 1.191 - entry = _adapters->lookup(total_args_passed, regs); 1.192 +#ifdef ASSERT 1.193 + AdapterHandlerEntry* shared_entry = NULL; 1.194 + if (VerifyAdapterSharing && entry != NULL) { 1.195 + shared_entry = entry; 1.196 + entry = NULL; 1.197 + } 1.198 +#endif 1.199 + 1.200 if (entry != NULL) { 1.201 return entry; 1.202 } 1.203 1.204 + // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage 1.205 + int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); 1.206 + 1.207 // Make a C heap allocated version of the fingerprint to store in the adapter 1.208 - fingerprint = new AdapterFingerPrint(total_args_passed, regs); 1.209 + fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); 1.210 1.211 // Create I2C & C2I handlers 1.212 1.213 @@ -2158,6 +2191,20 @@ 1.214 regs, 1.215 fingerprint); 1.216 1.217 +#ifdef ASSERT 1.218 + if (VerifyAdapterSharing) { 1.219 + if (shared_entry != NULL) { 1.220 + assert(shared_entry->compare_code(buf->instructions_begin(), buffer.code_size(), total_args_passed, sig_bt), 1.221 + "code must match"); 1.222 + // Release the one just created and return the original 1.223 + _adapters->free_entry(entry); 1.224 + return shared_entry; 1.225 + } else { 1.226 + entry->save_code(buf->instructions_begin(), buffer.code_size(), total_args_passed, sig_bt); 1.227 + } 1.228 + } 1.229 +#endif 1.230 + 1.231 B = BufferBlob::create(AdapterHandlerEntry::name, &buffer); 1.232 NOT_PRODUCT(code_size = buffer.code_size()); 1.233 } 1.234 @@ -2212,6 +2259,44 @@ 1.235 _c2i_unverified_entry += delta; 1.236 } 1.237 1.238 + 1.239 +void AdapterHandlerEntry::deallocate() { 1.240 + delete _fingerprint; 1.241 +#ifdef ASSERT 1.242 + if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code); 1.243 + if (_saved_sig) FREE_C_HEAP_ARRAY(Basictype, _saved_sig); 1.244 +#endif 1.245 +} 1.246 + 1.247 + 1.248 +#ifdef ASSERT 1.249 +// Capture the code before relocation so that it can be compared 1.250 +// against other versions. If the code is captured after relocation 1.251 +// then relative instructions won't be equivalent. 1.252 +void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { 1.253 + _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length); 1.254 + _code_length = length; 1.255 + memcpy(_saved_code, buffer, length); 1.256 + _total_args_passed = total_args_passed; 1.257 + _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed); 1.258 + memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType)); 1.259 +} 1.260 + 1.261 + 1.262 +bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { 1.263 + if (length != _code_length) { 1.264 + return false; 1.265 + } 1.266 + for (int i = 0; i < length; i++) { 1.267 + if (buffer[i] != _saved_code[i]) { 1.268 + return false; 1.269 + } 1.270 + } 1.271 + return true; 1.272 +} 1.273 +#endif 1.274 + 1.275 + 1.276 // Create a native wrapper for this native method. The wrapper converts the 1.277 // java compiled calling convention to the native convention, handlizes 1.278 // arguments, and transitions to native. On return from the native we transition