diff options
| -rw-r--r-- | runtime/gc/collector/concurrent_copying.h | 5 | ||||
| -rw-r--r-- | runtime/gc_root-inl.h | 5 | ||||
| -rw-r--r-- | runtime/gc_root.h | 3 | ||||
| -rw-r--r-- | runtime/jit/profiling_info.cc | 2 | ||||
| -rw-r--r-- | runtime/read_barrier-inl.h | 20 | ||||
| -rw-r--r-- | runtime/read_barrier.h | 4 |
6 files changed, 36 insertions, 3 deletions
diff --git a/runtime/gc/collector/concurrent_copying.h b/runtime/gc/collector/concurrent_copying.h index c09e0eb109..377f4d30ba 100644 --- a/runtime/gc/collector/concurrent_copying.h +++ b/runtime/gc/collector/concurrent_copying.h @@ -135,6 +135,9 @@ class ConcurrentCopying : public GarbageCollector { void RevokeThreadLocalMarkStack(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!mark_stack_lock_); + virtual mirror::Object* IsMarked(mirror::Object* from_ref) OVERRIDE + REQUIRES_SHARED(Locks::mutator_lock_); + private: void PushOntoMarkStack(mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!mark_stack_lock_); @@ -200,8 +203,6 @@ class ConcurrentCopying : public GarbageCollector { bool do_atomic_update) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!mark_stack_lock_, !skipped_blocks_lock_, !immune_gray_stack_lock_); - virtual mirror::Object* IsMarked(mirror::Object* from_ref) OVERRIDE - REQUIRES_SHARED(Locks::mutator_lock_); bool IsMarkedInUnevacFromSpace(mirror::Object* from_ref) REQUIRES_SHARED(Locks::mutator_lock_); virtual bool IsNullOrMarkedHeapReference(mirror::HeapReference<mirror::Object>* field, diff --git a/runtime/gc_root-inl.h b/runtime/gc_root-inl.h index 7795c661b6..66f605b646 100644 --- a/runtime/gc_root-inl.h +++ b/runtime/gc_root-inl.h @@ -34,6 +34,11 @@ inline MirrorType* GcRoot<MirrorType>::Read(GcRootSource* gc_root_source) const } template<class MirrorType> +inline MirrorType* GcRoot<MirrorType>::ReadIfMarked() const { + return down_cast<MirrorType*>(ReadBarrier::IsMarked(Read<kWithoutReadBarrier>())); +} + +template<class MirrorType> inline GcRoot<MirrorType>::GcRoot(MirrorType* ref) : root_(mirror::CompressedReference<mirror::Object>::FromMirrorPtr(ref)) { } diff --git a/runtime/gc_root.h b/runtime/gc_root.h index 0894e9bee5..57e407c945 100644 --- a/runtime/gc_root.h +++ b/runtime/gc_root.h @@ -188,6 +188,9 @@ class GcRoot { ALWAYS_INLINE MirrorType* Read(GcRootSource* gc_root_source = nullptr) const REQUIRES_SHARED(Locks::mutator_lock_); + // Return the mirror Object if it is marked, or null if not. + ALWAYS_INLINE MirrorType* ReadIfMarked() const REQUIRES_SHARED(Locks::mutator_lock_); + void VisitRoot(RootVisitor* visitor, const RootInfo& info) const REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(!IsNull()); diff --git a/runtime/jit/profiling_info.cc b/runtime/jit/profiling_info.cc index 7d80d2c208..2d85611e95 100644 --- a/runtime/jit/profiling_info.cc +++ b/runtime/jit/profiling_info.cc @@ -90,7 +90,7 @@ InlineCache* ProfilingInfo::GetInlineCache(uint32_t dex_pc) { void ProfilingInfo::AddInvokeInfo(uint32_t dex_pc, mirror::Class* cls) { InlineCache* cache = GetInlineCache(dex_pc); for (size_t i = 0; i < InlineCache::kIndividualCacheSize; ++i) { - mirror::Class* existing = cache->classes_[i].Read(); + mirror::Class* existing = cache->classes_[i].ReadIfMarked(); if (existing == cls) { // Receiver type is already in the cache, nothing else to do. return; diff --git a/runtime/read_barrier-inl.h b/runtime/read_barrier-inl.h index d3859b0dfa..dbe7f5c957 100644 --- a/runtime/read_barrier-inl.h +++ b/runtime/read_barrier-inl.h @@ -182,6 +182,26 @@ inline MirrorType* ReadBarrier::BarrierForRoot(mirror::CompressedReference<Mirro } } +template <typename MirrorType> +inline MirrorType* ReadBarrier::IsMarked(MirrorType* ref) { + // Only read-barrier configurations can have mutators run while + // the GC is marking. + if (!kUseReadBarrier) { + return ref; + } + // IsMarked does not handle null, so handle it here. + if (ref == nullptr) { + return nullptr; + } + // IsMarked should only be called when the GC is marking. + if (!Thread::Current()->GetIsGcMarking()) { + return ref; + } + + return reinterpret_cast<MirrorType*>( + Runtime::Current()->GetHeap()->ConcurrentCopyingCollector()->IsMarked(ref)); +} + inline bool ReadBarrier::IsDuringStartup() { gc::Heap* heap = Runtime::Current()->GetHeap(); if (heap == nullptr) { diff --git a/runtime/read_barrier.h b/runtime/read_barrier.h index cbc26977fb..207652d320 100644 --- a/runtime/read_barrier.h +++ b/runtime/read_barrier.h @@ -64,6 +64,10 @@ class ReadBarrier { GcRootSource* gc_root_source = nullptr) REQUIRES_SHARED(Locks::mutator_lock_); + template <typename MirrorType> + ALWAYS_INLINE static MirrorType* IsMarked(MirrorType* ref) + REQUIRES_SHARED(Locks::mutator_lock_); + static bool IsDuringStartup(); // Without the holder object. |