deps: V8: cherry-pick 6 commits · nodejs/node@b1015e0 (original) (raw)
`@@ -151,11 +151,25 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor {
`
151
151
`const bool record_slots_;
`
152
152
`};
`
153
153
``
154
``
`-
static bool IsUnscavengedHeapObject(Heap* heap, FullObjectSlot p) {
`
155
``
`-
return Heap::InFromPage(*p) &&
`
156
``
`-
!HeapObject::cast(*p)->map_word().IsForwardingAddress();
`
``
154
`+
namespace {
`
``
155
+
``
156
`+
V8_INLINE bool IsUnscavengedHeapObject(Heap* heap, Object object) {
`
``
157
`+
return Heap::InFromPage(object) &&
`
``
158
`+
!HeapObject::cast(object)->map_word().IsForwardingAddress();
`
``
159
`+
}
`
``
160
+
``
161
`+
// Same as IsUnscavengedHeapObject() above but specialized for HeapObjects.
`
``
162
`+
V8_INLINE bool IsUnscavengedHeapObject(Heap* heap, HeapObject heap_object) {
`
``
163
`+
return Heap::InFromPage(heap_object) &&
`
``
164
`+
!heap_object->map_word().IsForwardingAddress();
`
``
165
`+
}
`
``
166
+
``
167
`+
bool IsUnscavengedHeapObjectSlot(Heap* heap, FullObjectSlot p) {
`
``
168
`+
return IsUnscavengedHeapObject(heap, *p);
`
157
169
`}
`
158
170
``
``
171
`+
} // namespace
`
``
172
+
159
173
`class ScavengeWeakObjectRetainer : public WeakObjectRetainer {
`
160
174
`public:
`
161
175
` Object RetainAs(Object object) override {
`
`@@ -185,9 +199,10 @@ void ScavengerCollector::CollectGarbage() {
`
185
199
` OneshotBarrier barrier(base::TimeDelta::FromMilliseconds(kMaxWaitTimeMs));
`
186
200
` Scavenger::CopiedList copied_list(num_scavenge_tasks);
`
187
201
` Scavenger::PromotionList promotion_list(num_scavenge_tasks);
`
``
202
`+
EphemeronTableList ephemeron_table_list(num_scavenge_tasks);
`
188
203
`for (int i = 0; i < num_scavenge_tasks; i++) {
`
189
204
` scavengers[i] = new Scavenger(this, heap_, is_logging, &copied_list,
`
190
``
`-
&promotion_list, i);
`
``
205
`+
&promotion_list, &ephemeron_table_list, i);
`
191
206
` job.AddTask(new ScavengingTask(heap_, scavengers[i], &barrier));
`
192
207
` }
`
193
208
``
`@@ -235,7 +250,7 @@ void ScavengerCollector::CollectGarbage() {
`
235
250
`TRACE_GC(heap_->tracer(),
`
236
251
` GCTracer::Scope::SCAVENGER_SCAVENGE_WEAK_GLOBAL_HANDLES_PROCESS);
`
237
252
` isolate_->global_handles()->MarkYoungWeakUnmodifiedObjectsPending(
`
238
``
`-
&IsUnscavengedHeapObject);
`
``
253
`+
&IsUnscavengedHeapObjectSlot);
`
239
254
` isolate_->global_handles()->IterateYoungWeakUnmodifiedRootsForFinalizers(
`
240
255
` &root_scavenge_visitor);
`
241
256
` scavengers[kMainThreadId]->Process();
`
`@@ -244,7 +259,7 @@ void ScavengerCollector::CollectGarbage() {
`
244
259
`DCHECK(promotion_list.IsEmpty());
`
245
260
` isolate_->global_handles()
`
246
261
` ->IterateYoungWeakUnmodifiedRootsForPhantomHandles(
`
247
``
`-
&root_scavenge_visitor, &IsUnscavengedHeapObject);
`
``
262
`+
&root_scavenge_visitor, &IsUnscavengedHeapObjectSlot);
`
248
263
` }
`
249
264
``
250
265
` {
`
`@@ -280,8 +295,7 @@ void ScavengerCollector::CollectGarbage() {
`
280
295
` }
`
281
296
` }
`
282
297
``
283
``
`-
ScavengeWeakObjectRetainer weak_object_retainer;
`
284
``
`-
heap_->ProcessYoungWeakReferences(&weak_object_retainer);
`
``
298
`+
ProcessWeakReferences(&ephemeron_table_list);
`
285
299
``
286
300
`// Set age mark.
`
287
301
` heap_->new_space_->set_age_mark(heap_->new_space()->top());
`
`@@ -349,11 +363,12 @@ int ScavengerCollector::NumberOfScavengeTasks() {
`
349
363
``
350
364
`Scavenger::Scavenger(ScavengerCollector* collector, Heap* heap, bool is_logging,
`
351
365
` CopiedList* copied_list, PromotionList* promotion_list,
`
352
``
`-
int task_id)
`
``
366
`+
EphemeronTableList* ephemeron_table_list, int task_id)
`
353
367
` : collector_(collector),
`
354
368
` heap_(heap),
`
355
369
` promotion_list_(promotion_list, task_id),
`
356
370
` copied_list_(copied_list, task_id),
`
``
371
`+
ephemeron_table_list_(ephemeron_table_list, task_id),
`
357
372
` local_pretenuring_feedback_(kInitialLocalPretenuringFeedbackCapacity),
`
358
373
` copied_size_(0),
`
359
374
` promoted_size_(0),
`
`@@ -440,12 +455,45 @@ void Scavenger::Process(OneshotBarrier* barrier) {
`
440
455
` } while (!done);
`
441
456
`}
`
442
457
``
``
458
`+
void ScavengerCollector::ProcessWeakReferences(
`
``
459
`+
EphemeronTableList* ephemeron_table_list) {
`
``
460
`+
ScavengeWeakObjectRetainer weak_object_retainer;
`
``
461
`+
heap_->ProcessYoungWeakReferences(&weak_object_retainer);
`
``
462
`+
ClearYoungEphemerons(ephemeron_table_list);
`
``
463
`+
}
`
``
464
+
``
465
`+
// Clears ephemerons contained in {EphemeronHashTable}s in young generation.
`
``
466
`+
void ScavengerCollector::ClearYoungEphemerons(
`
``
467
`+
EphemeronTableList* ephemeron_table_list) {
`
``
468
`+
ephemeron_table_list->Iterate([this](EphemeronHashTable table) {
`
``
469
`+
for (int i = 0; i < table->Capacity(); i++) {
`
``
470
`+
ObjectSlot key_slot =
`
``
471
`+
table->RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(i));
`
``
472
`+
Object key = *key_slot;
`
``
473
`+
if (key->IsHeapObject()) {
`
``
474
`+
if (IsUnscavengedHeapObject(heap_, HeapObject::cast(key))) {
`
``
475
`+
table->RemoveEntry(i);
`
``
476
`+
} else {
`
``
477
`+
HeapObject forwarded = ForwardingAddress(HeapObject::cast(key));
`
``
478
`+
HeapObjectReference::Update(HeapObjectSlot(key_slot), forwarded);
`
``
479
`+
}
`
``
480
`+
}
`
``
481
`+
}
`
``
482
`+
});
`
``
483
`+
ephemeron_table_list->Clear();
`
``
484
`+
}
`
``
485
+
443
486
`void Scavenger::Finalize() {
`
444
487
`heap()->MergeAllocationSitePretenuringFeedback(local_pretenuring_feedback_);
`
445
488
`heap()->IncrementSemiSpaceCopiedObjectSize(copied_size_);
`
446
489
`heap()->IncrementPromotedObjectsSize(promoted_size_);
`
447
490
` collector_->MergeSurvivingNewLargeObjects(surviving_new_large_objects_);
`
448
491
` allocator_.Finalize();
`
``
492
`+
ephemeron_table_list_.FlushToGlobal();
`
``
493
`+
}
`
``
494
+
``
495
`+
void Scavenger::AddEphemeronHashTable(EphemeronHashTable table) {
`
``
496
`+
ephemeron_table_list_.Push(table);
`
449
497
`}
`
450
498
``
451
499
`void RootScavengeVisitor::VisitRootPointer(Root root, const char* description,
`