[heap] Factor out marking state of array buffer tracker

BUG=chromium:651354

Review-Url: https://codereview.chromium.org/2870683003
Cr-Commit-Position: refs/heads/master@{#45184}
This commit is contained in:
mlippautz 2017-05-09 03:09:12 -07:00 committed by Commit bot
parent 40ccadb619
commit 4aa5241fe9
3 changed files with 28 additions and 18 deletions

View File

@ -5,6 +5,7 @@
#include "src/heap/array-buffer-tracker.h"
#include "src/heap/array-buffer-tracker-inl.h"
#include "src/heap/heap.h"
#include "src/heap/spaces.h"
namespace v8 {
namespace internal {
@ -13,16 +14,13 @@ LocalArrayBufferTracker::~LocalArrayBufferTracker() {
CHECK(array_buffers_.empty());
}
template <LocalArrayBufferTracker::FreeMode free_mode>
void LocalArrayBufferTracker::Free() {
template <typename Callback>
void LocalArrayBufferTracker::Free(Callback should_free) {
size_t freed_memory = 0;
for (TrackingData::iterator it = array_buffers_.begin();
it != array_buffers_.end();) {
JSArrayBuffer* buffer = reinterpret_cast<JSArrayBuffer*>(it->first);
// TODO(mlippautz): Create a dependency on the collector to avoid getting
// the marking state out of thin air.
if ((free_mode == kFreeAll) ||
ObjectMarking::IsWhite(buffer, MarkingState::Internal(buffer))) {
if (should_free(buffer)) {
const size_t len = it->second;
heap_->isolate()->array_buffer_allocator()->Free(buffer->backing_store(),
len);
@ -88,12 +86,14 @@ void ArrayBufferTracker::FreeDeadInNewSpace(Heap* heap) {
heap->account_external_memory_concurrently_freed();
}
void ArrayBufferTracker::FreeDead(Page* page) {
void ArrayBufferTracker::FreeDead(Page* page,
const MarkingState& marking_state) {
// Callers need to ensure having the page lock.
LocalArrayBufferTracker* tracker = page->local_tracker();
if (tracker == nullptr) return;
DCHECK(!page->SweepingDone());
tracker->Free<LocalArrayBufferTracker::kFreeDead>();
tracker->Free([&marking_state](JSArrayBuffer* buffer) {
return ObjectMarking::IsWhite(buffer, marking_state);
});
if (tracker->IsEmpty()) {
page->ReleaseLocalTracker();
}
@ -102,7 +102,7 @@ void ArrayBufferTracker::FreeDead(Page* page) {
void ArrayBufferTracker::FreeAll(Page* page) {
LocalArrayBufferTracker* tracker = page->local_tracker();
if (tracker == nullptr) return;
tracker->Free<LocalArrayBufferTracker::kFreeAll>();
tracker->Free([](JSArrayBuffer* buffer) { return true; });
if (tracker->IsEmpty()) {
page->ReleaseLocalTracker();
}

View File

@ -16,6 +16,7 @@ namespace internal {
class Heap;
class JSArrayBuffer;
class MarkingState;
class Page;
class ArrayBufferTracker : public AllStatic {
@ -40,7 +41,7 @@ class ArrayBufferTracker : public AllStatic {
// Frees all backing store pointers for dead JSArrayBuffer on a given page.
// Requires marking information to be present. Requires the page lock to be
// taken by the caller.
static void FreeDead(Page* page);
static void FreeDead(Page* page, const MarkingState& marking_state);
// Frees all remaining, live or dead, array buffers on a page. Only useful
// during tear down.
@ -71,9 +72,15 @@ class LocalArrayBufferTracker {
inline void Add(Key key, const Value& value);
inline Value Remove(Key key);
// Frees up array buffers determined by |free_mode|.
template <FreeMode free_mode>
void Free();
// Frees up array buffers.
//
// Sample usage:
// Free([](HeapObject* array_buffer) {
// if (should_free_internal(array_buffer)) return true;
// return false;
// });
template <typename Callback>
void Free(Callback should_free);
// Processes buffers one by one. The CallbackResult of the callback decides
// what action to take on the buffer.

View File

@ -3784,6 +3784,9 @@ int MarkCompactCollector::Sweeper::RawSweep(
space->identity() == CODE_SPACE || space->identity() == MAP_SPACE);
DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone());
// Sweeper takes the marking state of the full collector.
const MarkingState state = MarkingState::Internal(p);
// If there are old-to-new slots in that page, we have to filter out slots
// that are in dead memory which is freed by the sweeper.
ClearOldToNewSlotsMode slots_clearing_mode = GetClearOldToNewSlotsMode(p);
@ -3793,7 +3796,7 @@ int MarkCompactCollector::Sweeper::RawSweep(
// Before we sweep objects on the page, we free dead array buffers which
// requires valid mark bits.
ArrayBufferTracker::FreeDead(p);
ArrayBufferTracker::FreeDead(p, state);
Address free_start = p->area_start();
DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
@ -3812,11 +3815,11 @@ int MarkCompactCollector::Sweeper::RawSweep(
intptr_t max_freed_bytes = 0;
int curr_region = -1;
LiveObjectIterator<kBlackObjects> it(p, MarkingState::Internal(p));
LiveObjectIterator<kBlackObjects> it(p, state);
HeapObject* object = NULL;
while ((object = it.Next()) != NULL) {
DCHECK(ObjectMarking::IsBlack(object, MarkingState::Internal(object)));
DCHECK(ObjectMarking::IsBlack(object, state));
Address free_end = object->address();
if (free_end != free_start) {
CHECK_GT(free_end, free_start);
@ -3890,7 +3893,7 @@ int MarkCompactCollector::Sweeper::RawSweep(
}
// Clear the mark bits of that page and reset live bytes count.
MarkingState::Internal(p).ClearLiveness();
state.ClearLiveness();
p->concurrent_sweeping_state().SetValue(Page::kSweepingDone);
if (free_list_mode == IGNORE_FREE_LIST) return 0;