Mercurial > hg > truffle
diff src/share/vm/classfile/systemDictionary.cpp @ 7185:90273fc0a981
8000662: NPG: nashorn ant clean test262 out-of-memory with Java heap
Summary: Add ClassLoaderData object for each anonymous class with metaspaces to allocate in.
Reviewed-by: twisti, jrose, stefank
author | coleenp |
---|---|
date | Thu, 29 Nov 2012 16:50:29 -0500 |
parents | 070d523b96a7 |
children | 291ffc492eb6 aefb345d3f5e |
line wrap: on
line diff
--- a/src/share/vm/classfile/systemDictionary.cpp Tue Nov 27 14:11:37 2012 -0800 +++ b/src/share/vm/classfile/systemDictionary.cpp Thu Nov 29 16:50:29 2012 -0500 @@ -106,9 +106,9 @@ } -ClassLoaderData* SystemDictionary::register_loader(Handle class_loader) { +ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, TRAPS) { if (class_loader() == NULL) return ClassLoaderData::the_null_class_loader_data(); - return ClassLoaderDataGraph::find_or_create(class_loader); + return ClassLoaderDataGraph::find_or_create(class_loader, CHECK_NULL); } // ---------------------------------------------------------------------------- @@ -591,7 +591,7 @@ // UseNewReflection // Fix for 4474172; see evaluation for more details class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); - ClassLoaderData *loader_data = register_loader(class_loader); + ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL); // Do lookup to see if class already exist and the protection domain // has the right access @@ -888,7 +888,7 @@ // of the call to resolve_instance_class_or_null(). // See evaluation 6790209 and 4474172 for more details. class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); - ClassLoaderData* loader_data = register_loader(class_loader); + ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL); unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data); int d_index = dictionary()->hash_to_index(d_hash); @@ -948,6 +948,18 @@ TRAPS) { TempNewSymbol parsed_name = NULL; + ClassLoaderData* loader_data; + if (host_klass.not_null()) { + // Create a new CLD for anonymous class, that uses the same class loader + // as the host_klass + assert(EnableInvokeDynamic, ""); + guarantee(host_klass->class_loader() == class_loader(), "should be the same"); + loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL); + loader_data->record_dependency(host_klass(), CHECK_NULL); + } else { + loader_data = ClassLoaderData::class_loader_data(class_loader()); + } + // Parse the stream. Note that we do this even though this klass might // already be present in the SystemDictionary, otherwise we would not // throw potential ClassFormatErrors. @@ -959,7 +971,7 @@ // java.lang.Object through resolve_or_fail, not this path. instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name, - class_loader, + loader_data, protection_domain, host_klass, cp_patches, @@ -973,8 +985,6 @@ // Parsed name could be null if we threw an error before we got far // enough along to parse it -- in that case, there is nothing to clean up. if (parsed_name != NULL) { - ClassLoaderData* loader_data = class_loader_data(class_loader); - unsigned int p_hash = placeholders()->compute_hash(parsed_name, loader_data); int p_index = placeholders()->hash_to_index(p_hash); @@ -987,9 +997,8 @@ if (host_klass.not_null() && k.not_null()) { assert(EnableInvokeDynamic, ""); + k->set_host_klass(host_klass()); // If it's anonymous, initialize it now, since nobody else will. - k->class_loader_data()->record_dependency(host_klass(), CHECK_NULL); - k->set_host_klass(host_klass()); { MutexLocker mu_r(Compile_lock, THREAD); @@ -1002,11 +1011,11 @@ } // Rewrite and patch constant pool here. - k->link_class(THREAD); + k->link_class(CHECK_NULL); if (cp_patches != NULL) { k->constants()->patch_resolved_references(cp_patches); } - k->eager_initialize(THREAD); + k->eager_initialize(CHECK_NULL); // notify jvmti if (JvmtiExport::should_post_class_load()) { @@ -1039,7 +1048,7 @@ DoObjectLock = false; } - ClassLoaderData* loader_data = register_loader(class_loader); + ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL); // Make sure we are synchronized on the class loader before we proceed Handle lockObject = compute_loader_lock_object(class_loader, THREAD); @@ -1059,7 +1068,7 @@ // java.lang.Object through resolve_or_fail, not this path. instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name, - class_loader, + loader_data, protection_domain, parsed_name, verify, @@ -2343,6 +2352,7 @@ // Helper for unpacking the return value from linkMethod and linkCallSite. static methodHandle unpack_method_and_appendix(Handle mname, + KlassHandle accessing_klass, objArrayHandle appendix_box, Handle* appendix_result, TRAPS) { @@ -2361,6 +2371,12 @@ #endif //PRODUCT } (*appendix_result) = Handle(THREAD, appendix); + // the target is stored in the cpCache and if a reference to this + // MethodName is dropped we need a way to make sure the + // class_loader containing this method is kept alive. + // FIXME: the appendix might also preserve this dependency. + ClassLoaderData* this_key = InstanceKlass::cast(accessing_klass())->class_loader_data(); + this_key->record_dependency(m->method_holder(), CHECK_NULL); // Can throw OOM return methodHandle(THREAD, m); } } @@ -2405,7 +2421,7 @@ &args, CHECK_(empty)); Handle mname(THREAD, (oop) result.get_jobject()); (*method_type_result) = method_type; - return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD); + return unpack_method_and_appendix(mname, accessing_klass, appendix_box, appendix_result, THREAD); } @@ -2596,7 +2612,7 @@ &args, CHECK_(empty)); Handle mname(THREAD, (oop) result.get_jobject()); (*method_type_result) = method_type; - return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD); + return unpack_method_and_appendix(mname, caller, appendix_box, appendix_result, THREAD); } // Since the identity hash code for symbols changes when the symbols are