LCOV - code coverage report
Current view: top level - src/heap - concurrent-marking.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 8 63 12.7 %
Date: 2017-04-26 Functions: 3 18 16.7 %

          Line data    Source code
       1             : // Copyright 2017 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             : #include "src/heap/concurrent-marking.h"
       6             : 
       7             : #include <stack>
       8             : #include <unordered_map>
       9             : 
      10             : #include "src/heap/heap-inl.h"
      11             : #include "src/heap/heap.h"
      12             : #include "src/heap/marking.h"
      13             : #include "src/isolate.h"
      14             : #include "src/locked-queue-inl.h"
      15             : #include "src/utils-inl.h"
      16             : #include "src/utils.h"
      17             : #include "src/v8.h"
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : 
      22             : class ConcurrentMarkingMarkbits {
      23             :  public:
      24           0 :   ConcurrentMarkingMarkbits() {}
      25           0 :   ~ConcurrentMarkingMarkbits() {
      26           0 :     for (auto chunk_bitmap : bitmap_) {
      27             :       FreeBitmap(chunk_bitmap.second);
      28             :     }
      29           0 :   }
      30           0 :   bool Mark(HeapObject* obj) {
      31           0 :     Address address = obj->address();
      32           0 :     MemoryChunk* chunk = MemoryChunk::FromAddress(address);
      33           0 :     if (bitmap_.count(chunk) == 0) {
      34           0 :       bitmap_[chunk] = AllocateBitmap();
      35             :     }
      36             :     MarkBit mark_bit =
      37           0 :         bitmap_[chunk]->MarkBitFromIndex(chunk->AddressToMarkbitIndex(address));
      38           0 :     if (mark_bit.Get()) return false;
      39             :     mark_bit.Set();
      40           0 :     return true;
      41             :   }
      42             : 
      43             :   Bitmap* AllocateBitmap() {
      44           0 :     return static_cast<Bitmap*>(calloc(1, Bitmap::kSize));
      45             :   }
      46             : 
      47           0 :   void FreeBitmap(Bitmap* bitmap) { free(bitmap); }
      48             : 
      49             :  private:
      50             :   std::unordered_map<MemoryChunk*, Bitmap*> bitmap_;
      51             : };
      52             : 
      53           0 : class ConcurrentMarkingVisitor : public ObjectVisitor {
      54             :  public:
      55           0 :   ConcurrentMarkingVisitor() : bytes_marked_(0) {}
      56             : 
      57           0 :   void VisitPointers(HeapObject* host, Object** start, Object** end) override {
      58           0 :     for (Object** p = start; p < end; p++) {
      59           0 :       if (!(*p)->IsHeapObject()) continue;
      60           0 :       MarkObject(HeapObject::cast(*p));
      61             :     }
      62           0 :   }
      63             : 
      64           0 :   void MarkObject(HeapObject* obj) {
      65           0 :     if (markbits_.Mark(obj)) {
      66           0 :       bytes_marked_ += obj->Size();
      67             :       marking_stack_.push(obj);
      68             :     }
      69           0 :   }
      70             : 
      71           0 :   void MarkTransitively() {
      72           0 :     while (!marking_stack_.empty()) {
      73           0 :       HeapObject* obj = marking_stack_.top();
      74             :       marking_stack_.pop();
      75           0 :       obj->Iterate(this);
      76             :     }
      77           0 :   }
      78             : 
      79             :   size_t bytes_marked() { return bytes_marked_; }
      80             : 
      81             :  private:
      82             :   size_t bytes_marked_;
      83             :   std::stack<HeapObject*> marking_stack_;
      84             :   ConcurrentMarkingMarkbits markbits_;
      85             : };
      86             : 
      87             : class ConcurrentMarking::Task : public CancelableTask {
      88             :  public:
      89           0 :   Task(Heap* heap, std::vector<HeapObject*>* root_set,
      90             :        base::Semaphore* on_finish)
      91             :       : CancelableTask(heap->isolate()),
      92             :         heap_(heap),
      93             :         on_finish_(on_finish),
      94           0 :         root_set_(root_set) {}
      95             : 
      96           0 :   virtual ~Task() {}
      97             : 
      98             :  private:
      99             :   // v8::internal::CancelableTask overrides.
     100           0 :   void RunInternal() override {
     101           0 :     double time_ms = heap_->MonotonicallyIncreasingTimeInMs();
     102             :     {
     103             :       TimedScope scope(&time_ms);
     104           0 :       for (HeapObject* obj : *root_set_) {
     105           0 :         marking_visitor_.MarkObject(obj);
     106             :       }
     107           0 :       marking_visitor_.MarkTransitively();
     108             :     }
     109           0 :     if (FLAG_trace_concurrent_marking) {
     110             :       heap_->isolate()->PrintWithTimestamp(
     111             :           "concurrently marked %dKB in %.2fms\n",
     112           0 :           static_cast<int>(marking_visitor_.bytes_marked() / KB), time_ms);
     113             :     }
     114           0 :     on_finish_->Signal();
     115           0 :   }
     116             : 
     117             :   Heap* heap_;
     118             :   base::Semaphore* on_finish_;
     119             :   ConcurrentMarkingVisitor marking_visitor_;
     120             :   std::vector<HeapObject*>* root_set_;
     121             :   DISALLOW_COPY_AND_ASSIGN(Task);
     122             : };
     123             : 
     124       60782 : ConcurrentMarking::ConcurrentMarking(Heap* heap)
     125       60782 :     : heap_(heap), pending_task_semaphore_(0), is_task_pending_(false) {
     126             :   // Concurrent marking does not work with double unboxing.
     127             :   STATIC_ASSERT(!(V8_CONCURRENT_MARKING && V8_DOUBLE_FIELDS_UNBOXING));
     128             :   // The runtime flag should be set only if the compile time flag was set.
     129       60782 :   CHECK(!FLAG_concurrent_marking || V8_CONCURRENT_MARKING);
     130       60782 : }
     131             : 
     132      118570 : ConcurrentMarking::~ConcurrentMarking() {}
     133             : 
     134           0 : void ConcurrentMarking::AddRoot(HeapObject* object) {
     135           0 :   root_set_.push_back(object);
     136           0 : }
     137             : 
     138           0 : void ConcurrentMarking::StartTask() {
     139           0 :   if (!FLAG_concurrent_marking) return;
     140           0 :   is_task_pending_ = true;
     141             : 
     142           0 :   V8::GetCurrentPlatform()->CallOnBackgroundThread(
     143           0 :       new Task(heap_, &root_set_, &pending_task_semaphore_),
     144           0 :       v8::Platform::kShortRunningTask);
     145             : }
     146             : 
     147           0 : void ConcurrentMarking::WaitForTaskToComplete() {
     148           0 :   if (!FLAG_concurrent_marking) return;
     149           0 :   pending_task_semaphore_.Wait();
     150           0 :   is_task_pending_ = false;
     151             :   root_set_.clear();
     152             : }
     153             : 
     154       53346 : void ConcurrentMarking::EnsureTaskCompleted() {
     155       53346 :   if (IsTaskPending()) {
     156             :     WaitForTaskToComplete();
     157             :   }
     158       53346 : }
     159             : 
     160             : }  // namespace internal
     161             : }  // namespace v8

Generated by: LCOV version 1.10