1.1 --- a/src/share/vm/oops/constantPoolOop.cpp Sat Oct 30 12:19:07 2010 -0700 1.2 +++ b/src/share/vm/oops/constantPoolOop.cpp Sat Oct 30 13:08:23 2010 -0700 1.3 @@ -267,7 +267,7 @@ 1.4 if (constantPoolCacheOopDesc::is_secondary_index(which)) { 1.5 // Invokedynamic index. 1.6 int pool_index = cache()->main_entry_at(which)->constant_pool_index(); 1.7 - if (tag_at(pool_index).is_invoke_dynamic()) 1.8 + if (!AllowTransitionalJSR292 || tag_at(pool_index).is_invoke_dynamic()) 1.9 pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index); 1.10 assert(tag_at(pool_index).is_name_and_type(), ""); 1.11 return pool_index; 1.12 @@ -275,11 +275,17 @@ 1.13 // change byte-ordering and go via cache 1.14 i = remap_instruction_operand_from_cache(which); 1.15 } else { 1.16 - if (tag_at(which).is_name_and_type()) 1.17 + if (AllowTransitionalJSR292 && tag_at(which).is_name_and_type()) 1.18 // invokedynamic index is a simple name-and-type 1.19 return which; 1.20 + if (tag_at(which).is_invoke_dynamic()) { 1.21 + int pool_index = invoke_dynamic_name_and_type_ref_index_at(which); 1.22 + assert(tag_at(pool_index).is_name_and_type(), ""); 1.23 + return pool_index; 1.24 + } 1.25 } 1.26 assert(tag_at(i).is_field_or_method(), "Corrupted constant pool"); 1.27 + assert(!tag_at(i).is_invoke_dynamic(), "Must be handled above"); 1.28 jint ref_index = *int_at_addr(i); 1.29 return extract_high_short_from_int(ref_index); 1.30 } 1.31 @@ -393,18 +399,61 @@ 1.32 } 1.33 } 1.34 1.35 +// A resolved constant value in the CP cache is represented as a non-null 1.36 +// value. As a special case, this value can be a 'systemObjArray' 1.37 +// which masks an exception object to throw. 1.38 +// This allows a MethodHandle constant reference to throw a consistent 1.39 +// exception every time, if it fails to resolve. 1.40 +static oop decode_exception_from_f1(oop result_oop, TRAPS) { 1.41 + if (result_oop->klass() != Universe::systemObjArrayKlassObj()) 1.42 + return result_oop; 1.43 + 1.44 + // Special cases here: Masked null, saved exception. 1.45 + objArrayOop sys_array = (objArrayOop) result_oop; 1.46 + assert(sys_array->length() == 1, "bad system array"); 1.47 + if (sys_array->length() == 1) { 1.48 + THROW_OOP_(sys_array->obj_at(0), NULL); 1.49 + } 1.50 + return NULL; 1.51 +} 1.52 + 1.53 oop constantPoolOopDesc::resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS) { 1.54 oop result_oop = NULL; 1.55 + Handle throw_exception; 1.56 + 1.57 + if (cache_index == _possible_index_sentinel) { 1.58 + // It is possible that this constant is one which is cached in the CP cache. 1.59 + // We'll do a linear search. This should be OK because this usage is rare. 1.60 + assert(index > 0, "valid index"); 1.61 + constantPoolCacheOop cache = this_oop()->cache(); 1.62 + for (int i = 0, len = cache->length(); i < len; i++) { 1.63 + ConstantPoolCacheEntry* cpc_entry = cache->entry_at(i); 1.64 + if (!cpc_entry->is_secondary_entry() && cpc_entry->constant_pool_index() == index) { 1.65 + // Switch the query to use this CPC entry. 1.66 + cache_index = i; 1.67 + index = _no_index_sentinel; 1.68 + break; 1.69 + } 1.70 + } 1.71 + if (cache_index == _possible_index_sentinel) 1.72 + cache_index = _no_index_sentinel; // not found 1.73 + } 1.74 + assert(cache_index == _no_index_sentinel || cache_index >= 0, ""); 1.75 + assert(index == _no_index_sentinel || index >= 0, ""); 1.76 + 1.77 if (cache_index >= 0) { 1.78 - assert(index < 0, "only one kind of index at a time"); 1.79 + assert(index == _no_index_sentinel, "only one kind of index at a time"); 1.80 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); 1.81 result_oop = cpc_entry->f1(); 1.82 if (result_oop != NULL) { 1.83 - return result_oop; // that was easy... 1.84 + return decode_exception_from_f1(result_oop, THREAD); 1.85 + // That was easy... 1.86 } 1.87 index = cpc_entry->constant_pool_index(); 1.88 } 1.89 1.90 + jvalue prim_value; // temp used only in a few cases below 1.91 + 1.92 int tag_value = this_oop->tag_at(index).value(); 1.93 switch (tag_value) { 1.94 1.95 @@ -448,9 +497,14 @@ 1.96 KlassHandle klass(THREAD, this_oop->pool_holder()); 1.97 Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind, 1.98 callee, name, signature, 1.99 - CHECK_NULL); 1.100 + THREAD); 1.101 + if (HAS_PENDING_EXCEPTION) { 1.102 + throw_exception = Handle(THREAD, PENDING_EXCEPTION); 1.103 + CLEAR_PENDING_EXCEPTION; 1.104 + break; 1.105 + } 1.106 result_oop = value(); 1.107 - // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error. 1.108 + assert(result_oop != NULL, ""); 1.109 break; 1.110 } 1.111 1.112 @@ -467,20 +521,36 @@ 1.113 klass, 1.114 false, 1.115 ignore_is_on_bcp, 1.116 - CHECK_NULL); 1.117 + THREAD); 1.118 + if (HAS_PENDING_EXCEPTION) { 1.119 + throw_exception = Handle(THREAD, PENDING_EXCEPTION); 1.120 + CLEAR_PENDING_EXCEPTION; 1.121 + break; 1.122 + } 1.123 result_oop = value(); 1.124 - // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error. 1.125 + assert(result_oop != NULL, ""); 1.126 break; 1.127 } 1.128 1.129 - /* maybe some day 1.130 case JVM_CONSTANT_Integer: 1.131 + prim_value.i = this_oop->int_at(index); 1.132 + result_oop = java_lang_boxing_object::create(T_INT, &prim_value, CHECK_NULL); 1.133 + break; 1.134 + 1.135 case JVM_CONSTANT_Float: 1.136 + prim_value.f = this_oop->float_at(index); 1.137 + result_oop = java_lang_boxing_object::create(T_FLOAT, &prim_value, CHECK_NULL); 1.138 + break; 1.139 + 1.140 case JVM_CONSTANT_Long: 1.141 + prim_value.j = this_oop->long_at(index); 1.142 + result_oop = java_lang_boxing_object::create(T_LONG, &prim_value, CHECK_NULL); 1.143 + break; 1.144 + 1.145 case JVM_CONSTANT_Double: 1.146 - result_oop = java_lang_boxing_object::create(...); 1.147 + prim_value.d = this_oop->double_at(index); 1.148 + result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL); 1.149 break; 1.150 - */ 1.151 1.152 default: 1.153 DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", 1.154 @@ -491,18 +561,31 @@ 1.155 1.156 if (cache_index >= 0) { 1.157 // Cache the oop here also. 1.158 - Handle result(THREAD, result_oop); 1.159 + if (throw_exception.not_null()) { 1.160 + objArrayOop sys_array = oopFactory::new_system_objArray(1, CHECK_NULL); 1.161 + sys_array->obj_at_put(0, throw_exception()); 1.162 + result_oop = sys_array; 1.163 + throw_exception = Handle(); // be tidy 1.164 + } 1.165 + Handle result_handle(THREAD, result_oop); 1.166 result_oop = NULL; // safety 1.167 ObjectLocker ol(this_oop, THREAD); 1.168 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); 1.169 - oop result_oop2 = cpc_entry->f1(); 1.170 - if (result_oop2 != NULL) { 1.171 - // Race condition: May already be filled in while we were trying to lock. 1.172 - return result_oop2; 1.173 + result_oop = cpc_entry->f1(); 1.174 + // Benign race condition: f1 may already be filled in while we were trying to lock. 1.175 + // The important thing here is that all threads pick up the same result. 1.176 + // It doesn't matter which racing thread wins, as long as only one 1.177 + // result is used by all threads, and all future queries. 1.178 + // That result may be either a resolved constant or a failure exception. 1.179 + if (result_oop == NULL) { 1.180 + result_oop = result_handle(); 1.181 + cpc_entry->set_f1(result_oop); 1.182 } 1.183 - cpc_entry->set_f1(result()); 1.184 - return result(); 1.185 + return decode_exception_from_f1(result_oop, THREAD); 1.186 } else { 1.187 + if (throw_exception.not_null()) { 1.188 + THROW_HANDLE_(throw_exception, NULL); 1.189 + } 1.190 return result_oop; 1.191 } 1.192 } 1.193 @@ -620,6 +703,7 @@ 1.194 1.195 void constantPoolOopDesc::shared_tags_iterate(OopClosure* closure) { 1.196 closure->do_oop(tags_addr()); 1.197 + closure->do_oop(operands_addr()); 1.198 } 1.199 1.200 1.201 @@ -837,13 +921,19 @@ 1.202 1.203 case JVM_CONSTANT_InvokeDynamic: 1.204 { 1.205 - int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1); 1.206 - int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2); 1.207 - if (k1 == k2) { 1.208 - int i1 = invoke_dynamic_name_and_type_ref_index_at(index1); 1.209 - int i2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); 1.210 - if (i1 == i2) { 1.211 - return true; 1.212 + int op_count = multi_operand_count_at(index1); 1.213 + if (op_count == cp2->multi_operand_count_at(index2)) { 1.214 + bool all_equal = true; 1.215 + for (int op_i = 0; op_i < op_count; op_i++) { 1.216 + int k1 = multi_operand_ref_at(index1, op_i); 1.217 + int k2 = cp2->multi_operand_ref_at(index2, op_i); 1.218 + if (k1 != k2) { 1.219 + all_equal = false; 1.220 + break; 1.221 + } 1.222 + } 1.223 + if (all_equal) { 1.224 + return true; // got through loop; all elements equal 1.225 } 1.226 } 1.227 } break; 1.228 @@ -880,6 +970,25 @@ 1.229 } // end compare_entry_to() 1.230 1.231 1.232 +// Grow this->operands() to the indicated length, unless it is already at least that long. 1.233 +void constantPoolOopDesc::multi_operand_buffer_grow(int min_length, TRAPS) { 1.234 + int old_length = multi_operand_buffer_fill_pointer(); 1.235 + if (old_length >= min_length) return; 1.236 + int new_length = min_length; 1.237 + assert(new_length > _multi_operand_buffer_fill_pointer_offset, ""); 1.238 + typeArrayHandle new_operands = oopFactory::new_permanent_intArray(new_length, CHECK); 1.239 + if (operands() == NULL) { 1.240 + new_operands->int_at_put(_multi_operand_buffer_fill_pointer_offset, old_length); 1.241 + } else { 1.242 + // copy fill pointer and everything else 1.243 + for (int i = 0; i < old_length; i++) { 1.244 + new_operands->int_at_put(i, operands()->int_at(i)); 1.245 + } 1.246 + } 1.247 + set_operands(new_operands()); 1.248 +} 1.249 + 1.250 + 1.251 // Copy this constant pool's entries at start_i to end_i (inclusive) 1.252 // to the constant pool to_cp's entries starting at to_i. A total of 1.253 // (end_i - start_i) + 1 entries are copied. 1.254 @@ -888,6 +997,13 @@ 1.255 1.256 int dest_i = to_i; // leave original alone for debug purposes 1.257 1.258 + if (operands() != NULL) { 1.259 + // pre-grow the target CP's operand buffer 1.260 + int nops = this->multi_operand_buffer_fill_pointer(); 1.261 + nops += to_cp->multi_operand_buffer_fill_pointer(); 1.262 + to_cp->multi_operand_buffer_grow(nops, CHECK); 1.263 + } 1.264 + 1.265 for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) { 1.266 copy_entry_to(src_i, to_cp, dest_i, CHECK); 1.267 1.268 @@ -1036,9 +1152,26 @@ 1.269 1.270 case JVM_CONSTANT_InvokeDynamic: 1.271 { 1.272 + int op_count = multi_operand_count_at(from_i); 1.273 + int fillp = to_cp->multi_operand_buffer_fill_pointer(); 1.274 + int to_op_base = fillp - _multi_operand_count_offset; // fillp is count offset; get to base 1.275 + to_cp->multi_operand_buffer_grow(to_op_base + op_count, CHECK); 1.276 + to_cp->operands()->int_at_put(fillp++, op_count); 1.277 + assert(fillp == to_op_base + _multi_operand_base_offset, "just wrote count, will now write args"); 1.278 + for (int op_i = 0; op_i < op_count; op_i++) { 1.279 + int op = multi_operand_ref_at(from_i, op_i); 1.280 + to_cp->operands()->int_at_put(fillp++, op); 1.281 + } 1.282 + assert(fillp <= to_cp->operands()->length(), "oob"); 1.283 + to_cp->set_multi_operand_buffer_fill_pointer(fillp); 1.284 + to_cp->invoke_dynamic_at_put(to_i, to_op_base, op_count); 1.285 +#ifdef ASSERT 1.286 int k1 = invoke_dynamic_bootstrap_method_ref_index_at(from_i); 1.287 int k2 = invoke_dynamic_name_and_type_ref_index_at(from_i); 1.288 - to_cp->invoke_dynamic_at_put(to_i, k1, k2); 1.289 + int k3 = invoke_dynamic_argument_count_at(from_i); 1.290 + assert(to_cp->check_invoke_dynamic_at(to_i, k1, k2, k3), 1.291 + "indy structure is OK"); 1.292 +#endif //ASSERT 1.293 } break; 1.294 1.295 // Invalid is used as the tag for the second constant pool entry 1.296 @@ -1256,8 +1389,11 @@ 1.297 case JVM_CONSTANT_Methodref: 1.298 case JVM_CONSTANT_InterfaceMethodref: 1.299 case JVM_CONSTANT_NameAndType: 1.300 + return 5; 1.301 + 1.302 case JVM_CONSTANT_InvokeDynamic: 1.303 - return 5; 1.304 + // u1 tag, u2 bsm, u2 nt, u2 argc, u2 argv[argc] 1.305 + return 7 + 2 * invoke_dynamic_argument_count_at(idx); 1.306 1.307 case JVM_CONSTANT_Long: 1.308 case JVM_CONSTANT_Double: 1.309 @@ -1474,9 +1610,15 @@ 1.310 *bytes = JVM_CONSTANT_InvokeDynamic; 1.311 idx1 = invoke_dynamic_bootstrap_method_ref_index_at(idx); 1.312 idx2 = invoke_dynamic_name_and_type_ref_index_at(idx); 1.313 + int argc = invoke_dynamic_argument_count_at(idx); 1.314 Bytes::put_Java_u2((address) (bytes+1), idx1); 1.315 Bytes::put_Java_u2((address) (bytes+3), idx2); 1.316 - DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2)); 1.317 + Bytes::put_Java_u2((address) (bytes+5), argc); 1.318 + for (int arg_i = 0; arg_i < argc; arg_i++) { 1.319 + int arg = invoke_dynamic_argument_index_at(idx, arg_i); 1.320 + Bytes::put_Java_u2((address) (bytes+7+2*arg_i), arg); 1.321 + } 1.322 + DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd [%d]", idx1, idx2, argc)); 1.323 break; 1.324 } 1.325 }