Commit 4693a433 authored by hpayer's avatar hpayer Committed by Commit bot

Revert "[heap] Make SlotSet allocation thread-safe and refactor code."

This reverts commit 00d3098d.

BUG=chromium:694255,v8:6138

Review-Url: https://codereview.chromium.org/2773093002
Cr-Commit-Position: refs/heads/master@{#44100}
parent 15898daf
...@@ -684,8 +684,8 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { ...@@ -684,8 +684,8 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
// of a GC all evacuation candidates are cleared and their slot buffers are // of a GC all evacuation candidates are cleared and their slot buffers are
// released. // released.
CHECK(!p->IsEvacuationCandidate()); CHECK(!p->IsEvacuationCandidate());
CHECK_NULL(p->slot_set<OLD_TO_OLD>()); CHECK_NULL(p->old_to_old_slots());
CHECK_NULL(p->typed_slot_set<OLD_TO_OLD>()); CHECK_NULL(p->typed_old_to_old_slots());
CHECK(p->SweepingDone()); CHECK(p->SweepingDone());
DCHECK(p->area_size() == area_size); DCHECK(p->area_size() == area_size);
pages.push_back(std::make_pair(p->LiveBytesFromFreeList(), p)); pages.push_back(std::make_pair(p->LiveBytesFromFreeList(), p));
...@@ -3399,10 +3399,10 @@ class EvacuationWeakObjectRetainer : public WeakObjectRetainer { ...@@ -3399,10 +3399,10 @@ class EvacuationWeakObjectRetainer : public WeakObjectRetainer {
MarkCompactCollector::Sweeper::ClearOldToNewSlotsMode MarkCompactCollector::Sweeper::ClearOldToNewSlotsMode
MarkCompactCollector::Sweeper::GetClearOldToNewSlotsMode(Page* p) { MarkCompactCollector::Sweeper::GetClearOldToNewSlotsMode(Page* p) {
AllocationSpace identity = p->owner()->identity(); AllocationSpace identity = p->owner()->identity();
if (p->slot_set<OLD_TO_NEW>() && if (p->old_to_new_slots() &&
(identity == OLD_SPACE || identity == MAP_SPACE)) { (identity == OLD_SPACE || identity == MAP_SPACE)) {
return MarkCompactCollector::Sweeper::CLEAR_REGULAR_SLOTS; return MarkCompactCollector::Sweeper::CLEAR_REGULAR_SLOTS;
} else if (p->typed_slot_set<OLD_TO_NEW>() && identity == CODE_SPACE) { } else if (p->typed_old_to_new_slots() && identity == CODE_SPACE) {
return MarkCompactCollector::Sweeper::CLEAR_TYPED_SLOTS; return MarkCompactCollector::Sweeper::CLEAR_TYPED_SLOTS;
} }
return MarkCompactCollector::Sweeper::DO_NOT_CLEAR; return MarkCompactCollector::Sweeper::DO_NOT_CLEAR;
...@@ -3516,7 +3516,7 @@ int MarkCompactCollector::Sweeper::RawSweep( ...@@ -3516,7 +3516,7 @@ int MarkCompactCollector::Sweeper::RawSweep(
// Clear invalid typed slots after collection all free ranges. // Clear invalid typed slots after collection all free ranges.
if (slots_clearing_mode == CLEAR_TYPED_SLOTS) { if (slots_clearing_mode == CLEAR_TYPED_SLOTS) {
p->typed_slot_set<OLD_TO_NEW>()->RemoveInvaldSlots(free_ranges); p->typed_old_to_new_slots()->RemoveInvaldSlots(free_ranges);
} }
// Clear the mark bits of that page and reset live bytes count. // Clear the mark bits of that page and reset live bytes count.
...@@ -3575,14 +3575,15 @@ bool LiveObjectVisitor::VisitBlackObjects(MemoryChunk* chunk, ...@@ -3575,14 +3575,15 @@ bool LiveObjectVisitor::VisitBlackObjects(MemoryChunk* chunk,
state.bitmap->ClearRange( state.bitmap->ClearRange(
chunk->AddressToMarkbitIndex(chunk->area_start()), chunk->AddressToMarkbitIndex(chunk->area_start()),
chunk->AddressToMarkbitIndex(object->address())); chunk->AddressToMarkbitIndex(object->address()));
SlotSet* slot_set = chunk->slot_set<OLD_TO_NEW>(); if (chunk->old_to_new_slots() != nullptr) {
if (slot_set != nullptr) { chunk->old_to_new_slots()->RemoveRange(
slot_set->RemoveRange(
0, static_cast<int>(object->address() - chunk->address()), 0, static_cast<int>(object->address() - chunk->address()),
SlotSet::PREFREE_EMPTY_BUCKETS); SlotSet::PREFREE_EMPTY_BUCKETS);
} }
RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(chunk, chunk->address(), if (chunk->typed_old_to_new_slots() != nullptr) {
object->address()); RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(chunk, chunk->address(),
object->address());
}
RecomputeLiveBytes(chunk, state); RecomputeLiveBytes(chunk, state);
} }
return false; return false;
...@@ -3682,7 +3683,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { ...@@ -3682,7 +3683,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
#endif #endif
} }
template <RememberedSetType type> template <PointerDirection direction>
class PointerUpdateJobTraits { class PointerUpdateJobTraits {
public: public:
typedef int PerPageData; // Per page data is not used in this job. typedef int PerPageData; // Per page data is not used in this job.
...@@ -3700,7 +3701,7 @@ class PointerUpdateJobTraits { ...@@ -3700,7 +3701,7 @@ class PointerUpdateJobTraits {
private: private:
static void UpdateUntypedPointers(Heap* heap, MemoryChunk* chunk) { static void UpdateUntypedPointers(Heap* heap, MemoryChunk* chunk) {
if (type == OLD_TO_NEW) { if (direction == OLD_TO_NEW) {
RememberedSet<OLD_TO_NEW>::Iterate(chunk, [heap](Address slot) { RememberedSet<OLD_TO_NEW>::Iterate(chunk, [heap](Address slot) {
return CheckAndUpdateOldToNewSlot(heap, slot); return CheckAndUpdateOldToNewSlot(heap, slot);
}); });
...@@ -3712,21 +3713,20 @@ class PointerUpdateJobTraits { ...@@ -3712,21 +3713,20 @@ class PointerUpdateJobTraits {
} }
static void UpdateTypedPointers(Heap* heap, MemoryChunk* chunk) { static void UpdateTypedPointers(Heap* heap, MemoryChunk* chunk) {
if (type == OLD_TO_OLD) { if (direction == OLD_TO_OLD) {
Isolate* isolate = heap->isolate(); Isolate* isolate = heap->isolate();
RememberedSet<OLD_TO_OLD>::IterateTyped( RememberedSet<OLD_TO_OLD>::IterateTyped(
chunk, chunk, [isolate](SlotType type, Address host_addr, Address slot) {
[isolate](SlotType slot_type, Address host_addr, Address slot) { return UpdateTypedSlotHelper::UpdateTypedSlot(isolate, type, slot,
return UpdateTypedSlotHelper::UpdateTypedSlot(isolate, slot_type, UpdateSlot);
slot, UpdateSlot);
}); });
} else { } else {
Isolate* isolate = heap->isolate(); Isolate* isolate = heap->isolate();
RememberedSet<OLD_TO_NEW>::IterateTyped( RememberedSet<OLD_TO_NEW>::IterateTyped(
chunk, chunk,
[isolate, heap](SlotType slot_type, Address host_addr, Address slot) { [isolate, heap](SlotType type, Address host_addr, Address slot) {
return UpdateTypedSlotHelper::UpdateTypedSlot( return UpdateTypedSlotHelper::UpdateTypedSlot(
isolate, slot_type, slot, [heap](Object** slot) { isolate, type, slot, [heap](Object** slot) {
return CheckAndUpdateOldToNewSlot( return CheckAndUpdateOldToNewSlot(
heap, reinterpret_cast<Address>(slot)); heap, reinterpret_cast<Address>(slot));
}); });
...@@ -3791,11 +3791,11 @@ int NumberOfPointerUpdateTasks(int pages) { ...@@ -3791,11 +3791,11 @@ int NumberOfPointerUpdateTasks(int pages) {
return Min(available_cores, (pages + kPagesPerTask - 1) / kPagesPerTask); return Min(available_cores, (pages + kPagesPerTask - 1) / kPagesPerTask);
} }
template <RememberedSetType type> template <PointerDirection direction>
void UpdatePointersInParallel(Heap* heap, base::Semaphore* semaphore) { void UpdatePointersInParallel(Heap* heap, base::Semaphore* semaphore) {
PageParallelJob<PointerUpdateJobTraits<type> > job( PageParallelJob<PointerUpdateJobTraits<direction> > job(
heap, heap->isolate()->cancelable_task_manager(), semaphore); heap, heap->isolate()->cancelable_task_manager(), semaphore);
RememberedSet<type>::IterateMemoryChunks( RememberedSet<direction>::IterateMemoryChunks(
heap, [&job](MemoryChunk* chunk) { job.AddPage(chunk, 0); }); heap, [&job](MemoryChunk* chunk) { job.AddPage(chunk, 0); });
int num_pages = job.NumberOfPages(); int num_pages = job.NumberOfPages();
int num_tasks = NumberOfPointerUpdateTasks(num_pages); int num_tasks = NumberOfPointerUpdateTasks(num_pages);
...@@ -3951,13 +3951,11 @@ int MarkCompactCollector::Sweeper::ParallelSweepPage(Page* page, ...@@ -3951,13 +3951,11 @@ int MarkCompactCollector::Sweeper::ParallelSweepPage(Page* page,
DCHECK(page->SweepingDone()); DCHECK(page->SweepingDone());
// After finishing sweeping of a page we clean up its remembered set. // After finishing sweeping of a page we clean up its remembered set.
TypedSlotSet* typed_slot_set = page->typed_slot_set<OLD_TO_NEW>(); if (page->typed_old_to_new_slots()) {
if (typed_slot_set) { page->typed_old_to_new_slots()->FreeToBeFreedChunks();
page->typed_slot_set<OLD_TO_NEW>()->FreeToBeFreedChunks();
} }
SlotSet* slot_set = page->slot_set<OLD_TO_NEW>(); if (page->old_to_new_slots()) {
if (slot_set) { page->old_to_new_slots()->FreeToBeFreedBuckets();
page->slot_set<OLD_TO_NEW>()->FreeToBeFreedBuckets();
} }
} }
......
...@@ -13,17 +13,19 @@ ...@@ -13,17 +13,19 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
enum PointerDirection { OLD_TO_OLD, OLD_TO_NEW };
// TODO(ulan): Investigate performance of de-templatizing this class. // TODO(ulan): Investigate performance of de-templatizing this class.
template <RememberedSetType type> template <PointerDirection direction>
class RememberedSet : public AllStatic { class RememberedSet : public AllStatic {
public: public:
// Given a page and a slot in that page, this function adds the slot to the // Given a page and a slot in that page, this function adds the slot to the
// remembered set. // remembered set.
static void Insert(MemoryChunk* chunk, Address slot_addr) { static void Insert(MemoryChunk* chunk, Address slot_addr) {
DCHECK(chunk->Contains(slot_addr)); DCHECK(chunk->Contains(slot_addr));
SlotSet* slot_set = chunk->slot_set<type>(); SlotSet* slot_set = GetSlotSet(chunk);
if (slot_set == nullptr) { if (slot_set == nullptr) {
slot_set = chunk->AllocateSlotSet<type>(); slot_set = AllocateSlotSet(chunk);
} }
uintptr_t offset = slot_addr - chunk->address(); uintptr_t offset = slot_addr - chunk->address();
slot_set[offset / Page::kPageSize].Insert(offset % Page::kPageSize); slot_set[offset / Page::kPageSize].Insert(offset % Page::kPageSize);
...@@ -33,7 +35,7 @@ class RememberedSet : public AllStatic { ...@@ -33,7 +35,7 @@ class RememberedSet : public AllStatic {
// the remembered set contains the slot. // the remembered set contains the slot.
static bool Contains(MemoryChunk* chunk, Address slot_addr) { static bool Contains(MemoryChunk* chunk, Address slot_addr) {
DCHECK(chunk->Contains(slot_addr)); DCHECK(chunk->Contains(slot_addr));
SlotSet* slot_set = chunk->slot_set<type>(); SlotSet* slot_set = GetSlotSet(chunk);
if (slot_set == nullptr) { if (slot_set == nullptr) {
return false; return false;
} }
...@@ -47,7 +49,7 @@ class RememberedSet : public AllStatic { ...@@ -47,7 +49,7 @@ class RememberedSet : public AllStatic {
// If the slot was never added, then the function does nothing. // If the slot was never added, then the function does nothing.
static void Remove(MemoryChunk* chunk, Address slot_addr) { static void Remove(MemoryChunk* chunk, Address slot_addr) {
DCHECK(chunk->Contains(slot_addr)); DCHECK(chunk->Contains(slot_addr));
SlotSet* slot_set = chunk->slot_set<type>(); SlotSet* slot_set = GetSlotSet(chunk);
if (slot_set != nullptr) { if (slot_set != nullptr) {
uintptr_t offset = slot_addr - chunk->address(); uintptr_t offset = slot_addr - chunk->address();
slot_set[offset / Page::kPageSize].Remove(offset % Page::kPageSize); slot_set[offset / Page::kPageSize].Remove(offset % Page::kPageSize);
...@@ -58,7 +60,7 @@ class RememberedSet : public AllStatic { ...@@ -58,7 +60,7 @@ class RememberedSet : public AllStatic {
// slots from the remembered set. // slots from the remembered set.
static void RemoveRange(MemoryChunk* chunk, Address start, Address end, static void RemoveRange(MemoryChunk* chunk, Address start, Address end,
SlotSet::EmptyBucketMode mode) { SlotSet::EmptyBucketMode mode) {
SlotSet* slot_set = chunk->slot_set<type>(); SlotSet* slot_set = GetSlotSet(chunk);
if (slot_set != nullptr) { if (slot_set != nullptr) {
uintptr_t start_offset = start - chunk->address(); uintptr_t start_offset = start - chunk->address();
uintptr_t end_offset = end - chunk->address(); uintptr_t end_offset = end - chunk->address();
...@@ -110,8 +112,8 @@ class RememberedSet : public AllStatic { ...@@ -110,8 +112,8 @@ class RememberedSet : public AllStatic {
MemoryChunkIterator it(heap); MemoryChunkIterator it(heap);
MemoryChunk* chunk; MemoryChunk* chunk;
while ((chunk = it.next()) != nullptr) { while ((chunk = it.next()) != nullptr) {
SlotSet* slots = chunk->slot_set<type>(); SlotSet* slots = GetSlotSet(chunk);
TypedSlotSet* typed_slots = chunk->typed_slot_set<type>(); TypedSlotSet* typed_slots = GetTypedSlotSet(chunk);
if (slots != nullptr || typed_slots != nullptr) { if (slots != nullptr || typed_slots != nullptr) {
callback(chunk); callback(chunk);
} }
...@@ -123,7 +125,7 @@ class RememberedSet : public AllStatic { ...@@ -123,7 +125,7 @@ class RememberedSet : public AllStatic {
// SlotCallbackResult. // SlotCallbackResult.
template <typename Callback> template <typename Callback>
static void Iterate(MemoryChunk* chunk, Callback callback) { static void Iterate(MemoryChunk* chunk, Callback callback) {
SlotSet* slots = chunk->slot_set<type>(); SlotSet* slots = GetSlotSet(chunk);
if (slots != nullptr) { if (slots != nullptr) {
size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize; size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize;
int new_count = 0; int new_count = 0;
...@@ -133,8 +135,8 @@ class RememberedSet : public AllStatic { ...@@ -133,8 +135,8 @@ class RememberedSet : public AllStatic {
} }
// Only old-to-old slot sets are released eagerly. Old-new-slot sets are // Only old-to-old slot sets are released eagerly. Old-new-slot sets are
// released by the sweeper threads. // released by the sweeper threads.
if (type == OLD_TO_OLD && new_count == 0) { if (direction == OLD_TO_OLD && new_count == 0) {
chunk->ReleaseSlotSet<OLD_TO_OLD>(); chunk->ReleaseOldToOldSlots();
} }
} }
} }
...@@ -143,9 +145,10 @@ class RememberedSet : public AllStatic { ...@@ -143,9 +145,10 @@ class RememberedSet : public AllStatic {
// to the remembered set. // to the remembered set.
static void InsertTyped(Page* page, Address host_addr, SlotType slot_type, static void InsertTyped(Page* page, Address host_addr, SlotType slot_type,
Address slot_addr) { Address slot_addr) {
TypedSlotSet* slot_set = page->typed_slot_set<type>(); TypedSlotSet* slot_set = GetTypedSlotSet(page);
if (slot_set == nullptr) { if (slot_set == nullptr) {
slot_set = page->AllocateTypedSlotSet<type>(); AllocateTypedSlotSet(page);
slot_set = GetTypedSlotSet(page);
} }
if (host_addr == nullptr) { if (host_addr == nullptr) {
host_addr = page->address(); host_addr = page->address();
...@@ -161,7 +164,7 @@ class RememberedSet : public AllStatic { ...@@ -161,7 +164,7 @@ class RememberedSet : public AllStatic {
// Given a page and a range of typed slots in that page, this function removes // Given a page and a range of typed slots in that page, this function removes
// the slots from the remembered set. // the slots from the remembered set.
static void RemoveRangeTyped(MemoryChunk* page, Address start, Address end) { static void RemoveRangeTyped(MemoryChunk* page, Address start, Address end) {
TypedSlotSet* slots = page->typed_slot_set<type>(); TypedSlotSet* slots = GetTypedSlotSet(page);
if (slots != nullptr) { if (slots != nullptr) {
slots->Iterate( slots->Iterate(
[start, end](SlotType slot_type, Address host_addr, [start, end](SlotType slot_type, Address host_addr,
...@@ -188,23 +191,23 @@ class RememberedSet : public AllStatic { ...@@ -188,23 +191,23 @@ class RememberedSet : public AllStatic {
// Address slot_addr) and return SlotCallbackResult. // Address slot_addr) and return SlotCallbackResult.
template <typename Callback> template <typename Callback>
static void IterateTyped(MemoryChunk* chunk, Callback callback) { static void IterateTyped(MemoryChunk* chunk, Callback callback) {
TypedSlotSet* slots = chunk->typed_slot_set<type>(); TypedSlotSet* slots = GetTypedSlotSet(chunk);
if (slots != nullptr) { if (slots != nullptr) {
int new_count = slots->Iterate(callback, TypedSlotSet::KEEP_EMPTY_CHUNKS); int new_count = slots->Iterate(callback, TypedSlotSet::KEEP_EMPTY_CHUNKS);
if (new_count == 0) { if (new_count == 0) {
chunk->ReleaseTypedSlotSet<type>(); ReleaseTypedSlotSet(chunk);
} }
} }
} }
// Clear all old to old slots from the remembered set. // Clear all old to old slots from the remembered set.
static void ClearAll(Heap* heap) { static void ClearAll(Heap* heap) {
STATIC_ASSERT(type == OLD_TO_OLD); STATIC_ASSERT(direction == OLD_TO_OLD);
MemoryChunkIterator it(heap); MemoryChunkIterator it(heap);
MemoryChunk* chunk; MemoryChunk* chunk;
while ((chunk = it.next()) != nullptr) { while ((chunk = it.next()) != nullptr) {
chunk->ReleaseSlotSet<OLD_TO_OLD>(); chunk->ReleaseOldToOldSlots();
chunk->ReleaseTypedSlotSet<OLD_TO_OLD>(); chunk->ReleaseTypedOldToOldSlots();
} }
} }
...@@ -215,6 +218,48 @@ class RememberedSet : public AllStatic { ...@@ -215,6 +218,48 @@ class RememberedSet : public AllStatic {
static void ClearInvalidTypedSlots(Heap* heap, MemoryChunk* chunk); static void ClearInvalidTypedSlots(Heap* heap, MemoryChunk* chunk);
private: private:
static SlotSet* GetSlotSet(MemoryChunk* chunk) {
if (direction == OLD_TO_OLD) {
return chunk->old_to_old_slots();
} else {
return chunk->old_to_new_slots();
}
}
static TypedSlotSet* GetTypedSlotSet(MemoryChunk* chunk) {
if (direction == OLD_TO_OLD) {
return chunk->typed_old_to_old_slots();
} else {
return chunk->typed_old_to_new_slots();
}
}
static void ReleaseTypedSlotSet(MemoryChunk* chunk) {
if (direction == OLD_TO_OLD) {
chunk->ReleaseTypedOldToOldSlots();
}
}
static SlotSet* AllocateSlotSet(MemoryChunk* chunk) {
if (direction == OLD_TO_OLD) {
chunk->AllocateOldToOldSlots();
return chunk->old_to_old_slots();
} else {
chunk->AllocateOldToNewSlots();
return chunk->old_to_new_slots();
}
}
static TypedSlotSet* AllocateTypedSlotSet(MemoryChunk* chunk) {
if (direction == OLD_TO_OLD) {
chunk->AllocateTypedOldToOldSlots();
return chunk->typed_old_to_old_slots();
} else {
chunk->AllocateTypedOldToNewSlots();
return chunk->typed_old_to_new_slots();
}
}
static bool IsValidSlot(Heap* heap, MemoryChunk* chunk, Object** slot); static bool IsValidSlot(Heap* heap, MemoryChunk* chunk, Object** slot);
}; };
......
...@@ -330,16 +330,16 @@ void Page::MarkNeverAllocateForTesting() { ...@@ -330,16 +330,16 @@ void Page::MarkNeverAllocateForTesting() {
void Page::MarkEvacuationCandidate() { void Page::MarkEvacuationCandidate() {
DCHECK(!IsFlagSet(NEVER_EVACUATE)); DCHECK(!IsFlagSet(NEVER_EVACUATE));
DCHECK_NULL(slot_set<OLD_TO_OLD>()); DCHECK_NULL(old_to_old_slots_);
DCHECK_NULL(typed_slot_set<OLD_TO_OLD>()); DCHECK_NULL(typed_old_to_old_slots_);
SetFlag(EVACUATION_CANDIDATE); SetFlag(EVACUATION_CANDIDATE);
reinterpret_cast<PagedSpace*>(owner())->free_list()->EvictFreeListItems(this); reinterpret_cast<PagedSpace*>(owner())->free_list()->EvictFreeListItems(this);
} }
void Page::ClearEvacuationCandidate() { void Page::ClearEvacuationCandidate() {
if (!IsFlagSet(COMPACTION_WAS_ABORTED)) { if (!IsFlagSet(COMPACTION_WAS_ABORTED)) {
DCHECK_NULL(slot_set<OLD_TO_OLD>()); DCHECK_NULL(old_to_old_slots_);
DCHECK_NULL(typed_slot_set<OLD_TO_OLD>()); DCHECK_NULL(typed_old_to_old_slots_);
} }
ClearFlag(EVACUATION_CANDIDATE); ClearFlag(EVACUATION_CANDIDATE);
InitializeFreeListCategories(); InitializeFreeListCategories();
......
...@@ -527,10 +527,10 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size, ...@@ -527,10 +527,10 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size,
chunk->flags_ = Flags(NO_FLAGS); chunk->flags_ = Flags(NO_FLAGS);
chunk->set_owner(owner); chunk->set_owner(owner);
chunk->InitializeReservedMemory(); chunk->InitializeReservedMemory();
chunk->slot_set_[OLD_TO_NEW].SetValue(nullptr); chunk->old_to_new_slots_.SetValue(nullptr);
chunk->slot_set_[OLD_TO_OLD].SetValue(nullptr); chunk->old_to_old_slots_ = nullptr;
chunk->typed_slot_set_[OLD_TO_NEW].SetValue(nullptr); chunk->typed_old_to_new_slots_.SetValue(nullptr);
chunk->typed_slot_set_[OLD_TO_OLD].SetValue(nullptr); chunk->typed_old_to_old_slots_ = nullptr;
chunk->skip_list_ = nullptr; chunk->skip_list_ = nullptr;
chunk->progress_bar_ = 0; chunk->progress_bar_ = 0;
chunk->high_water_mark_.SetValue(static_cast<intptr_t>(area_start - base)); chunk->high_water_mark_.SetValue(static_cast<intptr_t>(area_start - base));
...@@ -1114,15 +1114,15 @@ void MemoryChunk::ReleaseAllocatedMemory() { ...@@ -1114,15 +1114,15 @@ void MemoryChunk::ReleaseAllocatedMemory() {
delete mutex_; delete mutex_;
mutex_ = nullptr; mutex_ = nullptr;
} }
ReleaseSlotSet<OLD_TO_NEW>(); if (old_to_new_slots_.Value() != nullptr) ReleaseOldToNewSlots();
ReleaseSlotSet<OLD_TO_OLD>(); if (old_to_old_slots_ != nullptr) ReleaseOldToOldSlots();
ReleaseTypedSlotSet<OLD_TO_NEW>(); if (typed_old_to_new_slots_.Value() != nullptr) ReleaseTypedOldToNewSlots();
ReleaseTypedSlotSet<OLD_TO_OLD>(); if (typed_old_to_old_slots_ != nullptr) ReleaseTypedOldToOldSlots();
if (local_tracker_ != nullptr) ReleaseLocalTracker(); if (local_tracker_ != nullptr) ReleaseLocalTracker();
if (young_generation_bitmap_ != nullptr) ReleaseYoungGenerationBitmap(); if (young_generation_bitmap_ != nullptr) ReleaseYoungGenerationBitmap();
} }
static SlotSet* AllocateAndInitializeSlotSet(size_t size, Address page_start) { static SlotSet* AllocateSlotSet(size_t size, Address page_start) {
size_t pages = (size + Page::kPageSize - 1) / Page::kPageSize; size_t pages = (size + Page::kPageSize - 1) / Page::kPageSize;
DCHECK(pages > 0); DCHECK(pages > 0);
SlotSet* slot_set = new SlotSet[pages]; SlotSet* slot_set = new SlotSet[pages];
...@@ -1132,58 +1132,46 @@ static SlotSet* AllocateAndInitializeSlotSet(size_t size, Address page_start) { ...@@ -1132,58 +1132,46 @@ static SlotSet* AllocateAndInitializeSlotSet(size_t size, Address page_start) {
return slot_set; return slot_set;
} }
template SlotSet* MemoryChunk::AllocateSlotSet<OLD_TO_NEW>(); void MemoryChunk::AllocateOldToNewSlots() {
template SlotSet* MemoryChunk::AllocateSlotSet<OLD_TO_OLD>(); DCHECK(nullptr == old_to_new_slots_.Value());
old_to_new_slots_.SetValue(AllocateSlotSet(size_, address()));
}
template <RememberedSetType type> void MemoryChunk::ReleaseOldToNewSlots() {
SlotSet* MemoryChunk::AllocateSlotSet() { SlotSet* old_to_new_slots = old_to_new_slots_.Value();
SlotSet* slot_set = AllocateAndInitializeSlotSet(size_, address()); delete[] old_to_new_slots;
if (!slot_set_[type].TrySetValue(nullptr, slot_set)) { old_to_new_slots_.SetValue(nullptr);
delete[] slot_set;
slot_set = slot_set_[type].Value();
DCHECK(slot_set);
return slot_set;
}
return slot_set;
} }
template void MemoryChunk::ReleaseSlotSet<OLD_TO_NEW>(); void MemoryChunk::AllocateOldToOldSlots() {
template void MemoryChunk::ReleaseSlotSet<OLD_TO_OLD>(); DCHECK(nullptr == old_to_old_slots_);
old_to_old_slots_ = AllocateSlotSet(size_, address());
}
template <RememberedSetType type> void MemoryChunk::ReleaseOldToOldSlots() {
void MemoryChunk::ReleaseSlotSet() { delete[] old_to_old_slots_;
SlotSet* slot_set = slot_set_[type].Value(); old_to_old_slots_ = nullptr;
if (slot_set) {
delete[] slot_set;
slot_set_[type].SetValue(nullptr);
}
} }
template TypedSlotSet* MemoryChunk::AllocateTypedSlotSet<OLD_TO_NEW>(); void MemoryChunk::AllocateTypedOldToNewSlots() {
template TypedSlotSet* MemoryChunk::AllocateTypedSlotSet<OLD_TO_OLD>(); DCHECK(nullptr == typed_old_to_new_slots_.Value());
typed_old_to_new_slots_.SetValue(new TypedSlotSet(address()));
}
template <RememberedSetType type> void MemoryChunk::ReleaseTypedOldToNewSlots() {
TypedSlotSet* MemoryChunk::AllocateTypedSlotSet() { TypedSlotSet* typed_old_to_new_slots = typed_old_to_new_slots_.Value();
TypedSlotSet* slot_set = new TypedSlotSet(address()); delete typed_old_to_new_slots;
if (!typed_slot_set_[type].TrySetValue(nullptr, slot_set)) { typed_old_to_new_slots_.SetValue(nullptr);
delete slot_set;
slot_set = typed_slot_set_[type].Value();
DCHECK(slot_set);
return slot_set;
}
return slot_set;
} }
template void MemoryChunk::ReleaseTypedSlotSet<OLD_TO_NEW>(); void MemoryChunk::AllocateTypedOldToOldSlots() {
template void MemoryChunk::ReleaseTypedSlotSet<OLD_TO_OLD>(); DCHECK(nullptr == typed_old_to_old_slots_);
typed_old_to_old_slots_ = new TypedSlotSet(address());
}
template <RememberedSetType type> void MemoryChunk::ReleaseTypedOldToOldSlots() {
void MemoryChunk::ReleaseTypedSlotSet() { delete typed_old_to_old_slots_;
TypedSlotSet* typed_slot_set = typed_slot_set_[type].Value(); typed_old_to_old_slots_ = nullptr;
if (typed_slot_set) {
delete typed_slot_set;
typed_slot_set_[type].SetValue(nullptr);
}
} }
void MemoryChunk::AllocateLocalTracker() { void MemoryChunk::AllocateLocalTracker() {
......
...@@ -131,12 +131,6 @@ enum FreeListCategoryType { ...@@ -131,12 +131,6 @@ enum FreeListCategoryType {
enum FreeMode { kLinkCategory, kDoNotLinkCategory }; enum FreeMode { kLinkCategory, kDoNotLinkCategory };
enum RememberedSetType {
OLD_TO_NEW,
OLD_TO_OLD,
NUMBER_OF_REMEMBERED_SET_TYPES = OLD_TO_OLD + 1
};
// A free list category maintains a linked list of free memory blocks. // A free list category maintains a linked list of free memory blocks.
class FreeListCategory { class FreeListCategory {
public: public:
...@@ -344,15 +338,17 @@ class MemoryChunk { ...@@ -344,15 +338,17 @@ class MemoryChunk {
+ kPointerSize // Heap* heap_ + kPointerSize // Heap* heap_
+ kIntptrSize // intptr_t progress_bar_ + kIntptrSize // intptr_t progress_bar_
+ kIntptrSize // intptr_t live_byte_count_ + kIntptrSize // intptr_t live_byte_count_
+ kPointerSize * NUMBER_OF_REMEMBERED_SET_TYPES // SlotSet* array + kPointerSize // SlotSet* old_to_new_slots_
+ kPointerSize * NUMBER_OF_REMEMBERED_SET_TYPES // TypedSlotSet* array + kPointerSize // SlotSet* old_to_old_slots_
+ kPointerSize // SkipList* skip_list_ + kPointerSize // TypedSlotSet* typed_old_to_new_slots_
+ kPointerSize // AtomicValue high_water_mark_ + kPointerSize // TypedSlotSet* typed_old_to_old_slots_
+ kPointerSize // base::Mutex* mutex_ + kPointerSize // SkipList* skip_list_
+ kPointerSize // base::AtomicWord concurrent_sweeping_ + kPointerSize // AtomicValue high_water_mark_
+ 2 * kSizetSize // AtomicNumber free-list statistics + kPointerSize // base::Mutex* mutex_
+ kPointerSize // AtomicValue next_chunk_ + kPointerSize // base::AtomicWord concurrent_sweeping_
+ kPointerSize // AtomicValue prev_chunk_ + 2 * kSizetSize // AtomicNumber free-list statistics
+ kPointerSize // AtomicValue next_chunk_
+ kPointerSize // AtomicValue prev_chunk_
+ FreeListCategory::kSize * kNumberOfCategories + FreeListCategory::kSize * kNumberOfCategories
// FreeListCategory categories_[kNumberOfCategories] // FreeListCategory categories_[kNumberOfCategories]
+ kPointerSize // LocalArrayBufferTracker* local_tracker_ + kPointerSize // LocalArrayBufferTracker* local_tracker_
...@@ -467,26 +463,24 @@ class MemoryChunk { ...@@ -467,26 +463,24 @@ class MemoryChunk {
inline void set_skip_list(SkipList* skip_list) { skip_list_ = skip_list; } inline void set_skip_list(SkipList* skip_list) { skip_list_ = skip_list; }
template <RememberedSetType type> inline SlotSet* old_to_new_slots() { return old_to_new_slots_.Value(); }
SlotSet* slot_set() { inline SlotSet* old_to_old_slots() { return old_to_old_slots_; }
return slot_set_[type].Value(); inline TypedSlotSet* typed_old_to_new_slots() {
return typed_old_to_new_slots_.Value();
} }
inline TypedSlotSet* typed_old_to_old_slots() {
template <RememberedSetType type> return typed_old_to_old_slots_;
TypedSlotSet* typed_slot_set() {
return typed_slot_set_[type].Value();
} }
inline LocalArrayBufferTracker* local_tracker() { return local_tracker_; } inline LocalArrayBufferTracker* local_tracker() { return local_tracker_; }
template <RememberedSetType type> V8_EXPORT_PRIVATE void AllocateOldToNewSlots();
SlotSet* AllocateSlotSet(); void ReleaseOldToNewSlots();
template <RememberedSetType type> V8_EXPORT_PRIVATE void AllocateOldToOldSlots();
void ReleaseSlotSet(); void ReleaseOldToOldSlots();
template <RememberedSetType type> void AllocateTypedOldToNewSlots();
TypedSlotSet* AllocateTypedSlotSet(); void ReleaseTypedOldToNewSlots();
template <RememberedSetType type> void AllocateTypedOldToOldSlots();
void ReleaseTypedSlotSet(); void ReleaseTypedOldToOldSlots();
void AllocateLocalTracker(); void AllocateLocalTracker();
void ReleaseLocalTracker(); void ReleaseLocalTracker();
void AllocateYoungGenerationBitmap(); void AllocateYoungGenerationBitmap();
...@@ -658,9 +652,10 @@ class MemoryChunk { ...@@ -658,9 +652,10 @@ class MemoryChunk {
// A single slot set for small pages (of size kPageSize) or an array of slot // A single slot set for small pages (of size kPageSize) or an array of slot
// set for large pages. In the latter case the number of entries in the array // set for large pages. In the latter case the number of entries in the array
// is ceil(size() / kPageSize). // is ceil(size() / kPageSize).
base::AtomicValue<SlotSet*> slot_set_[NUMBER_OF_REMEMBERED_SET_TYPES]; base::AtomicValue<SlotSet*> old_to_new_slots_;
base::AtomicValue<TypedSlotSet*> SlotSet* old_to_old_slots_;
typed_slot_set_[NUMBER_OF_REMEMBERED_SET_TYPES]; base::AtomicValue<TypedSlotSet*> typed_old_to_new_slots_;
TypedSlotSet* typed_old_to_old_slots_;
SkipList* skip_list_; SkipList* skip_list_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment