summaryrefslogtreecommitdiffstats
path: root/runtime/gc
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-04-10 10:56:55 -0700
committerMathieu Chartier <mathieuc@google.com>2014-04-10 12:48:48 -0700
commitb38d483b742eafc7833fac1ebb4fa1481cbac179 (patch)
tree05437041ee24b89481e9c3ef0be7589fa3e25e44 /runtime/gc
parent22839a631bb3591a1c0037c388d51a4f18b5fb5e (diff)
downloadart-b38d483b742eafc7833fac1ebb4fa1481cbac179.zip
art-b38d483b742eafc7833fac1ebb4fa1481cbac179.tar.gz
art-b38d483b742eafc7833fac1ebb4fa1481cbac179.tar.bz2
Fix race condition in TransitionCollector.
There was a race condition where if multiple threads were calling TransitionCollector it could cause a crash due to an invalid collector transition if another thread did the collector transition before the SuspendAll. Bug: 13929101 Change-Id: I8c162a83c1f53d0cbdefab62b0a5bcbb151d6c42
Diffstat (limited to 'runtime/gc')
-rw-r--r--runtime/gc/heap.cc7
1 files changed, 7 insertions, 0 deletions
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 91f249a..fcf9fe9 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -1408,6 +1408,13 @@ void Heap::TransitionCollector(CollectorType collector_type) {
MutexLock mu(self, *gc_complete_lock_);
// Ensure there is only one GC at a time.
WaitForGcToCompleteLocked(self);
+ // If someone else beat us to it and changed the collector before we could, exit.
+ // This is safe to do before the suspend all since we set the collector_type_running_ before
+ // we exit the loop. If another thread attempts to do the heap transition before we exit,
+ // then it would get blocked on WaitForGcToCompleteLocked.
+ if (collector_type == collector_type_) {
+ return;
+ }
// GC can be disabled if someone has a used GetPrimitiveArrayCritical but not yet released.
if (!copying_transition || disable_moving_gc_count_ == 0) {
// TODO: Not hard code in semi-space collector?