1.1 --- a/src/share/vm/oops/constantPoolOop.cpp Mon Jul 23 13:04:59 2012 -0700 1.2 +++ b/src/share/vm/oops/constantPoolOop.cpp Tue Jul 24 10:51:00 2012 -0700 1.3 @@ -267,25 +267,61 @@ 1.4 1.5 1.6 methodOop constantPoolOopDesc::method_at_if_loaded(constantPoolHandle cpool, 1.7 - int which, Bytecodes::Code invoke_code) { 1.8 + int which) { 1.9 assert(!constantPoolCacheOopDesc::is_secondary_index(which), "no indy instruction here"); 1.10 if (cpool->cache() == NULL) return NULL; // nothing to load yet 1.11 - int cache_index = which - CPCACHE_INDEX_TAG; 1.12 + int cache_index = get_cpcache_index(which); 1.13 if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) { 1.14 if (PrintMiscellaneous && (Verbose||WizardMode)) { 1.15 - tty->print_cr("bad operand %d for %d in:", which, invoke_code); cpool->print(); 1.16 + tty->print_cr("bad operand %d in:", which); cpool->print(); 1.17 } 1.18 return NULL; 1.19 } 1.20 ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index); 1.21 - if (invoke_code != Bytecodes::_illegal) 1.22 - return e->get_method_if_resolved(invoke_code, cpool); 1.23 - Bytecodes::Code bc; 1.24 - if ((bc = e->bytecode_1()) != (Bytecodes::Code)0) 1.25 - return e->get_method_if_resolved(bc, cpool); 1.26 - if ((bc = e->bytecode_2()) != (Bytecodes::Code)0) 1.27 - return e->get_method_if_resolved(bc, cpool); 1.28 - return NULL; 1.29 + return e->method_if_resolved(cpool); 1.30 +} 1.31 + 1.32 + 1.33 +bool constantPoolOopDesc::has_appendix_at_if_loaded(constantPoolHandle cpool, int which) { 1.34 + if (cpool->cache() == NULL) return false; // nothing to load yet 1.35 + // XXX Is there a simpler way to get to the secondary entry? 1.36 + ConstantPoolCacheEntry* e; 1.37 + if (constantPoolCacheOopDesc::is_secondary_index(which)) { 1.38 + e = cpool->cache()->secondary_entry_at(which); 1.39 + } else { 1.40 + int cache_index = get_cpcache_index(which); 1.41 + if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) { 1.42 + if (PrintMiscellaneous && (Verbose||WizardMode)) { 1.43 + tty->print_cr("bad operand %d in:", which); cpool->print(); 1.44 + } 1.45 + return false; 1.46 + } 1.47 + e = cpool->cache()->entry_at(cache_index); 1.48 + } 1.49 + return e->has_appendix(); 1.50 +} 1.51 + 1.52 + 1.53 +oop constantPoolOopDesc::appendix_at_if_loaded(constantPoolHandle cpool, int which) { 1.54 + if (cpool->cache() == NULL) return NULL; // nothing to load yet 1.55 + // XXX Is there a simpler way to get to the secondary entry? 1.56 + ConstantPoolCacheEntry* e; 1.57 + if (constantPoolCacheOopDesc::is_secondary_index(which)) { 1.58 + e = cpool->cache()->secondary_entry_at(which); 1.59 + } else { 1.60 + int cache_index = get_cpcache_index(which); 1.61 + if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) { 1.62 + if (PrintMiscellaneous && (Verbose||WizardMode)) { 1.63 + tty->print_cr("bad operand %d in:", which); cpool->print(); 1.64 + } 1.65 + return NULL; 1.66 + } 1.67 + e = cpool->cache()->entry_at(cache_index); 1.68 + } 1.69 + if (!e->has_appendix()) { 1.70 + return NULL; 1.71 + } 1.72 + return e->f1_as_instance(); 1.73 } 1.74 1.75 1.76 @@ -481,7 +517,7 @@ 1.77 if (cache_index >= 0) { 1.78 assert(index == _no_index_sentinel, "only one kind of index at a time"); 1.79 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); 1.80 - result_oop = cpc_entry->f1(); 1.81 + result_oop = cpc_entry->f1_as_instance(); 1.82 if (result_oop != NULL) { 1.83 return decode_exception_from_f1(result_oop, THREAD); 1.84 // That was easy... 1.85 @@ -553,12 +589,7 @@ 1.86 index, this_oop->method_type_index_at(index), 1.87 signature->as_C_string()); 1.88 KlassHandle klass(THREAD, this_oop->pool_holder()); 1.89 - bool ignore_is_on_bcp = false; 1.90 - Handle value = SystemDictionary::find_method_handle_type(signature, 1.91 - klass, 1.92 - false, 1.93 - ignore_is_on_bcp, 1.94 - THREAD); 1.95 + Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD); 1.96 if (HAS_PENDING_EXCEPTION) { 1.97 throw_exception = Handle(THREAD, PENDING_EXCEPTION); 1.98 CLEAR_PENDING_EXCEPTION; 1.99 @@ -608,7 +639,7 @@ 1.100 result_oop = NULL; // safety 1.101 ObjectLocker ol(this_oop, THREAD); 1.102 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); 1.103 - result_oop = cpc_entry->f1(); 1.104 + result_oop = cpc_entry->f1_as_instance(); 1.105 // Benign race condition: f1 may already be filled in while we were trying to lock. 1.106 // The important thing here is that all threads pick up the same result. 1.107 // It doesn't matter which racing thread wins, as long as only one 1.108 @@ -627,6 +658,45 @@ 1.109 } 1.110 } 1.111 1.112 + 1.113 +oop constantPoolOopDesc::resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS) { 1.114 + assert(this_oop->tag_at(index).is_invoke_dynamic(), "Corrupted constant pool"); 1.115 + 1.116 + Handle bsm; 1.117 + int argc; 1.118 + { 1.119 + // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type], plus optional arguments 1.120 + // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry. 1.121 + // It is accompanied by the optional arguments. 1.122 + int bsm_index = this_oop->invoke_dynamic_bootstrap_method_ref_index_at(index); 1.123 + oop bsm_oop = this_oop->resolve_possibly_cached_constant_at(bsm_index, CHECK_NULL); 1.124 + if (!java_lang_invoke_MethodHandle::is_instance(bsm_oop)) { 1.125 + THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "BSM not an MethodHandle"); 1.126 + } 1.127 + 1.128 + // Extract the optional static arguments. 1.129 + argc = this_oop->invoke_dynamic_argument_count_at(index); 1.130 + if (argc == 0) return bsm_oop; 1.131 + 1.132 + bsm = Handle(THREAD, bsm_oop); 1.133 + } 1.134 + 1.135 + objArrayHandle info; 1.136 + { 1.137 + objArrayOop info_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1+argc, CHECK_NULL); 1.138 + info = objArrayHandle(THREAD, info_oop); 1.139 + } 1.140 + 1.141 + info->obj_at_put(0, bsm()); 1.142 + for (int i = 0; i < argc; i++) { 1.143 + int arg_index = this_oop->invoke_dynamic_argument_index_at(index, i); 1.144 + oop arg_oop = this_oop->resolve_possibly_cached_constant_at(arg_index, CHECK_NULL); 1.145 + info->obj_at_put(1+i, arg_oop); 1.146 + } 1.147 + 1.148 + return info(); 1.149 +} 1.150 + 1.151 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { 1.152 oop str = NULL; 1.153 CPSlot entry = this_oop->slot_at(which);