Commit debf2adc authored by ishell's avatar ishell Committed by Commit bot

[field type tracking] Fix handling of cleared WeakCells.

BUG=chromium:514080,chromium:527994,v8:4325
LOG=N

Review URL: https://codereview.chromium.org/1522413002

Cr-Commit-Position: refs/heads/master@{#32871}
parent 00f24ba7
......@@ -301,7 +301,11 @@ void JSObject::JSObjectVerify() {
if (r.IsNone()) {
CHECK(type_is_none);
} else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
CHECK(!field_type->NowStable() || field_type->NowContains(value));
// If allocation folding is off then GC could happen during inner
// object literal creation and we will end up having and undefined
// value that does not match the field type.
CHECK(!field_type->NowStable() || field_type->NowContains(value) ||
(!FLAG_use_allocation_folding && value->IsUndefined()));
}
}
}
......
......@@ -3046,7 +3046,7 @@ void Map::UpdateFieldType(int descriptor, Handle<Name> name,
}
bool FieldTypeIsCleared(Representation rep, Handle<HeapType> type) {
bool FieldTypeIsCleared(Representation rep, HeapType* type) {
return type->Is(HeapType::None()) && rep.IsHeapObject();
}
......@@ -3060,7 +3060,7 @@ Handle<HeapType> Map::GeneralizeFieldType(Representation rep1,
// Cleared field types need special treatment. They represent lost knowledge,
// so we must be conservative, so their generalization with any other type
// is "Any".
if (FieldTypeIsCleared(rep1, type1) || FieldTypeIsCleared(rep2, type2)) {
if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) {
return HeapType::Any(isolate);
}
if (type1->NowIs(type2)) return type2;
......@@ -3083,7 +3083,7 @@ void Map::GeneralizeFieldType(Handle<Map> map, int modify_index,
isolate);
if (old_representation.Equals(new_representation) &&
!FieldTypeIsCleared(new_representation, new_field_type) &&
!FieldTypeIsCleared(new_representation, *new_field_type) &&
// Checking old_field_type for being cleared is not necessary because
// the NowIs check below would fail anyway in that case.
new_field_type->NowIs(old_field_type)) {
......@@ -3735,10 +3735,16 @@ MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
switch (new_details.type()) {
case DATA: {
HeapType* new_type = new_descriptors->GetFieldType(i);
// Cleared field types need special treatment. They represent lost
// knowledge, so we must first generalize the old_type to "Any".
if (!FieldTypeIsCleared(new_details.representation(), new_type)) {
return MaybeHandle<Map>();
}
PropertyType old_property_type = old_details.type();
if (old_property_type == DATA) {
HeapType* old_type = old_descriptors->GetFieldType(i);
if (!old_type->NowIs(new_type)) {
if (FieldTypeIsCleared(old_details.representation(), old_type) ||
!old_type->NowIs(new_type)) {
return MaybeHandle<Map>();
}
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment