Add the missing link between compiled code and the debugger.
When a debugger connects and disconnects, we now let compiled code know that we
need to be kept informed about what's going on.
Also fix a threading bug when threads exit with a debugger attached.
Also some minor tidying, mostly involving naming.
Change-Id: Iba0e8b9d192ac76ba1cd29a8b1e6d94f6f20dea8
diff --git a/src/thread.cc b/src/thread.cc
index 5499091..522024c 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -100,8 +100,7 @@
pCmplFloat = CmplFloat;
pCmpgDouble = CmpgDouble;
pCmplDouble = CmplDouble;
-#endif
-#if defined(__arm__)
+#elif defined(__arm__)
pShlLong = art_shl_long;
pShrLong = art_shr_long;
pUshrLong = art_ushr_long;
@@ -172,9 +171,7 @@
pThrowStackOverflowFromCode = art_throw_stack_overflow_from_code;
pThrowVerificationErrorFromCode = art_throw_verification_error_from_code;
pUnlockObjectFromCode = art_unlock_object_from_code;
- pUpdateDebuggerFromCode = NULL; // To enable, set to art_update_debugger
-#endif
-#if defined(__i386__)
+#elif defined(__i386__)
pShlLong = NULL;
pShrLong = NULL;
pUshrLong = NULL;
@@ -245,7 +242,6 @@
pThrowStackOverflowFromCode = NULL;
pThrowVerificationErrorFromCode = NULL;
pUnlockObjectFromCode = NULL;
- pUpdateDebuggerFromCode = NULL; // To enable, set to art_update_debugger
#endif
pF2l = F2L;
pD2l = D2L;
@@ -258,6 +254,12 @@
pInstanceofNonTrivialFromCode = IsAssignableFromCode;
pThrowAbstractMethodErrorFromCode = ThrowAbstractMethodErrorFromCode;
pUnresolvedDirectMethodTrampolineFromCode = UnresolvedDirectMethodTrampolineFromCode;
+ pUpdateDebuggerFromCode = NULL; // Controlled by SetDebuggerUpdatesEnabled.
+}
+
+void Thread::SetDebuggerUpdatesEnabled(bool enabled) {
+ LOG(INFO) << "Turning debugger updates " << (enabled ? "on" : "off") << " for " << *this;
+ pUpdateDebuggerFromCode = (enabled ? art_update_debugger : NULL);
}
void Thread::InitTid() {
@@ -972,22 +974,22 @@
entered_monitor->MonitorExit(Thread::Current());
}
-Thread::~Thread() {
+void Thread::Destroy() {
// 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) {
+ Thread* self = this;
// this.vmData = 0;
SetVmData(peer_, NULL);
- Dbg::PostThreadDeath(this);
+ Dbg::PostThreadDeath(self);
// Thread.join() is implemented as an Object.wait() on the Thread.lock
// object. Signal anyone who is waiting.
- Thread* self = Thread::Current();
Object* lock = gThread_lock->GetObject(peer_);
// (This conditional is only needed for tests, where Thread.lock won't have been set.)
if (lock != NULL) {
@@ -996,7 +998,9 @@
lock->MonitorExit(self);
}
}
+}
+Thread::~Thread() {
delete jni_env_;
jni_env_ = NULL;