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