--- 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();