LCOV - code coverage report
Current view: top level - src/heap - array-buffer-tracker-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 37 37 100.0 %
Date: 2019-04-17 Functions: 8 10 80.0 %

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

Generated by: LCOV version 1.10