--- old/src/hotspot/share/prims/jvm.cpp 2018-09-28 11:53:43.000000000 -0700 +++ new/src/hotspot/share/prims/jvm.cpp 2018-09-28 11:53:42.000000000 -0700 @@ -45,6 +45,7 @@ #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" @@ -2000,9 +2001,8 @@ 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()); + Handle jcp = reflect_ConstantPool::create_from_pool(k_h->constants(), CHECK_NULL); + return JNIHandles::make_local(THREAD, jcp()); } } return NULL; @@ -2010,43 +2010,193 @@ JVM_END -JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject obj, jobject unused)) +// 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_ConstantPoolGetSize"); + JVMWrapper("JVM_ConstantPoolGetHolder"); constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj))); - return cp->length(); + return (jclass) JNIHandles::make_local(THREAD, cp->pool_holder()->java_mirror()); } JVM_END -JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject unused, jint index)) +JVM_ENTRY(jint, JVM_ConstantPool1GetSize(JNIEnv *env, jobject obj)) { - JVMWrapper("JVM_ConstantPoolGetClassAt"); + JVMWrapper("JVM_ConstantPoolGetSize"); 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()); + return cp->length(); } 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()) { + +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"); } - Klass* k = ConstantPool::klass_at_if_loaded(cp, index); - if (k == NULL) return NULL; - return (jclass) JNIHandles::make_local(k->java_mirror()); + 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; } -JVM_END + +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); @@ -2074,30 +2224,8 @@ } 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; + return JNIHandles::make_local(THREAD, method); } -JVM_END static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force_resolution, TRAPS) { constantTag tag = cp->tag_at(index); @@ -2121,108 +2249,200 @@ 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); + return JNIHandles::make_local(THREAD, 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; +// 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; } -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; + +// 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_END -JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject obj, jobject unused, jint index)) +JVM_ENTRY(jint, JVM_ConstantPool1GetWordCountAt(JNIEnv *env, jobject obj, 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()); + bounds_check(cp, index, CHECK_0); + return ref_word_count_at_helper(cp, index); } JVM_END -JVM_ENTRY(jint, JVM_ConstantPoolGetClassRefIndexAt(JNIEnv *env, jobject obj, jobject unused, jint index)) +JVM_ENTRY(jint, JVM_ConstantPool1GetWordAt(JNIEnv *env, jobject obj, jint index, jint word)) { - JVMWrapper("JVM_ConstantPoolGetClassRefIndexAt"); - JvmtiVMObjectAllocEventCollector oam; - constantPoolHandle cp(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj))); + JVMWrapper("JVM_ConstantPoolGetWordAt"); + 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 (!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); + return get_word_at_helper(cp, index, word, CHECK_0); } JVM_END -JVM_ENTRY(jint, JVM_ConstantPoolGetNameAndTypeRefIndexAt(JNIEnv *env, jobject obj, jobject unused, jint index)) +JVM_ENTRY(jobject, JVM_ConstantPool1GetRefAt(JNIEnv *env, jobject obj, jint index, jint word, + jbyte resolving, jobject if_not_present)) { - JVMWrapper("JVM_ConstantPoolGetNameAndTypeRefIndexAt"); + JVMWrapper("JVM_ConstantPoolGetRefAt"); 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"); + 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); } - return (jint) cp->uncached_name_and_type_ref_index_at(index); + THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "resolving mode must be 0, 1, or 2"); + return NULL; } JVM_END -JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetNameAndTypeRefInfoAt(JNIEnv *env, jobject obj, jobject unused, jint index)) + +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_ConstantPoolGetNameAndTypeRefInfoAt"); + JVMWrapper("JVM_ConstantPoolCopyOutRefsAt"); 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"); + 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)); + } } - 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)) + +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))); @@ -2235,7 +2455,7 @@ } JVM_END -JVM_ENTRY(jlong, JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject obj, jobject unused, jint index)) +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))); @@ -2248,7 +2468,7 @@ } JVM_END -JVM_ENTRY(jfloat, JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject obj, jobject unused, jint index)) +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))); @@ -2261,7 +2481,7 @@ } JVM_END -JVM_ENTRY(jdouble, JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject obj, jobject unused, jint index)) +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))); @@ -2274,61 +2494,34 @@ } JVM_END -JVM_ENTRY(jstring, JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject obj, jobject unused, jint index)) +JVM_ENTRY(jbyte, JVM_ConstantPool1GetTagAt(JNIEnv *env, jobject obj, jint index)) { - JVMWrapper("JVM_ConstantPoolGetStringAt"); + JVMWrapper("JVM_ConstantPoolGetTagAt"); constantPoolHandle cp = constantPoolHandle(THREAD, reflect_ConstantPool::get_cp(JNIHandles::resolve_non_null(obj))); - bounds_check(cp, index, CHECK_NULL); + bounds_check(cp, index, CHECK_0); 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); + // 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(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)) +JVM_ENTRY(jbyteArray, JVM_ConstantPool1GetTags(JNIEnv *env, jobject obj)) { - JVMWrapper("JVM_ConstantPoolGetTagAt"); + JVMWrapper("JVM_ConstantPoolGetTags"); 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; + 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 result; + return (jbyteArray) JNIHandles::make_local(THREAD, result_oop); } JVM_END + // Assertion support. ////////////////////////////////////////////////////////// JVM_ENTRY(jboolean, JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls))