< 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 >