LCOV - code coverage report
Current view: top level - src/heap - array-buffer-tracker-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 43 43 100.0 %
Date: 2019-01-20 Functions: 9 13 69.2 %

          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/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      453108 : void ArrayBufferTracker::RegisterNew(Heap* heap, JSArrayBuffer buffer) {
      19      906233 :   if (buffer->backing_store() == nullptr) return;
      20             : 
      21             :   const size_t length = buffer->byte_length();
      22      466619 :   Page* page = Page::FromHeapObject(buffer);
      23             :   {
      24      453110 :     base::MutexGuard guard(page->mutex());
      25             :     LocalArrayBufferTracker* tracker = page->local_tracker();
      26      453127 :     if (tracker == nullptr) {
      27       13492 :       page->AllocateLocalTracker();
      28             :       tracker = page->local_tracker();
      29             :     }
      30             :     DCHECK_NOT_NULL(tracker);
      31      453127 :     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      453127 :       ->AdjustAmountOfExternalAllocatedMemory(length);
      39             : }
      40             : 
      41        5595 : void ArrayBufferTracker::Unregister(Heap* heap, JSArrayBuffer buffer) {
      42       11190 :   if (buffer->backing_store() == nullptr) return;
      43             : 
      44        5571 :   Page* page = Page::FromHeapObject(buffer);
      45             :   const size_t length = buffer->byte_length();
      46             :   {
      47        5571 :     base::MutexGuard guard(page->mutex());
      48             :     LocalArrayBufferTracker* tracker = page->local_tracker();
      49             :     DCHECK_NOT_NULL(tracker);
      50        5571 :     tracker->Remove(buffer, length);
      51             :   }
      52             : 
      53             :   // TODO(wez): Remove backing-store from external memory accounting.
      54        5571 :   heap->update_external_memory(-static_cast<intptr_t>(length));
      55             : }
      56             : 
      57             : Space* LocalArrayBufferTracker::space() { return page_->owner(); }
      58             : 
      59             : template <typename Callback>
      60      169565 : void LocalArrayBufferTracker::Free(Callback should_free) {
      61             :   size_t freed_memory = 0;
      62      180579 :   Isolate* isolate = page_->heap()->isolate();
      63      722872 :   for (TrackingData::iterator it = array_buffers_.begin();
      64             :        it != array_buffers_.end();) {
      65             :     // Unchecked cast because the map might already be dead at this point.
      66      463825 :     JSArrayBuffer buffer = JSArrayBuffer::unchecked_cast(it->first);
      67      522967 :     const size_t length = it->second.length;
      68             : 
      69      463825 :     if (should_free(buffer)) {
      70      245037 :       JSArrayBuffer::FreeBackingStore(isolate, it->second);
      71             :       it = array_buffers_.erase(it);
      72      245041 :       freed_memory += length;
      73             :     } else {
      74             :       ++it;
      75             :     }
      76             :   }
      77      169568 :   if (freed_memory > 0) {
      78       11014 :     page_->DecrementExternalBackingStoreBytes(
      79       11014 :         ExternalBackingStoreType::kArrayBuffer, freed_memory);
      80             : 
      81             :     // TODO(wez): Remove backing-store from external memory accounting.
      82             :     page_->heap()->update_external_memory_concurrently_freed(
      83       11014 :         static_cast<intptr_t>(freed_memory));
      84             :   }
      85      169568 : }
      86             : 
      87             : template <typename MarkingState>
      88      527315 : void ArrayBufferTracker::FreeDead(Page* page, MarkingState* marking_state) {
      89             :   // Callers need to ensure having the page lock.
      90             :   LocalArrayBufferTracker* tracker = page->local_tracker();
      91     1054636 :   if (tracker == nullptr) return;
      92      494165 :   tracker->Free([marking_state](JSArrayBuffer buffer) {
      93             :     return marking_state->IsWhite(buffer);
      94      463823 :   });
      95       30340 :   if (tracker->IsEmpty()) {
      96        9740 :     page->ReleaseLocalTracker();
      97             :   }
      98             : }
      99             : 
     100      453126 : void LocalArrayBufferTracker::Add(JSArrayBuffer buffer, size_t length) {
     101             :   page_->IncrementExternalBackingStoreBytes(
     102      453126 :       ExternalBackingStoreType::kArrayBuffer, length);
     103             : 
     104      453126 :   AddInternal(buffer, length);
     105      453122 : }
     106             : 
     107      560123 : void LocalArrayBufferTracker::AddInternal(JSArrayBuffer buffer, size_t length) {
     108             :   auto ret = array_buffers_.insert(
     109             :       {buffer,
     110             :        {buffer->backing_store(), length, buffer->backing_store(),
     111      560112 :         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      560112 : }
     117             : 
     118        5571 : void LocalArrayBufferTracker::Remove(JSArrayBuffer buffer, size_t length) {
     119             :   page_->DecrementExternalBackingStoreBytes(
     120        5571 :       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        5571 : }
     128             : 
     129             : }  // namespace internal
     130             : }  // namespace v8
     131             : 
     132             : #endif  // V8_HEAP_ARRAY_BUFFER_TRACKER_INL_H_

Generated by: LCOV version 1.10