152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier/* 252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * Copyright (C) 2014 The Android Open Source Project 352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * 452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License"); 552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * you may not use this file except in compliance with the License. 652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * You may obtain a copy of the License at 752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * 852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * http://www.apache.org/licenses/LICENSE-2.0 952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * 1052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * Unless required by applicable law or agreed to in writing, software 1152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS, 1252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * See the License for the specific language governing permissions and 1452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier * limitations under the License. 1552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier */ 1652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 1752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "mark_compact.h" 1852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 1952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "base/logging.h" 2052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "base/mutex-inl.h" 2152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "base/timing_logger.h" 2252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/accounting/heap_bitmap-inl.h" 2352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/accounting/mod_union_table.h" 2452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/accounting/remembered_set.h" 2552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/accounting/space_bitmap-inl.h" 2652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/heap.h" 2752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/reference_processor.h" 2852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/space/bump_pointer_space.h" 2952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/space/bump_pointer_space-inl.h" 3052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/space/image_space.h" 3152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/space/large_object_space.h" 3252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "gc/space/space-inl.h" 3352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "indirect_reference_table.h" 3452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "intern_table.h" 3552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "jni_internal.h" 3652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "mark_sweep-inl.h" 3752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "monitor.h" 3852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "mirror/class-inl.h" 3952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "mirror/class_loader.h" 4052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "mirror/dex_cache.h" 4152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "mirror/reference-inl.h" 4252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "mirror/object-inl.h" 4352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "mirror/object_array.h" 4452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "mirror/object_array-inl.h" 4552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "runtime.h" 4652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "stack.h" 4752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "thread-inl.h" 4852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "thread_list.h" 4952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 5052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierusing ::art::mirror::Object; 5152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 5252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiernamespace art { 5352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiernamespace gc { 5452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiernamespace collector { 5552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 5652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::BindBitmaps() { 57f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 5852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_); 5952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Mark all of the spaces we never collect as immune. 6052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier for (const auto& space : GetHeap()->GetContinuousSpaces()) { 6152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (space->GetGcRetentionPolicy() == space::kGcRetentionPolicyNeverCollect || 6252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier space->GetGcRetentionPolicy() == space::kGcRetentionPolicyFullCollect) { 6352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CHECK(immune_region_.AddContinuousSpace(space)) << "Failed to add space " << *space; 6452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 6552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 6652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 6752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 6852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu ChartierMarkCompact::MarkCompact(Heap* heap, const std::string& name_prefix) 6952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier : GarbageCollector(heap, name_prefix + (name_prefix.empty() ? "" : " ") + "mark compact"), 7052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier space_(nullptr), collector_name_(name_) { 7152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 7252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 7352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::RunPhases() { 7452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier Thread* self = Thread::Current(); 7552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier InitializePhase(); 7652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CHECK(!Locks::mutator_lock_->IsExclusiveHeld(self)); 7752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier { 7852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ScopedPause pause(this); 7952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier GetHeap()->PreGcVerificationPaused(this); 8052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier GetHeap()->PrePauseRosAllocVerification(this); 8152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkingPhase(); 8252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ReclaimPhase(); 8352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 8452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier GetHeap()->PostGcVerification(this); 8552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier FinishPhase(); 8652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 8752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 8852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::ForwardObject(mirror::Object* obj) { 8952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier const size_t alloc_size = RoundUp(obj->SizeOf(), space::BumpPointerSpace::kAlignment); 9052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier LockWord lock_word = obj->GetLockWord(false); 9152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // If we have a non empty lock word, store it and restore it later. 92e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi if (!LockWord::IsDefault(lock_word)) { 9352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Set the bit in the bitmap so that we know to restore it later. 9452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier objects_with_lockword_->Set(obj); 9552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier lock_words_to_restore_.push_back(lock_word); 9652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 9752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier obj->SetLockWord(LockWord::FromForwardingAddress(reinterpret_cast<size_t>(bump_pointer_)), 9852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier false); 9952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier bump_pointer_ += alloc_size; 10052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ++live_objects_in_space_; 10152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 10252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 10352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierclass CalculateObjectForwardingAddressVisitor { 10452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier public: 10552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier explicit CalculateObjectForwardingAddressVisitor(MarkCompact* collector) 10652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier : collector_(collector) {} 10752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void operator()(mirror::Object* obj) const EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, 10852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier Locks::heap_bitmap_lock_) { 10952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK_ALIGNED(obj, space::BumpPointerSpace::kAlignment); 11052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(collector_->IsMarked(obj)); 11152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier collector_->ForwardObject(obj); 11252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 11352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 11452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier private: 11552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkCompact* const collector_; 11652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier}; 11752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 11852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::CalculateObjectForwardingAddresses() { 119f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 12052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // The bump pointer in the space where the next forwarding address will be. 12113735955f39b3b304c37d2b2840663c131262c18Ian Rogers bump_pointer_ = reinterpret_cast<uint8_t*>(space_->Begin()); 12252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Visit all the marked objects in the bitmap. 12352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CalculateObjectForwardingAddressVisitor visitor(this); 12452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier objects_before_forwarding_->VisitMarkedRange(reinterpret_cast<uintptr_t>(space_->Begin()), 12552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<uintptr_t>(space_->End()), 12652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier visitor); 12752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 12852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 12952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::InitializePhase() { 130f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 13152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier mark_stack_ = heap_->GetMarkStack(); 13252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(mark_stack_ != nullptr); 13352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier immune_region_.Reset(); 13452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CHECK(space_->CanMoveObjects()) << "Attempting compact non-movable space from " << *space_; 13552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // TODO: I don't think we should need heap bitmap lock to Get the mark bitmap. 13652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ReaderMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_); 13752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier mark_bitmap_ = heap_->GetMarkBitmap(); 13852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier live_objects_in_space_ = 0; 13952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 14052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 14152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::ProcessReferences(Thread* self) { 14252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier WriterMutexLock mu(self, *Locks::heap_bitmap_lock_); 14352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier heap_->GetReferenceProcessor()->ProcessReferences( 14410fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier false, GetTimings(), GetCurrentIteration()->GetClearSoftReferences(), 14510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier &HeapReferenceMarkedCallback, &MarkObjectCallback, &ProcessMarkStackCallback, this); 14652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 14752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 14852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierclass BitmapSetSlowPathVisitor { 14952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier public: 15052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void operator()(const mirror::Object* obj) const { 15152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Marking a large object, make sure its aligned as a sanity check. 15252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (!IsAligned<kPageSize>(obj)) { 15352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR)); 15452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier LOG(FATAL) << obj; 15552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 15652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 15752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier}; 15852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 15952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierinline void MarkCompact::MarkObject(mirror::Object* obj) { 16052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (obj == nullptr) { 16152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return; 16252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 16352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (kUseBakerOrBrooksReadBarrier) { 16452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Verify all the objects have the correct forward pointer installed. 16552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier obj->AssertReadBarrierPointer(); 16652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 16752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (immune_region_.ContainsObject(obj)) { 16852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return; 16952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 17052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (objects_before_forwarding_->HasAddress(obj)) { 17152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (!objects_before_forwarding_->Set(obj)) { 17252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkStackPush(obj); // This object was not previously marked. 17352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 17452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } else { 17552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(!space_->HasAddress(obj)); 17652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier BitmapSetSlowPathVisitor visitor; 17752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (!mark_bitmap_->Set(obj, visitor)) { 17852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // This object was not previously marked. 17952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkStackPush(obj); 18052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 18152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 18252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 18352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 18452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::MarkingPhase() { 185f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 18652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier Thread* self = Thread::Current(); 18752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Bitmap which describes which objects we have to move. 18852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier objects_before_forwarding_.reset(accounting::ContinuousSpaceBitmap::Create( 18952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier "objects before forwarding", space_->Begin(), space_->Size())); 19052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Bitmap which describes which lock words we need to restore. 19152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier objects_with_lockword_.reset(accounting::ContinuousSpaceBitmap::Create( 19252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier "objects with lock words", space_->Begin(), space_->Size())); 19352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CHECK(Locks::mutator_lock_->IsExclusiveHeld(self)); 19452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Assume the cleared space is already empty. 19552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier BindBitmaps(); 196f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier t.NewTiming("ProcessCards"); 19752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Process dirty cards and add dirty cards to mod-union tables. 1984add3b4fa38ec42bb3c71d01cf70bce8e9a9fb4eLei Li heap_->ProcessCards(GetTimings(), false, false, true); 19952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Clear the whole card table since we can not Get any additional dirty cards during the 20052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // paused GC. This saves memory but only works for pause the world collectors. 201f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier t.NewTiming("ClearCardTable"); 20252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier heap_->GetCardTable()->ClearCardTable(); 20352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Need to do this before the checkpoint since we don't want any threads to add references to 20452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // the live stack during the recursive mark. 20552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (kUseThreadLocalAllocationStack) { 206f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier t.NewTiming("RevokeAllThreadLocalAllocationStacks"); 20752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier heap_->RevokeAllThreadLocalAllocationStacks(self); 20852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 209f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier t.NewTiming("SwapStacks"); 21052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier heap_->SwapStacks(self); 21152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier { 21252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier WriterMutexLock mu(self, *Locks::heap_bitmap_lock_); 21352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkRoots(); 21452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Mark roots of immune spaces. 21552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier UpdateAndMarkModUnion(); 21652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Recursively mark remaining objects. 21752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkReachableObjects(); 21852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 21952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ProcessReferences(self); 22052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier { 22152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_); 22252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier SweepSystemWeaks(); 22352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 22452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Revoke buffers before measuring how many objects were moved since the TLABs need to be revoked 22552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // before they are properly counted. 22652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier RevokeAllThreadLocalBuffers(); 22752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Disabled due to an issue where we have objects in the bump pointer space which reference dead 22852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // objects. 22952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // heap_->PreSweepingGcVerification(this); 23052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 23152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 23252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::UpdateAndMarkModUnion() { 233f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 23452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier for (auto& space : heap_->GetContinuousSpaces()) { 23552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // If the space is immune then we need to mark the references to other spaces. 23652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (immune_region_.ContainsSpace(space)) { 23752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier accounting::ModUnionTable* table = heap_->FindModUnionTableFromSpace(space); 23852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (table != nullptr) { 23952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // TODO: Improve naming. 240277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe TimingLogger::ScopedTiming t2( 24152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier space->IsZygoteSpace() ? "UpdateAndMarkZygoteModUnionTable" : 24210fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier "UpdateAndMarkImageModUnionTable", GetTimings()); 24352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier table->UpdateAndMarkReferences(MarkHeapReferenceCallback, this); 24452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 24552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 24652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 24752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 24852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 24952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::MarkReachableObjects() { 250f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 25152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier accounting::ObjectStack* live_stack = heap_->GetLiveStack(); 252f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier { 253f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t2("MarkAllocStackAsLive", GetTimings()); 254f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier heap_->MarkAllocStackAsLive(live_stack); 255f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier } 25652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier live_stack->Reset(); 25752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Recursively process the mark stack. 25852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ProcessMarkStack(); 25952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 26052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 26152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::ReclaimPhase() { 262f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 26352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_); 26452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Reclaim unmarked objects. 26552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier Sweep(false); 26652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Swap the live and mark bitmaps for each space which we modified space. This is an 26752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // optimization that enables us to not clear live bits inside of the sweep. Only swaps unbound 26852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // bitmaps. 26952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier SwapBitmaps(); 27052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier GetHeap()->UnBindBitmaps(); // Unbind the live and mark bitmaps. 27152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier Compact(); 27252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 27352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 27452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::ResizeMarkStack(size_t new_size) { 275cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier std::vector<StackReference<Object>> temp(mark_stack_->Begin(), mark_stack_->End()); 27652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CHECK_LE(mark_stack_->Size(), new_size); 27752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier mark_stack_->Resize(new_size); 278cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier for (auto& obj : temp) { 279cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier mark_stack_->PushBack(obj.AsMirrorPtr()); 28052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 28152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 28252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 28352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierinline void MarkCompact::MarkStackPush(Object* obj) { 28452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (UNLIKELY(mark_stack_->Size() >= mark_stack_->Capacity())) { 28552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ResizeMarkStack(mark_stack_->Capacity() * 2); 28652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 28752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // The object must be pushed on to the mark stack. 28852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier mark_stack_->PushBack(obj); 28952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 29052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 29152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::ProcessMarkStackCallback(void* arg) { 29252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<MarkCompact*>(arg)->ProcessMarkStack(); 29352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 29452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 29552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiermirror::Object* MarkCompact::MarkObjectCallback(mirror::Object* root, void* arg) { 29652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<MarkCompact*>(arg)->MarkObject(root); 29752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return root; 29852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 29952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 30052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::MarkHeapReferenceCallback(mirror::HeapReference<mirror::Object>* obj_ptr, 301e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier void* arg) { 30252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<MarkCompact*>(arg)->MarkObject(obj_ptr->AsMirrorPtr()); 30352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 30452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 30552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::DelayReferenceReferentCallback(mirror::Class* klass, mirror::Reference* ref, 306e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier void* arg) { 30752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<MarkCompact*>(arg)->DelayReferenceReferent(klass, ref); 30852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 30952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 310bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid MarkCompact::VisitRoots( 311bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::Object*** roots, size_t count, const RootInfo& info ATTRIBUTE_UNUSED) { 312bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier for (size_t i = 0; i < count; ++i) { 313bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier MarkObject(*roots[i]); 314bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 31552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 31652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 317bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid MarkCompact::VisitRoots( 318bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::CompressedReference<mirror::Object>** roots, size_t count, 319bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier const RootInfo& info ATTRIBUTE_UNUSED) { 320bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier for (size_t i = 0; i < count; ++i) { 321bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier MarkObject(roots[i]->AsMirrorPtr()); 32252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 32352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 32452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 325bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass UpdateRootVisitor : public RootVisitor { 326bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public: 327bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier explicit UpdateRootVisitor(MarkCompact* collector) : collector_(collector) { 328bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 329bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 330bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info ATTRIBUTE_UNUSED) 331bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier OVERRIDE EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 332bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { 333bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier for (size_t i = 0; i < count; ++i) { 334bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::Object* obj = *roots[i]; 335bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::Object* new_obj = collector_->GetMarkedForwardAddress(obj); 336bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (obj != new_obj) { 337bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier *roots[i] = new_obj; 338bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier DCHECK(new_obj != nullptr); 339bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 340bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 341bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 342bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 343bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count, 344bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier const RootInfo& info ATTRIBUTE_UNUSED) 345bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier OVERRIDE EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 346bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { 347bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier for (size_t i = 0; i < count; ++i) { 348bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::Object* obj = roots[i]->AsMirrorPtr(); 349bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::Object* new_obj = collector_->GetMarkedForwardAddress(obj); 350bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (obj != new_obj) { 351bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier roots[i]->Assign(new_obj); 352bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier DCHECK(new_obj != nullptr); 353bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 354bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 355bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 356bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 357bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier private: 358bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier MarkCompact* const collector_; 359bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 360bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 36152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierclass UpdateObjectReferencesVisitor { 36252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier public: 36352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier explicit UpdateObjectReferencesVisitor(MarkCompact* collector) : collector_(collector) { 36452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 36552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void operator()(mirror::Object* obj) const SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) 36652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE { 36752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier collector_->UpdateObjectReferences(obj); 36852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 36952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 37052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier private: 37152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkCompact* const collector_; 37252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier}; 37352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 37452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::UpdateReferences() { 375f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 37652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier Runtime* runtime = Runtime::Current(); 37752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Update roots. 378bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier UpdateRootVisitor update_root_visitor(this); 379bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier runtime->VisitRoots(&update_root_visitor); 38052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Update object references in mod union tables and spaces. 38152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier for (const auto& space : heap_->GetContinuousSpaces()) { 38252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // If the space is immune then we need to mark the references to other spaces. 38352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier accounting::ModUnionTable* table = heap_->FindModUnionTableFromSpace(space); 38452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (table != nullptr) { 38552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // TODO: Improve naming. 386277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe TimingLogger::ScopedTiming t2( 38752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier space->IsZygoteSpace() ? "UpdateZygoteModUnionTableReferences" : 38852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier "UpdateImageModUnionTableReferences", 38910fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier GetTimings()); 39052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier table->UpdateAndMarkReferences(&UpdateHeapReferenceCallback, this); 39152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } else { 39252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // No mod union table, so we need to scan the space using bitmap visit. 39352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Scan the space using bitmap visit. 39452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier accounting::ContinuousSpaceBitmap* bitmap = space->GetLiveBitmap(); 39552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (bitmap != nullptr) { 39652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier UpdateObjectReferencesVisitor visitor(this); 39752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier bitmap->VisitMarkedRange(reinterpret_cast<uintptr_t>(space->Begin()), 39852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<uintptr_t>(space->End()), 39952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier visitor); 40052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 40152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 40252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 40352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CHECK(!kMovingClasses) 40452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier << "Didn't update large object classes since they are assumed to not move."; 40552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Update the system weaks, these should already have been swept. 40652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier runtime->SweepSystemWeaks(&MarkedForwardingAddressCallback, this); 40752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Update the objects in the bump pointer space last, these objects don't have a bitmap. 40852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier UpdateObjectReferencesVisitor visitor(this); 40952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier objects_before_forwarding_->VisitMarkedRange(reinterpret_cast<uintptr_t>(space_->Begin()), 41052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<uintptr_t>(space_->End()), 41152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier visitor); 41252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Update the reference processor cleared list. 41352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier heap_->GetReferenceProcessor()->UpdateRoots(&MarkedForwardingAddressCallback, this); 41452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 41552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 41652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::Compact() { 417f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 41852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CalculateObjectForwardingAddresses(); 41952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier UpdateReferences(); 42052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MoveObjects(); 42152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Space 42252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier int64_t objects_freed = space_->GetObjectsAllocated() - live_objects_in_space_; 42352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier int64_t bytes_freed = reinterpret_cast<int64_t>(space_->End()) - 42452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<int64_t>(bump_pointer_); 425f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier t.NewTiming("RecordFree"); 42652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier space_->RecordFree(objects_freed, bytes_freed); 42710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier RecordFree(ObjectBytePair(objects_freed, bytes_freed)); 42852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier space_->SetEnd(bump_pointer_); 42952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Need to zero out the memory we freed. TODO: Use madvise for pages. 43052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier memset(bump_pointer_, 0, bytes_freed); 43152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 43252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 43352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier// Marks all objects in the root set. 43452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::MarkRoots() { 435f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 436bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier Runtime::Current()->VisitRoots(this); 43752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 43852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 43952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiermirror::Object* MarkCompact::MarkedForwardingAddressCallback(mirror::Object* obj, void* arg) { 44052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return reinterpret_cast<MarkCompact*>(arg)->GetMarkedForwardAddress(obj); 44152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 44252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 44352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierinline void MarkCompact::UpdateHeapReference(mirror::HeapReference<mirror::Object>* reference) { 44452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier mirror::Object* obj = reference->AsMirrorPtr(); 44552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (obj != nullptr) { 44652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier mirror::Object* new_obj = GetMarkedForwardAddress(obj); 44752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (obj != new_obj) { 44852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(new_obj != nullptr); 44952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reference->Assign(new_obj); 45052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 45152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 45252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 45352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 45452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::UpdateHeapReferenceCallback(mirror::HeapReference<mirror::Object>* reference, 45552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void* arg) { 45652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<MarkCompact*>(arg)->UpdateHeapReference(reference); 45752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 45852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 45952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierclass UpdateReferenceVisitor { 46052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier public: 46152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier explicit UpdateReferenceVisitor(MarkCompact* collector) : collector_(collector) { 46252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 46352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 46452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void operator()(Object* obj, MemberOffset offset, bool /*is_static*/) const 46552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ALWAYS_INLINE EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) { 46652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier collector_->UpdateHeapReference(obj->GetFieldObjectReferenceAddr<kVerifyNone>(offset)); 46752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 46852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 46952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void operator()(mirror::Class* /*klass*/, mirror::Reference* ref) const 47052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) { 47152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier collector_->UpdateHeapReference( 47252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ref->GetFieldObjectReferenceAddr<kVerifyNone>(mirror::Reference::ReferentOffset())); 47352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 47452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 47552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier private: 47652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkCompact* const collector_; 47752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier}; 47852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 47952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::UpdateObjectReferences(mirror::Object* obj) { 48052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier UpdateReferenceVisitor visitor(this); 48152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier obj->VisitReferences<kMovingClasses>(visitor, visitor); 48252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 48352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 48452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierinline mirror::Object* MarkCompact::GetMarkedForwardAddress(mirror::Object* obj) const { 48552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(obj != nullptr); 48652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (objects_before_forwarding_->HasAddress(obj)) { 48752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(objects_before_forwarding_->Test(obj)); 48852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier mirror::Object* ret = 48952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<mirror::Object*>(obj->GetLockWord(false).ForwardingAddress()); 49052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(ret != nullptr); 49152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return ret; 49252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 49352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(!space_->HasAddress(obj)); 49452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(IsMarked(obj)); 49552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return obj; 49652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 49752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 49852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierinline bool MarkCompact::IsMarked(const Object* object) const { 49952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (immune_region_.ContainsObject(object)) { 50052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return true; 50152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 50252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (objects_before_forwarding_->HasAddress(object)) { 50352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return objects_before_forwarding_->Test(object); 50452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 50552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return mark_bitmap_->Test(object); 50652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 50752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 50852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiermirror::Object* MarkCompact::IsMarkedCallback(mirror::Object* object, void* arg) { 50952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return reinterpret_cast<MarkCompact*>(arg)->IsMarked(object) ? object : nullptr; 51052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 51152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 51252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierbool MarkCompact::HeapReferenceMarkedCallback(mirror::HeapReference<mirror::Object>* ref_ptr, 51352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void* arg) { 51452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Side effect free since we call this before ever moving objects. 51552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return reinterpret_cast<MarkCompact*>(arg)->IsMarked(ref_ptr->AsMirrorPtr()); 51652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 51752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 51852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::SweepSystemWeaks() { 519f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 52052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier Runtime::Current()->SweepSystemWeaks(IsMarkedCallback, this); 52152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 52252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 52352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierbool MarkCompact::ShouldSweepSpace(space::ContinuousSpace* space) const { 52452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier return space != space_ && !immune_region_.ContainsSpace(space); 52552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 52652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 52752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierclass MoveObjectVisitor { 52852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier public: 52952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier explicit MoveObjectVisitor(MarkCompact* collector) : collector_(collector) { 53052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 53152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void operator()(mirror::Object* obj) const SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) 53252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE { 53352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier collector_->MoveObject(obj, obj->SizeOf()); 53452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 53552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 53652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier private: 53752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkCompact* const collector_; 53852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier}; 53952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 54052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::MoveObject(mirror::Object* obj, size_t len) { 54152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Look at the forwarding address stored in the lock word to know where to copy. 54252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(space_->HasAddress(obj)) << obj; 54352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier uintptr_t dest_addr = obj->GetLockWord(false).ForwardingAddress(); 54452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier mirror::Object* dest_obj = reinterpret_cast<mirror::Object*>(dest_addr); 54552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(space_->HasAddress(dest_obj)) << dest_obj; 54652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Use memmove since there may be overlap. 54752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier memmove(reinterpret_cast<void*>(dest_addr), reinterpret_cast<const void*>(obj), len); 54852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Restore the saved lock word if needed. 549e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi LockWord lock_word = LockWord::Default(); 55052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (UNLIKELY(objects_with_lockword_->Test(obj))) { 55152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier lock_word = lock_words_to_restore_.front(); 55252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier lock_words_to_restore_.pop_front(); 55352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 55452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier dest_obj->SetLockWord(lock_word, false); 55552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 55652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 55752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::MoveObjects() { 558f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 55952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Move the objects in the before forwarding bitmap. 56052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MoveObjectVisitor visitor(this); 56152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier objects_before_forwarding_->VisitMarkedRange(reinterpret_cast<uintptr_t>(space_->Begin()), 56252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier reinterpret_cast<uintptr_t>(space_->End()), 56352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier visitor); 56452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CHECK(lock_words_to_restore_.empty()); 56552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 56652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 56752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::Sweep(bool swap_bitmaps) { 568f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 56952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(mark_stack_->IsEmpty()); 57052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier for (const auto& space : GetHeap()->GetContinuousSpaces()) { 57152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (space->IsContinuousMemMapAllocSpace()) { 57252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier space::ContinuousMemMapAllocSpace* alloc_space = space->AsContinuousMemMapAllocSpace(); 57352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier if (!ShouldSweepSpace(alloc_space)) { 57452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier continue; 57552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 576277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe TimingLogger::ScopedTiming t2( 57710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier alloc_space->IsZygoteSpace() ? "SweepZygoteSpace" : "SweepAllocSpace", GetTimings()); 57810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier RecordFree(alloc_space->Sweep(swap_bitmaps)); 57952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 58052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 58152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier SweepLargeObjects(swap_bitmaps); 58252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 58352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 58452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::SweepLargeObjects(bool swap_bitmaps) { 5852dbe627954fd78a3659ab3cd42d2ead5b4529441Mathieu Chartier space::LargeObjectSpace* los = heap_->GetLargeObjectsSpace(); 5862dbe627954fd78a3659ab3cd42d2ead5b4529441Mathieu Chartier if (los != nullptr) { 5872dbe627954fd78a3659ab3cd42d2ead5b4529441Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings());\ 5882dbe627954fd78a3659ab3cd42d2ead5b4529441Mathieu Chartier RecordFreeLOS(los->Sweep(swap_bitmaps)); 5892dbe627954fd78a3659ab3cd42d2ead5b4529441Mathieu Chartier } 59052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 59152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 59252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier// Process the "referent" field in a java.lang.ref.Reference. If the referent has not yet been 59352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier// marked, put it on the appropriate list in the heap for later processing. 59452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::DelayReferenceReferent(mirror::Class* klass, mirror::Reference* reference) { 59552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier heap_->GetReferenceProcessor()->DelayReferenceReferent(klass, reference, 59652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier &HeapReferenceMarkedCallback, this); 59752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 59852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 59952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartierclass MarkCompactMarkObjectVisitor { 60052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier public: 60152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier explicit MarkCompactMarkObjectVisitor(MarkCompact* collector) : collector_(collector) { 60252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 60352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 60452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void operator()(Object* obj, MemberOffset offset, bool /*is_static*/) const ALWAYS_INLINE 60552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) { 60652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Object was already verified when we scanned it. 60752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier collector_->MarkObject(obj->GetFieldObject<mirror::Object, kVerifyNone>(offset)); 60852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 60952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 61052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void operator()(mirror::Class* klass, mirror::Reference* ref) const 61152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 61252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { 61352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier collector_->DelayReferenceReferent(klass, ref); 61452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 61552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 61652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier private: 61752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkCompact* const collector_; 61852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier}; 61952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 62052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier// Visit all of the references of an object and update. 62152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::ScanObject(Object* obj) { 62252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier MarkCompactMarkObjectVisitor visitor(this); 62352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier obj->VisitReferences<kMovingClasses>(visitor, visitor); 62452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 62552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 62652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier// Scan anything that's on the mark stack. 62752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::ProcessMarkStack() { 628f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 62952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier while (!mark_stack_->IsEmpty()) { 63052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier Object* obj = mark_stack_->PopBack(); 63152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(obj != nullptr); 63252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier ScanObject(obj); 63352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier } 63452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 63552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 63652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::SetSpace(space::BumpPointerSpace* space) { 63752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(space != nullptr); 63852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier space_ = space; 63952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 64052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 64152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::FinishPhase() { 642f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 64352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier space_ = nullptr; 64452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier CHECK(mark_stack_->IsEmpty()); 64552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier mark_stack_->Reset(); 64652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Clear all of the spaces' mark bitmaps. 64752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_); 64852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier heap_->ClearMarkedObjects(); 64952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier // Release our bitmaps. 65052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier objects_before_forwarding_.reset(nullptr); 65152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier objects_with_lockword_.reset(nullptr); 65252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 65352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 65452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartiervoid MarkCompact::RevokeAllThreadLocalBuffers() { 655f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings()); 65652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier GetHeap()->RevokeAllThreadLocalBuffers(); 65752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} 65852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier 65952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} // namespace collector 66052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} // namespace gc 66152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier} // namespace art 662