[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:
parent
40ccadb619
commit
4aa5241fe9
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user