blob: 48311570b540d96a9bd0bdce35614edb903af8c3 [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ART_RUNTIME_GC_COLLECTOR_MARK_COMPACT_H_
#define ART_RUNTIME_GC_COLLECTOR_MARK_COMPACT_H_
#include <deque>
#include <memory> // For unique_ptr.
#include "atomic.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "garbage_collector.h"
#include "gc_root.h"
#include "gc/accounting/heap_bitmap.h"
#include "immune_spaces.h"
#include "lock_word.h"
#include "object_callbacks.h"
#include "offsets.h"
namespace art {
class Thread;
namespace mirror {
class Class;
class Object;
} // namespace mirror
namespace gc {
class Heap;
namespace accounting {
template <typename T> class AtomicStack;
typedef AtomicStack<mirror::Object> ObjectStack;
} // namespace accounting
namespace space {
class BumpPointerSpace;
class ContinuousMemMapAllocSpace;
class ContinuousSpace;
} // namespace space
namespace collector {
class MarkCompact : public GarbageCollector {
public:
explicit MarkCompact(Heap* heap, const std::string& name_prefix = "");
~MarkCompact() {}
virtual void RunPhases() OVERRIDE NO_THREAD_SAFETY_ANALYSIS;
void InitializePhase();
void MarkingPhase() REQUIRES(Locks::mutator_lock_)
REQUIRES(!Locks::heap_bitmap_lock_);
void ReclaimPhase() REQUIRES(Locks::mutator_lock_)
REQUIRES(!Locks::heap_bitmap_lock_);
void FinishPhase() REQUIRES(Locks::mutator_lock_);
void MarkReachableObjects()
REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
virtual GcType GetGcType() const OVERRIDE {
return kGcTypePartial;
}
virtual CollectorType GetCollectorType() const OVERRIDE {
return kCollectorTypeMC;
}
// Sets which space we will be copying objects in.
void SetSpace(space::BumpPointerSpace* space);
// Initializes internal structures.
void Init();
// Find the default mark bitmap.
void FindDefaultMarkBitmap();
void ScanObject(mirror::Object* obj)
REQUIRES(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
// Marks the root set at the start of a garbage collection.
void MarkRoots()
REQUIRES(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
// Bind the live bits to the mark bits of bitmaps for spaces that are never collected, ie
// the image. Mark that portion of the heap as immune.
void BindBitmaps() SHARED_REQUIRES(Locks::mutator_lock_)
REQUIRES(!Locks::heap_bitmap_lock_);
void UnBindBitmaps()
REQUIRES(Locks::heap_bitmap_lock_);
void ProcessReferences(Thread* self) REQUIRES(Locks::mutator_lock_)
REQUIRES(Locks::mutator_lock_);
// Sweeps unmarked objects to complete the garbage collection.
void Sweep(bool swap_bitmaps) REQUIRES(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
// Sweeps unmarked objects to complete the garbage collection.
void SweepLargeObjects(bool swap_bitmaps) REQUIRES(Locks::heap_bitmap_lock_);
void SweepSystemWeaks()
SHARED_REQUIRES(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
virtual void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info)
OVERRIDE REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
virtual void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count,
const RootInfo& info)
OVERRIDE REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
// Schedules an unmarked object for reference processing.
void DelayReferenceReferent(mirror::Class* klass, mirror::Reference* reference)
SHARED_REQUIRES(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
protected:
// Returns null if the object is not marked, otherwise returns the forwarding address (same as
// object for non movable things).
mirror::Object* GetMarkedForwardAddress(mirror::Object* object)
REQUIRES(Locks::mutator_lock_)
SHARED_REQUIRES(Locks::heap_bitmap_lock_);
// Marks or unmarks a large object based on whether or not set is true. If set is true, then we
// mark, otherwise we unmark.
bool MarkLargeObject(const mirror::Object* obj)
REQUIRES(Locks::heap_bitmap_lock_)
SHARED_REQUIRES(Locks::mutator_lock_);
// Expand mark stack to 2x its current size.
void ResizeMarkStack(size_t new_size) SHARED_REQUIRES(Locks::mutator_lock_);
// Returns true if we should sweep the space.
bool ShouldSweepSpace(space::ContinuousSpace* space) const;
// Push an object onto the mark stack.
void MarkStackPush(mirror::Object* obj) SHARED_REQUIRES(Locks::mutator_lock_);
void UpdateAndMarkModUnion()
REQUIRES(Locks::heap_bitmap_lock_)
SHARED_REQUIRES(Locks::mutator_lock_);
// Recursively blackens objects on the mark stack.
void ProcessMarkStack()
REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
// 3 pass mark compact approach.
void Compact() REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
// Calculate the forwarding address of objects marked as "live" in the objects_before_forwarding
// bitmap.
void CalculateObjectForwardingAddresses()
REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
// Update the references of objects by using the forwarding addresses.
void UpdateReferences() REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
// Move objects and restore lock words.
void MoveObjects() REQUIRES(Locks::mutator_lock_);
// Move a single object to its forward address.
void MoveObject(mirror::Object* obj, size_t len) REQUIRES(Locks::mutator_lock_);
// Mark a single object.
virtual mirror::Object* MarkObject(mirror::Object* obj) OVERRIDE
REQUIRES(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
virtual void MarkHeapReference(mirror::HeapReference<mirror::Object>* obj_ptr) OVERRIDE
REQUIRES(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
virtual mirror::Object* IsMarked(mirror::Object* obj) OVERRIDE
SHARED_REQUIRES(Locks::heap_bitmap_lock_)
REQUIRES(Locks::mutator_lock_);
virtual bool IsMarkedHeapReference(mirror::HeapReference<mirror::Object>* obj) OVERRIDE
SHARED_REQUIRES(Locks::heap_bitmap_lock_)
REQUIRES(Locks::mutator_lock_);
void ForwardObject(mirror::Object* obj) REQUIRES(Locks::heap_bitmap_lock_,
Locks::mutator_lock_);
// Update a single heap reference.
void UpdateHeapReference(mirror::HeapReference<mirror::Object>* reference)
SHARED_REQUIRES(Locks::heap_bitmap_lock_)
REQUIRES(Locks::mutator_lock_);
// Update all of the references of a single object.
void UpdateObjectReferences(mirror::Object* obj)
SHARED_REQUIRES(Locks::heap_bitmap_lock_)
REQUIRES(Locks::mutator_lock_);
// Revoke all the thread-local buffers.
void RevokeAllThreadLocalBuffers();
accounting::ObjectStack* mark_stack_;
// Every object inside the immune spaces is assumed to be marked.
ImmuneSpaces immune_spaces_;
// Bump pointer space which we are collecting.
space::BumpPointerSpace* space_;
// Cached mark bitmap as an optimization.
accounting::HeapBitmap* mark_bitmap_;
// The name of the collector.
std::string collector_name_;
// The bump pointer in the space where the next forwarding address will be.
uint8_t* bump_pointer_;
// How many live objects we have in the space.
size_t live_objects_in_space_;
// Bitmap which describes which objects we have to move, need to do / 2 so that we can handle
// objects which are only 8 bytes.
std::unique_ptr<accounting::ContinuousSpaceBitmap> objects_before_forwarding_;
// Bitmap which describes which lock words we need to restore.
std::unique_ptr<accounting::ContinuousSpaceBitmap> objects_with_lockword_;
// Which lock words we need to restore as we are moving objects.
std::deque<LockWord> lock_words_to_restore_;
// State whether or not we are updating references.
bool updating_references_;
private:
friend class BitmapSetSlowPathVisitor;
friend class CalculateObjectForwardingAddressVisitor;
friend class MarkCompactMarkObjectVisitor;
friend class MoveObjectVisitor;
friend class UpdateObjectReferencesVisitor;
friend class UpdateReferenceVisitor;
friend class UpdateRootVisitor;
DISALLOW_IMPLICIT_CONSTRUCTORS(MarkCompact);
};
} // namespace collector
} // namespace gc
} // namespace art
#endif // ART_RUNTIME_GC_COLLECTOR_MARK_COMPACT_H_