V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
array-buffer-tracker-inl.h
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/heap/spaces.h"
12 #include "src/objects.h"
13 #include "src/objects/js-array-buffer-inl.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 void ArrayBufferTracker::RegisterNew(Heap* heap, JSArrayBuffer* buffer) {
19  if (buffer->backing_store() == nullptr) return;
20 
21  const size_t length = buffer->byte_length();
22  Page* page = Page::FromAddress(buffer->address());
23  {
24  base::MutexGuard guard(page->mutex());
25  LocalArrayBufferTracker* tracker = page->local_tracker();
26  if (tracker == nullptr) {
27  page->AllocateLocalTracker();
28  tracker = page->local_tracker();
29  }
30  DCHECK_NOT_NULL(tracker);
31  tracker->Add(buffer, length);
32  }
33 
34  // TODO(wez): Remove backing-store from external memory accounting.
35  // We may go over the limit of externally allocated memory here. We call the
36  // api function to trigger a GC in this case.
37  reinterpret_cast<v8::Isolate*>(heap->isolate())
38  ->AdjustAmountOfExternalAllocatedMemory(length);
39 }
40 
41 void ArrayBufferTracker::Unregister(Heap* heap, JSArrayBuffer* buffer) {
42  if (buffer->backing_store() == nullptr) return;
43 
44  Page* page = Page::FromAddress(buffer->address());
45  const size_t length = buffer->byte_length();
46  {
47  base::MutexGuard guard(page->mutex());
48  LocalArrayBufferTracker* tracker = page->local_tracker();
49  DCHECK_NOT_NULL(tracker);
50  tracker->Remove(buffer, length);
51  }
52 
53  // TODO(wez): Remove backing-store from external memory accounting.
54  heap->update_external_memory(-static_cast<intptr_t>(length));
55 }
56 
57 Space* LocalArrayBufferTracker::space() { return page_->owner(); }
58 
59 template <typename Callback>
60 void LocalArrayBufferTracker::Free(Callback should_free) {
61  size_t freed_memory = 0;
62  Isolate* isolate = page_->heap()->isolate();
63  for (TrackingData::iterator it = array_buffers_.begin();
64  it != array_buffers_.end();) {
65  JSArrayBuffer* buffer = reinterpret_cast<JSArrayBuffer*>(it->first);
66  const size_t length = it->second.length;
67 
68  if (should_free(buffer)) {
69  JSArrayBuffer::FreeBackingStore(isolate, it->second);
70  it = array_buffers_.erase(it);
71  freed_memory += length;
72  } else {
73  ++it;
74  }
75  }
76  if (freed_memory > 0) {
77  page_->DecrementExternalBackingStoreBytes(
78  ExternalBackingStoreType::kArrayBuffer, freed_memory);
79 
80  // TODO(wez): Remove backing-store from external memory accounting.
81  page_->heap()->update_external_memory_concurrently_freed(
82  static_cast<intptr_t>(freed_memory));
83  }
84 }
85 
86 template <typename MarkingState>
87 void ArrayBufferTracker::FreeDead(Page* page, MarkingState* marking_state) {
88  // Callers need to ensure having the page lock.
89  LocalArrayBufferTracker* tracker = page->local_tracker();
90  if (tracker == nullptr) return;
91  tracker->Free([marking_state](JSArrayBuffer* buffer) {
92  return marking_state->IsWhite(buffer);
93  });
94  if (tracker->IsEmpty()) {
95  page->ReleaseLocalTracker();
96  }
97 }
98 
99 void LocalArrayBufferTracker::Add(JSArrayBuffer* buffer, size_t length) {
100  page_->IncrementExternalBackingStoreBytes(
101  ExternalBackingStoreType::kArrayBuffer, length);
102 
103  AddInternal(buffer, length);
104 }
105 
106 void LocalArrayBufferTracker::AddInternal(JSArrayBuffer* buffer,
107  size_t length) {
108  auto ret = array_buffers_.insert(
109  {buffer,
110  {buffer->backing_store(), length, buffer->backing_store(),
111  buffer->is_wasm_memory()}});
112  USE(ret);
113  // Check that we indeed inserted a new value and did not overwrite an existing
114  // one (which would be a bug).
115  DCHECK(ret.second);
116 }
117 
118 void LocalArrayBufferTracker::Remove(JSArrayBuffer* buffer, size_t length) {
119  page_->DecrementExternalBackingStoreBytes(
120  ExternalBackingStoreType::kArrayBuffer, length);
121 
122  TrackingData::iterator it = array_buffers_.find(buffer);
123  // Check that we indeed find a key to remove.
124  DCHECK(it != array_buffers_.end());
125  DCHECK_EQ(length, it->second.length);
126  array_buffers_.erase(it);
127 }
128 
129 } // namespace internal
130 } // namespace v8
131 
132 #endif // V8_HEAP_ARRAY_BUFFER_TRACKER_INL_H_
Definition: libplatform.h:13