Fixes for ThreadStress test
- Fix deadlock when ThreadGroup.remove(Thread) was run with
thread_list_lock_ but needed to GC to allocate an iterator
- Fix ~MonitorList to clean ownership of any locks that might be held
by JNI or daemon threads on shutdown.
Change-Id: I95e23c3b7c745f6a8387789949f3ec849458a27d
diff --git a/src/thread.cc b/src/thread.cc
index 1800834..cbd1bda 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -745,22 +745,12 @@
}
Thread::~Thread() {
- SetState(Thread::kRunnable);
-
// On thread detach, all monitors entered with JNI MonitorEnter are automatically exited.
if (jni_env_ != NULL) {
jni_env_->monitors.VisitRoots(MonitorExitVisitor, NULL);
}
if (peer_ != NULL) {
- // this.group.removeThread(this);
- // group can be null if we're in the compiler or a test.
- Object* group = gThread_group->GetObject(peer_);
- if (group != NULL) {
- Method* m = group->GetClass()->FindVirtualMethodForVirtualOrInterface(gThreadGroup_removeThread);
- Object* args = peer_;
- m->Invoke(this, group, reinterpret_cast<byte*>(&args), NULL);
- }
// this.vmData = 0;
SetVmData(peer_, NULL);
@@ -795,8 +785,6 @@
return;
}
- ScopedThreadStateChange tsc(this, Thread::kRunnable);
-
// Get and clear the exception.
Object* exception = GetException();
ClearException();
@@ -819,6 +807,17 @@
ClearException();
}
+void Thread::RemoveFromThreadGroup() {
+ // this.group.removeThread(this);
+ // group can be null if we're in the compiler or a test.
+ Object* group = gThread_group->GetObject(peer_);
+ if (group != NULL) {
+ Method* m = group->GetClass()->FindVirtualMethodForVirtualOrInterface(gThreadGroup_removeThread);
+ Object* args = peer_;
+ m->Invoke(this, group, reinterpret_cast<byte*>(&args), NULL);
+ }
+}
+
size_t Thread::NumSirtReferences() {
size_t count = 0;
for (StackIndirectReferenceTable* cur = top_sirt_; cur; cur = cur->GetLink()) {