cpp-heap.cc 5.85 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/heap/cppgc-js/cpp-heap.h"

#include "include/cppgc/platform.h"
#include "include/v8-platform.h"
#include "include/v8.h"
#include "src/base/macros.h"
#include "src/base/platform/time.h"
12
#include "src/execution/isolate.h"
13
#include "src/flags/flags.h"
14 15 16
#include "src/heap/base/stack.h"
#include "src/heap/cppgc-js/unified-heap-marking-state.h"
#include "src/heap/cppgc-js/unified-heap-marking-visitor.h"
17 18
#include "src/heap/cppgc/gc-info-table.h"
#include "src/heap/cppgc/heap-base.h"
19
#include "src/heap/cppgc/heap-object-header.h"
20
#include "src/heap/cppgc/marker.h"
21
#include "src/heap/cppgc/marking-state.h"
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#include "src/heap/cppgc/marking-visitor.h"
#include "src/heap/cppgc/object-allocator.h"
#include "src/heap/cppgc/prefinalizer-handler.h"
#include "src/heap/cppgc/stats-collector.h"
#include "src/heap/cppgc/sweeper.h"
#include "src/heap/marking-worklist.h"
#include "src/heap/sweeper.h"
#include "src/init/v8.h"

namespace v8 {
namespace internal {

namespace {

class CppgcPlatformAdapter final : public cppgc::Platform {
 public:
  explicit CppgcPlatformAdapter(v8::Isolate* isolate)
      : platform_(V8::GetCurrentPlatform()), isolate_(isolate) {}

  CppgcPlatformAdapter(const CppgcPlatformAdapter&) = delete;
  CppgcPlatformAdapter& operator=(const CppgcPlatformAdapter&) = delete;

  PageAllocator* GetPageAllocator() final {
    return platform_->GetPageAllocator();
  }

  double MonotonicallyIncreasingTime() final {
    return platform_->MonotonicallyIncreasingTime();
  }

  std::shared_ptr<TaskRunner> GetForegroundTaskRunner() final {
    return platform_->GetForegroundTaskRunner(isolate_);
  }

  std::unique_ptr<JobHandle> PostJob(TaskPriority priority,
                                     std::unique_ptr<JobTask> job_task) final {
    return platform_->PostJob(priority, std::move(job_task));
  }

 private:
  v8::Platform* platform_;
  v8::Isolate* isolate_;
};

66
class UnifiedHeapMarker final : public cppgc::internal::MarkerBase {
67
 public:
68
  UnifiedHeapMarker(Key, Heap& v8_heap, cppgc::internal::HeapBase& cpp_heap,
69
                    cppgc::Platform* platform, MarkingConfig config);
70 71

  ~UnifiedHeapMarker() final = default;
72 73 74

  void AddObject(void*);

75 76 77 78 79
 protected:
  cppgc::Visitor& visitor() final { return marking_visitor_; }
  cppgc::internal::ConservativeTracingVisitor& conservative_visitor() final {
    return conservative_marking_visitor_;
  }
80
  ::heap::base::StackVisitor& stack_visitor() final {
81 82 83 84
    return conservative_marking_visitor_;
  }

 private:
85 86
  UnifiedHeapMarkingState unified_heap_mutator_marking_state_;
  UnifiedHeapMarkingVisitor marking_visitor_;
87
  cppgc::internal::ConservativeMarkingVisitor conservative_marking_visitor_;
88 89
};

90
UnifiedHeapMarker::UnifiedHeapMarker(Key key, Heap& v8_heap,
91 92 93
                                     cppgc::internal::HeapBase& heap,
                                     cppgc::Platform* platform,
                                     MarkingConfig config)
94
    : cppgc::internal::MarkerBase(key, heap, platform, config),
95 96 97
      unified_heap_mutator_marking_state_(v8_heap),
      marking_visitor_(heap, mutator_marking_state_,
                       unified_heap_mutator_marking_state_),
98 99
      conservative_marking_visitor_(heap, mutator_marking_state_,
                                    marking_visitor_) {}
100 101

void UnifiedHeapMarker::AddObject(void* object) {
102
  mutator_marking_state_.MarkAndPush(
103
      cppgc::internal::HeapObjectHeader::FromPayload(object));
104 105 106 107 108 109
}

}  // namespace

CppHeap::CppHeap(v8::Isolate* isolate, size_t custom_spaces)
    : cppgc::internal::HeapBase(std::make_shared<CppgcPlatformAdapter>(isolate),
110 111
                                custom_spaces),
      isolate_(*reinterpret_cast<Isolate*>(isolate)) {
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
  CHECK(!FLAG_incremental_marking_wrappers);
}

void CppHeap::RegisterV8References(
    const std::vector<std::pair<void*, void*> >& embedder_fields) {
  DCHECK(marker_);
  for (auto& tuple : embedder_fields) {
    // First field points to type.
    // Second field points to object.
    static_cast<UnifiedHeapMarker*>(marker_.get())->AddObject(tuple.second);
  }
  marking_done_ = false;
}

void CppHeap::TracePrologue(TraceFlags flags) {
  const UnifiedHeapMarker::MarkingConfig marking_config{
      UnifiedHeapMarker::MarkingConfig::CollectionType::kMajor,
      cppgc::Heap::StackState::kNoHeapPointers,
130
      UnifiedHeapMarker::MarkingConfig::MarkingType::kIncremental};
131 132 133
  marker_ =
      cppgc::internal::MarkerFactory::CreateAndStartMarking<UnifiedHeapMarker>(
          *isolate_.heap(), AsBase(), platform_.get(), marking_config);
134 135 136 137
  marking_done_ = false;
}

bool CppHeap::AdvanceTracing(double deadline_in_ms) {
138 139
  // TODO(chromium:1056170): Replace std::numeric_limits<size_t>::max() with a
  // proper deadline when unified heap transitions to bytes-based deadline.
140
  marking_done_ = marker_->AdvanceMarkingWithMaxDuration(
141 142 143 144 145 146 147
      v8::base::TimeDelta::FromMillisecondsD(deadline_in_ms));
  return marking_done_;
}

bool CppHeap::IsTracingDone() { return marking_done_; }

void CppHeap::EnterFinalPause(EmbedderStackState stack_state) {
148
  marker_->EnterAtomicPause(cppgc::Heap::StackState::kNoHeapPointers);
149 150 151 152 153 154 155 156 157 158 159 160
}

void CppHeap::TraceEpilogue(TraceSummary* trace_summary) {
  CHECK(marking_done_);
  marker_->LeaveAtomicPause();
  {
    // Pre finalizers are forbidden from allocating objects
    cppgc::internal::ObjectAllocator::NoAllocationScope no_allocation_scope_(
        object_allocator_);
    marker()->ProcessWeakness();
    prefinalizer_handler()->InvokePreFinalizers();
  }
161 162 163 164 165
  marker_.reset();
  // TODO(chromium:1056170): replace build flag with dedicated flag.
#if DEBUG
  VerifyMarking(cppgc::Heap::StackState::kNoHeapPointers);
#endif
166 167 168 169 170 171 172 173
  {
    NoGCScope no_gc(*this);
    sweeper().Start(cppgc::internal::Sweeper::Config::kAtomic);
  }
}

}  // namespace internal
}  // namespace v8