comparison src/share/vm/oops/constantPoolOop.cpp @ 6266:1d7922586cf6

7023639: JSR 292 method handle invocation needs a fast path for compiled code 6984705: JSR 292 method handle creation should not go through JNI Summary: remove assembly code for JDK 7 chained method handles Reviewed-by: jrose, twisti, kvn, mhaupt Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>
author twisti
date Tue, 24 Jul 2012 10:51:00 -0700
parents f457154eee8b
children 957c266d8bc5
comparison
equal deleted inserted replaced
6241:aba91a731143 6266:1d7922586cf6
265 } 265 }
266 } 266 }
267 267
268 268
269 methodOop constantPoolOopDesc::method_at_if_loaded(constantPoolHandle cpool, 269 methodOop constantPoolOopDesc::method_at_if_loaded(constantPoolHandle cpool,
270 int which, Bytecodes::Code invoke_code) { 270 int which) {
271 assert(!constantPoolCacheOopDesc::is_secondary_index(which), "no indy instruction here"); 271 assert(!constantPoolCacheOopDesc::is_secondary_index(which), "no indy instruction here");
272 if (cpool->cache() == NULL) return NULL; // nothing to load yet 272 if (cpool->cache() == NULL) return NULL; // nothing to load yet
273 int cache_index = which - CPCACHE_INDEX_TAG; 273 int cache_index = get_cpcache_index(which);
274 if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) { 274 if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
275 if (PrintMiscellaneous && (Verbose||WizardMode)) { 275 if (PrintMiscellaneous && (Verbose||WizardMode)) {
276 tty->print_cr("bad operand %d for %d in:", which, invoke_code); cpool->print(); 276 tty->print_cr("bad operand %d in:", which); cpool->print();
277 } 277 }
278 return NULL; 278 return NULL;
279 } 279 }
280 ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index); 280 ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
281 if (invoke_code != Bytecodes::_illegal) 281 return e->method_if_resolved(cpool);
282 return e->get_method_if_resolved(invoke_code, cpool); 282 }
283 Bytecodes::Code bc; 283
284 if ((bc = e->bytecode_1()) != (Bytecodes::Code)0) 284
285 return e->get_method_if_resolved(bc, cpool); 285 bool constantPoolOopDesc::has_appendix_at_if_loaded(constantPoolHandle cpool, int which) {
286 if ((bc = e->bytecode_2()) != (Bytecodes::Code)0) 286 if (cpool->cache() == NULL) return false; // nothing to load yet
287 return e->get_method_if_resolved(bc, cpool); 287 // XXX Is there a simpler way to get to the secondary entry?
288 return NULL; 288 ConstantPoolCacheEntry* e;
289 if (constantPoolCacheOopDesc::is_secondary_index(which)) {
290 e = cpool->cache()->secondary_entry_at(which);
291 } else {
292 int cache_index = get_cpcache_index(which);
293 if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
294 if (PrintMiscellaneous && (Verbose||WizardMode)) {
295 tty->print_cr("bad operand %d in:", which); cpool->print();
296 }
297 return false;
298 }
299 e = cpool->cache()->entry_at(cache_index);
300 }
301 return e->has_appendix();
302 }
303
304
305 oop constantPoolOopDesc::appendix_at_if_loaded(constantPoolHandle cpool, int which) {
306 if (cpool->cache() == NULL) return NULL; // nothing to load yet
307 // XXX Is there a simpler way to get to the secondary entry?
308 ConstantPoolCacheEntry* e;
309 if (constantPoolCacheOopDesc::is_secondary_index(which)) {
310 e = cpool->cache()->secondary_entry_at(which);
311 } else {
312 int cache_index = get_cpcache_index(which);
313 if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
314 if (PrintMiscellaneous && (Verbose||WizardMode)) {
315 tty->print_cr("bad operand %d in:", which); cpool->print();
316 }
317 return NULL;
318 }
319 e = cpool->cache()->entry_at(cache_index);
320 }
321 if (!e->has_appendix()) {
322 return NULL;
323 }
324 return e->f1_as_instance();
289 } 325 }
290 326
291 327
292 Symbol* constantPoolOopDesc::impl_name_ref_at(int which, bool uncached) { 328 Symbol* constantPoolOopDesc::impl_name_ref_at(int which, bool uncached) {
293 int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached)); 329 int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached));
479 assert(index == _no_index_sentinel || index >= 0, ""); 515 assert(index == _no_index_sentinel || index >= 0, "");
480 516
481 if (cache_index >= 0) { 517 if (cache_index >= 0) {
482 assert(index == _no_index_sentinel, "only one kind of index at a time"); 518 assert(index == _no_index_sentinel, "only one kind of index at a time");
483 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); 519 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
484 result_oop = cpc_entry->f1(); 520 result_oop = cpc_entry->f1_as_instance();
485 if (result_oop != NULL) { 521 if (result_oop != NULL) {
486 return decode_exception_from_f1(result_oop, THREAD); 522 return decode_exception_from_f1(result_oop, THREAD);
487 // That was easy... 523 // That was easy...
488 } 524 }
489 index = cpc_entry->constant_pool_index(); 525 index = cpc_entry->constant_pool_index();
551 if (PrintMiscellaneous) 587 if (PrintMiscellaneous)
552 tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s", 588 tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
553 index, this_oop->method_type_index_at(index), 589 index, this_oop->method_type_index_at(index),
554 signature->as_C_string()); 590 signature->as_C_string());
555 KlassHandle klass(THREAD, this_oop->pool_holder()); 591 KlassHandle klass(THREAD, this_oop->pool_holder());
556 bool ignore_is_on_bcp = false; 592 Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);
557 Handle value = SystemDictionary::find_method_handle_type(signature,
558 klass,
559 false,
560 ignore_is_on_bcp,
561 THREAD);
562 if (HAS_PENDING_EXCEPTION) { 593 if (HAS_PENDING_EXCEPTION) {
563 throw_exception = Handle(THREAD, PENDING_EXCEPTION); 594 throw_exception = Handle(THREAD, PENDING_EXCEPTION);
564 CLEAR_PENDING_EXCEPTION; 595 CLEAR_PENDING_EXCEPTION;
565 break; 596 break;
566 } 597 }
606 } 637 }
607 Handle result_handle(THREAD, result_oop); 638 Handle result_handle(THREAD, result_oop);
608 result_oop = NULL; // safety 639 result_oop = NULL; // safety
609 ObjectLocker ol(this_oop, THREAD); 640 ObjectLocker ol(this_oop, THREAD);
610 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); 641 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
611 result_oop = cpc_entry->f1(); 642 result_oop = cpc_entry->f1_as_instance();
612 // Benign race condition: f1 may already be filled in while we were trying to lock. 643 // Benign race condition: f1 may already be filled in while we were trying to lock.
613 // The important thing here is that all threads pick up the same result. 644 // The important thing here is that all threads pick up the same result.
614 // It doesn't matter which racing thread wins, as long as only one 645 // It doesn't matter which racing thread wins, as long as only one
615 // result is used by all threads, and all future queries. 646 // result is used by all threads, and all future queries.
616 // That result may be either a resolved constant or a failure exception. 647 // That result may be either a resolved constant or a failure exception.
623 if (throw_exception.not_null()) { 654 if (throw_exception.not_null()) {
624 THROW_HANDLE_(throw_exception, NULL); 655 THROW_HANDLE_(throw_exception, NULL);
625 } 656 }
626 return result_oop; 657 return result_oop;
627 } 658 }
659 }
660
661
662 oop constantPoolOopDesc::resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS) {
663 assert(this_oop->tag_at(index).is_invoke_dynamic(), "Corrupted constant pool");
664
665 Handle bsm;
666 int argc;
667 {
668 // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type], plus optional arguments
669 // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry.
670 // It is accompanied by the optional arguments.
671 int bsm_index = this_oop->invoke_dynamic_bootstrap_method_ref_index_at(index);
672 oop bsm_oop = this_oop->resolve_possibly_cached_constant_at(bsm_index, CHECK_NULL);
673 if (!java_lang_invoke_MethodHandle::is_instance(bsm_oop)) {
674 THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "BSM not an MethodHandle");
675 }
676
677 // Extract the optional static arguments.
678 argc = this_oop->invoke_dynamic_argument_count_at(index);
679 if (argc == 0) return bsm_oop;
680
681 bsm = Handle(THREAD, bsm_oop);
682 }
683
684 objArrayHandle info;
685 {
686 objArrayOop info_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1+argc, CHECK_NULL);
687 info = objArrayHandle(THREAD, info_oop);
688 }
689
690 info->obj_at_put(0, bsm());
691 for (int i = 0; i < argc; i++) {
692 int arg_index = this_oop->invoke_dynamic_argument_index_at(index, i);
693 oop arg_oop = this_oop->resolve_possibly_cached_constant_at(arg_index, CHECK_NULL);
694 info->obj_at_put(1+i, arg_oop);
695 }
696
697 return info();
628 } 698 }
629 699
630 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { 700 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
631 oop str = NULL; 701 oop str = NULL;
632 CPSlot entry = this_oop->slot_at(which); 702 CPSlot entry = this_oop->slot_at(which);