comparison src/share/vm/oops/cpCache.cpp @ 6822:f6b0eb4e44cf

7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path Reviewed-by: jrose, kvn
author twisti
date Mon, 01 Oct 2012 14:50:10 -0700
parents 4bfe8b33cf66
children 18fb7da42534 64672b22ef05
comparison
equal deleted inserted replaced
6811:1b582b1bf7cb 6822:f6b0eb4e44cf
242 set_bytecode_1(Bytecodes::_invokeinterface); 242 set_bytecode_1(Bytecodes::_invokeinterface);
243 } 243 }
244 244
245 245
246 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, 246 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
247 methodHandle adapter, Handle appendix, 247 methodHandle adapter,
248 Handle appendix, Handle method_type,
248 objArrayHandle resolved_references) { 249 objArrayHandle resolved_references) {
249 set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, resolved_references); 250 set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, method_type, resolved_references);
250 } 251 }
251 252
252 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, 253 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
253 methodHandle adapter, Handle appendix, 254 methodHandle adapter,
255 Handle appendix, Handle method_type,
254 objArrayHandle resolved_references) { 256 objArrayHandle resolved_references) {
255 set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, resolved_references); 257 set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, method_type, resolved_references);
256 } 258 }
257 259
258 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool, 260 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
259 Bytecodes::Code invoke_code, 261 Bytecodes::Code invoke_code,
260 methodHandle adapter, 262 methodHandle adapter,
261 Handle appendix, 263 Handle appendix, Handle method_type,
262 objArrayHandle resolved_references) { 264 objArrayHandle resolved_references) {
263 // NOTE: This CPCE can be the subject of data races. 265 // NOTE: This CPCE can be the subject of data races.
264 // There are three words to update: flags, refs[f2], f1 (in that order). 266 // There are three words to update: flags, refs[f2], f1 (in that order).
265 // Writers must store all other values before f1. 267 // Writers must store all other values before f1.
266 // Readers must test f1 first for non-null before reading other fields. 268 // Readers must test f1 first for non-null before reading other fields.
272 MonitorLockerEx ml(cpool->lock()); 274 MonitorLockerEx ml(cpool->lock());
273 if (!is_f1_null()) { 275 if (!is_f1_null()) {
274 return; 276 return;
275 } 277 }
276 278
277 bool has_appendix = appendix.not_null(); 279 const bool has_appendix = appendix.not_null();
280 const bool has_method_type = method_type.not_null();
278 281
279 // Write the flags. 282 // Write the flags.
280 set_method_flags(as_TosState(adapter->result_type()), 283 set_method_flags(as_TosState(adapter->result_type()),
281 ((has_appendix ? 1 : 0) << has_appendix_shift) | 284 ((has_appendix ? 1 : 0) << has_appendix_shift ) |
282 ( 1 << is_final_shift), 285 ((has_method_type ? 1 : 0) << has_method_type_shift) |
286 ( 1 << is_final_shift ),
283 adapter->size_of_parameters()); 287 adapter->size_of_parameters());
284 288
285 if (TraceInvokeDynamic) { 289 if (TraceInvokeDynamic) {
286 tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method="PTR_FORMAT" ", 290 tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
287 invoke_code, 291 invoke_code,
288 (intptr_t)appendix(), (has_appendix ? "" : " (unused)"), 292 (intptr_t)appendix(), (has_appendix ? "" : " (unused)"),
293 (intptr_t)method_type(), (has_method_type ? "" : " (unused)"),
289 (intptr_t)adapter()); 294 (intptr_t)adapter());
290 adapter->print(); 295 adapter->print();
291 if (has_appendix) appendix()->print(); 296 if (has_appendix) appendix()->print();
292 } 297 }
293 298
308 // not '(Ljava/lang/String;)Ljava/util/List;'. 313 // not '(Ljava/lang/String;)Ljava/util/List;'.
309 // The fact that String and List are involved is encoded in the MethodType in refs[f2]. 314 // The fact that String and List are involved is encoded in the MethodType in refs[f2].
310 // This allows us to create fewer method oops, while keeping type safety. 315 // This allows us to create fewer method oops, while keeping type safety.
311 // 316 //
312 317
318 // Store appendix, if any.
313 if (has_appendix) { 319 if (has_appendix) {
314 int ref_index = f2_as_index(); 320 const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
315 assert(ref_index >= 0 && ref_index < resolved_references->length(), "oob"); 321 assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
316 assert(resolved_references->obj_at(ref_index) == NULL, "init just once"); 322 assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
317 resolved_references->obj_at_put(ref_index, appendix()); 323 resolved_references->obj_at_put(appendix_index, appendix());
324 }
325
326 // Store MethodType, if any.
327 if (has_method_type) {
328 const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset;
329 assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob");
330 assert(resolved_references->obj_at(method_type_index) == NULL, "init just once");
331 resolved_references->obj_at_put(method_type_index, method_type());
318 } 332 }
319 333
320 release_set_f1(adapter()); // This must be the last one to set (see NOTE above)! 334 release_set_f1(adapter()); // This must be the last one to set (see NOTE above)!
321 335
322 // The interpreter assembly code does not check byte_2, 336 // The interpreter assembly code does not check byte_2,
323 // but it is used by is_resolved, method_if_resolved, etc. 337 // but it is used by is_resolved, method_if_resolved, etc.
324 set_bytecode_1(invoke_code); 338 set_bytecode_1(invoke_code);
325 NOT_PRODUCT(verify(tty)); 339 NOT_PRODUCT(verify(tty));
326 if (TraceInvokeDynamic) { 340 if (TraceInvokeDynamic) {
327 this->print(tty, 0); 341 this->print(tty, 0);
328 } 342 }
374 388
375 389
376 oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) { 390 oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
377 if (is_f1_null() || !has_appendix()) 391 if (is_f1_null() || !has_appendix())
378 return NULL; 392 return NULL;
379 int ref_index = f2_as_index(); 393 const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset;
394 objArrayOop resolved_references = cpool->resolved_references();
395 return resolved_references->obj_at(ref_index);
396 }
397
398
399 oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
400 if (is_f1_null() || !has_method_type())
401 return NULL;
402 const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset;
380 objArrayOop resolved_references = cpool->resolved_references(); 403 objArrayOop resolved_references = cpool->resolved_references();
381 return resolved_references->obj_at(ref_index); 404 return resolved_references->obj_at(ref_index);
382 } 405 }
383 406
384 407
511 void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) { 534 void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) {
512 assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache"); 535 assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
513 for (int i = 0; i < length(); i++) { 536 for (int i = 0; i < length(); i++) {
514 ConstantPoolCacheEntry* e = entry_at(i); 537 ConstantPoolCacheEntry* e = entry_at(i);
515 int original_index = inverse_index_map[i]; 538 int original_index = inverse_index_map[i];
516 e->initialize_entry(original_index); 539 e->initialize_entry(original_index);
517 assert(entry_at(i) == e, "sanity"); 540 assert(entry_at(i) == e, "sanity");
518 } 541 }
519 for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) { 542 for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
520 int cpci = invokedynamic_references_map[ref]; 543 const int cpci = invokedynamic_references_map[ref];
521 if (cpci >= 0) 544 if (cpci >= 0) {
545 #ifdef ASSERT
546 // invokedynamic and invokehandle have more entries; check if they
547 // all point to the same constant pool cache entry.
548 for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
549 const int cpci_next = invokedynamic_references_map[ref + entry];
550 assert(cpci == cpci_next, err_msg_res("%d == %d", cpci, cpci_next));
551 }
552 #endif
522 entry_at(cpci)->initialize_resolved_reference_index(ref); 553 entry_at(cpci)->initialize_resolved_reference_index(ref);
554 ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1; // skip extra entries
555 }
523 } 556 }
524 } 557 }
525 558
526 // RedefineClasses() API support: 559 // RedefineClasses() API support:
527 // If any entry of this constantPoolCache points to any of 560 // If any entry of this constantPoolCache points to any of