hotspot/src/share/vm/runtime/thread.cpp
changeset 13728 882756847a04
parent 13196 6b399731153b
child 13744 631fe815def5
--- 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<Metadata*>(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();