[heap] Support for minor MC marking during incremental marking part 1
First part of relanding d2c093bcaf
.
BUG=chromium:651354
Change-Id: I34ebea331d482d5039626ccff48b11ad175793ee
Reviewed-on: https://chromium-review.googlesource.com/448518
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43541}
This commit is contained in:
parent
4a80642e54
commit
12963af725
@ -1332,12 +1332,12 @@ void MarkCompactCollector::PrepareForCodeFlushing() {
|
||||
heap()->isolate()->compilation_cache()->IterateFunctions(&visitor);
|
||||
heap()->isolate()->handle_scope_implementer()->Iterate(&visitor);
|
||||
|
||||
ProcessMarkingDeque<MarkCompactMode::FULL>();
|
||||
ProcessMarkingDeque<MarkingMode::FULL>();
|
||||
}
|
||||
|
||||
|
||||
// Visitor class for marking heap roots.
|
||||
template <MarkCompactMode mode>
|
||||
template <MarkingMode mode>
|
||||
class RootMarkingVisitor : public ObjectVisitor {
|
||||
public:
|
||||
explicit RootMarkingVisitor(Heap* heap)
|
||||
@ -1359,7 +1359,7 @@ class RootMarkingVisitor : public ObjectVisitor {
|
||||
|
||||
HeapObject* object = HeapObject::cast(*p);
|
||||
|
||||
if (mode == MarkCompactMode::YOUNG_GENERATION &&
|
||||
if (mode == MarkingMode::YOUNG_GENERATION &&
|
||||
!collector_->heap()->InNewSpace(object))
|
||||
return;
|
||||
|
||||
@ -1367,15 +1367,15 @@ class RootMarkingVisitor : public ObjectVisitor {
|
||||
|
||||
Map* map = object->map();
|
||||
// Mark the object.
|
||||
ObjectMarking::WhiteToBlack(object);
|
||||
ObjectMarking::WhiteToBlack<mode>(object);
|
||||
|
||||
switch (mode) {
|
||||
case MarkCompactMode::FULL: {
|
||||
case MarkingMode::FULL: {
|
||||
// Mark the map pointer and body, and push them on the marking stack.
|
||||
collector_->MarkObject(map);
|
||||
MarkCompactMarkingVisitor::IterateBody(map, object);
|
||||
} break;
|
||||
case MarkCompactMode::YOUNG_GENERATION:
|
||||
case MarkingMode::YOUNG_GENERATION:
|
||||
StaticYoungGenerationMarkingVisitor::IterateBody(map, object);
|
||||
break;
|
||||
}
|
||||
@ -1950,7 +1950,7 @@ bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap,
|
||||
}
|
||||
|
||||
void MarkCompactCollector::MarkStringTable(
|
||||
RootMarkingVisitor<MarkCompactMode::FULL>* visitor) {
|
||||
RootMarkingVisitor<MarkingMode::FULL>* visitor) {
|
||||
StringTable* string_table = heap()->string_table();
|
||||
// Mark the string table itself.
|
||||
if (ObjectMarking::IsWhite(string_table)) {
|
||||
@ -1959,11 +1959,11 @@ void MarkCompactCollector::MarkStringTable(
|
||||
}
|
||||
// Explicitly mark the prefix.
|
||||
string_table->IteratePrefix(visitor);
|
||||
ProcessMarkingDeque<MarkCompactMode::FULL>();
|
||||
ProcessMarkingDeque<MarkingMode::FULL>();
|
||||
}
|
||||
|
||||
void MarkCompactCollector::MarkRoots(
|
||||
RootMarkingVisitor<MarkCompactMode::FULL>* visitor) {
|
||||
RootMarkingVisitor<MarkingMode::FULL>* visitor) {
|
||||
// Mark the heap roots including global variables, stack variables,
|
||||
// etc., and all objects reachable from them.
|
||||
heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
|
||||
@ -1973,8 +1973,8 @@ void MarkCompactCollector::MarkRoots(
|
||||
|
||||
// There may be overflowed objects in the heap. Visit them now.
|
||||
while (marking_deque()->overflowed()) {
|
||||
RefillMarkingDeque<MarkCompactMode::FULL>();
|
||||
EmptyMarkingDeque<MarkCompactMode::FULL>();
|
||||
RefillMarkingDeque<MarkingMode::FULL>();
|
||||
EmptyMarkingDeque<MarkingMode::FULL>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2014,7 +2014,7 @@ void MarkCompactCollector::MarkImplicitRefGroups(
|
||||
// Before: the marking stack contains zero or more heap object pointers.
|
||||
// After: the marking stack is empty, and all objects reachable from the
|
||||
// marking stack have been marked, or are overflowed in the heap.
|
||||
template <MarkCompactMode mode>
|
||||
template <MarkingMode mode>
|
||||
void MarkCompactCollector::EmptyMarkingDeque() {
|
||||
while (!marking_deque()->IsEmpty()) {
|
||||
HeapObject* object = marking_deque()->Pop();
|
||||
@ -2026,11 +2026,11 @@ void MarkCompactCollector::EmptyMarkingDeque() {
|
||||
|
||||
Map* map = object->map();
|
||||
switch (mode) {
|
||||
case MarkCompactMode::FULL: {
|
||||
case MarkingMode::FULL: {
|
||||
MarkObject(map);
|
||||
MarkCompactMarkingVisitor::IterateBody(map, object);
|
||||
} break;
|
||||
case MarkCompactMode::YOUNG_GENERATION: {
|
||||
case MarkingMode::YOUNG_GENERATION: {
|
||||
DCHECK(ObjectMarking::IsBlack(object));
|
||||
StaticYoungGenerationMarkingVisitor::IterateBody(map, object);
|
||||
} break;
|
||||
@ -2044,7 +2044,7 @@ void MarkCompactCollector::EmptyMarkingDeque() {
|
||||
// before sweeping completes. If sweeping completes, there are no remaining
|
||||
// overflowed objects in the heap so the overflow flag on the markings stack
|
||||
// is cleared.
|
||||
template <MarkCompactMode mode>
|
||||
template <MarkingMode mode>
|
||||
void MarkCompactCollector::RefillMarkingDeque() {
|
||||
isolate()->CountUsage(v8::Isolate::UseCounterFeature::kMarkDequeOverflow);
|
||||
DCHECK(marking_deque()->overflowed());
|
||||
@ -2052,7 +2052,7 @@ void MarkCompactCollector::RefillMarkingDeque() {
|
||||
DiscoverGreyObjectsInNewSpace();
|
||||
if (marking_deque()->IsFull()) return;
|
||||
|
||||
if (mode == MarkCompactMode::FULL) {
|
||||
if (mode == MarkingMode::FULL) {
|
||||
DiscoverGreyObjectsInSpace(heap()->old_space());
|
||||
if (marking_deque()->IsFull()) return;
|
||||
DiscoverGreyObjectsInSpace(heap()->code_space());
|
||||
@ -2072,7 +2072,7 @@ void MarkCompactCollector::RefillMarkingDeque() {
|
||||
// stack. Before: the marking stack contains zero or more heap object
|
||||
// pointers. After: the marking stack is empty and there are no overflowed
|
||||
// objects in the heap.
|
||||
template <MarkCompactMode mode>
|
||||
template <MarkingMode mode>
|
||||
void MarkCompactCollector::ProcessMarkingDeque() {
|
||||
EmptyMarkingDeque<mode>();
|
||||
while (marking_deque()->overflowed()) {
|
||||
@ -2112,7 +2112,7 @@ void MarkCompactCollector::ProcessEphemeralMarking(
|
||||
}
|
||||
ProcessWeakCollections();
|
||||
work_to_do = !marking_deque()->IsEmpty();
|
||||
ProcessMarkingDeque<MarkCompactMode::FULL>();
|
||||
ProcessMarkingDeque<MarkingMode::FULL>();
|
||||
}
|
||||
CHECK(marking_deque()->IsEmpty());
|
||||
CHECK_EQ(0, heap()->local_embedder_heap_tracer()->NumberOfWrappersToTrace());
|
||||
@ -2129,7 +2129,7 @@ void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) {
|
||||
if (!code->CanDeoptAt(it.frame()->pc())) {
|
||||
Code::BodyDescriptor::IterateBody(code, visitor);
|
||||
}
|
||||
ProcessMarkingDeque<MarkCompactMode::FULL>();
|
||||
ProcessMarkingDeque<MarkingMode::FULL>();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2313,7 +2313,7 @@ void MarkCompactCollector::MarkLiveObjectsInYoungGeneration() {
|
||||
PostponeInterruptsScope postpone(isolate());
|
||||
|
||||
StaticYoungGenerationMarkingVisitor::Initialize(heap());
|
||||
RootMarkingVisitor<MarkCompactMode::YOUNG_GENERATION> root_visitor(heap());
|
||||
RootMarkingVisitor<MarkingMode::YOUNG_GENERATION> root_visitor(heap());
|
||||
|
||||
marking_deque()->StartUsing();
|
||||
|
||||
@ -2323,7 +2323,7 @@ void MarkCompactCollector::MarkLiveObjectsInYoungGeneration() {
|
||||
{
|
||||
TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_ROOTS);
|
||||
heap()->IterateRoots(&root_visitor, VISIT_ALL_IN_SCAVENGE);
|
||||
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>();
|
||||
ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
|
||||
}
|
||||
|
||||
{
|
||||
@ -2340,20 +2340,20 @@ void MarkCompactCollector::MarkLiveObjectsInYoungGeneration() {
|
||||
reinterpret_cast<Address>(addr));
|
||||
});
|
||||
});
|
||||
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>();
|
||||
ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
|
||||
}
|
||||
|
||||
{
|
||||
TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_WEAK);
|
||||
heap()->VisitEncounteredWeakCollections(&root_visitor);
|
||||
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>();
|
||||
ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
|
||||
}
|
||||
|
||||
if (is_code_flushing_enabled()) {
|
||||
TRACE_GC(heap()->tracer(),
|
||||
GCTracer::Scope::MINOR_MC_MARK_CODE_FLUSH_CANDIDATES);
|
||||
code_flusher()->IteratePointersToFromSpace(&root_visitor);
|
||||
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>();
|
||||
ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
|
||||
}
|
||||
|
||||
{
|
||||
@ -2364,7 +2364,7 @@ void MarkCompactCollector::MarkLiveObjectsInYoungGeneration() {
|
||||
->global_handles()
|
||||
->IterateNewSpaceWeakUnmodifiedRoots<GlobalHandles::VISIT_OTHERS>(
|
||||
&root_visitor);
|
||||
ProcessMarkingDeque<MarkCompactMode::YOUNG_GENERATION>();
|
||||
ProcessMarkingDeque<MarkingMode::YOUNG_GENERATION>();
|
||||
}
|
||||
|
||||
marking_deque()->StopUsing();
|
||||
@ -2401,7 +2401,7 @@ void MarkCompactCollector::MarkLiveObjects() {
|
||||
PrepareForCodeFlushing();
|
||||
}
|
||||
|
||||
RootMarkingVisitor<MarkCompactMode::FULL> root_visitor(heap());
|
||||
RootMarkingVisitor<MarkingMode::FULL> root_visitor(heap());
|
||||
|
||||
{
|
||||
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_ROOTS);
|
||||
@ -2433,7 +2433,7 @@ void MarkCompactCollector::MarkLiveObjects() {
|
||||
GCTracer::Scope::MC_MARK_WEAK_CLOSURE_WEAK_HANDLES);
|
||||
heap()->isolate()->global_handles()->IdentifyWeakHandles(
|
||||
&IsUnmarkedHeapObject);
|
||||
ProcessMarkingDeque<MarkCompactMode::FULL>();
|
||||
ProcessMarkingDeque<MarkingMode::FULL>();
|
||||
}
|
||||
// Then we mark the objects.
|
||||
|
||||
@ -2441,7 +2441,7 @@ void MarkCompactCollector::MarkLiveObjects() {
|
||||
TRACE_GC(heap()->tracer(),
|
||||
GCTracer::Scope::MC_MARK_WEAK_CLOSURE_WEAK_ROOTS);
|
||||
heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor);
|
||||
ProcessMarkingDeque<MarkCompactMode::FULL>();
|
||||
ProcessMarkingDeque<MarkingMode::FULL>();
|
||||
}
|
||||
|
||||
// Repeat Harmony weak maps marking to mark unmarked objects reachable from
|
||||
|
@ -17,8 +17,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
enum class MarkCompactMode { FULL, YOUNG_GENERATION };
|
||||
|
||||
// Callback function, returns whether an object is alive. The heap size
|
||||
// of the object is returned in size. It optionally updates the offset
|
||||
// to the first live object in the page (only used for old and map objects).
|
||||
@ -31,87 +29,103 @@ typedef void (*MarkObjectFunction)(Heap* heap, HeapObject* object);
|
||||
class CodeFlusher;
|
||||
class MarkCompactCollector;
|
||||
class MarkingVisitor;
|
||||
template <MarkCompactMode mode>
|
||||
template <MarkingMode mode>
|
||||
class RootMarkingVisitor;
|
||||
|
||||
class ObjectMarking : public AllStatic {
|
||||
public:
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static MarkBit MarkBitFrom(HeapObject* obj) {
|
||||
const Address address = obj->address();
|
||||
MemoryChunk* p = MemoryChunk::FromAddress(address);
|
||||
return p->markbits()->MarkBitFromIndex(p->AddressToMarkbitIndex(address));
|
||||
const MemoryChunk* p = MemoryChunk::FromAddress(address);
|
||||
return p->markbits<mode>()->MarkBitFromIndex(
|
||||
p->AddressToMarkbitIndex(address));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
static Marking::ObjectColor Color(HeapObject* obj) {
|
||||
return Marking::Color(ObjectMarking::MarkBitFrom(obj));
|
||||
return Marking::Color(ObjectMarking::MarkBitFrom<mode>(obj));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static bool IsImpossible(HeapObject* obj) {
|
||||
return Marking::IsImpossible(MarkBitFrom(obj));
|
||||
return Marking::IsImpossible(MarkBitFrom<mode>(obj));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static bool IsBlack(HeapObject* obj) {
|
||||
return Marking::IsBlack(MarkBitFrom(obj));
|
||||
return Marking::IsBlack(MarkBitFrom<mode>(obj));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static bool IsWhite(HeapObject* obj) {
|
||||
return Marking::IsWhite(MarkBitFrom(obj));
|
||||
return Marking::IsWhite(MarkBitFrom<mode>(obj));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static bool IsGrey(HeapObject* obj) {
|
||||
return Marking::IsGrey(MarkBitFrom(obj));
|
||||
return Marking::IsGrey(MarkBitFrom<mode>(obj));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static bool IsBlackOrGrey(HeapObject* obj) {
|
||||
return Marking::IsBlackOrGrey(MarkBitFrom(obj));
|
||||
return Marking::IsBlackOrGrey(MarkBitFrom<mode>(obj));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static void ClearMarkBit(HeapObject* obj) {
|
||||
Marking::MarkWhite(MarkBitFrom(obj));
|
||||
Marking::MarkWhite(MarkBitFrom<mode>(obj));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static void BlackToWhite(HeapObject* obj) {
|
||||
DCHECK(IsBlack(obj));
|
||||
MarkBit markbit = MarkBitFrom(obj);
|
||||
DCHECK(IsBlack<mode>(obj));
|
||||
MarkBit markbit = MarkBitFrom<mode>(obj);
|
||||
Marking::BlackToWhite(markbit);
|
||||
MemoryChunk::IncrementLiveBytes(obj, -obj->Size());
|
||||
MemoryChunk::IncrementLiveBytes<mode>(obj, -obj->Size());
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static void GreyToWhite(HeapObject* obj) {
|
||||
DCHECK(IsGrey(obj));
|
||||
Marking::GreyToWhite(MarkBitFrom(obj));
|
||||
DCHECK(IsGrey<mode>(obj));
|
||||
Marking::GreyToWhite(MarkBitFrom<mode>(obj));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static void BlackToGrey(HeapObject* obj) {
|
||||
DCHECK(IsBlack(obj));
|
||||
MarkBit markbit = MarkBitFrom(obj);
|
||||
DCHECK(IsBlack<mode>(obj));
|
||||
MarkBit markbit = MarkBitFrom<mode>(obj);
|
||||
Marking::BlackToGrey(markbit);
|
||||
MemoryChunk::IncrementLiveBytes(obj, -obj->Size());
|
||||
MemoryChunk::IncrementLiveBytes<mode>(obj, -obj->Size());
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static void WhiteToGrey(HeapObject* obj) {
|
||||
DCHECK(IsWhite(obj));
|
||||
Marking::WhiteToGrey(MarkBitFrom(obj));
|
||||
DCHECK(IsWhite<mode>(obj));
|
||||
Marking::WhiteToGrey(MarkBitFrom<mode>(obj));
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static void WhiteToBlack(HeapObject* obj) {
|
||||
DCHECK(IsWhite(obj));
|
||||
MarkBit markbit = MarkBitFrom(obj);
|
||||
DCHECK(IsWhite<mode>(obj));
|
||||
MarkBit markbit = MarkBitFrom<mode>(obj);
|
||||
Marking::WhiteToBlack(markbit);
|
||||
MemoryChunk::IncrementLiveBytes(obj, obj->Size());
|
||||
MemoryChunk::IncrementLiveBytes<mode>(obj, obj->Size());
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static void GreyToBlack(HeapObject* obj) {
|
||||
DCHECK(IsGrey(obj));
|
||||
MarkBit markbit = MarkBitFrom(obj);
|
||||
DCHECK(IsGrey<mode>(obj));
|
||||
MarkBit markbit = MarkBitFrom<mode>(obj);
|
||||
Marking::GreyToBlack(markbit);
|
||||
MemoryChunk::IncrementLiveBytes(obj, obj->Size());
|
||||
MemoryChunk::IncrementLiveBytes<mode>(obj, obj->Size());
|
||||
}
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
V8_INLINE static void AnyToGrey(HeapObject* obj) {
|
||||
MarkBit markbit = MarkBitFrom(obj);
|
||||
MarkBit markbit = MarkBitFrom<mode>(obj);
|
||||
if (Marking::IsBlack(markbit)) {
|
||||
MemoryChunk::IncrementLiveBytes(obj, -obj->Size());
|
||||
MemoryChunk::IncrementLiveBytes<mode>(obj, -obj->Size());
|
||||
}
|
||||
Marking::AnyToGrey(markbit);
|
||||
}
|
||||
@ -631,7 +645,7 @@ class MarkCompactCollector {
|
||||
friend class MarkCompactMarkingVisitor;
|
||||
friend class MarkingVisitor;
|
||||
friend class RecordMigratedSlotVisitor;
|
||||
template <MarkCompactMode mode>
|
||||
template <MarkingMode mode>
|
||||
friend class RootMarkingVisitor;
|
||||
friend class SharedFunctionInfoMarkingVisitor;
|
||||
friend class StaticYoungGenerationMarkingVisitor;
|
||||
@ -660,15 +674,15 @@ class MarkCompactCollector {
|
||||
INLINE(void MarkObject(HeapObject* obj));
|
||||
|
||||
// Mark the heap roots and all objects reachable from them.
|
||||
void MarkRoots(RootMarkingVisitor<MarkCompactMode::FULL>* visitor);
|
||||
void MarkRoots(RootMarkingVisitor<MarkingMode::FULL>* visitor);
|
||||
|
||||
// Mark the string table specially. References to internalized strings from
|
||||
// the string table are weak.
|
||||
void MarkStringTable(RootMarkingVisitor<MarkCompactMode::FULL>* visitor);
|
||||
void MarkStringTable(RootMarkingVisitor<MarkingMode::FULL>* visitor);
|
||||
|
||||
// Mark objects reachable (transitively) from objects in the marking stack
|
||||
// or overflowed in the heap.
|
||||
template <MarkCompactMode mode>
|
||||
template <MarkingMode mode>
|
||||
void ProcessMarkingDeque();
|
||||
|
||||
// Mark objects reachable (transitively) from objects in the marking stack
|
||||
@ -692,13 +706,13 @@ class MarkCompactCollector {
|
||||
// stack. This function empties the marking stack, but may leave
|
||||
// overflowed objects in the heap, in which case the marking stack's
|
||||
// overflow flag will be set.
|
||||
template <MarkCompactMode mode>
|
||||
template <MarkingMode mode>
|
||||
void EmptyMarkingDeque();
|
||||
|
||||
// Refill the marking stack with overflowed objects from the heap. This
|
||||
// function either leaves the marking stack full or clears the overflow
|
||||
// flag on the marking stack.
|
||||
template <MarkCompactMode mode>
|
||||
template <MarkingMode mode>
|
||||
void RefillMarkingDeque();
|
||||
|
||||
// Helper methods for refilling the marking stack by discovering grey objects
|
||||
|
@ -226,6 +226,7 @@ void Page::InitializeFreeListCategories() {
|
||||
}
|
||||
}
|
||||
|
||||
template <MarkingMode mode>
|
||||
void MemoryChunk::IncrementLiveBytes(HeapObject* object, int by) {
|
||||
MemoryChunk::FromAddress(object->address())->IncrementLiveBytes(by);
|
||||
}
|
||||
|
@ -224,6 +224,10 @@ class FreeListCategory {
|
||||
friend class PagedSpace;
|
||||
};
|
||||
|
||||
// MarkingMode determines which bitmaps and counters should be used when
|
||||
// accessing marking information on MemoryChunk.
|
||||
enum class MarkingMode { FULL, YOUNG_GENERATION };
|
||||
|
||||
// MemoryChunk represents a memory region owned by a specific space.
|
||||
// It is divided into the header and the body. Chunk start is always
|
||||
// 1MB aligned. Start of the body is aligned so it can accommodate
|
||||
@ -370,6 +374,7 @@ class MemoryChunk {
|
||||
|
||||
static const int kAllocatableMemory = kPageSize - kObjectStartOffset;
|
||||
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
static inline void IncrementLiveBytes(HeapObject* object, int by);
|
||||
|
||||
// Only works if the pointer is in the first kPageSize of the MemoryChunk.
|
||||
@ -395,7 +400,9 @@ class MemoryChunk {
|
||||
|
||||
static bool IsValid(MemoryChunk* chunk) { return chunk != nullptr; }
|
||||
|
||||
Address address() { return reinterpret_cast<Address>(this); }
|
||||
Address address() const {
|
||||
return reinterpret_cast<Address>(const_cast<MemoryChunk*>(this));
|
||||
}
|
||||
|
||||
base::Mutex* mutex() { return mutex_; }
|
||||
|
||||
@ -489,15 +496,16 @@ class MemoryChunk {
|
||||
}
|
||||
}
|
||||
|
||||
inline Bitmap* markbits() {
|
||||
template <MarkingMode mode = MarkingMode::FULL>
|
||||
inline Bitmap* markbits() const {
|
||||
return Bitmap::FromAddress(address() + kHeaderSize);
|
||||
}
|
||||
|
||||
inline uint32_t AddressToMarkbitIndex(Address addr) {
|
||||
inline uint32_t AddressToMarkbitIndex(Address addr) const {
|
||||
return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2;
|
||||
}
|
||||
|
||||
inline Address MarkbitIndexToAddress(uint32_t index) {
|
||||
inline Address MarkbitIndexToAddress(uint32_t index) const {
|
||||
return this->address() + (index << kPointerSizeLog2);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user