Vector-based ICs also need to hold maps weakly.
Regular ICs in MONOMORPHIC and POLYMORPHIC state now hold onto maps with WeakCells. Vector-based ICs should do the same. R=ulan@chromium.org Review URL: https://codereview.chromium.org/815953002 Cr-Commit-Position: refs/heads/master@{#25907}
This commit is contained in:
parent
5ac1f8dabb
commit
ad033893d6
@ -2043,8 +2043,13 @@ void CodeStubGraphBuilderBase::HandleArrayCases(HValue* array, HValue* receiver,
|
|||||||
HValue* receiver_map = AddLoadMap(receiver, nullptr);
|
HValue* receiver_map = AddLoadMap(receiver, nullptr);
|
||||||
HValue* start =
|
HValue* start =
|
||||||
keyed_load ? graph()->GetConstant1() : graph()->GetConstant0();
|
keyed_load ? graph()->GetConstant1() : graph()->GetConstant0();
|
||||||
HValue* array_map = Add<HLoadKeyed>(array, start, nullptr, FAST_ELEMENTS,
|
HValue* weak_cell = Add<HLoadKeyed>(array, start, nullptr, FAST_ELEMENTS,
|
||||||
ALLOW_RETURN_HOLE);
|
ALLOW_RETURN_HOLE);
|
||||||
|
// Load the weak cell value. It may be Smi(0), or a map. Compare nonetheless
|
||||||
|
// against the receiver_map.
|
||||||
|
HValue* array_map = Add<HLoadNamedField>(weak_cell, nullptr,
|
||||||
|
HObjectAccess::ForWeakCellValue());
|
||||||
|
|
||||||
IfBuilder if_correct_map(this);
|
IfBuilder if_correct_map(this);
|
||||||
if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
|
if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
|
||||||
if_correct_map.Then();
|
if_correct_map.Then();
|
||||||
@ -2059,8 +2064,10 @@ void CodeStubGraphBuilderBase::HandleArrayCases(HValue* array, HValue* receiver,
|
|||||||
start = keyed_load ? constant_three : constant_two;
|
start = keyed_load ? constant_three : constant_two;
|
||||||
HValue* key = builder.BeginBody(start, length, Token::LT);
|
HValue* key = builder.BeginBody(start, length, Token::LT);
|
||||||
{
|
{
|
||||||
HValue* array_map = Add<HLoadKeyed>(array, key, nullptr, FAST_ELEMENTS,
|
HValue* weak_cell = Add<HLoadKeyed>(array, key, nullptr, FAST_ELEMENTS,
|
||||||
ALLOW_RETURN_HOLE);
|
ALLOW_RETURN_HOLE);
|
||||||
|
HValue* array_map = Add<HLoadNamedField>(
|
||||||
|
weak_cell, nullptr, HObjectAccess::ForWeakCellValue());
|
||||||
IfBuilder if_correct_poly_map(this);
|
IfBuilder if_correct_poly_map(this);
|
||||||
if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map,
|
if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map,
|
||||||
array_map);
|
array_map);
|
||||||
|
@ -223,12 +223,13 @@ Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
|
|||||||
void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types,
|
void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types,
|
||||||
CodeHandleList* handlers) {
|
CodeHandleList* handlers) {
|
||||||
Isolate* isolate = GetIsolate();
|
Isolate* isolate = GetIsolate();
|
||||||
FixedArray* array = FixedArray::cast(GetFeedback());
|
Handle<FixedArray> array = handle(FixedArray::cast(GetFeedback()), isolate);
|
||||||
int receiver_count = types->length();
|
int receiver_count = types->length();
|
||||||
for (int current = 0; current < receiver_count; ++current) {
|
for (int current = 0; current < receiver_count; ++current) {
|
||||||
Handle<HeapType> type = types->at(current);
|
Handle<HeapType> type = types->at(current);
|
||||||
Handle<Map> map = IC::TypeToMap(*type, isolate);
|
Handle<Map> map = IC::TypeToMap(*type, isolate);
|
||||||
array->set(start_index + (current * 2), *map);
|
Handle<WeakCell> cell = Map::WeakCellForMap(map);
|
||||||
|
array->set(start_index + (current * 2), *cell);
|
||||||
array->set(start_index + (current * 2 + 1), *handlers->at(current));
|
array->set(start_index + (current * 2 + 1), *handlers->at(current));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,6 +245,8 @@ InlineCacheState LoadICNexus::StateFromFeedback() const {
|
|||||||
} else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
|
} else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
|
||||||
return PREMONOMORPHIC;
|
return PREMONOMORPHIC;
|
||||||
} else if (feedback->IsFixedArray()) {
|
} else if (feedback->IsFixedArray()) {
|
||||||
|
// Determine state purely by our structure, don't check if the maps are
|
||||||
|
// cleared.
|
||||||
FixedArray* array = FixedArray::cast(feedback);
|
FixedArray* array = FixedArray::cast(feedback);
|
||||||
int length = array->length();
|
int length = array->length();
|
||||||
DCHECK(length >= 2);
|
DCHECK(length >= 2);
|
||||||
@ -264,6 +267,8 @@ InlineCacheState KeyedLoadICNexus::StateFromFeedback() const {
|
|||||||
} else if (feedback == *vector()->GenericSentinel(isolate)) {
|
} else if (feedback == *vector()->GenericSentinel(isolate)) {
|
||||||
return GENERIC;
|
return GENERIC;
|
||||||
} else if (feedback->IsFixedArray()) {
|
} else if (feedback->IsFixedArray()) {
|
||||||
|
// Determine state purely by our structure, don't check if the maps are
|
||||||
|
// cleared.
|
||||||
FixedArray* array = FixedArray::cast(feedback);
|
FixedArray* array = FixedArray::cast(feedback);
|
||||||
int length = array->length();
|
int length = array->length();
|
||||||
DCHECK(length >= 3);
|
DCHECK(length >= 3);
|
||||||
@ -344,7 +349,8 @@ void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type,
|
|||||||
Handle<Code> handler) {
|
Handle<Code> handler) {
|
||||||
Handle<FixedArray> array = EnsureArrayOfSize(2);
|
Handle<FixedArray> array = EnsureArrayOfSize(2);
|
||||||
Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
|
Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
|
||||||
array->set(0, *receiver_map);
|
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||||
|
array->set(0, *cell);
|
||||||
array->set(1, *handler);
|
array->set(1, *handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +365,8 @@ void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
|
|||||||
} else {
|
} else {
|
||||||
array->set(0, *name);
|
array->set(0, *name);
|
||||||
}
|
}
|
||||||
array->set(1, *receiver_map);
|
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||||
|
array->set(1, *cell);
|
||||||
array->set(2, *handler);
|
array->set(2, *handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,15 +397,20 @@ int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const {
|
|||||||
Isolate* isolate = GetIsolate();
|
Isolate* isolate = GetIsolate();
|
||||||
Object* feedback = GetFeedback();
|
Object* feedback = GetFeedback();
|
||||||
if (feedback->IsFixedArray()) {
|
if (feedback->IsFixedArray()) {
|
||||||
|
int found = 0;
|
||||||
FixedArray* array = FixedArray::cast(feedback);
|
FixedArray* array = FixedArray::cast(feedback);
|
||||||
// The array should be of the form [<optional name>], then
|
// The array should be of the form [<optional name>], then
|
||||||
// [map, handler, map, handler, ... ]
|
// [map, handler, map, handler, ... ]
|
||||||
DCHECK(array->length() >= (2 + start_index));
|
DCHECK(array->length() >= (2 + start_index));
|
||||||
for (int i = start_index; i < array->length(); i += 2) {
|
for (int i = start_index; i < array->length(); i += 2) {
|
||||||
Map* map = Map::cast(array->get(i));
|
WeakCell* cell = WeakCell::cast(array->get(i));
|
||||||
maps->Add(handle(map, isolate));
|
if (!cell->cleared()) {
|
||||||
|
Map* map = Map::cast(cell->value());
|
||||||
|
maps->Add(handle(map, isolate));
|
||||||
|
found++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (array->length() - start_index) / 2;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -411,11 +423,14 @@ MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index,
|
|||||||
if (feedback->IsFixedArray()) {
|
if (feedback->IsFixedArray()) {
|
||||||
FixedArray* array = FixedArray::cast(feedback);
|
FixedArray* array = FixedArray::cast(feedback);
|
||||||
for (int i = start_index; i < array->length(); i += 2) {
|
for (int i = start_index; i < array->length(); i += 2) {
|
||||||
Map* array_map = Map::cast(array->get(i));
|
WeakCell* cell = WeakCell::cast(array->get(i));
|
||||||
if (array_map == *map) {
|
if (!cell->cleared()) {
|
||||||
Code* code = Code::cast(array->get(i + 1));
|
Map* array_map = Map::cast(cell->value());
|
||||||
DCHECK(code->kind() == Code::HANDLER);
|
if (array_map == *map) {
|
||||||
return handle(code);
|
Code* code = Code::cast(array->get(i + 1));
|
||||||
|
DCHECK(code->kind() == Code::HANDLER);
|
||||||
|
return handle(code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,13 +446,17 @@ bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list,
|
|||||||
if (feedback->IsFixedArray()) {
|
if (feedback->IsFixedArray()) {
|
||||||
FixedArray* array = FixedArray::cast(feedback);
|
FixedArray* array = FixedArray::cast(feedback);
|
||||||
// The array should be of the form [<optional name>], then
|
// The array should be of the form [<optional name>], then
|
||||||
// [map, handler, map, handler, ... ]
|
// [map, handler, map, handler, ... ]. Be sure to skip handlers whose maps
|
||||||
|
// have been cleared.
|
||||||
DCHECK(array->length() >= (2 + start_index));
|
DCHECK(array->length() >= (2 + start_index));
|
||||||
for (int i = start_index; i < array->length(); i += 2) {
|
for (int i = start_index; i < array->length(); i += 2) {
|
||||||
Code* code = Code::cast(array->get(i + 1));
|
WeakCell* cell = WeakCell::cast(array->get(i));
|
||||||
DCHECK(code->kind() == Code::HANDLER);
|
if (!cell->cleared()) {
|
||||||
code_list->Add(handle(code));
|
Code* code = Code::cast(array->get(i + 1));
|
||||||
count++;
|
DCHECK(code->kind() == Code::HANDLER);
|
||||||
|
code_list->Add(handle(code));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count == length;
|
return count == length;
|
||||||
|
@ -3407,8 +3407,6 @@ static void CheckVectorICCleared(Handle<JSFunction> f, int ic_slot_index) {
|
|||||||
|
|
||||||
TEST(IncrementalMarkingPreservesMonomorphicIC) {
|
TEST(IncrementalMarkingPreservesMonomorphicIC) {
|
||||||
if (i::FLAG_always_opt) return;
|
if (i::FLAG_always_opt) return;
|
||||||
// TODO(mvstanton): vector-ics need to treat maps weakly.
|
|
||||||
if (i::FLAG_vector_ics) return;
|
|
||||||
CcTest::InitializeVM();
|
CcTest::InitializeVM();
|
||||||
v8::HandleScope scope(CcTest::isolate());
|
v8::HandleScope scope(CcTest::isolate());
|
||||||
|
|
||||||
@ -3806,8 +3804,6 @@ TEST(Regress169209) {
|
|||||||
i::FLAG_stress_compaction = false;
|
i::FLAG_stress_compaction = false;
|
||||||
i::FLAG_allow_natives_syntax = true;
|
i::FLAG_allow_natives_syntax = true;
|
||||||
i::FLAG_flush_code_incrementally = true;
|
i::FLAG_flush_code_incrementally = true;
|
||||||
// TODO(mvstanton): vector ics need weak support.
|
|
||||||
if (i::FLAG_vector_ics) return;
|
|
||||||
|
|
||||||
CcTest::InitializeVM();
|
CcTest::InitializeVM();
|
||||||
Isolate* isolate = CcTest::i_isolate();
|
Isolate* isolate = CcTest::i_isolate();
|
||||||
@ -4161,8 +4157,6 @@ static int AllocationSitesCount(Heap* heap) {
|
|||||||
|
|
||||||
|
|
||||||
TEST(EnsureAllocationSiteDependentCodesProcessed) {
|
TEST(EnsureAllocationSiteDependentCodesProcessed) {
|
||||||
// TODO(mvstanton): vector ics need weak support!
|
|
||||||
if (FLAG_vector_ics) return;
|
|
||||||
if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
|
if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
|
||||||
i::FLAG_allow_natives_syntax = true;
|
i::FLAG_allow_natives_syntax = true;
|
||||||
CcTest::InitializeVM();
|
CcTest::InitializeVM();
|
||||||
@ -4211,10 +4205,6 @@ TEST(EnsureAllocationSiteDependentCodesProcessed) {
|
|||||||
heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
|
heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mvstanton): this test fails when FLAG_vector_ics is true because
|
|
||||||
// monomorphic load ics are preserved, but also strongly walked. They
|
|
||||||
// end up keeping function bar alive.
|
|
||||||
|
|
||||||
// The site still exists because of our global handle, but the code is no
|
// The site still exists because of our global handle, but the code is no
|
||||||
// longer referred to by dependent_code().
|
// longer referred to by dependent_code().
|
||||||
DependentCode::GroupStartIndexes starts(site->dependent_code());
|
DependentCode::GroupStartIndexes starts(site->dependent_code());
|
||||||
@ -4225,8 +4215,6 @@ TEST(EnsureAllocationSiteDependentCodesProcessed) {
|
|||||||
|
|
||||||
TEST(CellsInOptimizedCodeAreWeak) {
|
TEST(CellsInOptimizedCodeAreWeak) {
|
||||||
if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
|
if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
|
||||||
// TODO(mvstanton): vector-ics need to treat maps weakly.
|
|
||||||
if (i::FLAG_vector_ics) return;
|
|
||||||
i::FLAG_weak_embedded_objects_in_optimized_code = true;
|
i::FLAG_weak_embedded_objects_in_optimized_code = true;
|
||||||
i::FLAG_allow_natives_syntax = true;
|
i::FLAG_allow_natives_syntax = true;
|
||||||
CcTest::InitializeVM();
|
CcTest::InitializeVM();
|
||||||
@ -4269,8 +4257,6 @@ TEST(CellsInOptimizedCodeAreWeak) {
|
|||||||
|
|
||||||
|
|
||||||
TEST(ObjectsInOptimizedCodeAreWeak) {
|
TEST(ObjectsInOptimizedCodeAreWeak) {
|
||||||
// TODO(mvstanton): vector ics need weak support!
|
|
||||||
if (FLAG_vector_ics) return;
|
|
||||||
if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
|
if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
|
||||||
i::FLAG_weak_embedded_objects_in_optimized_code = true;
|
i::FLAG_weak_embedded_objects_in_optimized_code = true;
|
||||||
i::FLAG_allow_natives_syntax = true;
|
i::FLAG_allow_natives_syntax = true;
|
||||||
@ -4314,8 +4300,6 @@ TEST(ObjectsInOptimizedCodeAreWeak) {
|
|||||||
TEST(NoWeakHashTableLeakWithIncrementalMarking) {
|
TEST(NoWeakHashTableLeakWithIncrementalMarking) {
|
||||||
if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
|
if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
|
||||||
if (!i::FLAG_incremental_marking) return;
|
if (!i::FLAG_incremental_marking) return;
|
||||||
// TODO(mvstanton): vector ics need weak support.
|
|
||||||
if (FLAG_vector_ics) return;
|
|
||||||
i::FLAG_weak_embedded_objects_in_optimized_code = true;
|
i::FLAG_weak_embedded_objects_in_optimized_code = true;
|
||||||
i::FLAG_allow_natives_syntax = true;
|
i::FLAG_allow_natives_syntax = true;
|
||||||
i::FLAG_compilation_cache = false;
|
i::FLAG_compilation_cache = false;
|
||||||
@ -4487,8 +4471,6 @@ void CheckWeakness(const char* source) {
|
|||||||
// Each of the following "weak IC" tests creates an IC that embeds a map with
|
// Each of the following "weak IC" tests creates an IC that embeds a map with
|
||||||
// the prototype pointing to _proto_ and checks that the _proto_ dies on GC.
|
// the prototype pointing to _proto_ and checks that the _proto_ dies on GC.
|
||||||
TEST(WeakMapInMonomorphicLoadIC) {
|
TEST(WeakMapInMonomorphicLoadIC) {
|
||||||
// TODO(mvstanton): vector ics need weak support!
|
|
||||||
if (FLAG_vector_ics) return;
|
|
||||||
CheckWeakness("function loadIC(obj) {"
|
CheckWeakness("function loadIC(obj) {"
|
||||||
" return obj.name;"
|
" return obj.name;"
|
||||||
"}"
|
"}"
|
||||||
@ -4504,8 +4486,6 @@ TEST(WeakMapInMonomorphicLoadIC) {
|
|||||||
|
|
||||||
|
|
||||||
TEST(WeakMapInPolymorphicLoadIC) {
|
TEST(WeakMapInPolymorphicLoadIC) {
|
||||||
// TODO(mvstanton): vector-ics need to treat maps weakly.
|
|
||||||
if (i::FLAG_vector_ics) return;
|
|
||||||
CheckWeakness(
|
CheckWeakness(
|
||||||
"function loadIC(obj) {"
|
"function loadIC(obj) {"
|
||||||
" return obj.name;"
|
" return obj.name;"
|
||||||
@ -4525,8 +4505,6 @@ TEST(WeakMapInPolymorphicLoadIC) {
|
|||||||
|
|
||||||
|
|
||||||
TEST(WeakMapInMonomorphicKeyedLoadIC) {
|
TEST(WeakMapInMonomorphicKeyedLoadIC) {
|
||||||
// TODO(mvstanton): vector ics need weak support!
|
|
||||||
if (FLAG_vector_ics) return;
|
|
||||||
CheckWeakness("function keyedLoadIC(obj, field) {"
|
CheckWeakness("function keyedLoadIC(obj, field) {"
|
||||||
" return obj[field];"
|
" return obj[field];"
|
||||||
"}"
|
"}"
|
||||||
|
Loading…
Reference in New Issue
Block a user