< prev index next >

src/hotspot/share/classfile/systemDictionary.cpp

Print this page

        

*** 38,48 **** #include "classfile/packageEntry.hpp" #include "classfile/placeholders.hpp" #include "classfile/protectionDomainCache.hpp" #include "classfile/resolutionErrors.hpp" #include "classfile/stringTable.hpp" - #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" #include "gc/shared/gcTraceTime.inline.hpp" --- 38,47 ----
*** 55,65 **** #include "memory/filemap.hpp" #include "memory/heapShared.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" - #include "memory/universe.hpp" #include "oops/access.inline.hpp" #include "oops/instanceKlass.hpp" #include "oops/instanceRefKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/method.inline.hpp" --- 54,63 ----
*** 68,77 **** --- 66,76 ---- #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" #include "prims/jvmtiExport.hpp" + #include "prims/resolvedMethodTable.hpp" #include "prims/methodHandles.hpp" #include "runtime/arguments.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/fieldType.hpp" #include "runtime/handles.inline.hpp"
*** 86,95 **** --- 85,97 ---- #include "services/threadService.hpp" #include "utilities/macros.hpp" #if INCLUDE_CDS #include "classfile/systemDictionaryShared.hpp" #endif + #if INCLUDE_JVMCI + #include "jvmci/jvmciRuntime.hpp" + #endif #if INCLUDE_JFR #include "jfr/jfr.hpp" #endif PlaceholderTable* SystemDictionary::_placeholders = NULL;
*** 261,271 **** assert(class_name != NULL && !FieldType::is_array(class_name), "must be"); if (FieldType::is_obj(class_name)) { ResourceMark rm(THREAD); // Ignore wrapping L and ;. TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1, ! class_name->utf8_length() - 2); return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD); } else { return resolve_instance_class_or_null(class_name, class_loader, protection_domain, THREAD); } } --- 263,273 ---- assert(class_name != NULL && !FieldType::is_array(class_name), "must be"); if (FieldType::is_obj(class_name)) { ResourceMark rm(THREAD); // Ignore wrapping L and ;. TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1, ! class_name->utf8_length() - 2, CHECK_NULL); return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD); } else { return resolve_instance_class_or_null(class_name, class_loader, protection_domain, THREAD); } }
*** 1821,1841 **** GCTraceTime(Debug, gc, phases) t("ClassLoaderData", gc_timer); assert_locked_or_safepoint(ClassLoaderDataGraph_lock); // caller locks. // First, mark for unload all ClassLoaderData referencing a dead class loader. unloading_occurred = ClassLoaderDataGraph::do_unloading(); if (unloading_occurred) { ! MutexLocker ml2(is_concurrent ? Module_lock : NULL); JFR_ONLY(Jfr::on_unloading_classes();) ! MutexLocker ml1(is_concurrent ? SystemDictionary_lock : NULL); ClassLoaderDataGraph::clean_module_and_package_info(); constraints()->purge_loader_constraints(); resolution_errors()->purge_resolution_errors(); } } GCTraceTime(Debug, gc, phases) t("Trigger cleanups", gc_timer); if (unloading_occurred) { SymbolTable::trigger_cleanup(); // Oops referenced by the protection domain cache table may get unreachable independently --- 1823,1845 ---- GCTraceTime(Debug, gc, phases) t("ClassLoaderData", gc_timer); assert_locked_or_safepoint(ClassLoaderDataGraph_lock); // caller locks. // First, mark for unload all ClassLoaderData referencing a dead class loader. unloading_occurred = ClassLoaderDataGraph::do_unloading(); if (unloading_occurred) { ! MutexLockerEx ml2(is_concurrent ? Module_lock : NULL); JFR_ONLY(Jfr::on_unloading_classes();) ! MutexLockerEx ml1(is_concurrent ? SystemDictionary_lock : NULL); ClassLoaderDataGraph::clean_module_and_package_info(); constraints()->purge_loader_constraints(); resolution_errors()->purge_resolution_errors(); } } GCTraceTime(Debug, gc, phases) t("Trigger cleanups", gc_timer); + // Trigger cleaning the ResolvedMethodTable even if no unloading occurred. + ResolvedMethodTable::trigger_cleanup(); if (unloading_occurred) { SymbolTable::trigger_cleanup(); // Oops referenced by the protection domain cache table may get unreachable independently
*** 1919,1928 **** --- 1923,1939 ---- assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob"); int sid = wk_init_info[id - FIRST_WKID]; Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid); InstanceKlass** klassp = &_well_known_klasses[id]; + + #if INCLUDE_JVMCI + if (id >= FIRST_JVMCI_WKID) { + assert(EnableJVMCI, "resolve JVMCI classes only when EnableJVMCI is true"); + } + #endif + if ((*klassp) == NULL) { Klass* k = resolve_or_fail(symbol, true, CHECK_0); (*klassp) = InstanceKlass::cast(k); } return ((*klassp) != NULL);
*** 2007,2017 **** // JSR 292 classes WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass); WKID jsr292_group_end = WK_KLASS_ENUM_NAME(VolatileCallSite_klass); resolve_wk_klasses_until(jsr292_group_start, scan, CHECK); resolve_wk_klasses_through(jsr292_group_end, scan, CHECK); ! WKID last = WKID_LIMIT; resolve_wk_klasses_until(last, scan, CHECK); _box_klasses[T_BOOLEAN] = WK_KLASS(Boolean_klass); _box_klasses[T_CHAR] = WK_KLASS(Character_klass); _box_klasses[T_FLOAT] = WK_KLASS(Float_klass); --- 2018,2028 ---- // JSR 292 classes WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass); WKID jsr292_group_end = WK_KLASS_ENUM_NAME(VolatileCallSite_klass); resolve_wk_klasses_until(jsr292_group_start, scan, CHECK); resolve_wk_klasses_through(jsr292_group_end, scan, CHECK); ! WKID last = NOT_JVMCI(WKID_LIMIT) JVMCI_ONLY(FIRST_JVMCI_WKID); resolve_wk_klasses_until(last, scan, CHECK); _box_klasses[T_BOOLEAN] = WK_KLASS(Boolean_klass); _box_klasses[T_CHAR] = WK_KLASS(Character_klass); _box_klasses[T_FLOAT] = WK_KLASS(Float_klass);
*** 2354,2364 **** } SignatureStream sig_strm(signature, is_method); while (!sig_strm.is_done()) { if (sig_strm.is_object()) { ! Symbol* sig = sig_strm.as_symbol(); if (!add_loader_constraint(sig, loader1, loader2, THREAD)) { return sig; } } sig_strm.next(); --- 2365,2375 ---- } SignatureStream sig_strm(signature, is_method); while (!sig_strm.is_done()) { if (sig_strm.is_object()) { ! Symbol* sig = sig_strm.as_symbol(CHECK_NULL); if (!add_loader_constraint(sig, loader1, loader2, THREAD)) { return sig; } } sig_strm.next();
*** 2624,2634 **** if (!can_be_cached) { // Resolve, throwing a real error if it doesn't work. mirror = ss.as_java_mirror(class_loader, protection_domain, SignatureStream::NCDFError, CHECK_(empty)); } ! assert(mirror != NULL, "%s", ss.as_symbol()->as_C_string()); if (ss.at_return_type()) rt = Handle(THREAD, mirror); else pts->obj_at_put(arg++, mirror); --- 2635,2645 ---- if (!can_be_cached) { // Resolve, throwing a real error if it doesn't work. mirror = ss.as_java_mirror(class_loader, protection_domain, SignatureStream::NCDFError, CHECK_(empty)); } ! assert(mirror != NULL, "%s", ss.as_symbol(THREAD)->as_C_string()); if (ss.at_return_type()) rt = Handle(THREAD, mirror); else pts->obj_at_put(arg++, mirror);
*** 2740,2804 **** vmSymbols::linkMethodHandleConstant_signature(), &args, CHECK_(empty)); return Handle(THREAD, (oop) result.get_jobject()); } ! // Ask Java to run a bootstrap method, in order to create a dynamic call site ! // while linking an invokedynamic op, or compute a constant for Dynamic_info CP entry ! // with linkage results being stored back into the bootstrap specifier. ! void SystemDictionary::invoke_bootstrap_method(BootstrapInfo& bootstrap_specifier, TRAPS) { ! // Resolve the bootstrap specifier, its name, type, and static arguments ! bootstrap_specifier.resolve_bsm(CHECK); // This should not happen. JDK code should take care of that. ! if (bootstrap_specifier.caller() == NULL || bootstrap_specifier.type_arg().is_null()) { ! THROW_MSG(vmSymbols::java_lang_InternalError(), "Invalid bootstrap method invocation with no caller or type argument"); } ! bool is_indy = bootstrap_specifier.is_method_call(); ! objArrayHandle appendix_box; ! if (is_indy) { ! // Some method calls may require an appendix argument. Arrange to receive it. ! appendix_box = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), 1, CHECK); ! assert(appendix_box->obj_at(0) == NULL, ""); ! } ! // call condy: java.lang.invoke.MethodHandleNatives::linkDynamicConstant(caller, condy_index, bsm, type, info) ! // indy: java.lang.invoke.MethodHandleNatives::linkCallSite(caller, indy_index, bsm, name, mtype, info, &appendix) JavaCallArguments args; ! args.push_oop(Handle(THREAD, bootstrap_specifier.caller_mirror())); ! args.push_int(bootstrap_specifier.bss_index()); ! args.push_oop(bootstrap_specifier.bsm()); ! args.push_oop(bootstrap_specifier.name_arg()); ! args.push_oop(bootstrap_specifier.type_arg()); ! args.push_oop(bootstrap_specifier.arg_values()); ! if (is_indy) { ! args.push_oop(appendix_box); ! } JavaValue result(T_OBJECT); JavaCalls::call_static(&result, SystemDictionary::MethodHandleNatives_klass(), ! is_indy ? vmSymbols::linkCallSite_name() : vmSymbols::linkDynamicConstant_name(), ! is_indy ? vmSymbols::linkCallSite_signature() : vmSymbols::linkDynamicConstant_signature(), ! &args, CHECK); ! ! Handle value(THREAD, (oop) result.get_jobject()); ! if (is_indy) { ! Handle appendix; ! methodHandle method = unpack_method_and_appendix(value, ! bootstrap_specifier.caller(), ! appendix_box, ! &appendix, CHECK); ! bootstrap_specifier.set_resolved_method(method, appendix); } else { ! bootstrap_specifier.set_resolved_value(value); } ! // sanity check ! assert(bootstrap_specifier.is_resolved() || ! (bootstrap_specifier.is_method_call() && ! bootstrap_specifier.resolved_method().not_null()), "bootstrap method call failed"); } // Protection domain cache table handling ProtectionDomainCacheEntry* SystemDictionary::cache_get(Handle protection_domain) { --- 2751,2860 ---- vmSymbols::linkMethodHandleConstant_signature(), &args, CHECK_(empty)); return Handle(THREAD, (oop) result.get_jobject()); } ! // Ask Java to compute a constant by invoking a BSM given a Dynamic_info CP entry ! Handle SystemDictionary::link_dynamic_constant(Klass* caller, ! int condy_index, ! Handle bootstrap_specifier, ! Symbol* name, ! Symbol* type, ! TRAPS) { ! Handle empty; ! Handle bsm, info; ! if (java_lang_invoke_MethodHandle::is_instance(bootstrap_specifier())) { ! bsm = bootstrap_specifier; ! } else { ! assert(bootstrap_specifier->is_objArray(), ""); ! objArrayOop args = (objArrayOop) bootstrap_specifier(); ! assert(args->length() == 2, ""); ! bsm = Handle(THREAD, args->obj_at(0)); ! info = Handle(THREAD, args->obj_at(1)); ! } ! guarantee(java_lang_invoke_MethodHandle::is_instance(bsm()), ! "caller must supply a valid BSM"); // This should not happen. JDK code should take care of that. ! if (caller == NULL) { ! THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad dynamic constant", empty); } ! Handle constant_name = java_lang_String::create_from_symbol(name, CHECK_(empty)); ! // Resolve the constant type in the context of the caller class ! Handle type_mirror = find_java_mirror_for_type(type, caller, SignatureStream::NCDFError, ! CHECK_(empty)); ! ! // call java.lang.invoke.MethodHandleNatives::linkConstantDyanmic(caller, condy_index, bsm, type, info) JavaCallArguments args; ! args.push_oop(Handle(THREAD, caller->java_mirror())); ! args.push_int(condy_index); ! args.push_oop(bsm); ! args.push_oop(constant_name); ! args.push_oop(type_mirror); ! args.push_oop(info); JavaValue result(T_OBJECT); JavaCalls::call_static(&result, SystemDictionary::MethodHandleNatives_klass(), ! vmSymbols::linkDynamicConstant_name(), ! vmSymbols::linkDynamicConstant_signature(), ! &args, CHECK_(empty)); ! ! return Handle(THREAD, (oop) result.get_jobject()); ! } ! ! // Ask Java code to find or construct a java.lang.invoke.CallSite for the given ! // name and signature, as interpreted relative to the given class loader. ! methodHandle SystemDictionary::find_dynamic_call_site_invoker(Klass* caller, ! int indy_index, ! Handle bootstrap_specifier, ! Symbol* name, ! Symbol* type, ! Handle *appendix_result, ! TRAPS) { ! methodHandle empty; ! Handle bsm, info; ! if (java_lang_invoke_MethodHandle::is_instance(bootstrap_specifier())) { ! bsm = bootstrap_specifier; } else { ! objArrayOop args = (objArrayOop) bootstrap_specifier(); ! assert(args->length() == 2, ""); ! bsm = Handle(THREAD, args->obj_at(0)); ! info = Handle(THREAD, args->obj_at(1)); } + guarantee(java_lang_invoke_MethodHandle::is_instance(bsm()), + "caller must supply a valid BSM"); ! Handle method_name = java_lang_String::create_from_symbol(name, CHECK_(empty)); ! Handle method_type = find_method_handle_type(type, caller, CHECK_(empty)); ! ! // This should not happen. JDK code should take care of that. ! if (caller == NULL || method_type.is_null()) { ! THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokedynamic", empty); ! } ! ! objArrayHandle appendix_box = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), 1, CHECK_(empty)); ! assert(appendix_box->obj_at(0) == NULL, ""); ! ! // call java.lang.invoke.MethodHandleNatives::linkCallSite(caller, indy_index, bsm, name, mtype, info, &appendix) ! JavaCallArguments args; ! args.push_oop(Handle(THREAD, caller->java_mirror())); ! args.push_int(indy_index); ! args.push_oop(bsm); ! args.push_oop(method_name); ! args.push_oop(method_type); ! args.push_oop(info); ! args.push_oop(appendix_box); ! JavaValue result(T_OBJECT); ! JavaCalls::call_static(&result, ! SystemDictionary::MethodHandleNatives_klass(), ! vmSymbols::linkCallSite_name(), ! vmSymbols::linkCallSite_signature(), ! &args, CHECK_(empty)); ! Handle mname(THREAD, (oop) result.get_jobject()); ! return unpack_method_and_appendix(mname, caller, appendix_box, appendix_result, THREAD); } // Protection domain cache table handling ProtectionDomainCacheEntry* SystemDictionary::cache_get(Handle protection_domain) {
*** 2823,2834 **** _pd_cache_table->print_on(st); st->cr(); } - void SystemDictionary::print() { print_on(tty); } - void SystemDictionary::verify() { guarantee(constraints() != NULL, "Verify of loader constraints failed"); guarantee(placeholders()->number_of_entries() >= 0, "Verify of placeholders failed"); --- 2879,2888 ----
*** 2851,2879 **** assert_locked_or_safepoint(SystemDictionary_lock); if (verbose) { print_on(st); } else { CDS_ONLY(SystemDictionaryShared::print_table_statistics(st)); ! ClassLoaderDataGraph::print_table_statistics(st); placeholders()->print_table_statistics(st, "Placeholder Table"); constraints()->print_table_statistics(st, "LoaderConstraints Table"); ! pd_cache_table()->print_table_statistics(st, "ProtectionDomainCache Table"); } } - TableStatistics SystemDictionary::placeholders_statistics() { - return placeholders()->statistics_calculate(); - } - - TableStatistics SystemDictionary::loader_constraints_statistics() { - return constraints()->statistics_calculate(); - } - - TableStatistics SystemDictionary::protection_domain_cache_statistics() { - return pd_cache_table()->statistics_calculate(); - } - // Utility for dumping dictionaries. SystemDictionaryDCmd::SystemDictionaryDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), _verbose("-verbose", "Dump the content of each dictionary entry for all class loaders", "BOOLEAN", false, "false") { --- 2905,2921 ---- assert_locked_or_safepoint(SystemDictionary_lock); if (verbose) { print_on(st); } else { CDS_ONLY(SystemDictionaryShared::print_table_statistics(st)); ! ClassLoaderDataGraph::print_dictionary_statistics(st); placeholders()->print_table_statistics(st, "Placeholder Table"); constraints()->print_table_statistics(st, "LoaderConstraints Table"); ! _pd_cache_table->print_table_statistics(st, "ProtectionDomainCache Table"); } } // Utility for dumping dictionaries. SystemDictionaryDCmd::SystemDictionaryDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), _verbose("-verbose", "Dump the content of each dictionary entry for all class loaders", "BOOLEAN", false, "false") {
< prev index next >