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 |