Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | List of all members
dart::GCSweeper Class Reference

#include <sweeper.h>

Public Member Functions

 GCSweeper ()
 
 ~GCSweeper ()
 
bool SweepPage (Page *page, FreeList *freelist)
 
intptr_t SweepLargePage (Page *page)
 
intptr_t SweepNewPage (Page *page)
 

Static Public Member Functions

static void SweepConcurrent (IsolateGroup *isolate_group)
 

Detailed Description

Definition at line 21 of file sweeper.h.

Constructor & Destructor Documentation

◆ GCSweeper()

dart::GCSweeper::GCSweeper ( )
inline

Definition at line 23 of file sweeper.h.

23{}

◆ ~GCSweeper()

dart::GCSweeper::~GCSweeper ( )
inline

Definition at line 24 of file sweeper.h.

24{}

Member Function Documentation

◆ SweepConcurrent()

void dart::GCSweeper::SweepConcurrent ( IsolateGroup isolate_group)
static

Definition at line 213 of file sweeper.cc.

213 {
214 bool result = Dart::thread_pool()->Run<ConcurrentSweeperTask>(isolate_group);
215 ASSERT(result);
216}
static ThreadPool * thread_pool()
Definition dart.h:73
bool Run(Args &&... args)
Definition thread_pool.h:45
#define ASSERT(E)
GAsyncResult * result

◆ SweepLargePage()

intptr_t dart::GCSweeper::SweepLargePage ( Page page)

Definition at line 137 of file sweeper.cc.

137 {
138 ASSERT(!page->is_image());
139 ASSERT(page->is_large() && !page->is_executable());
140
141 intptr_t words_to_end = 0;
142 ObjectPtr raw_obj = UntaggedObject::FromAddr(page->object_start());
143 ASSERT(Page::Of(raw_obj) == page);
144 if (raw_obj->untag()->IsMarked()) {
145 raw_obj->untag()->ClearMarkBit();
146 words_to_end = (raw_obj->untag()->HeapSize() >> kWordSizeLog2);
147 }
148#ifdef DEBUG
149 // Array::MakeFixedLength creates trailing filler objects,
150 // but they are always unreachable. Verify that they are not marked.
151 uword current =
152 UntaggedObject::ToAddr(raw_obj) + raw_obj->untag()->HeapSize();
153 uword end = page->object_end();
154 while (current < end) {
155 ObjectPtr cur_obj = UntaggedObject::FromAddr(current);
156 ASSERT(!cur_obj->untag()->IsMarked());
157 intptr_t obj_size = cur_obj->untag()->HeapSize();
158 memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size);
159 current += obj_size;
160 }
161#endif // DEBUG
162 return words_to_end;
163}
static constexpr uint8_t kZapByte
Definition heap.h:58
static Page * Of(ObjectPtr obj)
Definition page.h:141
static ObjectPtr FromAddr(uword addr)
Definition raw_object.h:495
static uword ToAddr(const UntaggedObject *raw_obj)
Definition raw_object.h:501
glong glong end
constexpr intptr_t kWordSizeLog2
Definition globals.h:507
uintptr_t uword
Definition globals.h:501

◆ SweepNewPage()

intptr_t dart::GCSweeper::SweepNewPage ( Page page)

Definition at line 18 of file sweeper.cc.

18 {
19 ASSERT(!page->is_image());
20 ASSERT(!page->is_old());
21 ASSERT(!page->is_executable());
22
23 uword start = page->object_start();
24 uword end = page->object_end();
25 uword current = start;
26 intptr_t free = 0;
27 while (current < end) {
28 ObjectPtr raw_obj = UntaggedObject::FromAddr(current);
29 ASSERT(Page::Of(raw_obj) == page);
30 uword tags = raw_obj->untag()->tags_.load(std::memory_order_relaxed);
31 intptr_t obj_size = raw_obj->untag()->HeapSize(tags);
32 if (UntaggedObject::IsMarked(tags)) {
33 // Found marked object. Clear the mark bit and update swept bytes.
34 raw_obj->untag()->ClearMarkBitUnsynchronized();
36 } else {
37 uword free_end = current + obj_size;
38 while (free_end < end) {
39 ObjectPtr next_obj = UntaggedObject::FromAddr(free_end);
40 tags = next_obj->untag()->tags_.load(std::memory_order_relaxed);
41 if (UntaggedObject::IsMarked(tags)) {
42 // Reached the end of the free block.
43 break;
44 }
45 // Expand the free block by the size of this object.
46 free_end += next_obj->untag()->HeapSize(tags);
47 }
48 obj_size = free_end - current;
49#if defined(DEBUG)
50 memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size);
51#endif // DEBUG
52 FreeListElement::AsElementNew(current, obj_size);
53 free += obj_size;
54 }
55 current += obj_size;
56 }
57 return free;
58}
static FreeListElement * AsElementNew(uword addr, intptr_t size)
Definition freelist.cc:43
bool IsMarked() const
Definition raw_object.h:299
bool IsAllocatableInNewSpace(intptr_t size)
Definition spaces.h:57

