diff options
| author | 2017-01-05 17:53:00 -0800 | |
|---|---|---|
| committer | 2017-01-05 18:19:07 -0800 | |
| commit | 6abd53926e30bde0cb3c80a308e047595007f855 (patch) | |
| tree | b72b69be4b822765855baf632ec30f7a1ff7a937 | |
| parent | 8ba654956553d79a2478f6d050044c5a963a3512 (diff) | |
Prevent moving GC from running during redefinition.
This could cause a deadlock during deoptimization.
Test: ART_USE_READ_BARRIER=true ART_READ_BARRIER_TYPE=TABLELOOKUP mma -j40 test-art-host
Change-Id: I57e4f1a50709bf4a1817227913e61f3ef434d04a
| -rw-r--r-- | runtime/openjdkjvmti/ti_redefine.cc | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc index 57cc938ec7..926819d1d0 100644 --- a/runtime/openjdkjvmti/ti_redefine.cc +++ b/runtime/openjdkjvmti/ti_redefine.cc @@ -39,6 +39,7 @@ #include "base/logging.h" #include "events-inl.h" #include "gc/allocation_listener.h" +#include "gc/heap.h" #include "instrumentation.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" @@ -574,6 +575,13 @@ jvmtiError Redefiner::Run() { } // Get the mirror class now that we aren't allocating anymore. art::Handle<art::mirror::Class> art_class(hs.NewHandle(GetMirrorClass())); + // Disable GC and wait for it to be done if we are a moving GC. This is fine since we are done + // allocating so no deadlocks. + art::gc::Heap* heap = runtime_->GetHeap(); + if (heap->IsGcConcurrentAndMoving()) { + // GC moving objects can cause deadlocks as we are deoptimizing the stack. + heap->IncrementDisableMovingGC(self_); + } // Enable assertion that this thread isn't interrupted during this installation. // After this we will need to do real cleanup in case of failure. Prior to this we could simply // return and would let everything get cleaned up or harmlessly leaked. @@ -601,6 +609,9 @@ jvmtiError Redefiner::Run() { runtime_->GetThreadList()->ResumeAll(); // Get back shared mutator lock as expected for return. self_->TransitionFromSuspendedToRunnable(); + if (heap->IsGcConcurrentAndMoving()) { + heap->DecrementDisableMovingGC(self_); + } return result_; } if (!UpdateClass(art_class.Get(), new_dex_cache.Get())) { @@ -610,6 +621,9 @@ jvmtiError Redefiner::Run() { runtime_->GetThreadList()->ResumeAll(); // Get back shared mutator lock as expected for return. self_->TransitionFromSuspendedToRunnable(); + if (heap->IsGcConcurrentAndMoving()) { + heap->DecrementDisableMovingGC(self_); + } return result_; } // Ensure that obsolete methods are deoptimized. This is needed since optimized methods may have @@ -632,6 +646,9 @@ jvmtiError Redefiner::Run() { // TODO Do the dex_file_ release at a more reasonable place. This works but it muddles who really // owns the DexFile. dex_file_.release(); + if (heap->IsGcConcurrentAndMoving()) { + heap->DecrementDisableMovingGC(self_); + } return OK; } |