Line data Source code
1 : // Copyright 2016 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_HEAP_ARRAY_BUFFER_TRACKER_INL_H_
6 : #define V8_HEAP_ARRAY_BUFFER_TRACKER_INL_H_
7 :
8 : #include "src/conversions-inl.h"
9 : #include "src/heap/array-buffer-tracker.h"
10 : #include "src/heap/heap.h"
11 : #include "src/objects.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 243808 : void ArrayBufferTracker::RegisterNew(Heap* heap, JSArrayBuffer* buffer) {
17 487616 : if (buffer->backing_store() == nullptr) return;
18 :
19 243808 : const size_t length = NumberToSize(buffer->byte_length());
20 243808 : Page* page = Page::FromAddress(buffer->address());
21 : {
22 489942 : base::LockGuard<base::RecursiveMutex> guard(page->mutex());
23 : LocalArrayBufferTracker* tracker = page->local_tracker();
24 243808 : if (tracker == nullptr) {
25 2326 : page->AllocateLocalTracker();
26 : tracker = page->local_tracker();
27 : }
28 : DCHECK_NOT_NULL(tracker);
29 : tracker->Add(buffer, length);
30 : }
31 : // We may go over the limit of externally allocated memory here. We call the
32 : // api function to trigger a GC in this case.
33 : reinterpret_cast<v8::Isolate*>(heap->isolate())
34 243808 : ->AdjustAmountOfExternalAllocatedMemory(length);
35 : }
36 :
37 2541 : void ArrayBufferTracker::Unregister(Heap* heap, JSArrayBuffer* buffer) {
38 5082 : if (buffer->backing_store() == nullptr) return;
39 :
40 2491 : Page* page = Page::FromAddress(buffer->address());
41 2491 : const size_t length = NumberToSize(buffer->byte_length());
42 : {
43 4982 : base::LockGuard<base::RecursiveMutex> guard(page->mutex());
44 : LocalArrayBufferTracker* tracker = page->local_tracker();
45 : DCHECK_NOT_NULL(tracker);
46 2491 : tracker->Remove(buffer, length);
47 : }
48 2491 : heap->update_external_memory(-static_cast<intptr_t>(length));
49 : }
50 :
51 : template <typename Callback>
52 155690 : void LocalArrayBufferTracker::Free(Callback should_free) {
53 : size_t new_retained_size = 0;
54 224605 : for (TrackingData::iterator it = array_buffers_.begin();
55 : it != array_buffers_.end();) {
56 68915 : JSArrayBuffer* buffer = reinterpret_cast<JSArrayBuffer*>(*it);
57 : const size_t length = buffer->allocation_length();
58 14867 : if (should_free(buffer)) {
59 56733 : buffer->FreeBackingStore();
60 : it = array_buffers_.erase(it);
61 : } else {
62 12182 : new_retained_size += length;
63 : ++it;
64 : }
65 : }
66 155690 : const size_t freed_memory = retained_size_ - new_retained_size;
67 155690 : if (freed_memory > 0) {
68 : heap_->update_external_memory_concurrently_freed(
69 5182 : static_cast<intptr_t>(freed_memory));
70 : }
71 155690 : retained_size_ = new_retained_size;
72 155690 : }
73 :
74 : template <typename MarkingState>
75 423741 : void ArrayBufferTracker::FreeDead(Page* page, MarkingState* marking_state) {
76 : // Callers need to ensure having the page lock.
77 423741 : LocalArrayBufferTracker* tracker = page->local_tracker();
78 847482 : if (tracker == nullptr) return;
79 22668 : tracker->Free([marking_state](JSArrayBuffer* buffer) {
80 : return marking_state->IsWhite(buffer);
81 14867 : });
82 7801 : if (tracker->IsEmpty()) {
83 1928 : page->ReleaseLocalTracker();
84 : }
85 : }
86 :
87 : void LocalArrayBufferTracker::Add(JSArrayBuffer* buffer, size_t length) {
88 : DCHECK_GE(retained_size_ + length, retained_size_);
89 266038 : retained_size_ += length;
90 : auto ret = array_buffers_.insert(buffer);
91 : USE(ret);
92 : // Check that we indeed inserted a new value and did not overwrite an existing
93 : // one (which would be a bug).
94 : DCHECK(ret.second);
95 : }
96 :
97 2491 : void LocalArrayBufferTracker::Remove(JSArrayBuffer* buffer, size_t length) {
98 : DCHECK_GE(retained_size_, retained_size_ - length);
99 2491 : retained_size_ -= length;
100 : TrackingData::iterator it = array_buffers_.find(buffer);
101 : // Check that we indeed find a key to remove.
102 : DCHECK(it != array_buffers_.end());
103 : array_buffers_.erase(it);
104 2491 : }
105 :
106 : } // namespace internal
107 : } // namespace v8
108 :
109 : #endif // V8_HEAP_ARRAY_BUFFER_TRACKER_INL_H_
|