< prev index next >
src/hotspot/share/prims/jvm.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
*** 43,52 ****
--- 43,53 ----
#include "memory/oopFactory.hpp"
#include "memory/referenceType.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/access.inline.hpp"
+ #include "oops/constantPool.inline.hpp"
#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/method.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
*** 1998,2054 ****
// Return null for primitives and arrays
if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
if (k->is_instance_klass()) {
InstanceKlass* k_h = InstanceKlass::cast(k);
! Handle jcp = reflect_ConstantPool::create(CHECK_NULL);
! reflect_ConstantPool::set_cp(jcp(), k_h->constants());
! return JNIHandles::make_local(jcp());
}
}
return NULL;
}
JVM_END
! JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject obj, jobject unused))
{
! JVMWrapper("JVM_ConstantPoolGetSize");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! return cp->length();
}
JVM_END
! JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
! JVMWrapper("JVM_ConstantPoolGetClassAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_NULL);
! constantTag tag = cp->tag_at(index);
! if (!tag.is_klass() && !tag.is_unresolved_klass()) {
! THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
! }
! Klass* k = cp->klass_at(index, CHECK_NULL);
! return (jclass) JNIHandles::make_local(k->java_mirror());
}
JVM_END
! JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
! {
! JVMWrapper("JVM_ConstantPoolGetClassAtIfLoaded");
! constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_NULL);
! constantTag tag = cp->tag_at(index);
! if (!tag.is_klass() && !tag.is_unresolved_klass()) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
}
! Klass* k = ConstantPool::klass_at_if_loaded(cp, index);
! if (k == NULL) return NULL;
! return (jclass) JNIHandles::make_local(k->java_mirror());
}
! JVM_END
static jobject get_method_at_helper(const constantPoolHandle& cp, jint index, bool force_resolution, TRAPS) {
constantTag tag = cp->tag_at(index);
if (!tag.is_method() && !tag.is_interface_method()) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
--- 1999,2204 ----
// Return null for primitives and arrays
if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
if (k->is_instance_klass()) {
InstanceKlass* k_h = InstanceKlass::cast(k);
! Handle jcp = reflect_ConstantPool::create_from_pool(k_h->constants(), CHECK_NULL);
! return JNIHandles::make_local(THREAD, jcp());
}
}
return NULL;
}
JVM_END
! // The name "ConstantPool1" means the successor to the original JVM_ConstantPool* API.
! // That API had a confusing pair of arguments to specify the constant pool.
! // This API has a single normal 'this' argument.
!
! JVM_ENTRY(jclass, JVM_ConstantPool1GetHolder(JNIEnv *env, jobject obj))
{
! JVMWrapper("JVM_ConstantPoolGetHolder");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! return (jclass) JNIHandles::make_local(THREAD, cp->pool_holder()->java_mirror());
}
JVM_END
! JVM_ENTRY(jint, JVM_ConstantPool1GetSize(JNIEnv *env, jobject obj))
{
! JVMWrapper("JVM_ConstantPoolGetSize");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! return cp->length();
}
JVM_END
!
! static jint ref_word_count_at_helper(constantPoolHandle cp, jint index) {
! if (!cp->is_within_bounds(index)) return 0;
! switch (cp->tag_at(index).classfile_value()) {
! case JVM_CONSTANT_Utf8:
! case JVM_CONSTANT_Class:
! case JVM_CONSTANT_String:
! case JVM_CONSTANT_MethodType:
! return 1;
!
! case JVM_CONSTANT_Fieldref:
! case JVM_CONSTANT_Methodref:
! case JVM_CONSTANT_InterfaceMethodref:
! return 5; // { klass, nat, klass_sym, name_sym, type_sym }
!
! case JVM_CONSTANT_NameAndType:
! return 2; // { name_sym, type_sym }
!
! case JVM_CONSTANT_MethodHandle:
! return 2; // { ref_kind, ref_index }
!
! case JVM_CONSTANT_InvokeDynamic:
! case JVM_CONSTANT_Dynamic:
! int word_count = 6; // { bsms_attr, nat, bsm, name_sym, type_sym, argc, arg* }
! word_count += cp->bootstrap_argument_count_at(index); // arg*
! return word_count;
! }
!
! return 0;
! }
!
! static void word_bounds_check(const constantPoolHandle& cp, jint index, jint word, jint word_count, TRAPS) {
! assert(word_count == ref_word_count_at_helper(cp, index), "");
! if (word < 0 || word >= word_count) {
! THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool field request out of bounds");
! }
! }
!
! static jint get_ref_index_at_helper(constantPoolHandle cp, jint index, jint word,
! jint* non_ref_word, TRAPS) {
! int ref_index = -1;
! int word_limit = 1;
! switch (cp->tag_at(index).classfile_value()) {
! case JVM_CONSTANT_Utf8:
! // A Utf8 string is its own reference index, but return zero
! // If you ask for the string itself, you'll see that string.
! ref_index = 0;
! break;
! case JVM_CONSTANT_Class:
! // Unwrap the Class and return the underlying name
! ref_index = cp->klass_name_index_at(index);
! break;
! case JVM_CONSTANT_String:
! // The CP does not record Utf8 indexes for strings, so just return zero.
! ref_index = 0;
! break;
!
! case JVM_CONSTANT_Fieldref:
! case JVM_CONSTANT_Methodref:
! case JVM_CONSTANT_InterfaceMethodref:
! {
! // Unwrap the field or method to reveal three Utf8 strings.
! word_limit = 5;
! int klass_ref = cp->uncached_klass_ref_index_at(index);
! int nat_ref = cp->uncached_name_and_type_ref_index_at(index);
! switch (word) {
! case 0: return klass_ref;
! case 1: return nat_ref;
! // Flatten out the structure to reveal Utf8 references.
! case 2: return cp->klass_name_index_at(klass_ref);
! case 3: return cp->name_ref_index_at(nat_ref);
! case 4: return cp->signature_ref_index_at(nat_ref);
! }
! }
! ref_index = 0; // trigger the correct error
! break;
!
! case JVM_CONSTANT_NameAndType:
! // Unwrap the NameAndType to reveal two Utf8 strings.
! {
! word_limit = 2;
! ref_index = (word == 0
! ? cp->name_ref_index_at(index)
! : cp->signature_ref_index_at(index));
! }
! break;
!
! case JVM_CONSTANT_MethodType:
! // Unwrap the MethodType and return the underlying descriptor.
! ref_index = cp->method_type_index_at(index);
! break;
!
! case JVM_CONSTANT_MethodHandle:
! // Unwrap the MH and return the member kind.
! if (word == 0) {
! int ref_kind = cp->method_handle_ref_kind_at(index);
! assert(ref_kind > 0 && ref_kind <= JVM_REF_invokeInterface, "");
! (*non_ref_word) = ref_kind;
! return 0;
! }
! ref_index = cp->method_handle_index_at(index);
! word_limit = 2;
! break;
!
! case JVM_CONSTANT_InvokeDynamic:
! case JVM_CONSTANT_Dynamic:
! // Unwrap { bsms_attr, nat, bsm, name_sym, type_sym, argc, arg* }
! switch (word) {
! case 0: (*non_ref_word) = cp->bootstrap_methods_attribute_index(index); return 0;
! case 1: return cp->bootstrap_name_and_type_ref_index_at(index);
! case 2: return cp->bootstrap_method_ref_index_at(index);
! case 3: return cp->name_ref_index_at(cp->bootstrap_name_and_type_ref_index_at(index));
! case 4: return cp->signature_ref_index_at(cp->bootstrap_name_and_type_ref_index_at(index));
! case 5: (*non_ref_word) = cp->bootstrap_argument_count_at(index); return 0;
! }
! word_limit = 6 + cp->bootstrap_argument_count_at(index);
! if (word >= 0 && word < word_limit) {
! return cp->bootstrap_argument_index_at(index, word - 6);
! }
! ref_index = 0; // trigger the correct error
! break;
! }
!
! // Perform final checks and return result.
! if (ref_index == -1) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
}
! word_bounds_check(cp, index, word, word_limit, CHECK_0);
! return ref_index;
! }
!
! static jint get_word_at_helper(constantPoolHandle cp, jint index, jint word, TRAPS) {
! jint non_ref_word = 0;
! jint ref_index = get_ref_index_at_helper(cp, index, word, &non_ref_word, CHECK_0);
! return (ref_index != 0) ? ref_index : non_ref_word;
}
!
! static jstring get_utf8_at_helper(constantPoolHandle cp, jint index, jint word, TRAPS) {
! Symbol* sym = NULL;
! if (cp->tag_at(index).is_symbol() && word == 0) {
! // Just report the Utf8 string that's here.
! sym = cp->symbol_at(index);
! } else if (cp->tag_at(index).is_string() && word == 0) {
! // Report the String, as a resolved value if possible.
! if (cp->resolved_references_or_null() != NULL
! && cp->cp_to_object_index(index) >= 0) {
! oop str = cp->resolved_string_at(index);
! if (java_lang_String::is_instance(str)) {
! // In this one case, return the actual interned string.
! return (jstring) JNIHandles::make_local(THREAD, str);
! }
! }
! sym = cp->unresolved_string_at(index);
! } else {
! jint ignore_non_ref_word = 0;
! jint ref_index = get_ref_index_at_helper(cp, index, word, &ignore_non_ref_word, CHECK_NULL);
! if (ref_index != 0 && !cp->tag_at(ref_index).is_symbol()) {
! return NULL; // there is a word here, but it is not a Utf8 index
! }
! sym = cp->symbol_at(ref_index);
! }
! // Build a java.lang.String to hold the Utf8 spelling.
! Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
! return (jstring) JNIHandles::make_local(THREAD, str());
! }
!
static jobject get_method_at_helper(const constantPoolHandle& cp, jint index, bool force_resolution, TRAPS) {
constantTag tag = cp->tag_at(index);
if (!tag.is_method() && !tag.is_interface_method()) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
*** 2072,2106 ****
if (!m->is_initializer() || m->is_static()) {
method = Reflection::new_method(m, true, CHECK_NULL);
} else {
method = Reflection::new_constructor(m, CHECK_NULL);
}
! return JNIHandles::make_local(method);
}
- JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject obj, jobject unused, jint index))
- {
- JVMWrapper("JVM_ConstantPoolGetMethodAt");
- JvmtiVMObjectAllocEventCollector oam;
- constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
- bounds_check(cp, index, CHECK_NULL);
- jobject res = get_method_at_helper(cp, index, true, CHECK_NULL);
- return res;
- }
- JVM_END
-
- JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
- {
- JVMWrapper("JVM_ConstantPoolGetMethodAtIfLoaded");
- JvmtiVMObjectAllocEventCollector oam;
- constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
- bounds_check(cp, index, CHECK_NULL);
- jobject res = get_method_at_helper(cp, index, false, CHECK_NULL);
- return res;
- }
- JVM_END
-
static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) {
constantTag tag = cp->tag_at(index);
if (!tag.is_field()) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
}
--- 2222,2234 ----
if (!m->is_initializer() || m->is_static()) {
method = Reflection::new_method(m, true, CHECK_NULL);
} else {
method = Reflection::new_constructor(m, CHECK_NULL);
}
! return JNIHandles::make_local(THREAD, method);
}
static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) {
constantTag tag = cp->tag_at(index);
if (!tag.is_field()) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
}
*** 2119,2230 ****
Klass* target_klass = k->find_field(name, sig, &fd);
if (target_klass == NULL) {
THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class");
}
oop field = Reflection::new_field(&fd, CHECK_NULL);
! return JNIHandles::make_local(field);
}
! JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject obj, jobject unusedl, jint index))
! {
! JVMWrapper("JVM_ConstantPoolGetFieldAt");
! JvmtiVMObjectAllocEventCollector oam;
! constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_NULL);
! jobject res = get_field_at_helper(cp, index, true, CHECK_NULL);
! return res;
}
- JVM_END
! JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
! {
! JVMWrapper("JVM_ConstantPoolGetFieldAtIfLoaded");
! JvmtiVMObjectAllocEventCollector oam;
! constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_NULL);
! jobject res = get_field_at_helper(cp, index, false, CHECK_NULL);
! return res;
}
- JVM_END
! JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
- JVMWrapper("JVM_ConstantPoolGetMemberRefInfoAt");
- JvmtiVMObjectAllocEventCollector oam;
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_NULL);
! constantTag tag = cp->tag_at(index);
! if (!tag.is_field_or_method()) {
! THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
! }
! int klass_ref = cp->uncached_klass_ref_index_at(index);
! Symbol* klass_name = cp->klass_name_at(klass_ref);
! Symbol* member_name = cp->uncached_name_ref_at(index);
! Symbol* member_sig = cp->uncached_signature_ref_at(index);
! objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::String_klass(), 3, CHECK_NULL);
! objArrayHandle dest(THREAD, dest_o);
! Handle str = java_lang_String::create_from_symbol(klass_name, CHECK_NULL);
! dest->obj_at_put(0, str());
! str = java_lang_String::create_from_symbol(member_name, CHECK_NULL);
! dest->obj_at_put(1, str());
! str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL);
! dest->obj_at_put(2, str());
! return (jobjectArray) JNIHandles::make_local(dest());
}
JVM_END
! JVM_ENTRY(jint, JVM_ConstantPoolGetClassRefIndexAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
! JVMWrapper("JVM_ConstantPoolGetClassRefIndexAt");
! JvmtiVMObjectAllocEventCollector oam;
! constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_0);
! constantTag tag = cp->tag_at(index);
! if (!tag.is_field_or_method()) {
! THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
! }
! return (jint) cp->uncached_klass_ref_index_at(index);
}
JVM_END
! JVM_ENTRY(jint, JVM_ConstantPoolGetNameAndTypeRefIndexAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
! JVMWrapper("JVM_ConstantPoolGetNameAndTypeRefIndexAt");
JvmtiVMObjectAllocEventCollector oam;
! constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_0);
! constantTag tag = cp->tag_at(index);
! if (!tag.is_invoke_dynamic() && !tag.is_field_or_method()) {
! THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
}
! return (jint) cp->uncached_name_and_type_ref_index_at(index);
}
JVM_END
! JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetNameAndTypeRefInfoAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
! JVMWrapper("JVM_ConstantPoolGetNameAndTypeRefInfoAt");
JvmtiVMObjectAllocEventCollector oam;
! constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_NULL);
! constantTag tag = cp->tag_at(index);
! if (!tag.is_name_and_type()) {
! THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
}
- Symbol* member_name = cp->symbol_at(cp->name_ref_index_at(index));
- Symbol* member_sig = cp->symbol_at(cp->signature_ref_index_at(index));
- objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::String_klass(), 2, CHECK_NULL);
- objArrayHandle dest(THREAD, dest_o);
- Handle str = java_lang_String::create_from_symbol(member_name, CHECK_NULL);
- dest->obj_at_put(0, str());
- str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL);
- dest->obj_at_put(1, str());
- return (jobjectArray) JNIHandles::make_local(dest());
}
JVM_END
! JVM_ENTRY(jint, JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
JVMWrapper("JVM_ConstantPoolGetIntAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_0);
constantTag tag = cp->tag_at(index);
--- 2247,2450 ----
Klass* target_klass = k->find_field(name, sig, &fd);
if (target_klass == NULL) {
THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class");
}
oop field = Reflection::new_field(&fd, CHECK_NULL);
! return JNIHandles::make_local(THREAD, field);
}
! // when get_ref is pointed at word#0 we just fetch the value:
! static jobject get_value_at_helper(constantPoolHandle cp, jint index,
! bool force_resolution, jobject if_not_present,
! TRAPS) {
! constantTag tag = cp->tag_at(index);
! jobject result = NULL;
! switch (tag.classfile_value()) {
! case JVM_CONSTANT_Utf8:
! case JVM_CONSTANT_String:
! return get_utf8_at_helper(cp, index, 0, CHECK_NULL);
!
! case JVM_CONSTANT_Class:
! {
! if (!tag.is_klass() && !tag.is_unresolved_klass()) break;
! Klass* k = NULL;
! if (force_resolution) {
! k = cp->klass_at(index, CHECK_NULL);
! } else {
! k = ConstantPool::klass_at_if_loaded(cp, index);
! if (k == NULL) return if_not_present;
! }
! assert(k != NULL, "");
! return JNIHandles::make_local(THREAD, k->java_mirror());
! }
!
! case JVM_CONSTANT_Integer:
! case JVM_CONSTANT_Long:
! case JVM_CONSTANT_Float:
! case JVM_CONSTANT_Double:
! case JVM_CONSTANT_MethodType:
! case JVM_CONSTANT_MethodHandle:
! case JVM_CONSTANT_Dynamic:
! //case JVM_CONSTANT_InvokeDynamic:
! {
! oop ref_oop = NULL;
! if (force_resolution) {
! ref_oop = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
! } else {
! bool found_it = false;
! ref_oop = cp->find_cached_constant_at(index, found_it, CHECK_NULL);
! if (!found_it) return if_not_present;
! }
! return JNIHandles::make_local(THREAD, ref_oop);
! }
!
! case JVM_CONSTANT_Methodref:
! case JVM_CONSTANT_InterfaceMethodref:
! result = get_method_at_helper(cp, index, force_resolution, CHECK_NULL);
! if (result == NULL) result = if_not_present;
! return result;
!
! case JVM_CONSTANT_Fieldref:
! result = get_field_at_helper(cp, index, force_resolution, CHECK_NULL);
! if (result == NULL) result = if_not_present;
! return result;
!
! case JVM_CONSTANT_NameAndType:
! // This one is lame. Just make up a 2-array of the component strings.
! {
! objArrayOop result_oop = oopFactory::new_objArray(SystemDictionary::String_klass(), 2, CHECK_NULL);
! objArrayHandle result(THREAD, result_oop);
! for (int word = 0; word < 2; word++) {
! int ignore_non_ref_word = 0;
! jobject ref = get_utf8_at_helper(cp, index, word, CHECK_NULL);
! result->obj_at_put(word, JNIHandles::resolve(ref));
! }
! return JNIHandles::make_local(THREAD, result());
! }
! }
!
! return NULL;
}
!
! // Extract an underlying reference object (or Utf8 string) for a CP entry
! // of type Class, Fieldref, [Interface]Methodref, [Invoke]Dynamic, etc.
! // If word is -1, extract the value of the CP entry itself.
! static jobject get_ref_at_helper(const constantPoolHandle& cp, jint index, jint word,
! bool force_resolution, jobject if_not_present,
! TRAPS) {
! if (word != -1) {
! jint non_ref_word = 0;
! jint ref_index = get_ref_index_at_helper(cp, index, word, &non_ref_word, CHECK_NULL);
! if (ref_index == 0) return NULL;
! index = ref_index; // and fall through:
! }
! return get_value_at_helper(cp, index, force_resolution, if_not_present, THREAD);
}
! JVM_ENTRY(jint, JVM_ConstantPool1GetWordCountAt(JNIEnv *env, jobject obj, jint index))
{
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_0);
! return ref_word_count_at_helper(cp, index);
}
JVM_END
! JVM_ENTRY(jint, JVM_ConstantPool1GetWordAt(JNIEnv *env, jobject obj, jint index, jint word))
{
! JVMWrapper("JVM_ConstantPoolGetWordAt");
! constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_0);
! return get_word_at_helper(cp, index, word, CHECK_0);
}
JVM_END
! JVM_ENTRY(jobject, JVM_ConstantPool1GetRefAt(JNIEnv *env, jobject obj, jint index, jint word,
! jbyte resolving, jobject if_not_present))
{
! JVMWrapper("JVM_ConstantPoolGetRefAt");
JvmtiVMObjectAllocEventCollector oam;
! constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_NULL);
! switch (resolving) {
! case ConstantPool::R_SYMREF:
! // Caller must handle symbolic refs other than Utf8.
! return get_utf8_at_helper(cp, index, word, THREAD);
! case ConstantPool::R_FORCE:
! return get_ref_at_helper(cp, index, word, true, NULL, THREAD);
! case ConstantPool::R_IFPRESENT:
! return get_ref_at_helper(cp, index, word, false, if_not_present, THREAD);
}
! THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "resolving mode must be 0, 1, or 2");
! return NULL;
}
JVM_END
!
! JVM_ENTRY(void, JVM_ConstantPool1CopyOutRefsAt(JNIEnv *env, jobject obj, jint index, jint start_word, jint end_word,
! jobject buf_jobject, jint buf_pos, jbyte resolving,
! jobject if_not_present, jobject if_null_constant, jboolean skip_non_null))
{
! JVMWrapper("JVM_ConstantPoolCopyOutRefsAt");
JvmtiVMObjectAllocEventCollector oam;
! constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK);
! objArrayHandle obj_buf; // set to buf if type Object[]
! typeArrayHandle int_buf; // set to buf if type int[]
! bool force_resolution = (resolving == ConstantPool::R_FORCE);
! jint buf_len = 0;
! if (buf_jobject != NULL) {
! oop buf = JNIHandles::resolve_non_null(buf_jobject);
! switch (resolving) {
! case ConstantPool::R_IFPRESENT: // mode = do not resolve new values
! case ConstantPool::R_FORCE: // mode = resolve any requested values (cf. skip_non_null)
! if (buf->klass() == Universe::objectArrayKlassObj())
! obj_buf = objArrayHandle(THREAD, (objArrayOop) buf);
! break;
! case ConstantPool::R_SYMREF: // mode = return only CP indexes (symbolic refs)
! if (buf->klass() == Universe::intArrayKlassObj())
! int_buf = typeArrayHandle(THREAD, (typeArrayOop) buf);
! break;
! default:
! THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "resolving mode must be 0, 1, or 2");
! }
! if (obj_buf.not_null())
! buf_len = obj_buf->length();
! else if (int_buf.not_null())
! buf_len = int_buf->length();
! }
! jint word_limit = ref_word_count_at_helper(cp, index);
! jint word_count = (end_word - start_word);
! if ((obj_buf.is_null() && int_buf.is_null()) ||
! 0 > start_word || start_word > end_word || end_word > word_limit ||
! 0 > buf_pos || buf_pos + word_count > buf_len) {
! THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "bad buffer index");
! }
! if (int_buf.not_null()) {
! for (int word = start_word; word < end_word; word++) {
! int result = get_word_at_helper(cp, index, word, CHECK);
! int_buf->int_at_put(buf_pos++, result);
! }
! } else {
! for (int word = start_word; word < end_word; word++) {
! if (skip_non_null && obj_buf->obj_at(buf_pos) != NULL) {
! ++buf_pos; continue;
! }
! jobject sentinel = obj; // safely unique: pool doesn't contain itself
! jobject result = get_ref_at_helper(cp, index, word, force_resolution, sentinel, CHECK);
! if (result == sentinel)
! result = if_not_present;
! else if (result == NULL) // note that if_not_present might also be NULL
! result = if_null_constant;
! obj_buf->obj_at_put(buf_pos++, JNIHandles::resolve(result));
! }
}
}
JVM_END
!
! JVM_ENTRY(jint, JVM_ConstantPool1GetIntAt(JNIEnv *env, jobject obj, jint index))
{
JVMWrapper("JVM_ConstantPoolGetIntAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_0);
constantTag tag = cp->tag_at(index);
*** 2233,2243 ****
}
return cp->int_at(index);
}
JVM_END
! JVM_ENTRY(jlong, JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
JVMWrapper("JVM_ConstantPoolGetLongAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_(0L));
constantTag tag = cp->tag_at(index);
--- 2453,2463 ----
}
return cp->int_at(index);
}
JVM_END
! JVM_ENTRY(jlong, JVM_ConstantPool1GetLongAt(JNIEnv *env, jobject obj, jint index))
{
JVMWrapper("JVM_ConstantPoolGetLongAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_(0L));
constantTag tag = cp->tag_at(index);
*** 2246,2256 ****
}
return cp->long_at(index);
}
JVM_END
! JVM_ENTRY(jfloat, JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
JVMWrapper("JVM_ConstantPoolGetFloatAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_(0.0f));
constantTag tag = cp->tag_at(index);
--- 2466,2476 ----
}
return cp->long_at(index);
}
JVM_END
! JVM_ENTRY(jfloat, JVM_ConstantPool1GetFloatAt(JNIEnv *env, jobject obj, jint index))
{
JVMWrapper("JVM_ConstantPoolGetFloatAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_(0.0f));
constantTag tag = cp->tag_at(index);
*** 2259,2269 ****
}
return cp->float_at(index);
}
JVM_END
! JVM_ENTRY(jdouble, JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
JVMWrapper("JVM_ConstantPoolGetDoubleAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_(0.0));
constantTag tag = cp->tag_at(index);
--- 2479,2489 ----
}
return cp->float_at(index);
}
JVM_END
! JVM_ENTRY(jdouble, JVM_ConstantPool1GetDoubleAt(JNIEnv *env, jobject obj, jint index))
{
JVMWrapper("JVM_ConstantPoolGetDoubleAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
bounds_check(cp, index, CHECK_(0.0));
constantTag tag = cp->tag_at(index);
*** 2272,2336 ****
}
return cp->double_at(index);
}
JVM_END
! JVM_ENTRY(jstring, JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
! JVMWrapper("JVM_ConstantPoolGetStringAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_NULL);
constantTag tag = cp->tag_at(index);
! if (!tag.is_string()) {
! THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
! }
! oop str = cp->string_at(index, CHECK_NULL);
! return (jstring) JNIHandles::make_local(str);
}
JVM_END
- JVM_ENTRY(jstring, JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject obj, jobject unused, jint index))
- {
- JVMWrapper("JVM_ConstantPoolGetUTF8At");
- JvmtiVMObjectAllocEventCollector oam;
- constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
- bounds_check(cp, index, CHECK_NULL);
- constantTag tag = cp->tag_at(index);
- if (!tag.is_symbol()) {
- THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
- }
- Symbol* sym = cp->symbol_at(index);
- Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
- return (jstring) JNIHandles::make_local(str());
- }
- JVM_END
! JVM_ENTRY(jbyte, JVM_ConstantPoolGetTagAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
! JVMWrapper("JVM_ConstantPoolGetTagAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_0);
! constantTag tag = cp->tag_at(index);
! jbyte result = tag.value();
! // If returned tag values are not from the JVM spec, e.g. tags from 100 to 105,
! // they are changed to the corresponding tags from the JVM spec, so that java code in
! // sun.reflect.ConstantPool will return only tags from the JVM spec, not internal ones.
! if (tag.is_klass_or_reference()) {
! result = JVM_CONSTANT_Class;
! } else if (tag.is_string_index()) {
! result = JVM_CONSTANT_String;
! } else if (tag.is_method_type_in_error()) {
! result = JVM_CONSTANT_MethodType;
! } else if (tag.is_method_handle_in_error()) {
! result = JVM_CONSTANT_MethodHandle;
! } else if (tag.is_dynamic_constant_in_error()) {
! result = JVM_CONSTANT_Dynamic;
}
! return result;
}
JVM_END
// Assertion support. //////////////////////////////////////////////////////////
JVM_ENTRY(jboolean, JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls))
JVMWrapper("JVM_DesiredAssertionStatus");
assert(cls != NULL, "bad class");
--- 2492,2529 ----
}
return cp->double_at(index);
}
JVM_END
! JVM_ENTRY(jbyte, JVM_ConstantPool1GetTagAt(JNIEnv *env, jobject obj, jint index))
{
! JVMWrapper("JVM_ConstantPoolGetTagAt");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! bounds_check(cp, index, CHECK_0);
constantTag tag = cp->tag_at(index);
! // If returned tag values are not from the JVM spec, e.g. tags from 100 to 105,
! // they are changed to the corresponding tags from the JVM spec, so that java code in
! // sun.reflect.ConstantPool will return only tags from the JVM spec, not internal ones.
! return tag.classfile_value();
}
JVM_END
! JVM_ENTRY(jbyteArray, JVM_ConstantPool1GetTags(JNIEnv *env, jobject obj))
{
! JVMWrapper("JVM_ConstantPoolGetTags");
constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj)));
! jint length = cp->length();
! typeArrayOop result_oop = oopFactory::new_typeArray(T_BYTE, length, CHECK_NULL);
! for (jint index = 0; index < length; index++) {
! result_oop->byte_at_put(index, cp->tag_at(index).classfile_value());
}
! return (jbyteArray) JNIHandles::make_local(THREAD, result_oop);
}
JVM_END
+
// Assertion support. //////////////////////////////////////////////////////////
JVM_ENTRY(jboolean, JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls))
JVMWrapper("JVM_DesiredAssertionStatus");
assert(cls != NULL, "bad class");
< prev index next >