| Index: src/heap/array-buffer-tracker.cc
|
| diff --git a/src/heap/array-buffer-tracker.cc b/src/heap/array-buffer-tracker.cc
|
| index 6e389c1cbf6abe216c782bae30fedcba5b283443..767385f759d0b7cbf030e6cd7c99b9ebc6327bfd 100644
|
| --- a/src/heap/array-buffer-tracker.cc
|
| +++ b/src/heap/array-buffer-tracker.cc
|
| @@ -15,18 +15,20 @@ namespace internal {
|
| ArrayBufferTracker::~ArrayBufferTracker() {
|
| Isolate* isolate = heap()->isolate();
|
| 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_old_gen_) {
|
| + isolate->array_buffer_allocator()->Free(buffer.second.first,
|
| + buffer.second.second);
|
| + freed_memory += buffer.second.second;
|
| }
|
| - for (auto& buffer : live_array_buffers_for_scavenge_) {
|
| - isolate->array_buffer_allocator()->Free(buffer.first, buffer.second);
|
| - freed_memory += buffer.second;
|
| + for (auto& buffer : live_young_gen_) {
|
| + isolate->array_buffer_allocator()->Free(buffer.second.first,
|
| + buffer.second.second);
|
| + freed_memory += buffer.second.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();
|
| + live_old_gen_.clear();
|
| + live_young_gen_.clear();
|
| + not_yet_discovered_old_gen_.clear();
|
| + not_yet_discovered_young_gen_.clear();
|
|
|
| if (freed_memory > 0) {
|
| heap()->update_amount_of_external_allocated_memory(
|
| @@ -42,9 +44,13 @@ void ArrayBufferTracker::RegisterNew(JSArrayBuffer* buffer) {
|
| bool in_new_space = heap()->InNewSpace(buffer);
|
| size_t length = NumberToSize(heap()->isolate(), buffer->byte_length());
|
| if (in_new_space) {
|
| - live_array_buffers_for_scavenge_[data] = length;
|
| + live_young_gen_[buffer->address()] = std::make_pair(data, length);
|
| + not_yet_discovered_young_gen_[buffer->address()] =
|
| + std::make_pair(data, length);
|
| } else {
|
| - live_array_buffers_[data] = length;
|
| + live_old_gen_[buffer->address()] = std::make_pair(data, length);
|
| + not_yet_discovered_old_gen_[buffer->address()] =
|
| + std::make_pair(data, length);
|
| }
|
|
|
| // We may go over the limit of externally allocated memory here. We call the
|
| @@ -59,82 +65,115 @@ void ArrayBufferTracker::Unregister(JSArrayBuffer* buffer) {
|
| if (!data) return;
|
|
|
| bool in_new_space = heap()->InNewSpace(buffer);
|
| - 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_;
|
| + Key key = buffer->address();
|
| + TrackingMap* live_buffers = in_new_space ? &live_young_gen_ : &live_old_gen_;
|
| + TrackingMap* not_yet_discovered_buffers = in_new_space
|
| + ? ¬_yet_discovered_young_gen_
|
| + : ¬_yet_discovered_old_gen_;
|
|
|
| - DCHECK(live_buffers->count(data) > 0);
|
| + DCHECK(live_buffers->count(key) > 0);
|
|
|
| - size_t length = (*live_buffers)[data];
|
| - live_buffers->erase(data);
|
| - not_yet_discovered_buffers->erase(data);
|
| + size_t length = (*live_buffers)[key].second;
|
| + live_buffers->erase(key);
|
| + not_yet_discovered_buffers->erase(key);
|
|
|
| heap()->update_amount_of_external_allocated_memory(
|
| -static_cast<int64_t>(length));
|
| }
|
|
|
| -
|
| -void ArrayBufferTracker::MarkLive(JSArrayBuffer* buffer) {
|
| - base::LockGuard<base::Mutex> guard(&mutex_);
|
| - void* data = buffer->backing_store();
|
| -
|
| - // ArrayBuffer might be in the middle of being constructed.
|
| - if (data == heap()->undefined_value()) return;
|
| - if (heap()->InNewSpace(buffer)) {
|
| - not_yet_discovered_array_buffers_for_scavenge_.erase(data);
|
| - } else {
|
| - not_yet_discovered_array_buffers_.erase(data);
|
| - }
|
| -}
|
| -
|
| -
|
| void ArrayBufferTracker::FreeDead(bool from_scavenge) {
|
| size_t freed_memory = 0;
|
| Isolate* isolate = heap()->isolate();
|
| - 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);
|
| + for (auto& buffer : not_yet_discovered_young_gen_) {
|
| + isolate->array_buffer_allocator()->Free(buffer.second.first,
|
| + buffer.second.second);
|
| + freed_memory += buffer.second.second;
|
| + live_young_gen_.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);
|
| + for (auto& buffer : not_yet_discovered_old_gen_) {
|
| + isolate->array_buffer_allocator()->Free(buffer.second.first,
|
| + buffer.second.second);
|
| + freed_memory += buffer.second.second;
|
| + live_old_gen_.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_;
|
| + not_yet_discovered_young_gen_ = live_young_gen_;
|
| + if (!from_scavenge) not_yet_discovered_old_gen_ = live_old_gen_;
|
|
|
| // Do not call through the api as this code is triggered while doing a GC.
|
| heap()->update_amount_of_external_allocated_memory(
|
| -static_cast<int64_t>(freed_memory));
|
| }
|
|
|
| +#define UPDATE_GUARD(buffer, data) \
|
| + if (buffer->is_external()) return; \
|
| + data = buffer->backing_store(); \
|
| + if (data == nullptr) return; \
|
| + if (data == heap()->undefined_value()) return; \
|
| + base::LockGuard<base::Mutex> guard(&mutex_);
|
| +
|
| +void ArrayBufferTracker::MarkLive(JSArrayBuffer* buffer) {
|
| + void* data = nullptr;
|
| + UPDATE_GUARD(buffer, data);
|
|
|
| -void ArrayBufferTracker::PrepareDiscoveryInNewSpace() {
|
| - not_yet_discovered_array_buffers_for_scavenge_ =
|
| - live_array_buffers_for_scavenge_;
|
| + if (heap()->InNewSpace(buffer)) {
|
| + not_yet_discovered_young_gen_.erase(buffer->address());
|
| + } else {
|
| + not_yet_discovered_old_gen_.erase(buffer->address());
|
| + }
|
| }
|
|
|
| +void ArrayBufferTracker::Promote(JSArrayBuffer* new_buffer,
|
| + JSArrayBuffer* old_buffer) {
|
| + void* data = nullptr;
|
| + UPDATE_GUARD(new_buffer, data);
|
| +
|
| + Key new_key = new_buffer->address();
|
| + Key old_key = old_buffer->address();
|
| + DCHECK(live_young_gen_.count(old_key) > 0);
|
| + live_old_gen_[new_key] = live_young_gen_[old_key];
|
| + live_young_gen_.erase(old_key);
|
| + not_yet_discovered_young_gen_.erase(old_key);
|
| +}
|
|
|
| -void ArrayBufferTracker::Promote(JSArrayBuffer* buffer) {
|
| - base::LockGuard<base::Mutex> guard(&mutex_);
|
| +void ArrayBufferTracker::Compact(JSArrayBuffer* new_buffer,
|
| + JSArrayBuffer* old_buffer) {
|
| + void* data = nullptr;
|
| + UPDATE_GUARD(new_buffer, data);
|
| +
|
| + Key new_key = new_buffer->address();
|
| + Key old_key = old_buffer->address();
|
| + DCHECK_NE(new_key, old_key);
|
| + DCHECK(live_old_gen_.count(old_key) > 0);
|
| + live_old_gen_[new_key] = live_old_gen_[old_key];
|
| + live_old_gen_.erase(old_key);
|
| + not_yet_discovered_old_gen_.erase(old_key);
|
| +}
|
|
|
| - if (buffer->is_external()) return;
|
| - void* data = buffer->backing_store();
|
| - if (!data) return;
|
| - // ArrayBuffer might be in the middle of being constructed.
|
| - if (data == heap()->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 ArrayBufferTracker::SemiSpaceCopy(JSArrayBuffer* new_buffer,
|
| + JSArrayBuffer* old_buffer) {
|
| + void* data = nullptr;
|
| + UPDATE_GUARD(new_buffer, data);
|
| +
|
| + Key new_key = new_buffer->address();
|
| + Key old_key = old_buffer->address();
|
| + DCHECK(live_young_gen_.count(old_key) > 0);
|
| + live_young_gen_[new_key] = live_young_gen_[old_key];
|
| + live_young_gen_.erase(old_key);
|
| + not_yet_discovered_young_gen_.erase(old_key);
|
| +}
|
| +
|
| +#undef UPDATE_GUARD
|
| +
|
| +bool ArrayBufferTracker::IsTrackedInOldGenForTesting(JSArrayBuffer* buffer) {
|
| + return live_old_gen_.find(buffer->address()) != live_old_gen_.end();
|
| +}
|
| +
|
| +bool ArrayBufferTracker::IsTrackedInYoungGenForTesting(JSArrayBuffer* buffer) {
|
| + return live_young_gen_.find(buffer->address()) != live_young_gen_.end();
|
| }
|
|
|
| } // namespace internal
|
|
|