Index: src/heap/heap.cc |
diff --git a/src/heap/heap.cc b/src/heap/heap.cc |
index 5137301ddf46bc324da3c5784959085fefbabab3..7fae9171b7a9d15103836735cf7815fab8596f70 100644 |
--- a/src/heap/heap.cc |
+++ b/src/heap/heap.cc |
@@ -5311,6 +5311,9 @@ DependentCode* Heap::LookupWeakObjectToCodeDependency(Handle<HeapObject> obj) { |
void Heap::AddRetainedMap(Handle<Map> map) { |
Handle<WeakCell> cell = Map::WeakCellForMap(map); |
Handle<ArrayList> array(retained_maps(), isolate()); |
+ if (array->IsFull()) { |
+ CompactRetainedMaps(*array); |
+ } |
array = ArrayList::Add( |
array, cell, handle(Smi::FromInt(FLAG_retain_maps_for_n_gc), isolate()), |
ArrayList::kReloadLengthAfterAllocation); |
@@ -5320,6 +5323,35 @@ void Heap::AddRetainedMap(Handle<Map> map) { |
} |
+void Heap::CompactRetainedMaps(ArrayList* retained_maps) { |
+ DCHECK_EQ(retained_maps, this->retained_maps()); |
+ int length = retained_maps->Length(); |
+ int new_length = 0; |
+ int new_number_of_disposed_maps = 0; |
+ // This loop compacts the array by removing cleared weak cells. |
+ for (int i = 0; i < length; i += 2) { |
+ DCHECK(retained_maps->Get(i)->IsWeakCell()); |
+ WeakCell* cell = WeakCell::cast(retained_maps->Get(i)); |
+ Object* age = retained_maps->Get(i + 1); |
+ if (cell->cleared()) continue; |
+ if (i != new_length) { |
+ retained_maps->Set(new_length, cell); |
+ retained_maps->Set(new_length + 1, age); |
+ } |
+ if (i < number_of_disposed_maps_) { |
+ new_number_of_disposed_maps += 2; |
+ } |
+ new_length += 2; |
+ } |
+ number_of_disposed_maps_ = new_number_of_disposed_maps; |
+ Object* undefined = undefined_value(); |
+ for (int i = new_length; i < length; i++) { |
+ retained_maps->Clear(i, undefined); |
+ } |
+ if (new_length != length) retained_maps->SetLength(new_length); |
+} |
+ |
+ |
void Heap::FatalProcessOutOfMemory(const char* location, bool take_snapshot) { |
v8::internal::V8::FatalProcessOutOfMemory(location, take_snapshot); |
} |