Chromium Code Reviews| Index: src/heap/heap.cc |
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc |
| index bfd1fb50958ee8288422606051700c4324438775..46b6d61f6bcc1a797264966ac62748ac49c6a1ae 100644 |
| --- a/src/heap/heap.cc |
| +++ b/src/heap/heap.cc |
| @@ -1642,6 +1642,8 @@ void Heap::Scavenge() { |
| new_space_.LowerInlineAllocationLimit( |
| new_space_.inline_allocation_limit_step()); |
| + FreeDeadArrayBuffers(true); |
| + |
| // Update how much has survived scavenge. |
| IncrementYoungSurvivorsCounter(static_cast<int>( |
| (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); |
| @@ -1735,46 +1737,116 @@ void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) { |
| } |
| -void Heap::RegisterNewArrayBuffer(void* data, size_t length) { |
| +namespace { |
| + |
| +void RegisterNewArrayBufferHelper(std::map<void*, size_t>& live_buffers, |
| + void* data, size_t length) { |
| + live_buffers[data] = length; |
| +} |
| + |
| + |
| +void UnregisterArrayBufferHelper( |
| + std::map<void*, size_t>& live_buffers, |
| + std::map<void*, size_t>& not_yet_discovered_buffers, void* data) { |
| + DCHECK(live_buffers.count(data) > 0); |
| + live_buffers.erase(data); |
| + not_yet_discovered_buffers.erase(data); |
| +} |
| + |
| + |
| +void RegisterLiveArrayBufferHelper( |
| + std::map<void*, size_t>& not_yet_discovered_buffers, void* data) { |
| + not_yet_discovered_buffers.erase(data); |
| +} |
| + |
| + |
| +size_t FreeDeadArrayBuffersHelper( |
| + Isolate* isolate, std::map<void*, size_t>& live_buffers, |
| + std::map<void*, size_t>& not_yet_discovered_buffers) { |
| + size_t freed_memory = 0; |
| + for (auto buffer = not_yet_discovered_buffers.begin(); |
| + buffer != not_yet_discovered_buffers.end(); ++buffer) { |
| + isolate->array_buffer_allocator()->Free(buffer->first, buffer->second); |
| + freed_memory += buffer->second; |
| + live_buffers.erase(buffer->first); |
| + } |
| + not_yet_discovered_buffers = live_buffers; |
| + return freed_memory; |
| +} |
| + |
| + |
| +void TearDownArrayBuffersHelper( |
| + Isolate* isolate, std::map<void*, size_t>& live_buffers, |
| + std::map<void*, size_t>& not_yet_discovered_buffers) { |
| + for (auto buffer = live_buffers.begin(); buffer != live_buffers.end(); |
| + ++buffer) { |
| + isolate->array_buffer_allocator()->Free(buffer->first, buffer->second); |
| + } |
| + live_buffers.clear(); |
| + not_yet_discovered_buffers.clear(); |
| +} |
| + |
| +} // namespace |
|
Hannes Payer (out of office)
2015/05/08 13:39:29
Why did you add a namespace?
jochen (gone - plz use gerrit)
2015/05/08 14:42:56
so the helpers above don't pollute the global name
Hannes Payer (out of office)
2015/05/12 06:33:28
I looked it up in the style guide. That's fine. Ho
|
| + |
| + |
| +void Heap::RegisterNewArrayBuffer(bool in_new_space, void* data, |
| + size_t length) { |
| if (!data) return; |
| - live_array_buffers_[data] = length; |
| + RegisterNewArrayBufferHelper( |
| + in_new_space ? live_new_array_buffers_ : live_array_buffers_, data, |
| + length); |
| reinterpret_cast<v8::Isolate*>(isolate_) |
| ->AdjustAmountOfExternalAllocatedMemory(length); |
| } |
| -void Heap::UnregisterArrayBuffer(void* data) { |
| +void Heap::UnregisterArrayBuffer(bool in_new_space, void* data) { |
| if (!data) return; |
| - DCHECK(live_array_buffers_.count(data) > 0); |
| - live_array_buffers_.erase(data); |
| - not_yet_discovered_array_buffers_.erase(data); |
| + UnregisterArrayBufferHelper( |
| + in_new_space ? live_new_array_buffers_ : live_array_buffers_, |
| + in_new_space ? not_yet_discovered_new_array_buffers_ |
| + : not_yet_discovered_array_buffers_, |
| + data); |
| } |
| -void Heap::RegisterLiveArrayBuffer(void* data) { |
| - not_yet_discovered_array_buffers_.erase(data); |
| +void Heap::RegisterLiveArrayBuffer(bool in_new_space, void* data) { |
| + RegisterLiveArrayBufferHelper(in_new_space |
| + ? not_yet_discovered_new_array_buffers_ |
| + : not_yet_discovered_array_buffers_, |
| + data); |
| } |
| -void Heap::FreeDeadArrayBuffers() { |
| - for (auto buffer = not_yet_discovered_array_buffers_.begin(); |
| - buffer != not_yet_discovered_array_buffers_.end(); ++buffer) { |
| - isolate_->array_buffer_allocator()->Free(buffer->first, buffer->second); |
| - // Don't use the API method here since this could trigger another GC. |
| - amount_of_external_allocated_memory_ -= buffer->second; |
| - live_array_buffers_.erase(buffer->first); |
| +void Heap::FreeDeadArrayBuffers(bool in_new_space) { |
| + size_t freed_memory = FreeDeadArrayBuffersHelper( |
| + isolate_, in_new_space ? live_new_array_buffers_ : live_array_buffers_, |
| + in_new_space ? not_yet_discovered_new_array_buffers_ |
| + : not_yet_discovered_array_buffers_); |
| + if (freed_memory) { |
| + reinterpret_cast<v8::Isolate*>(isolate_) |
| + ->AdjustAmountOfExternalAllocatedMemory( |
| + -static_cast<int64_t>(freed_memory)); |
| } |
| - not_yet_discovered_array_buffers_ = live_array_buffers_; |
| } |
| void Heap::TearDownArrayBuffers() { |
| - for (auto buffer = live_array_buffers_.begin(); |
| - buffer != live_array_buffers_.end(); ++buffer) { |
| - isolate_->array_buffer_allocator()->Free(buffer->first, buffer->second); |
| - } |
| - live_array_buffers_.clear(); |
| - not_yet_discovered_array_buffers_.clear(); |
| + TearDownArrayBuffersHelper(isolate_, live_array_buffers_, |
| + not_yet_discovered_array_buffers_); |
| + TearDownArrayBuffersHelper(isolate_, live_new_array_buffers_, |
| + not_yet_discovered_new_array_buffers_); |
| +} |
| + |
| + |
| +void Heap::PromoteArrayBuffer(JSArrayBuffer* buffer) { |
| + if (buffer->is_external()) return; |
| + void* data = buffer->backing_store(); |
| + if (!data) return; |
| + DCHECK(live_new_array_buffers_.count(data) > 0); |
| + live_array_buffers_[data] = live_new_array_buffers_[data]; |
| + live_new_array_buffers_.erase(data); |
| + not_yet_discovered_new_array_buffers_.erase(data); |
| } |
| @@ -2173,6 +2245,9 @@ class ScavengingVisitor : public StaticVisitorBase { |
| heap->promotion_queue()->insert(target, object_size); |
| } |
| } |
| + if (map->instance_type() == JS_ARRAY_BUFFER_TYPE) { |
| + heap->PromoteArrayBuffer(JSArrayBuffer::cast(target)); |
| + } |
| heap->IncrementPromotedObjectsSize(object_size); |
| return true; |
| } |