| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index 9c6a2a1690cdba36130ba3147302a84acf43d45d..b2b8a6a4609cd4105ea33d0767790b15d566a4c0 100644
|
| --- a/src/heap/heap.cc
|
| +++ b/src/heap/heap.cc
|
| @@ -17,6 +17,7 @@
|
| #include "src/debug/debug.h"
|
| #include "src/deoptimizer.h"
|
| #include "src/global-handles.h"
|
| +#include "src/heap/array-buffer-tracker.h"
|
| #include "src/heap/gc-idle-time-handler.h"
|
| #include "src/heap/gc-tracer.h"
|
| #include "src/heap/incremental-marking.h"
|
| @@ -144,7 +145,8 @@ Heap::Heap()
|
| gc_callbacks_depth_(0),
|
| deserialization_complete_(false),
|
| concurrent_sweeping_enabled_(false),
|
| - strong_roots_list_(NULL) {
|
| + strong_roots_list_(NULL),
|
| + array_buffer_tracker_(NULL) {
|
| // Allow build-time customization of the max semispace size. Building
|
| // V8 with snapshots and a non-default max semispace size is much
|
| // easier if you can define it as part of the build environment.
|
| @@ -1547,7 +1549,7 @@ void Heap::Scavenge() {
|
|
|
| SelectScavengingVisitorsTable();
|
|
|
| - PrepareArrayBufferDiscoveryInNewSpace();
|
| + array_buffer_tracker()->PrepareDiscoveryInNewSpace();
|
|
|
| // Flip the semispaces. After flipping, to space is empty, from space has
|
| // live objects.
|
| @@ -1649,7 +1651,7 @@ void Heap::Scavenge() {
|
| new_space_.LowerInlineAllocationLimit(
|
| new_space_.inline_allocation_limit_step());
|
|
|
| - FreeDeadArrayBuffers(true);
|
| + array_buffer_tracker()->FreeDead(true);
|
|
|
| // Update how much has survived scavenge.
|
| IncrementYoungSurvivorsCounter(static_cast<int>(
|
| @@ -1744,120 +1746,6 @@ void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) {
|
| }
|
|
|
|
|
| -void Heap::RegisterNewArrayBuffer(bool in_new_space, void* data,
|
| - size_t length) {
|
| - if (!data) return;
|
| - if (in_new_space) {
|
| - live_array_buffers_for_scavenge_[data] = length;
|
| - } else {
|
| - live_array_buffers_[data] = length;
|
| - }
|
| -
|
| - // We may go over the limit of externally allocated memory here. We call the
|
| - // api function to trigger a GC in this case.
|
| - reinterpret_cast<v8::Isolate*>(isolate_)
|
| - ->AdjustAmountOfExternalAllocatedMemory(length);
|
| -}
|
| -
|
| -
|
| -void Heap::UnregisterArrayBuffer(bool in_new_space, void* data) {
|
| - if (!data) return;
|
| -
|
| - std::map<void*, size_t>* live_buffers =
|
| - in_new_space ? &live_array_buffers_for_scavenge_ : &live_array_buffers_;
|
| - std::map<void*, size_t>* not_yet_discovered_buffers =
|
| - in_new_space ? ¬_yet_discovered_array_buffers_for_scavenge_
|
| - : ¬_yet_discovered_array_buffers_;
|
| -
|
| - DCHECK(live_buffers->count(data) > 0);
|
| -
|
| - size_t length = (*live_buffers)[data];
|
| - live_buffers->erase(data);
|
| - not_yet_discovered_buffers->erase(data);
|
| -
|
| - amount_of_external_allocated_memory_ -= length;
|
| -}
|
| -
|
| -
|
| -void Heap::RegisterLiveArrayBuffer(bool in_new_space, void* data) {
|
| - // ArrayBuffer might be in the middle of being constructed.
|
| - if (data == undefined_value()) return;
|
| - if (in_new_space) {
|
| - not_yet_discovered_array_buffers_for_scavenge_.erase(data);
|
| - } else {
|
| - not_yet_discovered_array_buffers_.erase(data);
|
| - }
|
| -}
|
| -
|
| -
|
| -void Heap::FreeDeadArrayBuffers(bool from_scavenge) {
|
| - size_t freed_memory = 0;
|
| - for (auto& buffer : not_yet_discovered_array_buffers_for_scavenge_) {
|
| - isolate()->array_buffer_allocator()->Free(buffer.first, buffer.second);
|
| - freed_memory += buffer.second;
|
| - live_array_buffers_for_scavenge_.erase(buffer.first);
|
| - }
|
| -
|
| - if (!from_scavenge) {
|
| - for (auto& buffer : not_yet_discovered_array_buffers_) {
|
| - isolate()->array_buffer_allocator()->Free(buffer.first, buffer.second);
|
| - freed_memory += buffer.second;
|
| - live_array_buffers_.erase(buffer.first);
|
| - }
|
| - }
|
| -
|
| - not_yet_discovered_array_buffers_for_scavenge_ =
|
| - live_array_buffers_for_scavenge_;
|
| - if (!from_scavenge) not_yet_discovered_array_buffers_ = live_array_buffers_;
|
| -
|
| - // Do not call through the api as this code is triggered while doing a GC.
|
| - amount_of_external_allocated_memory_ -= freed_memory;
|
| -}
|
| -
|
| -
|
| -void Heap::TearDownArrayBuffers() {
|
| - size_t freed_memory = 0;
|
| - for (auto& buffer : live_array_buffers_) {
|
| - isolate()->array_buffer_allocator()->Free(buffer.first, buffer.second);
|
| - freed_memory += buffer.second;
|
| - }
|
| - for (auto& buffer : live_array_buffers_for_scavenge_) {
|
| - isolate()->array_buffer_allocator()->Free(buffer.first, buffer.second);
|
| - freed_memory += buffer.second;
|
| - }
|
| - live_array_buffers_.clear();
|
| - live_array_buffers_for_scavenge_.clear();
|
| - not_yet_discovered_array_buffers_.clear();
|
| - not_yet_discovered_array_buffers_for_scavenge_.clear();
|
| -
|
| - if (freed_memory > 0) {
|
| - reinterpret_cast<v8::Isolate*>(isolate_)
|
| - ->AdjustAmountOfExternalAllocatedMemory(
|
| - -static_cast<int64_t>(freed_memory));
|
| - }
|
| -}
|
| -
|
| -
|
| -void Heap::PrepareArrayBufferDiscoveryInNewSpace() {
|
| - not_yet_discovered_array_buffers_for_scavenge_ =
|
| - live_array_buffers_for_scavenge_;
|
| -}
|
| -
|
| -
|
| -void Heap::PromoteArrayBuffer(Object* obj) {
|
| - JSArrayBuffer* buffer = JSArrayBuffer::cast(obj);
|
| - if (buffer->is_external()) return;
|
| - void* data = buffer->backing_store();
|
| - if (!data) return;
|
| - // ArrayBuffer might be in the middle of being constructed.
|
| - if (data == undefined_value()) return;
|
| - DCHECK(live_array_buffers_for_scavenge_.count(data) > 0);
|
| - live_array_buffers_[data] = live_array_buffers_for_scavenge_[data];
|
| - live_array_buffers_for_scavenge_.erase(data);
|
| - not_yet_discovered_array_buffers_for_scavenge_.erase(data);
|
| -}
|
| -
|
| -
|
| void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) {
|
| Object* allocation_site_obj =
|
| VisitWeakList<AllocationSite>(this, allocation_sites_list(), retainer);
|
| @@ -2087,6 +1975,16 @@ HeapObject* Heap::DoubleAlignForDeserialization(HeapObject* object, int size) {
|
| }
|
|
|
|
|
| +void Heap::RegisterNewArrayBuffer(JSArrayBuffer* buffer) {
|
| + return array_buffer_tracker()->RegisterNew(buffer);
|
| +}
|
| +
|
| +
|
| +void Heap::UnregisterArrayBuffer(JSArrayBuffer* buffer) {
|
| + return array_buffer_tracker()->Unregister(buffer);
|
| +}
|
| +
|
| +
|
| enum LoggingAndProfiling {
|
| LOGGING_AND_PROFILING_ENABLED,
|
| LOGGING_AND_PROFILING_DISABLED
|
| @@ -2388,7 +2286,9 @@ class ScavengingVisitor : public StaticVisitorBase {
|
| MapWord map_word = object->map_word();
|
| DCHECK(map_word.IsForwardingAddress());
|
| HeapObject* target = map_word.ToForwardingAddress();
|
| - if (!heap->InNewSpace(target)) heap->PromoteArrayBuffer(target);
|
| + if (!heap->InNewSpace(target)) {
|
| + heap->array_buffer_tracker()->Promote(JSArrayBuffer::cast(target));
|
| + }
|
| }
|
|
|
|
|
| @@ -5646,6 +5546,8 @@ bool Heap::SetUp() {
|
| object_stats_ = new ObjectStats(this);
|
| object_stats_->ClearObjectStats(true);
|
|
|
| + array_buffer_tracker_ = new ArrayBufferTracker(this);
|
| +
|
| LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
|
| LOG(isolate_, IntPtrTEvent("heap-available", Available()));
|
|
|
| @@ -5761,7 +5663,8 @@ void Heap::TearDown() {
|
|
|
| WaitUntilUnmappingOfFreeChunksCompleted();
|
|
|
| - TearDownArrayBuffers();
|
| + delete array_buffer_tracker_;
|
| + array_buffer_tracker_ = nullptr;
|
|
|
| isolate_->global_handles()->TearDown();
|
|
|
|
|