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:
ulan 2015-03-24 07:35:55 -07:00 committed by Commit bot
parent 1fefa31df6
commit 1efcca7f04
4 changed files with 53 additions and 13 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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();