v8  8.6.395 (node 15.0.1)
V8 is Google's open source JavaScript engine
write-barrier.h
Go to the documentation of this file.
1 // Copyright 2020 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 INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
6 #define INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
7 
8 #include "cppgc/internal/api-constants.h"
9 #include "cppgc/internal/process-heap.h"
10 #include "v8config.h" // NOLINT(build/include_directory)
11 
12 #if defined(CPPGC_CAGED_HEAP)
13 #include "cppgc/internal/caged-heap-local-data.h"
14 #endif
15 
16 namespace cppgc {
17 namespace internal {
18 
19 class V8_EXPORT WriteBarrier final {
20  public:
21  static V8_INLINE void MarkingBarrier(const void* slot, const void* value) {
22 #if defined(CPPGC_CAGED_HEAP)
23  const uintptr_t start =
24  reinterpret_cast<uintptr_t>(value) &
25  ~(api_constants::kCagedHeapReservationAlignment - 1);
26  const uintptr_t slot_offset = reinterpret_cast<uintptr_t>(slot) - start;
27  if (slot_offset > api_constants::kCagedHeapReservationSize) {
28  // Check if slot is on stack or value is sentinel or nullptr. This relies
29  // on the fact that kSentinelPointer is encoded as 0x1.
30  return;
31  }
32 
33  CagedHeapLocalData* local_data =
34  reinterpret_cast<CagedHeapLocalData*>(start);
35  if (V8_UNLIKELY(local_data->is_marking_in_progress)) {
36  MarkingBarrierSlow(value);
37  return;
38  }
39 #if defined(CPPGC_YOUNG_GENERATION)
40  GenerationalBarrier(local_data, slot, slot_offset,
41  reinterpret_cast<uintptr_t>(value) - start);
42 #endif
43 #else
44  if (V8_LIKELY(!ProcessHeap::IsAnyIncrementalOrConcurrentMarking())) return;
45 
46  MarkingBarrierSlowWithSentinelCheck(value);
47 #endif // CPPGC_CAGED_HEAP
48  }
49 
50  private:
51  WriteBarrier() = delete;
52 
53  static void MarkingBarrierSlow(const void* value);
54  static void MarkingBarrierSlowWithSentinelCheck(const void* value);
55 
56 #if defined(CPPGC_YOUNG_GENERATION)
57  static V8_INLINE void GenerationalBarrier(CagedHeapLocalData* local_data,
58  const void* slot,
59  uintptr_t slot_offset,
60  uintptr_t value_offset) {
61  const AgeTable& age_table = local_data->age_table;
62 
63  // Bail out if the slot is in young generation.
64  if (V8_LIKELY(age_table[slot_offset] == AgeTable::Age::kYoung)) return;
65 
66  GenerationalBarrierSlow(local_data, age_table, slot, value_offset);
67  }
68 
69  static void GenerationalBarrierSlow(CagedHeapLocalData* local_data,
70  const AgeTable& ageTable,
71  const void* slot, uintptr_t value_offset);
72 #endif
73 };
74 
75 } // namespace internal
76 } // namespace cppgc
77 
78 #endif // INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_