diff options
| -rw-r--r-- | runtime/gc/collector/mark_sweep.cc | 27 | ||||
| -rw-r--r-- | runtime/gc/collector/mark_sweep.h | 6 | ||||
| -rw-r--r-- | runtime/utils.h | 13 |
3 files changed, 21 insertions, 25 deletions
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc index a5e66d20df..2c69c77187 100644 --- a/runtime/gc/collector/mark_sweep.cc +++ b/runtime/gc/collector/mark_sweep.cc @@ -776,7 +776,6 @@ class CardScanTask : public MarkStackTask<false> { ScanObjectParallelVisitor visitor(this); accounting::CardTable* card_table = mark_sweep_->GetHeap()->GetCardTable(); size_t cards_scanned = card_table->Scan(bitmap_, begin_, end_, visitor, minimum_age_); - mark_sweep_->cards_scanned_.fetch_add(cards_scanned); VLOG(heap) << "Parallel scanning cards " << reinterpret_cast<void*>(begin_) << " - " << reinterpret_cast<void*>(end_) << " = " << cards_scanned; // Finish by emptying our local mark stack. @@ -814,11 +813,14 @@ void MarkSweep::ScanGrayObjects(bool paused, byte minimum_age) { DCHECK_NE(mark_stack_tasks, 0U); const size_t mark_stack_delta = std::min(CardScanTask::kMaxSize / 2, mark_stack_size / mark_stack_tasks + 1); - size_t ref_card_count = 0; - cards_scanned_ = 0; for (const auto& space : GetHeap()->GetContinuousSpaces()) { byte* card_begin = space->Begin(); byte* card_end = space->End(); + // Align up the end address. For example, the image space's end + // may not be card-size-aligned. + card_end = AlignUp(card_end, accounting::CardTable::kCardSize); + DCHECK(IsAligned<accounting::CardTable::kCardSize>(card_begin)); + DCHECK(IsAligned<accounting::CardTable::kCardSize>(card_end)); // Calculate how many bytes of heap we will scan, const size_t address_range = card_end - card_begin; // Calculate how much address range each task gets. @@ -842,24 +844,15 @@ void MarkSweep::ScanGrayObjects(bool paused, byte minimum_age) { thread_pool->AddTask(self, task); card_begin += card_increment; } - - if (paused && kIsDebugBuild) { - // Make sure we don't miss scanning any cards. - size_t scanned_cards = card_table->Scan(space->GetMarkBitmap(), space->Begin(), - space->End(), VoidFunctor(), minimum_age); - VLOG(heap) << "Scanning space cards " << reinterpret_cast<void*>(space->Begin()) << " - " - << reinterpret_cast<void*>(space->End()) << " = " << scanned_cards; - ref_card_count += scanned_cards; - } } + // Note: the card scan below may dirty new cards (and scan them) + // as a side effect when a Reference object is encountered and + // queued during the marking. See b/11465268. thread_pool->SetMaxActiveWorkers(thread_count - 1); thread_pool->StartWorkers(self); thread_pool->Wait(self, true, true); thread_pool->StopWorkers(self); - if (paused) { - DCHECK_EQ(ref_card_count, static_cast<size_t>(cards_scanned_.load())); - } timings_.EndSplit(); } else { for (const auto& space : GetHeap()->GetContinuousSpaces()) { @@ -1356,10 +1349,6 @@ void MarkSweep::DelayReferenceReferent(mirror::Class* klass, Object* obj) { } } -void MarkSweep::ScanRoot(const Object* obj) { - ScanObject(obj); -} - class MarkObjectVisitor { public: explicit MarkObjectVisitor(MarkSweep* const mark_sweep) ALWAYS_INLINE : mark_sweep_(mark_sweep) {} diff --git a/runtime/gc/collector/mark_sweep.h b/runtime/gc/collector/mark_sweep.h index 7e051369f0..3bc014aa1e 100644 --- a/runtime/gc/collector/mark_sweep.h +++ b/runtime/gc/collector/mark_sweep.h @@ -157,11 +157,6 @@ class MarkSweep : public GarbageCollector { return cleared_reference_list_; } - // Proxy for external access to ScanObject. - void ScanRoot(const mirror::Object* obj) - EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - // Blackens an object. void ScanObject(const mirror::Object* obj) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) @@ -438,7 +433,6 @@ class MarkSweep : public GarbageCollector { AtomicInteger work_chunks_created_; AtomicInteger work_chunks_deleted_; AtomicInteger reference_count_; - AtomicInteger cards_scanned_; // Verification. size_t live_stack_freeze_size_; diff --git a/runtime/utils.h b/runtime/utils.h index 0174b37dcc..51035b697f 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -119,6 +119,7 @@ struct TypeStaticIf<false, A, B> { typedef B value; }; +// For rounding integers. template<typename T> static inline T RoundDown(T x, int n) { CHECK(IsPowerOfTwo(n)); @@ -130,6 +131,18 @@ static inline T RoundUp(T x, int n) { return RoundDown(x + n - 1, n); } +// For aligning pointers. +template<typename T> +static inline T* AlignDown(T* x, int n) { + CHECK(IsPowerOfTwo(n)); + return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(x) & -static_cast<uintptr_t>(n)); +} + +template<typename T> +static inline T* AlignUp(T* x, int n) { + return AlignDown(reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(x) + static_cast<uintptr_t>(n - 1)), n); +} + // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr., // figure 3-3, page 48, where the function is called clp2. static inline uint32_t RoundUpToPowerOfTwo(uint32_t x) { |