Reload length of retained_maps array after GC.
This fixes flaky GC stress failure: > Fatal error in ../src/heap/mark-compact.cc, line 2127 > Check failed: retained_maps->Get(i)->IsWeakCell(). BUG= TEST=test-heap/RegressArrayListGC Review URL: https://codereview.chromium.org/1026113004 Cr-Commit-Position: refs/heads/master@{#27412}
This commit is contained in:
parent
1fefa31df6
commit
1efcca7f04
@ -5613,7 +5613,8 @@ void Heap::AddRetainedMap(Handle<Map> map) {
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(map);
|
||||
Handle<ArrayList> array(retained_maps(), isolate());
|
||||
array = ArrayList::Add(
|
||||
array, cell, handle(Smi::FromInt(FLAG_retain_maps_for_n_gc), isolate()));
|
||||
array, cell, handle(Smi::FromInt(FLAG_retain_maps_for_n_gc), isolate()),
|
||||
ArrayList::kReloadLengthAfterAllocation);
|
||||
if (*array != retained_maps()) {
|
||||
set_retained_maps(*array);
|
||||
}
|
||||
|
@ -8277,9 +8277,14 @@ Handle<WeakFixedArray> WeakFixedArray::Allocate(
|
||||
}
|
||||
|
||||
|
||||
Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj) {
|
||||
Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj,
|
||||
AddMode mode) {
|
||||
int length = array->Length();
|
||||
array = EnsureSpace(array, length + 1);
|
||||
if (mode == kReloadLengthAfterAllocation) {
|
||||
DCHECK(array->Length() <= length);
|
||||
length = array->Length();
|
||||
}
|
||||
array->Set(length, *obj);
|
||||
array->SetLength(length + 1);
|
||||
return array;
|
||||
@ -8287,9 +8292,12 @@ Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj) {
|
||||
|
||||
|
||||
Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj1,
|
||||
Handle<Object> obj2) {
|
||||
Handle<Object> obj2, AddMode mode) {
|
||||
int length = array->Length();
|
||||
array = EnsureSpace(array, length + 2);
|
||||
if (mode == kReloadLengthAfterAllocation) {
|
||||
length = array->Length();
|
||||
}
|
||||
array->Set(length, *obj1);
|
||||
array->Set(length + 1, *obj2);
|
||||
array->SetLength(length + 2);
|
||||
@ -8299,10 +8307,12 @@ Handle<ArrayList> ArrayList::Add(Handle<ArrayList> array, Handle<Object> obj1,
|
||||
|
||||
Handle<ArrayList> ArrayList::EnsureSpace(Handle<ArrayList> array, int length) {
|
||||
int capacity = array->length();
|
||||
bool empty = (capacity == 0);
|
||||
if (capacity < kFirstIndex + length) {
|
||||
capacity = kFirstIndex + length;
|
||||
capacity = capacity + Max(capacity / 2, 2);
|
||||
array = Handle<ArrayList>::cast(FixedArray::CopySize(array, capacity));
|
||||
if (empty) array->SetLength(0);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
@ -2631,9 +2631,15 @@ class WeakFixedArray : public FixedArray {
|
||||
// Generic array grows dynamically with O(1) amortized insertion.
|
||||
class ArrayList : public FixedArray {
|
||||
public:
|
||||
static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj);
|
||||
enum AddMode {
|
||||
kNone,
|
||||
// Use this if GC can delete elements from the array.
|
||||
kReloadLengthAfterAllocation,
|
||||
};
|
||||
static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj,
|
||||
AddMode mode = kNone);
|
||||
static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj1,
|
||||
Handle<Object> obj2);
|
||||
Handle<Object> obj2, AddMode = kNone);
|
||||
inline int Length();
|
||||
inline void SetLength(int length);
|
||||
inline Object* Get(int index);
|
||||
|
@ -5105,12 +5105,7 @@ TEST(Regress3877) {
|
||||
}
|
||||
|
||||
|
||||
void CheckMapRetainingFor(int n) {
|
||||
FLAG_retain_maps_for_n_gc = n;
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Heap* heap = isolate->heap();
|
||||
Handle<WeakCell> weak_cell;
|
||||
{
|
||||
Handle<WeakCell> AddRetainedMap(Isolate* isolate, Heap* heap) {
|
||||
HandleScope inner_scope(isolate);
|
||||
Handle<Map> map = Map::Create(isolate, 1);
|
||||
v8::Local<v8::Value> result =
|
||||
@ -5119,8 +5114,15 @@ void CheckMapRetainingFor(int n) {
|
||||
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result));
|
||||
map->set_prototype(*proto);
|
||||
heap->AddRetainedMap(map);
|
||||
weak_cell = inner_scope.CloseAndEscape(Map::WeakCellForMap(map));
|
||||
}
|
||||
return inner_scope.CloseAndEscape(Map::WeakCellForMap(map));
|
||||
}
|
||||
|
||||
|
||||
void CheckMapRetainingFor(int n) {
|
||||
FLAG_retain_maps_for_n_gc = n;
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Heap* heap = isolate->heap();
|
||||
Handle<WeakCell> weak_cell = AddRetainedMap(isolate, heap);
|
||||
CHECK(!weak_cell->cleared());
|
||||
for (int i = 0; i < n; i++) {
|
||||
heap->CollectGarbage(OLD_POINTER_SPACE);
|
||||
@ -5141,6 +5143,27 @@ TEST(MapRetaining) {
|
||||
}
|
||||
|
||||
|
||||
TEST(RegressArrayListGC) {
|
||||
FLAG_retain_maps_for_n_gc = 1;
|
||||
FLAG_incremental_marking = 0;
|
||||
FLAG_gc_global = true;
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Heap* heap = isolate->heap();
|
||||
AddRetainedMap(isolate, heap);
|
||||
Handle<Map> map = Map::Create(isolate, 1);
|
||||
heap->CollectGarbage(OLD_POINTER_SPACE);
|
||||
// Force GC in old space on next addition of retained map.
|
||||
Map::WeakCellForMap(map);
|
||||
SimulateFullSpace(CcTest::heap()->new_space());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
heap->AddRetainedMap(map);
|
||||
}
|
||||
heap->CollectGarbage(OLD_POINTER_SPACE);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
TEST(PathTracer) {
|
||||
CcTest::InitializeVM();
|
||||
|
Loading…
Reference in New Issue
Block a user