Explicitly pass Thread::Current to MutexLock and Alloc.
Change-Id: I8b75bc0617915465f102815b32306aa7760dcae4
diff --git a/src/debugger.cc b/src/debugger.cc
index e28845f..c8e7381 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -55,19 +55,19 @@
return 0;
}
JDWP::ObjectId id = static_cast<JDWP::ObjectId>(reinterpret_cast<uintptr_t>(o));
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
map_.Overwrite(id, o);
return id;
}
void Clear() {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
LOG(DEBUG) << "Debugger has detached; object registry had " << map_.size() << " entries";
map_.clear();
}
bool Contains(JDWP::ObjectId id) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
return map_.find(id) != map_.end();
}
@@ -76,14 +76,14 @@
return NULL;
}
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
typedef SafeMap<JDWP::ObjectId, Object*>::iterator It; // C++0x auto
It it = map_.find(id);
return (it != map_.end()) ? reinterpret_cast<T>(it->second) : reinterpret_cast<T>(kInvalidId);
}
void VisitRoots(Heap::RootVisitor* visitor, void* arg) {
- MutexLock mu(lock_);
+ MutexLock mu(Thread::Current(), lock_);
typedef SafeMap<JDWP::ObjectId, Object*>::iterator It; // C++0x auto
for (It it = map_.begin(); it != map_.end(); ++it) {
visitor(it->second, arg);
@@ -184,7 +184,7 @@
static bool IsBreakpoint(AbstractMethod* m, uint32_t dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
for (size_t i = 0; i < gBreakpoints.size(); ++i) {
if (gBreakpoints[i].method == m && gBreakpoints[i].dex_pc == dex_pc) {
VLOG(jdwp) << "Hit breakpoint #" << i << ": " << gBreakpoints[i];
@@ -492,7 +492,7 @@
}
static void SetDebuggerUpdatesEnabled(bool enabled) {
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
Runtime::Current()->GetThreadList()->ForEach(SetDebuggerUpdatesEnabledCallback, &enabled);
}
@@ -508,7 +508,7 @@
{
// TODO: dalvik only warned if there were breakpoints left over. clear in Dbg::Disconnected?
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
CHECK_EQ(gBreakpoints.size(), 0U);
}
@@ -884,7 +884,7 @@
}
JDWP::ObjectId Dbg::CreateString(const std::string& str) {
- return gRegistry->Add(String::AllocFromModifiedUtf8(str.c_str()));
+ return gRegistry->Add(String::AllocFromModifiedUtf8(Thread::Current(), str.c_str()));
}
JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object) {
@@ -893,7 +893,7 @@
if (c == NULL) {
return status;
}
- new_object = gRegistry->Add(c->AllocObject());
+ new_object = gRegistry->Add(c->AllocObject(Thread::Current()));
return JDWP::ERR_NONE;
}
@@ -907,7 +907,7 @@
if (c == NULL) {
return status;
}
- new_array = gRegistry->Add(Array::Alloc(c, length));
+ new_array = gRegistry->Add(Array::Alloc(Thread::Current(), c, length));
return JDWP::ERR_NONE;
}
@@ -1331,8 +1331,9 @@
}
bool Dbg::GetThreadName(JDWP::ObjectId threadId, std::string& name) {
- MutexLock mu(*Locks::thread_list_lock_);
- ScopedObjectAccessUnchecked soa(Thread::Current());
+ Thread* self = Thread::Current();
+ MutexLock mu(self, *Locks::thread_list_lock_);
+ ScopedObjectAccessUnchecked soa(self);
Thread* thread = DecodeThread(soa, threadId);
if (thread == NULL) {
return false;
@@ -1349,7 +1350,7 @@
}
// Okay, so it's an object, but is it actually a thread?
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
if (DecodeThread(soa, threadId) == NULL) {
return JDWP::ERR_INVALID_THREAD;
}
@@ -1408,13 +1409,13 @@
bool Dbg::GetThreadStatus(JDWP::ObjectId threadId, JDWP::JdwpThreadStatus* pThreadStatus, JDWP::JdwpSuspendStatus* pSuspendStatus) {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = DecodeThread(soa, threadId);
if (thread == NULL) {
return false;
}
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
// TODO: if we're in Thread.sleep(long), we should return TS_SLEEPING,
// even if it's implemented using Object.wait(long).
@@ -1448,28 +1449,28 @@
JDWP::JdwpError Dbg::GetThreadDebugSuspendCount(JDWP::ObjectId threadId, JDWP::ExpandBuf* pReply) {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = DecodeThread(soa, threadId);
if (thread == NULL) {
return JDWP::ERR_INVALID_THREAD;
}
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
expandBufAdd4BE(pReply, thread->GetDebugSuspendCount());
return JDWP::ERR_NONE;
}
bool Dbg::ThreadExists(JDWP::ObjectId threadId) {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
return DecodeThread(soa, threadId) != NULL;
}
bool Dbg::IsSuspended(JDWP::ObjectId threadId) {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = DecodeThread(soa, threadId);
CHECK(thread != NULL);
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
return thread->IsSuspended();
}
@@ -1513,7 +1514,7 @@
ScopedObjectAccessUnchecked soa(Thread::Current());
Object* thread_group = gRegistry->Get<Object*>(thread_group_id);
ThreadListVisitor tlv(soa, thread_group, thread_ids);
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Runtime::Current()->GetThreadList()->ForEach(ThreadListVisitor::Visit, &tlv);
}
@@ -1554,7 +1555,7 @@
};
if (kIsDebugBuild) {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
+ MutexLock mu(Thread::Current(), *Locks::thread_suspend_count_lock_);
CHECK(thread->IsSuspended());
}
CountStackDepthVisitor visitor(thread->GetManagedStack(), thread->GetTraceStack());
@@ -1652,7 +1653,7 @@
void Dbg::ResumeThread(JDWP::ObjectId threadId) {
ScopedObjectAccessUnchecked soa(Thread::Current());
Object* peer = gRegistry->Get<Object*>(threadId);
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Thread* thread = Thread::FromManagedThread(soa, peer);
if (thread == NULL) {
LOG(WARNING) << "No such thread for resume: " << peer;
@@ -1660,7 +1661,7 @@
}
bool needs_resume;
{
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
needs_resume = thread->GetSuspendCount() > 0;
}
if (needs_resume) {
@@ -1716,12 +1717,12 @@
ScopedObjectAccessUnchecked soa(Thread::Current());
Thread* thread;
{
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
thread = DecodeThread(soa, thread_id);
if (thread == NULL) {
return JDWP::ERR_INVALID_THREAD;
}
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
if (!thread->IsSuspended()) {
return JDWP::ERR_THREAD_NOT_SUSPENDED;
}
@@ -2020,7 +2021,7 @@
// If the debugger is single-stepping one of our threads, check to
// see if we're that thread and we've reached a step point.
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
if (gSingleStepControl.is_active && gSingleStepControl.thread == self) {
CHECK(!m->IsNative());
if (gSingleStepControl.step_depth == JDWP::SD_INTO) {
@@ -2104,14 +2105,14 @@
}
void Dbg::WatchLocation(const JDWP::JdwpLocation* location) {
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
AbstractMethod* m = FromMethodId(location->method_id);
gBreakpoints.push_back(Breakpoint(m, location->dex_pc));
VLOG(jdwp) << "Set breakpoint #" << (gBreakpoints.size() - 1) << ": " << gBreakpoints[gBreakpoints.size() - 1];
}
void Dbg::UnwatchLocation(const JDWP::JdwpLocation* location) {
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
AbstractMethod* m = FromMethodId(location->method_id);
for (size_t i = 0; i < gBreakpoints.size(); ++i) {
if (gBreakpoints[i].method == m && gBreakpoints[i].dex_pc == location->dex_pc) {
@@ -2130,7 +2131,7 @@
return JDWP::ERR_INVALID_THREAD;
}
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(soa.Self(), gBreakpointsLock);
// TODO: there's no theoretical reason why we couldn't support single-stepping
// of multiple threads at once, but we never did so historically.
if (gSingleStepControl.thread != NULL && thread != gSingleStepControl.thread) {
@@ -2149,7 +2150,7 @@
EXCLUSIVE_LOCKS_REQUIRED(gBreakpointsLock)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: StackVisitor(stack, trace_stack, NULL) {
- gBreakpointsLock.AssertHeld();
+ gBreakpointsLock.AssertHeld(Thread::Current());
gSingleStepControl.method = NULL;
gSingleStepControl.stack_depth = 0;
}
@@ -2157,7 +2158,7 @@
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
- gBreakpointsLock.AssertHeld();
+ gBreakpointsLock.AssertHeld(Thread::Current());
const AbstractMethod* m = GetMethod();
if (!m->IsRuntimeMethod()) {
++gSingleStepControl.stack_depth;
@@ -2188,7 +2189,7 @@
}
static bool Callback(void* raw_context, uint32_t address, uint32_t line_number) {
- MutexLock mu(gBreakpointsLock); // Keep GCC happy.
+ MutexLock mu(Thread::Current(), gBreakpointsLock); // Keep GCC happy.
DebugCallbackContext* context = reinterpret_cast<DebugCallbackContext*>(raw_context);
if (static_cast<int32_t>(line_number) == gSingleStepControl.line_number) {
if (!context->last_pc_valid) {
@@ -2209,7 +2210,7 @@
}
~DebugCallbackContext() {
- MutexLock mu(gBreakpointsLock); // Keep GCC happy.
+ MutexLock mu(Thread::Current(), gBreakpointsLock); // Keep GCC happy.
// If the line number was the last in the position table...
if (last_pc_valid) {
size_t end = MethodHelper(gSingleStepControl.method).GetCodeItem()->insns_size_in_code_units_;
@@ -2259,7 +2260,7 @@
}
void Dbg::UnconfigureStep(JDWP::ObjectId /*threadId*/) {
- MutexLock mu(gBreakpointsLock);
+ MutexLock mu(Thread::Current(), gBreakpointsLock);
gSingleStepControl.is_active = false;
gSingleStepControl.thread = NULL;
@@ -2307,7 +2308,7 @@
Thread* self = Thread::Current();
{
ScopedObjectAccessUnchecked soa(self);
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
targetThread = DecodeThread(soa, threadId);
if (targetThread == NULL) {
LOG(ERROR) << "InvokeMethod request for non-existent thread " << threadId;
@@ -2335,7 +2336,7 @@
*/
int suspend_count;
{
- MutexLock mu2(*Locks::thread_suspend_count_lock_);
+ MutexLock mu2(soa.Self(), *Locks::thread_suspend_count_lock_);
suspend_count = targetThread->GetSuspendCount();
}
if (suspend_count > 1) {
@@ -2411,7 +2412,7 @@
VLOG(jdwp) << " Transferring control to event thread";
{
- MutexLock mu(req->lock_);
+ MutexLock mu(self, req->lock_);
if ((options & JDWP::INVOKE_SINGLE_THREADED) == 0) {
VLOG(jdwp) << " Resuming all threads";
@@ -2631,12 +2632,9 @@
VLOG(jdwp) << "Broadcasting DDM " << (connect ? "connect" : "disconnect") << "...";
Thread* self = Thread::Current();
- {
- MutexLock mu(*Locks::thread_suspend_count_lock_);
- if (self->GetState() != kRunnable) {
- LOG(ERROR) << "DDM broadcast in thread state " << self->GetState();
- /* try anyway? */
- }
+ if (self->GetState() != kRunnable) {
+ LOG(ERROR) << "DDM broadcast in thread state " << self->GetState();
+ /* try anyway? */
}
JNIEnv* env = self->GetJniEnv();
@@ -2699,12 +2697,13 @@
// notification.
SuspendVM();
std::list<Thread*> threads;
+ Thread* self = Thread::Current();
{
- MutexLock mu(*Locks::thread_list_lock_);
+ MutexLock mu(self, *Locks::thread_list_lock_);
threads = Runtime::Current()->GetThreadList()->GetList();
}
{
- ScopedObjectAccess soa(Thread::Current());
+ ScopedObjectAccess soa(self);
typedef std::list<Thread*>::const_iterator It; // TODO: C++0x auto
for (It it = threads.begin(), end = threads.end(); it != end; ++it) {
Dbg::DdmSendThreadNotification(*it, CHUNK_TYPE("THCR"));
@@ -3096,9 +3095,10 @@
} else {
Heap* heap = Runtime::Current()->GetHeap();
const Spaces& spaces = heap->GetSpaces();
+ Thread* self = Thread::Current();
for (Spaces::const_iterator cur = spaces.begin(); cur != spaces.end(); ++cur) {
if ((*cur)->IsAllocSpace()) {
- ReaderMutexLock mu(*Locks::heap_bitmap_lock_);
+ ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
(*cur)->AsAllocSpace()->Walk(HeapChunkContext::HeapChunkCallback, &context);
}
}
@@ -3111,7 +3111,7 @@
}
void Dbg::SetAllocTrackingEnabled(bool enabled) {
- MutexLock mu(gAllocTrackerLock);
+ MutexLock mu(Thread::Current(), gAllocTrackerLock);
if (enabled) {
if (recent_allocation_records_ == NULL) {
LOG(INFO) << "Enabling alloc tracker (" << kNumAllocRecords << " entries, "
@@ -3164,7 +3164,7 @@
Thread* self = Thread::Current();
CHECK(self != NULL);
- MutexLock mu(gAllocTrackerLock);
+ MutexLock mu(self, gAllocTrackerLock);
if (recent_allocation_records_ == NULL) {
return;
}
@@ -3203,7 +3203,7 @@
void Dbg::DumpRecentAllocations() {
ScopedObjectAccess soa(Thread::Current());
- MutexLock mu(gAllocTrackerLock);
+ MutexLock mu(soa.Self(), gAllocTrackerLock);
if (recent_allocation_records_ == NULL) {
LOG(INFO) << "Not recording tracked allocations";
return;
@@ -3323,7 +3323,8 @@
DumpRecentAllocations();
}
- MutexLock mu(gAllocTrackerLock);
+ Thread* self = Thread::Current();
+ MutexLock mu(self, gAllocTrackerLock);
//
// Part 1: generate string tables.
@@ -3428,7 +3429,7 @@
method_names.WriteTo(bytes);
filenames.WriteTo(bytes);
- JNIEnv* env = Thread::Current()->GetJniEnv();
+ JNIEnv* env = self->GetJniEnv();
jbyteArray result = env->NewByteArray(bytes.size());
if (result != NULL) {
env->SetByteArrayRegion(result, 0, bytes.size(), reinterpret_cast<const jbyte*>(&bytes[0]));