◆ SweepPage()

bool dart::GCSweeper::SweepPage ( Page page,
FreeList freelist 
)

Definition at line 60 of file sweeper.cc.

60 {
61 ASSERT(!page->is_image());
62 // Large executable pages are handled here. We never truncate Instructions
63 // objects, so we never truncate executable pages.
64 ASSERT(!page->is_large() || page->is_executable());
65 DEBUG_ASSERT(freelist->mutex()->IsOwnedByCurrentThread());
66
67 // Keep track whether this page is still in use.
68 intptr_t used_in_bytes = 0;
69
70 bool is_executable = page->is_executable();
71 uword start = page->object_start();
72 uword end = page->object_end();
73 uword current = start;
74 const bool dontneed_on_sweep = FLAG_dontneed_on_sweep;
75 const uword page_size = VirtualMemory::PageSize();
76
77 while (current < end) {
78 ObjectPtr raw_obj = UntaggedObject::FromAddr(current);
79 ASSERT(Page::Of(raw_obj) == page);
80 // These acquire operations balance release operations in array
81 // truncation, ensuring the writes creating the filler object are ordered
82 // before the writes inserting the filler object into the freelist.
83 uword tags = raw_obj->untag()->tags_.load(std::memory_order_acquire);
84 intptr_t obj_size = raw_obj->untag()->HeapSize(tags);
85 if (UntaggedObject::IsMarked(tags)) {
86 // Found marked object. Clear the mark bit and update swept bytes.
87 raw_obj->untag()->ClearMarkBit();
88 used_in_bytes += obj_size;
89 // Large objects should never appear on regular pages.
90 ASSERT(IsAllocatableViaFreeLists(obj_size) || page->is_large());
91 } else {
92 uword free_end = current + obj_size;
93 while (free_end < end) {
94 ObjectPtr next_obj = UntaggedObject::FromAddr(free_end);
95 tags = next_obj->untag()->tags_.load(std::memory_order_acquire);
96 if (UntaggedObject::IsMarked(tags)) {
97 // Reached the end of the free block.
98 break;
99 }
100 // Expand the free block by the size of this object.
101 free_end += next_obj->untag()->HeapSize(tags);
102 }
103 // Only add to the free list if not covering the whole page.
104 if ((current == start) && (free_end == end)) {
105 return false; // Not in use.
106 }
107 obj_size = free_end - current;
108 if (is_executable) {
109 uword cursor = current;
110 uword end = current + obj_size;
111 while (cursor < end) {
112 *reinterpret_cast<uword*>(cursor) = kBreakInstructionFiller;
113 cursor += kWordSize;
114 }
115 } else if (UNLIKELY(dontneed_on_sweep)) {
116 uword page_aligned_start = Utils::RoundUp(
117 current + FreeListElement::kLargeHeaderSize, page_size);
118 uword page_aligned_end = Utils::RoundDown(free_end, page_size);
119 if (UNLIKELY(page_aligned_start < page_aligned_end)) {
120 VirtualMemory::DontNeed(reinterpret_cast<void*>(page_aligned_start),
121 page_aligned_end - page_aligned_start);
122 }
123 } else {
124#if defined(DEBUG)
125 memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size);
126#endif // DEBUG
127 }
128 freelist->FreeLocked(current, obj_size);
129 }
130 current += obj_size;
131 }
132 ASSERT(current == end);
133 ASSERT(used_in_bytes != 0);
134 return true; // In use.
135}
#define DEBUG_ASSERT(cond)
Definition assert.h:321
static constexpr intptr_t kLargeHeaderSize
Definition freelist.h:44
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:105
static constexpr T RoundDown(T x, intptr_t alignment)
Definition utils.h:93
static intptr_t PageSize()
static void DontNeed(void *address, intptr_t size)
constexpr uword kBreakInstructionFiller
constexpr intptr_t kWordSize
Definition globals.h:509
bool IsAllocatableViaFreeLists(intptr_t size)
Definition spaces.h:60
#define UNLIKELY(cond)
Definition globals.h:261

The documentation for this class was generated from the following files: