1// Copyright 2019 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/basic-memory-chunk.h"
6
7#include <cstdlib>
8
9#include "src/heap/heap-write-barrier-inl.h"
10#include "src/heap/incremental-marking.h"
11#include "src/objects/heap-object.h"
12#include "src/utils/allocation.h"
13
14namespace v8 {
15namespace internal {
16
17// Verify write barrier offsets match the the real offsets.
18STATIC_ASSERT(BasicMemoryChunk::Flag::IS_EXECUTABLE ==
19              heap_internals::MemoryChunk::kIsExecutableBit);
20STATIC_ASSERT(BasicMemoryChunk::Flag::INCREMENTAL_MARKING ==
21              heap_internals::MemoryChunk::kMarkingBit);
22STATIC_ASSERT(BasicMemoryChunk::Flag::FROM_PAGE ==
23              heap_internals::MemoryChunk::kFromPageBit);
24STATIC_ASSERT(BasicMemoryChunk::Flag::TO_PAGE ==
25              heap_internals::MemoryChunk::kToPageBit);
26STATIC_ASSERT(BasicMemoryChunk::Flag::READ_ONLY_HEAP ==
27              heap_internals::MemoryChunk::kReadOnlySpaceBit);
28STATIC_ASSERT(BasicMemoryChunk::kFlagsOffset ==
29              heap_internals::MemoryChunk::kFlagsOffset);
30STATIC_ASSERT(BasicMemoryChunk::kHeapOffset ==
31              heap_internals::MemoryChunk::kHeapOffset);
32
33// static
34constexpr BasicMemoryChunk::MainThreadFlags BasicMemoryChunk::kAllFlagsMask;
35// static
36constexpr BasicMemoryChunk::MainThreadFlags
37    BasicMemoryChunk::kPointersToHereAreInterestingMask;
38// static
39constexpr BasicMemoryChunk::MainThreadFlags
40    BasicMemoryChunk::kPointersFromHereAreInterestingMask;
41// static
42constexpr BasicMemoryChunk::MainThreadFlags
43    BasicMemoryChunk::kEvacuationCandidateMask;
44// static
45constexpr BasicMemoryChunk::MainThreadFlags
46    BasicMemoryChunk::kIsInYoungGenerationMask;
47// static
48constexpr BasicMemoryChunk::MainThreadFlags BasicMemoryChunk::kIsLargePageMask;
49// static
50constexpr BasicMemoryChunk::MainThreadFlags
51    BasicMemoryChunk::kSkipEvacuationSlotsRecordingMask;
52
53BasicMemoryChunk::BasicMemoryChunk(Heap* heap, BaseSpace* space,
54                                   size_t chunk_size, Address area_start,
55                                   Address area_end, VirtualMemory reservation)
56    : size_(chunk_size),
57      heap_(heap),
58      area_start_(area_start),
59      area_end_(area_end),
60      allocated_bytes_(area_end - area_start),
61      wasted_memory_(0),
62      high_water_mark_(area_start - reinterpret_cast<Address>(this)),
63      owner_(space),
64      reservation_(std::move(reservation)) {
65  marking_bitmap<AccessMode::NON_ATOMIC>()->Clear();
66}
67
68bool BasicMemoryChunk::InOldSpace() const {
69  return owner()->identity() == OLD_SPACE;
70}
71
72bool BasicMemoryChunk::InLargeObjectSpace() const {
73  return owner()->identity() == LO_SPACE;
74}
75
76#ifdef THREAD_SANITIZER
77void BasicMemoryChunk::SynchronizedHeapLoad() const {
78  CHECK(reinterpret_cast<Heap*>(
79            base::Acquire_Load(reinterpret_cast<base::AtomicWord*>(
80                &(const_cast<BasicMemoryChunk*>(this)->heap_)))) != nullptr ||
81        InReadOnlySpaceRaw());
82}
83#endif
84
85class BasicMemoryChunkValidator {
86  // Computed offsets should match the compiler generated ones.
87  STATIC_ASSERT(BasicMemoryChunk::kSizeOffset ==
88                offsetof(BasicMemoryChunk, size_));
89  STATIC_ASSERT(BasicMemoryChunk::kFlagsOffset ==
90                offsetof(BasicMemoryChunk, main_thread_flags_));
91  STATIC_ASSERT(BasicMemoryChunk::kHeapOffset ==
92                offsetof(BasicMemoryChunk, heap_));
93  STATIC_ASSERT(offsetof(BasicMemoryChunk, size_) ==
94                MemoryChunkLayout::kSizeOffset);
95  STATIC_ASSERT(offsetof(BasicMemoryChunk, heap_) ==
96                MemoryChunkLayout::kHeapOffset);
97  STATIC_ASSERT(offsetof(BasicMemoryChunk, area_start_) ==
98                MemoryChunkLayout::kAreaStartOffset);
99  STATIC_ASSERT(offsetof(BasicMemoryChunk, area_end_) ==
100                MemoryChunkLayout::kAreaEndOffset);
101  STATIC_ASSERT(offsetof(BasicMemoryChunk, allocated_bytes_) ==
102                MemoryChunkLayout::kAllocatedBytesOffset);
103  STATIC_ASSERT(offsetof(BasicMemoryChunk, wasted_memory_) ==
104                MemoryChunkLayout::kWastedMemoryOffset);
105  STATIC_ASSERT(offsetof(BasicMemoryChunk, high_water_mark_) ==
106                MemoryChunkLayout::kHighWaterMarkOffset);
107  STATIC_ASSERT(offsetof(BasicMemoryChunk, owner_) ==
108                MemoryChunkLayout::kOwnerOffset);
109  STATIC_ASSERT(offsetof(BasicMemoryChunk, reservation_) ==
110                MemoryChunkLayout::kReservationOffset);
111};
112
113}  // namespace internal
114}  // namespace v8
115