11#ifdef V8_COMPRESS_POINTERS
17uint32_t CppHeapPointerTable::SweepAndCompact(Space* space,
19 DCHECK(space->BelongsTo(
this));
26 base::MutexGuard invalidated_fields_guard(&space->invalidated_fields_mutex_);
31 space->freelist_head_.store(kEntryAllocationIsForbiddenMarker,
32 std::memory_order_relaxed);
36 uint32_t start_of_evacuation_area =
37 space->start_of_evacuation_area_.load(std::memory_order_relaxed);
38 bool evacuation_was_successful =
false;
39 if (space->IsCompacting()) {
40 if (space->CompactingWasAborted()) {
43 start_of_evacuation_area &= ~Space::kCompactionAbortedMarker;
45 evacuation_was_successful =
true;
49 space->StopCompacting();
60 uint32_t current_freelist_head = 0;
61 uint32_t current_freelist_length = 0;
62 auto AddToFreelist = [&](uint32_t entry_index) {
63 at(entry_index).MakeFreelistEntry(current_freelist_head);
64 current_freelist_head = entry_index;
65 current_freelist_length++;
68 std::vector<Segment> segments_to_deallocate;
70 bool segment_will_be_evacuated =
71 evacuation_was_successful &&
72 segment.first_entry() >= start_of_evacuation_area;
75 uint32_t previous_freelist_head = current_freelist_head;
76 uint32_t previous_freelist_length = current_freelist_length;
79 for (uint32_t
i = segment.last_entry();
i >= segment.first_entry();
i--) {
80 auto payload = at(
i).GetRawPayload();
81 if (payload.ContainsEvacuationEntry()) {
84 DCHECK(!segment_will_be_evacuated);
89 payload.ExtractEvacuationEntryHandleLocation();
92 DCHECK(!space->FieldWasInvalidated(handle_location));
104 ResolveEvacuationEntryDuringSweeping(
106 start_of_evacuation_area);
112 DCHECK(at(
i).GetRawPayload().ContainsPointer());
113 DCHECK(!at(
i).GetRawPayload().HasMarkBitSet());
114 }
else if (!payload.HasMarkBitSet()) {
117 auto new_payload = payload;
118 new_payload.ClearMarkBit();
119 at(
i).SetRawPayload(new_payload);
124 DCHECK(!at(
i).HasEvacuationEntry());
131 uint32_t free_entries = current_freelist_length - previous_freelist_length;
132 bool segment_is_empty = free_entries == kEntriesPerSegment;
133 if (segment_is_empty || segment_will_be_evacuated) {
134 segments_to_deallocate.push_back(segment);
136 current_freelist_head = previous_freelist_head;
137 current_freelist_length = previous_freelist_length;
142 for (
auto segment : segments_to_deallocate) {
143 FreeTableSegment(segment);
144 space->segments_.erase(segment);
147 FreelistHead new_freelist(current_freelist_head, current_freelist_length);
148 space->freelist_head_.store(new_freelist, std::memory_order_release);
149 DCHECK_EQ(space->freelist_length(), current_freelist_length);
151 uint32_t num_live_entries = space->capacity() - current_freelist_length;
152 counters->cppheap_pointers_count()->AddSample(num_live_entries);
153 return num_live_entries;
156void CppHeapPointerTable::ResolveEvacuationEntryDuringSweeping(
158 uint32_t start_of_evacuation_area) {
160 CHECK(IsValidHandle(old_handle));
162 uint32_t old_index = HandleToIndex(old_handle);
167 DCHECK_GE(old_index, start_of_evacuation_area);
168 DCHECK_LT(new_index, start_of_evacuation_area);
169 auto& new_entry = at(new_index);
170 at(old_index).Evacuate(new_entry);
171 *handle_location = new_handle;
LockGuard< Mutex > MutexGuard
uint32_t CppHeapPointerHandle
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
constexpr bool IsAligned(T value, U alignment)