Skip to content

Commit debf2ad

Browse files
isheludkoCommit bot
authored andcommitted
[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}
1 parent 00f24ba commit debf2ad

2 files changed

Lines changed: 15 additions & 5 deletions

File tree

src/objects-debug.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,11 @@ void JSObject::JSObjectVerify() {
301301
if (r.IsNone()) {
302302
CHECK(type_is_none);
303303
} else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
304-
CHECK(!field_type->NowStable() || field_type->NowContains(value));
304+
// If allocation folding is off then GC could happen during inner
305+
// object literal creation and we will end up having and undefined
306+
// value that does not match the field type.
307+
CHECK(!field_type->NowStable() || field_type->NowContains(value) ||
308+
(!FLAG_use_allocation_folding && value->IsUndefined()));
305309
}
306310
}
307311
}

src/objects.cc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,7 +3046,7 @@ void Map::UpdateFieldType(int descriptor, Handle<Name> name,
30463046
}
30473047

30483048

3049-
bool FieldTypeIsCleared(Representation rep, Handle<HeapType> type) {
3049+
bool FieldTypeIsCleared(Representation rep, HeapType* type) {
30503050
return type->Is(HeapType::None()) && rep.IsHeapObject();
30513051
}
30523052

@@ -3060,7 +3060,7 @@ Handle<HeapType> Map::GeneralizeFieldType(Representation rep1,
30603060
// Cleared field types need special treatment. They represent lost knowledge,
30613061
// so we must be conservative, so their generalization with any other type
30623062
// is "Any".
3063-
if (FieldTypeIsCleared(rep1, type1) || FieldTypeIsCleared(rep2, type2)) {
3063+
if (FieldTypeIsCleared(rep1, *type1) || FieldTypeIsCleared(rep2, *type2)) {
30643064
return HeapType::Any(isolate);
30653065
}
30663066
if (type1->NowIs(type2)) return type2;
@@ -3083,7 +3083,7 @@ void Map::GeneralizeFieldType(Handle<Map> map, int modify_index,
30833083
isolate);
30843084

30853085
if (old_representation.Equals(new_representation) &&
3086-
!FieldTypeIsCleared(new_representation, new_field_type) &&
3086+
!FieldTypeIsCleared(new_representation, *new_field_type) &&
30873087
// Checking old_field_type for being cleared is not necessary because
30883088
// the NowIs check below would fail anyway in that case.
30893089
new_field_type->NowIs(old_field_type)) {
@@ -3735,10 +3735,16 @@ MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
37353735
switch (new_details.type()) {
37363736
case DATA: {
37373737
HeapType* new_type = new_descriptors->GetFieldType(i);
3738+
// Cleared field types need special treatment. They represent lost
3739+
// knowledge, so we must first generalize the old_type to "Any".
3740+
if (!FieldTypeIsCleared(new_details.representation(), new_type)) {
3741+
return MaybeHandle<Map>();
3742+
}
37383743
PropertyType old_property_type = old_details.type();
37393744
if (old_property_type == DATA) {
37403745
HeapType* old_type = old_descriptors->GetFieldType(i);
3741-
if (!old_type->NowIs(new_type)) {
3746+
if (FieldTypeIsCleared(old_details.representation(), old_type) ||
3747+
!old_type->NowIs(new_type)) {
37423748
return MaybeHandle<Map>();
37433749
}
37443750
} else {

0 commit comments

Comments
 (0)