diff options
author | 2019-05-13 16:35:02 -0700 | |
---|---|---|
committer | 2019-05-14 20:22:20 +0000 | |
commit | e302088f50244f10c90e5f40b6e05c9574c4cf32 (patch) | |
tree | 8551a3c7d9ed52af88260307e7d0a88a00f83be8 /runtime/gc/reference_processor.cc | |
parent | 23ca8fbcb23fb1eb95d192995a35f4fed53bffbd (diff) |
Call ReferenceQueue add outside of active GC block
We were calling ReferenceQueue.add within the runtime GC active block.
This caused java code to be run and could (potentially) cause
deadlocks with JVMTI and debuggers.
To fix this we collect the cleared references during the GC and only
enqueue them after FinishGC.
Test: ./test.py --host
Test: atest CtsJdwpTunnelHostTestCases # with goldfish emulator
Test: ./art/tools/run-libjdwp-tests.sh --mode=host
Bug: 132460313
Change-Id: I276870096fb60a06afba7f850325d06709227b8e
Diffstat (limited to 'runtime/gc/reference_processor.cc')
-rw-r--r-- | runtime/gc/reference_processor.cc | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc index b0fc7a6ae4..498013e5b9 100644 --- a/runtime/gc/reference_processor.cc +++ b/runtime/gc/reference_processor.cc @@ -31,6 +31,7 @@ #include "reflection.h" #include "scoped_thread_state_change-inl.h" #include "task_processor.h" +#include "thread_pool.h" #include "well_known_classes.h" namespace art { @@ -289,8 +290,11 @@ class ClearedReferenceTask : public HeapTask { const jobject cleared_references_; }; -void ReferenceProcessor::EnqueueClearedReferences(Thread* self) { +SelfDeletingTask* ReferenceProcessor::CollectClearedReferences(Thread* self) { Locks::mutator_lock_->AssertNotHeld(self); + // By default we don't actually need to do anything. Just return this no-op task to avoid having + // to put in ifs. + std::unique_ptr<SelfDeletingTask> result(new FunctionTask([](Thread*) {})); // When a runtime isn't started there are no reference queues to care about so ignore. if (!cleared_references_.IsEmpty()) { if (LIKELY(Runtime::Current()->IsStarted())) { @@ -306,12 +310,12 @@ void ReferenceProcessor::EnqueueClearedReferences(Thread* self) { Runtime::Current()->GetHeap()->GetTaskProcessor()->AddTask( self, new ClearedReferenceTask(cleared_references)); } else { - ClearedReferenceTask task(cleared_references); - task.Run(self); + result.reset(new ClearedReferenceTask(cleared_references)); } } cleared_references_.Clear(); } + return result.release(); } void ReferenceProcessor::ClearReferent(ObjPtr<mirror::Reference> ref) { |