summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/gc/collector/concurrent_copying.h5
-rw-r--r--runtime/gc_root-inl.h5
-rw-r--r--runtime/gc_root.h3
-rw-r--r--runtime/jit/profiling_info.cc2
-rw-r--r--runtime/read_barrier-inl.h20
-rw-r--r--runtime/read_barrier.h4
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.