184 {
185 SetupImagePageBoundaries();
186
187 Page* fixed_head = nullptr;
188 Page* fixed_tail = nullptr;
189
190
191
192 intptr_t num_pages = 0;
194 Page*
prev =
nullptr;
195 while (
page !=
nullptr) {
197 if (
page->is_never_evacuate()) {
198 if (
prev !=
nullptr) {
200 } else {
202 }
203 if (fixed_tail == nullptr) {
205 }
206 page->set_next(fixed_head);
208 } else {
210 num_pages++;
211 }
213 }
214 fixed_pages_ = fixed_head;
215
216 intptr_t num_tasks = FLAG_compactor_tasks;
218 if (num_pages < num_tasks) {
219 num_tasks = num_pages;
220 }
221 if (num_tasks == 0) {
223
224
226 heap_->
old_space()->pages_tail_ =
nullptr;
227 heap_->
old_space()->sweep_regular_ = fixed_head;
228
231 return;
232 }
233
234 Partition* partitions = new Partition[num_tasks];
235
236 {
237 const intptr_t pages_per_task = num_pages / num_tasks;
238 intptr_t task_index = 0;
239 intptr_t page_index = 0;
241 Page*
prev =
nullptr;
242 while (task_index < num_tasks) {
244 if (page_index % pages_per_task == 0) {
245 partitions[task_index].head =
page;
246 partitions[task_index].tail = nullptr;
247 if (
prev !=
nullptr) {
248 prev->set_next(
nullptr);
249 }
250 task_index++;
251 }
254 page_index++;
255 }
256 ASSERT(page_index <= num_pages);
257 ASSERT(task_index == num_tasks);
258 }
259
260 if (FLAG_force_evacuation) {
261
262
263
264
265 bool oom = false;
266 for (intptr_t task_index = 0; task_index < num_tasks && !oom;
267 task_index++) {
268 const intptr_t pages_per_task = num_pages / num_tasks;
269 for (intptr_t j = 0; j < pages_per_task; j++) {
271 false);
272
273 if (
page ==
nullptr) {
274 oom = true;
275 break;
276 }
277
279 page->object_end() -
page->object_start());
280
281
282 page->set_next(partitions[task_index].
head);
283 partitions[task_index].head =
page;
284 }
285 }
286 }
287
288 {
289 ThreadBarrier* barrier = new ThreadBarrier(num_tasks, 1);
290 RelaxedAtomic<intptr_t> next_planning_task = {0};
291 RelaxedAtomic<intptr_t> next_setup_task = {0};
292 RelaxedAtomic<intptr_t> next_sliding_task = {0};
293 RelaxedAtomic<intptr_t> next_forwarding_task = {0};
294
295 for (intptr_t task_index = 0; task_index < num_tasks; task_index++) {
296 if (task_index < (num_tasks - 1)) {
297
300 &next_setup_task, &next_sliding_task, &next_forwarding_task,
301 num_tasks, partitions, freelist);
302 } else {
303
305 &next_planning_task, &next_setup_task,
306 &next_sliding_task, &next_forwarding_task, num_tasks,
307 partitions, freelist);
308 task.RunEnteredIsolateGroup();
309 barrier->Sync();
310 barrier->Release();
311 }
312 }
313 }
314
315
316
317
318
319
320
321
322
323
324 {
326 "ForwardTypedDataViewInternalPointers");
329 auto raw_view = typed_data_views_[
i];
331 raw_view->untag()->typed_data()->GetClassIdMayBeSmi();
332
333
334
335
337 raw_view->untag()->RecomputeDataFieldForInternalTypedData();
338 } else {
340 }
341 }
342 }
343
344 for (intptr_t task_index = 0; task_index < num_tasks; task_index++) {
345 ASSERT(partitions[task_index].
tail !=
nullptr);
346 }
347
348 {
350 ForwardStackPointers();
351 }
352
353 {
355 "ForwardPostponedSuspendStatePointers");
356
357
358 can_visit_stack_frames_ = true;
359 const intptr_t
length = postponed_suspend_states_.
length();
361 auto suspend_state = postponed_suspend_states_[
i];
362 suspend_state->untag()->VisitPointers(this);
363 }
364 }
365
367
368 {
369 MutexLocker ml(pages_lock);
370
371
372 for (intptr_t task_index = 0; task_index < num_tasks; task_index++) {
373 Page*
page = partitions[task_index].tail->next();
374 while (
page !=
nullptr) {
380 }
381 }
382
383
384 for (intptr_t task_index = 0; task_index < num_tasks - 1; task_index++) {
385 partitions[task_index].tail->set_next(partitions[task_index + 1].
head);
386 }
387 partitions[num_tasks - 1].tail->set_next(nullptr);
388 heap_->
old_space()->pages_ = pages = partitions[0].head;
389 heap_->
old_space()->pages_tail_ = partitions[num_tasks - 1].tail;
390 if (fixed_head != nullptr) {
393
395 }
396
397 delete[] partitions;
398 }
399}
static float next(float f)
static float prev(float f)
#define RELEASE_ASSERT(cond)
static ThreadPool * thread_pool()
static FreeListElement * AsElement(uword addr, intptr_t size)
friend class CompactorTask
IsolateGroup * isolate_group() const
void IncreaseCapacityInWordsLocked(intptr_t increase_in_words)
void VisitRoots(ObjectPointerVisitor *visitor)
void set_next(Page *next)
bool Run(Args &&... args)
bool IsTypedDataClassId(intptr_t index)
constexpr intptr_t kWordSizeLog2
bool IsExternalTypedDataClassId(intptr_t index)
#define TIMELINE_FUNCTION_GC_DURATION(thread, name)