| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/array-buffer-tracker.h" | 5 #include "src/heap/array-buffer-tracker.h" |
| 6 #include "src/heap/array-buffer-tracker-inl.h" |
| 6 #include "src/heap/heap.h" | 7 #include "src/heap/heap.h" |
| 7 #include "src/isolate.h" | |
| 8 #include "src/objects-inl.h" | |
| 9 #include "src/objects.h" | |
| 10 #include "src/v8.h" | |
| 11 | 8 |
| 12 namespace v8 { | 9 namespace v8 { |
| 13 namespace internal { | 10 namespace internal { |
| 14 | 11 |
| 15 LocalArrayBufferTracker::~LocalArrayBufferTracker() { | 12 LocalArrayBufferTracker::~LocalArrayBufferTracker() { |
| 16 CHECK(array_buffers_.empty()); | 13 CHECK(array_buffers_.empty()); |
| 17 } | 14 } |
| 18 | 15 |
| 19 void LocalArrayBufferTracker::Add(Key key, const Value& value) { | |
| 20 auto ret = array_buffers_.insert(std::make_pair(key, value)); | |
| 21 USE(ret); | |
| 22 // Check that we indeed inserted a new value and did not overwrite an existing | |
| 23 // one (which would be a bug). | |
| 24 DCHECK(ret.second); | |
| 25 } | |
| 26 | |
| 27 LocalArrayBufferTracker::Value LocalArrayBufferTracker::Remove(Key key) { | |
| 28 TrackingMap::iterator it = array_buffers_.find(key); | |
| 29 DCHECK(it != array_buffers_.end()); | |
| 30 Value value = it->second; | |
| 31 array_buffers_.erase(it); | |
| 32 return value; | |
| 33 } | |
| 34 | |
| 35 template <LocalArrayBufferTracker::FreeMode free_mode> | 16 template <LocalArrayBufferTracker::FreeMode free_mode> |
| 36 void LocalArrayBufferTracker::Free() { | 17 void LocalArrayBufferTracker::Free() { |
| 37 size_t freed_memory = 0; | 18 size_t freed_memory = 0; |
| 38 for (TrackingMap::iterator it = array_buffers_.begin(); | 19 for (TrackingMap::iterator it = array_buffers_.begin(); |
| 39 it != array_buffers_.end();) { | 20 it != array_buffers_.end();) { |
| 40 if ((free_mode == kFreeAll) || | 21 if ((free_mode == kFreeAll) || |
| 41 Marking::IsWhite(Marking::MarkBitFrom(it->first))) { | 22 Marking::IsWhite(Marking::MarkBitFrom(it->first))) { |
| 42 heap_->isolate()->array_buffer_allocator()->Free(it->second.first, | 23 heap_->isolate()->array_buffer_allocator()->Free(it->second.first, |
| 43 it->second.second); | 24 it->second.second); |
| 44 freed_memory += it->second.second; | 25 freed_memory += it->second.second; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 } else { | 66 } else { |
| 86 UNREACHABLE(); | 67 UNREACHABLE(); |
| 87 } | 68 } |
| 88 } | 69 } |
| 89 if (freed_memory > 0) { | 70 if (freed_memory > 0) { |
| 90 heap_->update_amount_of_external_allocated_freed_memory( | 71 heap_->update_amount_of_external_allocated_freed_memory( |
| 91 static_cast<intptr_t>(freed_memory)); | 72 static_cast<intptr_t>(freed_memory)); |
| 92 } | 73 } |
| 93 } | 74 } |
| 94 | 75 |
| 95 void ArrayBufferTracker::RegisterNew(Heap* heap, JSArrayBuffer* buffer) { | |
| 96 void* data = buffer->backing_store(); | |
| 97 if (!data) return; | |
| 98 | |
| 99 size_t length = NumberToSize(heap->isolate(), buffer->byte_length()); | |
| 100 Page* page = Page::FromAddress(buffer->address()); | |
| 101 { | |
| 102 base::LockGuard<base::Mutex> guard(page->mutex()); | |
| 103 LocalArrayBufferTracker* tracker = page->local_tracker(); | |
| 104 if (tracker == nullptr) { | |
| 105 page->AllocateLocalTracker(); | |
| 106 tracker = page->local_tracker(); | |
| 107 } | |
| 108 DCHECK_NOT_NULL(tracker); | |
| 109 tracker->Add(buffer, std::make_pair(data, length)); | |
| 110 } | |
| 111 // We may go over the limit of externally allocated memory here. We call the | |
| 112 // api function to trigger a GC in this case. | |
| 113 reinterpret_cast<v8::Isolate*>(heap->isolate()) | |
| 114 ->AdjustAmountOfExternalAllocatedMemory(length); | |
| 115 } | |
| 116 | |
| 117 void ArrayBufferTracker::Unregister(Heap* heap, JSArrayBuffer* buffer) { | |
| 118 void* data = buffer->backing_store(); | |
| 119 if (!data) return; | |
| 120 | |
| 121 Page* page = Page::FromAddress(buffer->address()); | |
| 122 size_t length = 0; | |
| 123 { | |
| 124 base::LockGuard<base::Mutex> guard(page->mutex()); | |
| 125 LocalArrayBufferTracker* tracker = page->local_tracker(); | |
| 126 DCHECK_NOT_NULL(tracker); | |
| 127 length = tracker->Remove(buffer).second; | |
| 128 } | |
| 129 heap->update_amount_of_external_allocated_memory( | |
| 130 -static_cast<intptr_t>(length)); | |
| 131 } | |
| 132 | |
| 133 void ArrayBufferTracker::FreeDeadInNewSpace(Heap* heap) { | 76 void ArrayBufferTracker::FreeDeadInNewSpace(Heap* heap) { |
| 134 DCHECK_EQ(heap->gc_state(), Heap::HeapState::SCAVENGE); | 77 DCHECK_EQ(heap->gc_state(), Heap::HeapState::SCAVENGE); |
| 135 NewSpacePageIterator from_it(heap->new_space()->FromSpaceStart(), | 78 NewSpacePageIterator from_it(heap->new_space()->FromSpaceStart(), |
| 136 heap->new_space()->FromSpaceEnd()); | 79 heap->new_space()->FromSpaceEnd()); |
| 137 while (from_it.has_next()) { | 80 while (from_it.has_next()) { |
| 138 Page* page = from_it.next(); | 81 Page* page = from_it.next(); |
| 139 bool empty = ProcessBuffers(page, kUpdateForwardedRemoveOthers); | 82 bool empty = ProcessBuffers(page, kUpdateForwardedRemoveOthers); |
| 140 CHECK(empty); | 83 CHECK(empty); |
| 141 } | 84 } |
| 142 heap->account_amount_of_external_allocated_freed_memory(); | 85 heap->account_amount_of_external_allocated_freed_memory(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 { | 129 { |
| 187 base::LockGuard<base::Mutex> guard(page->mutex()); | 130 base::LockGuard<base::Mutex> guard(page->mutex()); |
| 188 LocalArrayBufferTracker* tracker = page->local_tracker(); | 131 LocalArrayBufferTracker* tracker = page->local_tracker(); |
| 189 if (tracker == nullptr) return false; | 132 if (tracker == nullptr) return false; |
| 190 return tracker->IsTracked(buffer); | 133 return tracker->IsTracked(buffer); |
| 191 } | 134 } |
| 192 } | 135 } |
| 193 | 136 |
| 194 } // namespace internal | 137 } // namespace internal |
| 195 } // namespace v8 | 138 } // namespace v8 |
| OLD | NEW |