Mercurial > hg > truffle
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); |