@@ -114,7 +114,7 @@ class WriteBarrierElimination : public ValueObject {
114114
115115 // Bitvector with all non-Array-allocation instructions set. Used to
116116 // un-mark Array allocations as usable.
117- BitVector* array_allocations_mask_ ;
117+ BitVector* large_array_allocations_mask_ ;
118118
119119 // Bitvectors for each block of which allocations are new or remembered
120120 // at the start (after Phis).
@@ -189,16 +189,29 @@ void WriteBarrierElimination::SaveResults() {
189189 }
190190}
191191
192+ static bool IsCreateLargeArray (Definition* defn) {
193+ if (auto create_array = defn->AsCreateArray ()) {
194+ static_assert (!Array::UseCardMarkingForAllocation (
195+ Array::kMaxLengthForWriteBarrierElimination ),
196+ " Invariant restoration code does not handle card marking." );
197+ // Note: IsUsable would reject CreateArray instructions with non-constant
198+ // number of elements.
199+ return create_array->GetConstantNumElements () >
200+ Array::kMaxLengthForWriteBarrierElimination ;
201+ }
202+ return false ;
203+ }
204+
192205void WriteBarrierElimination::IndexDefinitions (Zone* zone) {
193- BitmapBuilder array_allocations ;
206+ BitmapBuilder large_array_allocations ;
194207
195208 GrowableArray<Definition*> create_array_worklist;
196209
197210 for (intptr_t i = 0 ; i < block_order_->length (); ++i) {
198211 BlockEntryInstr* const block = block_order_->At (i);
199212 if (auto join_block = block->AsJoinEntry ()) {
200213 for (PhiIterator it (join_block); !it.Done (); it.Advance ()) {
201- array_allocations .Set (definition_count_, false );
214+ large_array_allocations .Set (definition_count_, false );
202215 definition_indices_.Insert ({it.Current (), definition_count_++});
203216#if defined(DEBUG)
204217 if (tracing_) {
@@ -211,10 +224,10 @@ void WriteBarrierElimination::IndexDefinitions(Zone* zone) {
211224 for (ForwardInstructionIterator it (block); !it.Done (); it.Advance ()) {
212225 if (Definition* current = it.Current ()->AsDefinition ()) {
213226 if (IsUsable (current)) {
214- const bool is_create_array = current-> IsCreateArray ( );
215- array_allocations .Set (definition_count_, is_create_array );
227+ const bool is_create_large_array = IsCreateLargeArray (current );
228+ large_array_allocations .Set (definition_count_, is_create_large_array );
216229 definition_indices_.Insert ({current, definition_count_++});
217- if (is_create_array ) {
230+ if (is_create_large_array ) {
218231 create_array_worklist.Add (current);
219232 }
220233#if defined(DEBUG)
@@ -234,8 +247,9 @@ void WriteBarrierElimination::IndexDefinitions(Zone* zone) {
234247 it.Advance ()) {
235248 if (auto phi_use = it.Current ()->instruction ()->AsPhi ()) {
236249 const intptr_t index = Index (phi_use);
237- if (!array_allocations.Get (index)) {
238- array_allocations.Set (index, /* can_be_create_array=*/ true );
250+ if (!large_array_allocations.Get (index)) {
251+ large_array_allocations.Set (index,
252+ /* can_be_create_large_array=*/ true );
239253 create_array_worklist.Add (phi_use);
240254 }
241255 }
@@ -244,9 +258,9 @@ void WriteBarrierElimination::IndexDefinitions(Zone* zone) {
244258
245259 vector_ = new (zone) BitVector (zone, definition_count_);
246260 vector_->SetAll ();
247- array_allocations_mask_ = new (zone) BitVector (zone, definition_count_);
261+ large_array_allocations_mask_ = new (zone) BitVector (zone, definition_count_);
248262 for (intptr_t i = 0 ; i < definition_count_; ++i) {
249- if (!array_allocations .Get (i)) array_allocations_mask_ ->Add (i);
263+ if (!large_array_allocations .Get (i)) large_array_allocations_mask_ ->Add (i);
250264 }
251265}
252266
@@ -388,9 +402,9 @@ void WriteBarrierElimination::UpdateVectorForBlock(BlockEntryInstr* entry,
388402 if (current->CanCallDart ()) {
389403 vector_->Clear ();
390404 } else if (current->CanTriggerGC ()) {
391- // Clear array allocations. These are not added to the remembered set
392- // by Thread::RememberLiveTemporaries() after a scavenge.
393- vector_->Intersect (array_allocations_mask_ );
405+ // Clear large array allocations. These are not added to the remembered
406+ // set by Thread::RememberLiveTemporaries() after a scavenge.
407+ vector_->Intersect (large_array_allocations_mask_ );
394408 }
395409
396410 if (AllocationInstr* const alloc = current->AsAllocation ()) {
0 commit comments