diff -r caf5eb7dd4a7 -r 882756847a04 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Fri Aug 31 16:39:35 2012 -0700 +++ b/hotspot/src/share/vm/runtime/thread.cpp Sat Sep 01 13:25:18 2012 -0400 @@ -34,6 +34,7 @@ #include "interpreter/oopMapCache.hpp" #include "jvmtifiles/jvmtiEnv.hpp" #include "memory/gcLocker.inline.hpp" +#include "memory/metaspaceShared.hpp" #include "memory/oopFactory.hpp" #include "memory/universe.inline.hpp" #include "oops/instanceKlass.hpp" @@ -219,6 +220,7 @@ set_osthread(NULL); set_resource_area(new (mtThread)ResourceArea()); set_handle_area(new (mtThread) HandleArea(NULL)); + set_metadata_handles(new (ResourceObj::C_HEAP, mtClass) GrowableArray(300, true)); set_active_handles(NULL); set_free_handle_block(NULL); set_last_handle_mark(NULL); @@ -346,6 +348,7 @@ ParkEvent::Release (_MuxEvent) ; _MuxEvent = NULL ; delete handle_area(); + delete metadata_handles(); // osthread() can be NULL, if creation of thread failed. if (osthread() != NULL) os::free_thread(osthread()); @@ -817,6 +820,14 @@ // no nmethods in a generic thread... } +void Thread::metadata_do(void f(Metadata*)) { + if (metadata_handles() != NULL) { + for (int i = 0; i< metadata_handles()->length(); i++) { + f(metadata_handles()->at(i)); + } + } +} + void Thread::print_on(outputStream* st) const { // get_priority assumes osthread initialized if (osthread() != NULL) { @@ -916,6 +927,8 @@ bool Thread::is_in_stack(address adr) const { assert(Thread::current() == this, "is_in_stack can only be called from current thread"); address end = os::current_stack_pointer(); + // Allow non Java threads to call this without stack_base + if (_stack_base == NULL) return true; if (stack_base() >= adr && adr >= end) return true; return false; @@ -937,14 +950,14 @@ } static void initialize_class(Symbol* class_name, TRAPS) { - klassOop klass = SystemDictionary::resolve_or_fail(class_name, true, CHECK); - instanceKlass::cast(klass)->initialize(CHECK); + Klass* klass = SystemDictionary::resolve_or_fail(class_name, true, CHECK); + InstanceKlass::cast(klass)->initialize(CHECK); } // Creates the initial ThreadGroup static Handle create_initial_thread_group(TRAPS) { - klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ThreadGroup(), true, CHECK_NH); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ThreadGroup(), true, CHECK_NH); instanceKlassHandle klass (THREAD, k); Handle system_instance = klass->allocate_instance_handle(CHECK_NH); @@ -977,7 +990,7 @@ // Creates the initial Thread static oop create_initial_thread(Handle thread_group, JavaThread* thread, TRAPS) { - klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL); @@ -999,7 +1012,7 @@ } static void call_initializeSystemClass(TRAPS) { - klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); instanceKlassHandle klass (THREAD, k); JavaValue result(T_VOID); @@ -1011,11 +1024,11 @@ // extract the JRE name from sun.misc.Version.java_runtime_name static const char* get_java_runtime_name(TRAPS) { - klassOop k = SystemDictionary::find(vmSymbols::sun_misc_Version(), + Klass* k = SystemDictionary::find(vmSymbols::sun_misc_Version(), Handle(), Handle(), CHECK_AND_CLEAR_NULL); fieldDescriptor fd; bool found = k != NULL && - instanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_name_name(), + InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_name_name(), vmSymbols::string_signature(), &fd); if (found) { oop name_oop = k->java_mirror()->obj_field(fd.offset()); @@ -1033,7 +1046,7 @@ // General purpose hook into Java code, run once when the VM is initialized. // The Java library method itself may be changed independently from the VM. static void call_postVMInitHook(TRAPS) { - klassOop k = SystemDictionary::PostVMInitHook_klass(); + Klass* k = SystemDictionary::PostVMInitHook_klass(); instanceKlassHandle klass (THREAD, k); if (klass.not_null()) { JavaValue result(T_VOID); @@ -1049,7 +1062,7 @@ const char *vm_info = VM_Version::vm_info_string(); // java.lang.System class - klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); instanceKlassHandle klass (THREAD, k); // setProperty arguments @@ -1074,7 +1087,7 @@ assert(thread_group.not_null(), "thread group should be specified"); assert(threadObj() == NULL, "should only create Java thread object once"); - klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK); @@ -1982,7 +1995,7 @@ frame f = last_frame(); tty->print(" (pc: " INTPTR_FORMAT " sp: " INTPTR_FORMAT " )", f.pc(), f.sp()); } - tty->print_cr(" of type: %s", instanceKlass::cast(_pending_async_exception->klass())->external_name()); + tty->print_cr(" of type: %s", InstanceKlass::cast(_pending_async_exception->klass())->external_name()); } _pending_async_exception = NULL; clear_has_async_exception(); @@ -2103,10 +2116,10 @@ if (TraceExceptions) { ResourceMark rm; - tty->print_cr("Pending Async. exception installed of type: %s", instanceKlass::cast(_pending_async_exception->klass())->external_name()); + tty->print_cr("Pending Async. exception installed of type: %s", InstanceKlass::cast(_pending_async_exception->klass())->external_name()); } // for AbortVMOnException flag - NOT_PRODUCT(Exceptions::debug_check_abort(instanceKlass::cast(_pending_async_exception->klass())->external_name())); + NOT_PRODUCT(Exceptions::debug_check_abort(InstanceKlass::cast(_pending_async_exception->klass())->external_name())); } } @@ -2656,7 +2669,6 @@ // around using this function f->do_oop((oop*) &_threadObj); f->do_oop((oop*) &_vm_result); - f->do_oop((oop*) &_vm_result_2); f->do_oop((oop*) &_exception_oop); f->do_oop((oop*) &_pending_async_exception); @@ -2679,6 +2691,22 @@ } } +void JavaThread::metadata_do(void f(Metadata*)) { + Thread::metadata_do(f); + if (has_last_Java_frame()) { + // Traverse the execution stack to call f() on the methods in the stack + for(StackFrameStream fst(this); !fst.is_done(); fst.next()) { + fst.current()->metadata_do(f); + } + } else if (is_Compiler_thread()) { + // need to walk ciMetadata in current compile tasks to keep alive. + CompilerThread* ct = (CompilerThread*)this; + if (ct->env() != NULL) { + ct->env()->metadata_do(f); + } + } +} + // Printing const char* _get_thread_state_name(JavaThreadState _thread_state) { switch (_thread_state) { @@ -2869,7 +2897,7 @@ Handle thread_oop(Thread::current(), JNIHandles::resolve_non_null(jni_thread)); - assert(instanceKlass::cast(thread_oop->klass())->is_linked(), + assert(InstanceKlass::cast(thread_oop->klass())->is_linked(), "must be initialized"); set_threadObj(thread_oop()); java_lang_Thread::set_thread(thread_oop(), this); @@ -3070,7 +3098,7 @@ } -klassOop JavaThread::security_get_caller_class(int depth) { +Klass* JavaThread::security_get_caller_class(int depth) { vframeStream vfst(this); vfst.security_get_caller_frame(depth); if (!vfst.at_end()) { @@ -3123,6 +3151,9 @@ int Threads::_number_of_non_daemon_threads = 0; int Threads::_return_code = 0; size_t JavaThread::_stack_size_at_create = 0; +#ifdef ASSERT +bool Threads::_vm_complete = false; +#endif // All JavaThreads #define ALL_JAVA_THREADS(X) for (JavaThread* X = _thread_list; X; X = X->next()) @@ -3320,9 +3351,8 @@ // At this point, the Universe is initialized, but we have not executed // any byte code. Now is a good time (the only time) to dump out the // internal state of the JVM for sharing. - if (DumpSharedSpaces) { - Universe::heap()->preload_and_dump(CHECK_0); + MetaspaceShared::preload_and_dump(CHECK_0); ShouldNotReachHere(); } @@ -3351,10 +3381,10 @@ // Forcibly initialize java/util/HashMap and mutate the private // static final "frontCacheEnabled" field before we start creating instances #ifdef ASSERT - klassOop tmp_k = SystemDictionary::find(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0); + Klass* tmp_k = SystemDictionary::find(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0); assert(tmp_k == NULL, "java/util/HashMap should not be loaded yet"); #endif - klassOop k_o = SystemDictionary::resolve_or_null(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0); + Klass* k_o = SystemDictionary::resolve_or_null(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0); KlassHandle k = KlassHandle(THREAD, k_o); guarantee(k.not_null(), "Must find java/util/HashMap"); instanceKlassHandle ik = instanceKlassHandle(THREAD, k()); @@ -3369,7 +3399,7 @@ if (UseStringCache) { // Forcibly initialize java/lang/StringValue and mutate the private // static final "stringCacheEnabled" field before we start creating instances - klassOop k_o = SystemDictionary::resolve_or_null(vmSymbols::java_lang_StringValue(), Handle(), Handle(), CHECK_0); + Klass* k_o = SystemDictionary::resolve_or_null(vmSymbols::java_lang_StringValue(), Handle(), Handle(), CHECK_0); // Possible that StringValue isn't present: if so, silently don't break if (k_o != NULL) { KlassHandle k = KlassHandle(THREAD, k_o); @@ -3574,6 +3604,9 @@ os::init_3(); create_vm_timer.end(); +#ifdef ASSERT + _vm_complete = true; +#endif return JNI_OK; } @@ -3781,7 +3814,7 @@ } EXCEPTION_MARK; - klassOop k = + Klass* k = SystemDictionary::resolve_or_null(vmSymbols::java_lang_Shutdown(), THREAD); if (k != NULL) { @@ -3840,6 +3873,9 @@ bool Threads::destroy_vm() { JavaThread* thread = JavaThread::current(); +#ifdef ASSERT + _vm_complete = false; +#endif // Wait until we are the last non-daemon thread to execute { MutexLocker nu(Threads_lock); while (Threads::number_of_non_daemon_threads() > 1 ) @@ -4100,6 +4136,12 @@ VMThread::vm_thread()->nmethods_do(cf); } +void Threads::metadata_do(void f(Metadata*)) { + ALL_JAVA_THREADS(p) { + p->metadata_do(f); + } +} + void Threads::gc_epilogue() { ALL_JAVA_THREADS(p) { p->gc_epilogue();