< prev index next >

src/hotspot/share/oops/constantPool.cpp

Print this page
rev 52749 : Bootstrap method consolidation
* clean up and simplify JDK support code for BSM invocation
* simplify JVM bootstrap handshake: use BootstrapCallInfo only
* remove unused JVM paths and data fields
* move bootstrap argument processing from MethodHandleNatives to ConstantPool
* remove ConstantGroup; merge argument access into BootstrapCallInfo
* adjust BSM argument access: remove copyArguments, add argumentRef API
* add metadata-free BSM modes, including symbolic arguments from CP

*** 586,610 **** ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index); return e->appendix_if_resolved(cpool); } ! bool ConstantPool::has_method_type_at_if_loaded(const constantPoolHandle& cpool, int which) { if (cpool->cache() == NULL) return false; // nothing to load yet int cache_index = decode_cpcache_index(which, true); ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index); ! return e->has_method_type(); } - oop ConstantPool::method_type_at_if_loaded(const constantPoolHandle& cpool, int which) { - if (cpool->cache() == NULL) return NULL; // nothing to load yet - int cache_index = decode_cpcache_index(which, true); - ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index); - return e->method_type_if_resolved(cpool); - } - - Symbol* ConstantPool::impl_name_ref_at(int which, bool uncached) { int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached)); return symbol_at(name_index); } --- 586,602 ---- ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index); return e->appendix_if_resolved(cpool); } ! bool ConstantPool::has_local_signature_at_if_loaded(const constantPoolHandle& cpool, int which) { if (cpool->cache() == NULL) return false; // nothing to load yet int cache_index = decode_cpcache_index(which, true); ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index); ! return e->has_local_signature(); } Symbol* ConstantPool::impl_name_ref_at(int which, bool uncached) { int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached)); return symbol_at(name_index); }
*** 617,656 **** int ConstantPool::impl_name_and_type_ref_index_at(int which, bool uncached) { int i = which; if (!uncached && cache() != NULL) { if (ConstantPool::is_invokedynamic_index(which)) { // Invokedynamic index is index into the constant pool cache ! int pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index(); ! pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index); assert(tag_at(pool_index).is_name_and_type(), ""); return pool_index; } // change byte-ordering and go via cache i = remap_instruction_operand_from_cache(which); } else { ! if (tag_at(which).is_invoke_dynamic() || ! tag_at(which).is_dynamic_constant() || ! tag_at(which).is_dynamic_constant_in_error()) { ! int pool_index = invoke_dynamic_name_and_type_ref_index_at(which); assert(tag_at(pool_index).is_name_and_type(), ""); return pool_index; } } assert(tag_at(i).is_field_or_method(), "Corrupted constant pool"); ! assert(!tag_at(i).is_invoke_dynamic() && ! !tag_at(i).is_dynamic_constant() && ! !tag_at(i).is_dynamic_constant_in_error(), "Must be handled above"); jint ref_index = *int_at_addr(i); return extract_high_short_from_int(ref_index); } constantTag ConstantPool::impl_tag_ref_at(int which, bool uncached) { int pool_index = which; if (!uncached && cache() != NULL) { if (ConstantPool::is_invokedynamic_index(which)) { // Invokedynamic index is index into resolved_references ! pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index(); } else { // change byte-ordering and go via cache pool_index = remap_instruction_operand_from_cache(which); } } --- 609,644 ---- int ConstantPool::impl_name_and_type_ref_index_at(int which, bool uncached) { int i = which; if (!uncached && cache() != NULL) { if (ConstantPool::is_invokedynamic_index(which)) { // Invokedynamic index is index into the constant pool cache ! int pool_index = invokedynamic_bootstrap_ref_index_at(which); ! pool_index = bootstrap_name_and_type_ref_index_at(pool_index); assert(tag_at(pool_index).is_name_and_type(), ""); return pool_index; } // change byte-ordering and go via cache i = remap_instruction_operand_from_cache(which); } else { ! if (tag_at(which).has_bootstrap()) { ! int pool_index = bootstrap_name_and_type_ref_index_at(which); assert(tag_at(pool_index).is_name_and_type(), ""); return pool_index; } } assert(tag_at(i).is_field_or_method(), "Corrupted constant pool"); ! assert(!tag_at(i).has_bootstrap(), "Must be handled above"); jint ref_index = *int_at_addr(i); return extract_high_short_from_int(ref_index); } constantTag ConstantPool::impl_tag_ref_at(int which, bool uncached) { int pool_index = which; if (!uncached && cache() != NULL) { if (ConstantPool::is_invokedynamic_index(which)) { // Invokedynamic index is index into resolved_references ! pool_index = invokedynamic_bootstrap_ref_index_at(which); } else { // change byte-ordering and go via cache pool_index = remap_instruction_operand_from_cache(which); } }
*** 851,860 **** --- 839,851 ---- // It is possible that this constant is one which is cached in the objects. // We'll do a linear search. This should be OK because this usage is rare. // FIXME: If bootstrap specifiers stress this code, consider putting in // a reverse index. Binary search over a short array should do it. assert(index > 0, "valid index"); + if (this_cp->reference_map() == NULL) + cache_index = _no_index_sentinel; + else cache_index = this_cp->cp_to_object_index(index); } assert(cache_index == _no_index_sentinel || cache_index >= 0, ""); assert(index == _no_index_sentinel || index >= 0, "");
*** 919,961 **** break; } case JVM_CONSTANT_Dynamic: { - Klass* current_klass = this_cp->pool_holder(); - Symbol* constant_name = this_cp->uncached_name_ref_at(index); - Symbol* constant_type = this_cp->uncached_signature_ref_at(index); - // The initial step in resolving an unresolved symbolic reference to a // dynamically-computed constant is to resolve the symbolic reference to a // method handle which will be the bootstrap method for the dynamically-computed // constant. If resolution of the java.lang.invoke.MethodHandle for the bootstrap // method fails, then a MethodHandleInError is stored at the corresponding // bootstrap method's CP index for the CONSTANT_MethodHandle_info. No need to // set a DynamicConstantInError here since any subsequent use of this // bootstrap method will encounter the resolution of MethodHandleInError. ! oop bsm_info = this_cp->resolve_bootstrap_specifier_at(index, THREAD); ! Exceptions::wrap_dynamic_exception(CHECK_NULL); ! assert(bsm_info != NULL, ""); ! // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_Dynamic. ! Handle bootstrap_specifier = Handle(THREAD, bsm_info); // Resolve the Dynamically-Computed constant to invoke the BSM in order to obtain the resulting oop. ! Handle value = SystemDictionary::link_dynamic_constant(current_klass, ! index, ! bootstrap_specifier, ! constant_name, ! constant_type, ! THREAD); ! result_oop = value(); Exceptions::wrap_dynamic_exception(THREAD); if (HAS_PENDING_EXCEPTION) { // Resolution failure of the dynamically-computed constant, save_and_throw_exception // will check for a LinkageError and store a DynamicConstantInError. save_and_throw_exception(this_cp, index, tag, CHECK_NULL); } ! BasicType type = FieldType::basic_type(constant_type); if (!is_reference_type(type)) { // Make sure the primitive value is properly boxed. // This is a JDK responsibility. const char* fail = NULL; if (result_oop == NULL) { --- 910,939 ---- break; } case JVM_CONSTANT_Dynamic: { // The initial step in resolving an unresolved symbolic reference to a // dynamically-computed constant is to resolve the symbolic reference to a // method handle which will be the bootstrap method for the dynamically-computed // constant. If resolution of the java.lang.invoke.MethodHandle for the bootstrap // method fails, then a MethodHandleInError is stored at the corresponding // bootstrap method's CP index for the CONSTANT_MethodHandle_info. No need to // set a DynamicConstantInError here since any subsequent use of this // bootstrap method will encounter the resolution of MethodHandleInError. ! BootstrapInfo bootstrap_specifier(this_cp, index); // Resolve the Dynamically-Computed constant to invoke the BSM in order to obtain the resulting oop. ! SystemDictionary::invoke_bootstrap_method(bootstrap_specifier, THREAD); Exceptions::wrap_dynamic_exception(THREAD); if (HAS_PENDING_EXCEPTION) { // Resolution failure of the dynamically-computed constant, save_and_throw_exception // will check for a LinkageError and store a DynamicConstantInError. save_and_throw_exception(this_cp, index, tag, CHECK_NULL); } ! result_oop = bootstrap_specifier.resolved_value()(); ! BasicType type = FieldType::basic_type(bootstrap_specifier.signature()); if (!is_reference_type(type)) { // Make sure the primitive value is properly boxed. // This is a JDK responsibility. const char* fail = NULL; if (result_oop == NULL) {
*** 1109,1266 **** oop str = StringTable::intern(sym, CHECK_(NULL)); assert(java_lang_String::is_instance(str), "must be string"); return str; } - - oop ConstantPool::resolve_bootstrap_specifier_at_impl(const constantPoolHandle& this_cp, int index, TRAPS) { - assert((this_cp->tag_at(index).is_invoke_dynamic() || - this_cp->tag_at(index).is_dynamic_constant()), "Corrupted constant pool"); - Handle bsm; - int argc; - { - // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&mtype], plus optional arguments - // JVM_CONSTANT_Dynamic is an ordered pair of [bootm, name&ftype], plus optional arguments - // In both cases, the bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry. - // It is accompanied by the optional arguments. - int bsm_index = this_cp->invoke_dynamic_bootstrap_method_ref_index_at(index); - oop bsm_oop = this_cp->resolve_possibly_cached_constant_at(bsm_index, CHECK_NULL); - if (!java_lang_invoke_MethodHandle::is_instance(bsm_oop)) { - THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "BSM not an MethodHandle"); - } - - // Extract the optional static arguments. - argc = this_cp->invoke_dynamic_argument_count_at(index); - - // if there are no static arguments, return the bsm by itself: - if (argc == 0 && UseBootstrapCallInfo < 2) return bsm_oop; - - bsm = Handle(THREAD, bsm_oop); - } - - // We are going to return an ordered pair of {bsm, info}, using a 2-array. - objArrayHandle info; - { - objArrayOop info_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), 2, CHECK_NULL); - info = objArrayHandle(THREAD, info_oop); - } - - info->obj_at_put(0, bsm()); - - bool use_BSCI; - switch (UseBootstrapCallInfo) { - default: use_BSCI = true; break; // stress mode - case 0: use_BSCI = false; break; // stress mode - case 1: // normal mode - // If we were to support an alternative mode of BSM invocation, - // we'd convert to pull mode here if the BSM could be a candidate - // for that alternative mode. We can't easily test for things - // like varargs here, but we can get away with approximate testing, - // since the JDK runtime will make up the difference either way. - // For now, exercise the pull-mode path if the BSM is of arity 2, - // or if there is a potential condy loop (see below). - oop mt_oop = java_lang_invoke_MethodHandle::type(bsm()); - use_BSCI = (java_lang_invoke_MethodType::ptype_count(mt_oop) == 2); - break; - } - - // Here's a reason to use BSCI even if it wasn't requested: - // If a condy uses a condy argument, we want to avoid infinite - // recursion (condy loops) in the C code. It's OK in Java, - // because Java has stack overflow checking, so we punt - // potentially cyclic cases from C to Java. - if (!use_BSCI && this_cp->tag_at(index).is_dynamic_constant()) { - bool found_unresolved_condy = false; - for (int i = 0; i < argc; i++) { - int arg_index = this_cp->invoke_dynamic_argument_index_at(index, i); - if (this_cp->tag_at(arg_index).is_dynamic_constant()) { - // potential recursion point condy -> condy - bool found_it = false; - this_cp->find_cached_constant_at(arg_index, found_it, CHECK_NULL); - if (!found_it) { found_unresolved_condy = true; break; } - } - } - if (found_unresolved_condy) - use_BSCI = true; - } - - const int SMALL_ARITY = 5; - if (use_BSCI && argc <= SMALL_ARITY && UseBootstrapCallInfo <= 2) { - // If there are only a few arguments, and none of them need linking, - // push them, instead of asking the JDK runtime to turn around and - // pull them, saving a JVM/JDK transition in some simple cases. - bool all_resolved = true; - for (int i = 0; i < argc; i++) { - bool found_it = false; - int arg_index = this_cp->invoke_dynamic_argument_index_at(index, i); - this_cp->find_cached_constant_at(arg_index, found_it, CHECK_NULL); - if (!found_it) { all_resolved = false; break; } - } - if (all_resolved) - use_BSCI = false; - } - - if (!use_BSCI) { - // return {bsm, {arg...}}; resolution of arguments is done immediately, before JDK code is called - objArrayOop args_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), argc, CHECK_NULL); - info->obj_at_put(1, args_oop); // may overwrite with args[0] below - objArrayHandle args(THREAD, args_oop); - copy_bootstrap_arguments_at_impl(this_cp, index, 0, argc, args, 0, true, Handle(), CHECK_NULL); - if (argc == 1) { - // try to discard the singleton array - oop arg_oop = args->obj_at(0); - if (arg_oop != NULL && !arg_oop->is_array()) { - // JVM treats arrays and nulls specially in this position, - // but other things are just single arguments - info->obj_at_put(1, arg_oop); - } - } - } else { - // return {bsm, {arg_count, pool_index}}; JDK code must pull the arguments as needed - typeArrayOop ints_oop = oopFactory::new_typeArray(T_INT, 2, CHECK_NULL); - ints_oop->int_at_put(0, argc); - ints_oop->int_at_put(1, index); - info->obj_at_put(1, ints_oop); - } - return info(); - } - void ConstantPool::copy_bootstrap_arguments_at_impl(const constantPoolHandle& this_cp, int index, int start_arg, int end_arg, ! objArrayHandle info, int pos, ! bool must_resolve, Handle if_not_available, TRAPS) { int argc; int limit = pos + end_arg - start_arg; // checks: index in range [0..this_cp->length), // tag at index, start..end in range [0..argc], ! // info array non-null, pos..limit in [0..info.length] if ((0 >= index || index >= this_cp->length()) || ! !(this_cp->tag_at(index).is_invoke_dynamic() || ! this_cp->tag_at(index).is_dynamic_constant()) || (0 > start_arg || start_arg > end_arg) || ! (end_arg > (argc = this_cp->invoke_dynamic_argument_count_at(index))) || (0 > pos || pos > limit) || ! (info.is_null() || limit > info->length())) { // An index or something else went wrong; throw an error. // Since this is an internal API, we don't expect this, // so we don't bother to craft a nice message. THROW_MSG(vmSymbols::java_lang_LinkageError(), "bad BSM argument access"); } // now we can loop safely ! int info_i = pos; for (int i = start_arg; i < end_arg; i++) { ! int arg_index = this_cp->invoke_dynamic_argument_index_at(index, i); ! oop arg_oop; ! if (must_resolve) { arg_oop = this_cp->resolve_possibly_cached_constant_at(arg_index, CHECK); ! } else { ! bool found_it = false; arg_oop = this_cp->find_cached_constant_at(arg_index, found_it, CHECK); ! if (!found_it) arg_oop = if_not_available(); ! } ! info->obj_at_put(info_i++, arg_oop); } } oop ConstantPool::string_at_impl(const constantPoolHandle& this_cp, int which, int obj_index, TRAPS) { // If the string has already been interned, this entry will be non-null --- 1087,1174 ---- oop str = StringTable::intern(sym, CHECK_(NULL)); assert(java_lang_String::is_instance(str), "must be string"); return str; } void ConstantPool::copy_bootstrap_arguments_at_impl(const constantPoolHandle& this_cp, int index, int start_arg, int end_arg, ! arrayHandle buf, int pos, ! BootstrapArgumentReferenceMode resolving, ! Handle if_not_available, ! Handle if_null_constant, ! bool skip_non_null, ! bool skip_recursion, TRAPS) { + objArrayHandle obj_buf; // set to buf if type Object[] + typeArrayHandle int_buf; // set to buf if type int[] + if (buf.not_null()) { + switch (resolving) { + case R_IFPRESENT: // mode = do not resolve new values + case R_FORCE: // mode = resolve any requested values (cf. skip_non_null) + if (buf->klass() == Universe::objectArrayKlassObj()) + obj_buf = objArrayHandle(THREAD, (objArrayOop) buf()); + break; + case R_SYMREF: // mode = return only CP indexes (symbolic refs) + if (buf->klass() == Universe::intArrayKlassObj()) + int_buf = typeArrayHandle(THREAD, (typeArrayOop) buf()); + break; + } + if (obj_buf.is_null() && int_buf.is_null()) + buf = arrayHandle(); // buf matches neither case; nullify + } int argc; int limit = pos + end_arg - start_arg; // checks: index in range [0..this_cp->length), // tag at index, start..end in range [0..argc], ! // buf array non-null, pos..limit in [0..buf.length] if ((0 >= index || index >= this_cp->length()) || ! !this_cp->tag_at(index).has_bootstrap() || (0 > start_arg || start_arg > end_arg) || ! (end_arg > (argc = this_cp->bootstrap_argument_count_at(index))) || (0 > pos || pos > limit) || ! (buf.is_null() || limit > buf->length())) { // An index or something else went wrong; throw an error. // Since this is an internal API, we don't expect this, // so we don't bother to craft a nice message. THROW_MSG(vmSymbols::java_lang_LinkageError(), "bad BSM argument access"); } // now we can loop safely ! int buf_i = pos; for (int i = start_arg; i < end_arg; i++) { ! if (skip_non_null && obj_buf.not_null() && obj_buf->obj_at(buf_i) != NULL) { ! // buf is somebody's cache; don't disturb non-null entries ! buf_i++; ! continue; ! } ! int arg_index = this_cp->bootstrap_argument_index_at(index, i); ! BootstrapArgumentReferenceMode mode = resolving; ! if (mode == R_FORCE && skip_recursion && this_cp->tag_at(arg_index).has_bootstrap()) { ! // don't force recursive execution of BSMs (via condy) ! mode = R_IFPRESENT; // but *do* return a value if it is available ! } ! oop arg_oop = NULL; ! int arg_int = 0; ! bool found_it; ! if (mode == R_FORCE) { arg_oop = this_cp->resolve_possibly_cached_constant_at(arg_index, CHECK); ! found_it = true; ! } else if (mode == R_IFPRESENT) { ! found_it = false; arg_oop = this_cp->find_cached_constant_at(arg_index, found_it, CHECK); ! } else { ! assert(mode == R_SYMREF, ""); ! arg_int = arg_index; ! found_it = true; ! } ! if (!found_it) ! arg_oop = if_not_available(); // might be NULL! ! else if (arg_oop == NULL) ! arg_oop = if_null_constant(); ! if (obj_buf.not_null()) ! obj_buf->obj_at_put(buf_i++, arg_oop); ! else ! int_buf->int_at_put(buf_i++, arg_int); } } oop ConstantPool::string_at_impl(const constantPoolHandle& this_cp, int which, int obj_index, TRAPS) { // If the string has already been interned, this entry will be non-null
*** 1446,1471 **** } } break; case JVM_CONSTANT_Dynamic: { ! int k1 = invoke_dynamic_name_and_type_ref_index_at(index1); ! int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); ! int i1 = invoke_dynamic_bootstrap_specifier_index(index1); ! int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2); // separate statements and variables because CHECK_false is used bool match_entry = compare_entry_to(k1, cp2, k2, CHECK_false); bool match_operand = compare_operand_to(i1, cp2, i2, CHECK_false); return (match_entry && match_operand); } break; case JVM_CONSTANT_InvokeDynamic: { ! int k1 = invoke_dynamic_name_and_type_ref_index_at(index1); ! int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); ! int i1 = invoke_dynamic_bootstrap_specifier_index(index1); ! int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2); // separate statements and variables because CHECK_false is used bool match_entry = compare_entry_to(k1, cp2, k2, CHECK_false); bool match_operand = compare_operand_to(i1, cp2, i2, CHECK_false); return (match_entry && match_operand); } break; --- 1354,1379 ---- } } break; case JVM_CONSTANT_Dynamic: { ! int k1 = bootstrap_name_and_type_ref_index_at(index1); ! int k2 = cp2->bootstrap_name_and_type_ref_index_at(index2); ! int i1 = bootstrap_methods_attribute_index(index1); ! int i2 = cp2->bootstrap_methods_attribute_index(index2); // separate statements and variables because CHECK_false is used bool match_entry = compare_entry_to(k1, cp2, k2, CHECK_false); bool match_operand = compare_operand_to(i1, cp2, i2, CHECK_false); return (match_entry && match_operand); } break; case JVM_CONSTANT_InvokeDynamic: { ! int k1 = bootstrap_name_and_type_ref_index_at(index1); ! int k2 = cp2->bootstrap_name_and_type_ref_index_at(index2); ! int i1 = bootstrap_methods_attribute_index(index1); ! int i2 = cp2->bootstrap_methods_attribute_index(index2); // separate statements and variables because CHECK_false is used bool match_entry = compare_entry_to(k1, cp2, k2, CHECK_false); bool match_operand = compare_operand_to(i1, cp2, i2, CHECK_false); return (match_entry && match_operand); } break;
*** 1785,1804 **** } break; case JVM_CONSTANT_Dynamic: case JVM_CONSTANT_DynamicInError: { ! int k1 = from_cp->invoke_dynamic_bootstrap_specifier_index(from_i); ! int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i); k1 += operand_array_length(to_cp->operands()); // to_cp might already have operands to_cp->dynamic_constant_at_put(to_i, k1, k2); } break; case JVM_CONSTANT_InvokeDynamic: { ! int k1 = from_cp->invoke_dynamic_bootstrap_specifier_index(from_i); ! int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i); k1 += operand_array_length(to_cp->operands()); // to_cp might already have operands to_cp->invoke_dynamic_at_put(to_i, k1, k2); } break; // Invalid is used as the tag for the second constant pool entry --- 1693,1712 ---- } break; case JVM_CONSTANT_Dynamic: case JVM_CONSTANT_DynamicInError: { ! int k1 = from_cp->bootstrap_methods_attribute_index(from_i); ! int k2 = from_cp->bootstrap_name_and_type_ref_index_at(from_i); k1 += operand_array_length(to_cp->operands()); // to_cp might already have operands to_cp->dynamic_constant_at_put(to_i, k1, k2); } break; case JVM_CONSTANT_InvokeDynamic: { ! int k1 = from_cp->bootstrap_methods_attribute_index(from_i); ! int k2 = from_cp->bootstrap_name_and_type_ref_index_at(from_i); k1 += operand_array_length(to_cp->operands()); // to_cp might already have operands to_cp->invoke_dynamic_at_put(to_i, k1, k2); } break; // Invalid is used as the tag for the second constant pool entry
*** 1855,1875 **** } return false; } // end compare_operand_to() // Search constant pool search_cp for a bootstrap specifier that matches ! // this constant pool's bootstrap specifier at pattern_i index. ! // Return the index of a matching bootstrap specifier or (-1) if there is no match. int ConstantPool::find_matching_operand(int pattern_i, const constantPoolHandle& search_cp, int search_len, TRAPS) { for (int i = 0; i < search_len; i++) { bool found = compare_operand_to(pattern_i, search_cp, i, CHECK_(-1)); if (found) { return i; } } ! return -1; // bootstrap specifier not found; return unused index (-1) } // end find_matching_operand() #ifndef PRODUCT --- 1763,1783 ---- } return false; } // end compare_operand_to() // Search constant pool search_cp for a bootstrap specifier that matches ! // this constant pool's bootstrap specifier data at pattern_i index. ! // Return the index of a matching bootstrap attribute record or (-1) if there is no match. int ConstantPool::find_matching_operand(int pattern_i, const constantPoolHandle& search_cp, int search_len, TRAPS) { for (int i = 0; i < search_len; i++) { bool found = compare_operand_to(pattern_i, search_cp, i, CHECK_(-1)); if (found) { return i; } } ! return -1; // bootstrap specifier data not found; return unused index (-1) } // end find_matching_operand() #ifndef PRODUCT
*** 2244,2264 **** case JVM_CONSTANT_Dynamic: case JVM_CONSTANT_DynamicInError: { *bytes = tag; idx1 = extract_low_short_from_int(*int_at_addr(idx)); idx2 = extract_high_short_from_int(*int_at_addr(idx)); ! assert(idx2 == invoke_dynamic_name_and_type_ref_index_at(idx), "correct half of u4"); Bytes::put_Java_u2((address) (bytes+1), idx1); Bytes::put_Java_u2((address) (bytes+3), idx2); DBG(printf("JVM_CONSTANT_Dynamic: %hd %hd", idx1, idx2)); break; } case JVM_CONSTANT_InvokeDynamic: { *bytes = tag; idx1 = extract_low_short_from_int(*int_at_addr(idx)); idx2 = extract_high_short_from_int(*int_at_addr(idx)); ! assert(idx2 == invoke_dynamic_name_and_type_ref_index_at(idx), "correct half of u4"); Bytes::put_Java_u2((address) (bytes+1), idx1); Bytes::put_Java_u2((address) (bytes+3), idx2); DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2)); break; } --- 2152,2172 ---- case JVM_CONSTANT_Dynamic: case JVM_CONSTANT_DynamicInError: { *bytes = tag; idx1 = extract_low_short_from_int(*int_at_addr(idx)); idx2 = extract_high_short_from_int(*int_at_addr(idx)); ! assert(idx2 == bootstrap_name_and_type_ref_index_at(idx), "correct half of u4"); Bytes::put_Java_u2((address) (bytes+1), idx1); Bytes::put_Java_u2((address) (bytes+3), idx2); DBG(printf("JVM_CONSTANT_Dynamic: %hd %hd", idx1, idx2)); break; } case JVM_CONSTANT_InvokeDynamic: { *bytes = tag; idx1 = extract_low_short_from_int(*int_at_addr(idx)); idx2 = extract_high_short_from_int(*int_at_addr(idx)); ! assert(idx2 == bootstrap_name_and_type_ref_index_at(idx), "correct half of u4"); Bytes::put_Java_u2((address) (bytes+1), idx1); Bytes::put_Java_u2((address) (bytes+3), idx2); DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2)); break; }
*** 2458,2487 **** st->print("signature_index=%d", method_type_index_at(index)); break; case JVM_CONSTANT_Dynamic : case JVM_CONSTANT_DynamicInError : { ! st->print("bootstrap_method_index=%d", invoke_dynamic_bootstrap_method_ref_index_at(index)); ! st->print(" type_index=%d", invoke_dynamic_name_and_type_ref_index_at(index)); ! int argc = invoke_dynamic_argument_count_at(index); if (argc > 0) { for (int arg_i = 0; arg_i < argc; arg_i++) { ! int arg = invoke_dynamic_argument_index_at(index, arg_i); st->print((arg_i == 0 ? " arguments={%d" : ", %d"), arg); } st->print("}"); } } break; case JVM_CONSTANT_InvokeDynamic : { ! st->print("bootstrap_method_index=%d", invoke_dynamic_bootstrap_method_ref_index_at(index)); ! st->print(" name_and_type_index=%d", invoke_dynamic_name_and_type_ref_index_at(index)); ! int argc = invoke_dynamic_argument_count_at(index); if (argc > 0) { for (int arg_i = 0; arg_i < argc; arg_i++) { ! int arg = invoke_dynamic_argument_index_at(index, arg_i); st->print((arg_i == 0 ? " arguments={%d" : ", %d"), arg); } st->print("}"); } } --- 2366,2395 ---- st->print("signature_index=%d", method_type_index_at(index)); break; case JVM_CONSTANT_Dynamic : case JVM_CONSTANT_DynamicInError : { ! st->print("bootstrap_method_index=%d", bootstrap_method_ref_index_at(index)); ! st->print(" type_index=%d", bootstrap_name_and_type_ref_index_at(index)); ! int argc = bootstrap_argument_count_at(index); if (argc > 0) { for (int arg_i = 0; arg_i < argc; arg_i++) { ! int arg = bootstrap_argument_index_at(index, arg_i); st->print((arg_i == 0 ? " arguments={%d" : ", %d"), arg); } st->print("}"); } } break; case JVM_CONSTANT_InvokeDynamic : { ! st->print("bootstrap_method_index=%d", bootstrap_method_ref_index_at(index)); ! st->print(" name_and_type_index=%d", bootstrap_name_and_type_ref_index_at(index)); ! int argc = bootstrap_argument_count_at(index); if (argc > 0) { for (int arg_i = 0; arg_i < argc; arg_i++) { ! int arg = bootstrap_argument_index_at(index, arg_i); st->print((arg_i == 0 ? " arguments={%d" : ", %d"), arg); } st->print("}"); } }
< prev index next >