@@ -143,8 +143,9 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
143
143
freelist_(freelist),
144
144
bytes_promoted_(0 ),
145
145
visiting_old_object_(nullptr ),
146
+ pending_(nullptr ),
146
147
promoted_list_(promotion_stack) {}
147
- ~ScavengerVisitorBase () {}
148
+ ~ScavengerVisitorBase () { ASSERT (pending_ == nullptr ); }
148
149
149
150
#ifdef DEBUG
150
151
constexpr static const char * const kName = " Scavenger" ;
@@ -354,24 +355,31 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
354
355
thread_ = nullptr ;
355
356
}
356
357
357
- void Finalize () {
358
+ void Finalize (StoreBuffer* store_buffer ) {
358
359
if (!scavenger_->abort_ ) {
359
360
promoted_list_.Finalize ();
360
361
weak_array_list_.Finalize ();
361
362
weak_property_list_.Finalize ();
362
363
weak_reference_list_.Finalize ();
363
364
finalizer_entry_list_.Finalize ();
365
+ ASSERT (pending_ == nullptr );
364
366
} else {
365
367
promoted_list_.AbandonWork ();
366
368
weak_array_list_.AbandonWork ();
367
369
weak_property_list_.AbandonWork ();
368
370
weak_reference_list_.AbandonWork ();
369
371
finalizer_entry_list_.AbandonWork ();
372
+ if (pending_ != nullptr ) {
373
+ pending_->Reset ();
374
+ store_buffer->PushBlock (pending_, StoreBuffer::kIgnoreThreshold );
375
+ pending_ = nullptr ;
376
+ }
370
377
}
371
378
}
372
379
373
380
Page* head () const { return head_; }
374
381
Page* tail () const { return tail_; }
382
+ void set_pending (StoreBufferBlock* pending) { pending_ = pending; }
375
383
376
384
static bool ForwardOrSetNullIfCollected (ObjectPtr parent,
377
385
CompressedObjectPtr* ptr_address);
@@ -611,6 +619,7 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
611
619
FreeList* freelist_;
612
620
intptr_t bytes_promoted_;
613
621
ObjectPtr visiting_old_object_;
622
+ StoreBufferBlock* pending_;
614
623
PromotionWorkList promoted_list_;
615
624
LocalBlockWorkList<64 , WeakArrayPtr> weak_array_list_;
616
625
LocalBlockWorkList<64 , WeakPropertyPtr> weak_property_list_;
@@ -1188,12 +1197,17 @@ template <bool parallel>
1188
1197
void Scavenger::IterateStoreBuffers (ScavengerVisitorBase<parallel>* visitor) {
1189
1198
TIMELINE_FUNCTION_GC_DURATION (Thread::Current (), " IterateStoreBuffers" );
1190
1199
1191
- // Iterating through the store buffers.
1192
- // Grab the deduplication sets out of the isolate's consolidated store buffer.
1193
1200
StoreBuffer* store_buffer = heap_->isolate_group ()->store_buffer ();
1194
- StoreBufferBlock* pending = blocks_;
1195
- while (pending != nullptr ) {
1196
- StoreBufferBlock* next = pending->next ();
1201
+ StoreBufferBlock* pending;
1202
+ for (;;) {
1203
+ {
1204
+ MutexLocker ml (&space_lock_);
1205
+ pending = blocks_;
1206
+ if (pending == nullptr ) break ;
1207
+ blocks_ = pending->next ();
1208
+ }
1209
+ // Ensure the block is freed in case of scavenger abort.
1210
+ visitor->set_pending (pending);
1197
1211
// Generated code appends to store buffers; tell MemorySanitizer.
1198
1212
MSAN_UNPOISON (pending, sizeof (*pending));
1199
1213
while (!pending->IsEmpty ()) {
@@ -1207,9 +1221,8 @@ void Scavenger::IterateStoreBuffers(ScavengerVisitorBase<parallel>* visitor) {
1207
1221
pending->Reset ();
1208
1222
// Return the emptied block for recycling (no need to check threshold).
1209
1223
store_buffer->PushBlock (pending, StoreBuffer::kIgnoreThreshold );
1210
- blocks_ = pending = next ;
1224
+ visitor-> set_pending ( nullptr ) ;
1211
1225
}
1212
- // Done iterating through old objects remembered in the store buffers.
1213
1226
}
1214
1227
1215
1228
template <bool parallel>
@@ -1229,7 +1242,6 @@ void Scavenger::IterateObjectIdTable(ObjectPointerVisitor* visitor) {
1229
1242
enum RootSlices {
1230
1243
kIsolate = 0 ,
1231
1244
kObjectIdRing ,
1232
- kStoreBuffer ,
1233
1245
kNumRootSlices ,
1234
1246
};
1235
1247
@@ -1248,14 +1260,12 @@ void Scavenger::IterateRoots(ScavengerVisitorBase<parallel>* visitor) {
1248
1260
case kObjectIdRing :
1249
1261
IterateObjectIdTable (visitor);
1250
1262
break ;
1251
- case kStoreBuffer :
1252
- IterateStoreBuffers (visitor);
1253
- break ;
1254
1263
default :
1255
1264
UNREACHABLE ();
1256
1265
}
1257
1266
}
1258
1267
1268
+ IterateStoreBuffers (visitor);
1259
1269
IterateRememberedCards (visitor);
1260
1270
}
1261
1271
@@ -1873,7 +1883,7 @@ intptr_t Scavenger::SerialScavenge(SemiSpace* from) {
1873
1883
visitor.ProcessRoots ();
1874
1884
visitor.ProcessAll ();
1875
1885
visitor.ProcessWeak ();
1876
- visitor.Finalize ();
1886
+ visitor.Finalize (heap_-> isolate_group ()-> store_buffer () );
1877
1887
to_->AddList (visitor.head (), visitor.tail ());
1878
1888
return visitor.bytes_promoted ();
1879
1889
}
@@ -1907,9 +1917,10 @@ intptr_t Scavenger::ParallelScavenge(SemiSpace* from) {
1907
1917
}
1908
1918
}
1909
1919
1920
+ StoreBuffer* store_buffer = heap_->isolate_group ()->store_buffer ();
1910
1921
for (intptr_t i = 0 ; i < num_tasks; i++) {
1911
1922
ParallelScavengerVisitor* visitor = visitors[i];
1912
- visitor->Finalize ();
1923
+ visitor->Finalize (store_buffer );
1913
1924
to_->AddList (visitor->head (), visitor->tail ());
1914
1925
bytes_promoted += visitor->bytes_promoted ();
1915
1926
delete visitor;
0 commit comments