Skip to content

Commit e2c40cc

Browse files
mmarchinicodebytere
authored andcommittedMar 30, 2020
deps: V8: backport f7771e5b0cc4
Original commit message: [runtime] Recompute enumeration indices of dictionaries upon bitfield overflow Otherwise we'll get weird semantics when enumerating objects after many deletes/reinserts. Bug: chromium:1033771 Change-Id: If0a459169c3794a30d9632d09e80da3cfcd4302c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1993966 Commit-Queue: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Victor Gomes <victorgomes@chromium.org> Cr-Commit-Position: refs/heads/master@{#65690} Refs: v8/v8@f7771e5 PR-URL: #31957 Backport-PR-URL: #32053 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
1 parent df8d51b commit e2c40cc

8 files changed

+48
-42
lines changed
 

‎common.gypi

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
# Reset this number to 0 on major V8 upgrades.
4040
# Increment by one for each non-official patch applied to deps/v8.
41-
'v8_embedder_string': '-node.31',
41+
'v8_embedder_string': '-node.32',
4242

4343
##### V8 defaults for Node.js #####
4444

‎deps/v8/src/objects/dictionary-inl.h

+11
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ template <typename Derived, typename Shape>
3131
BaseNameDictionary<Derived, Shape>::BaseNameDictionary(Address ptr)
3232
: Dictionary<Derived, Shape>(ptr) {}
3333

34+
template <typename Derived, typename Shape>
35+
void BaseNameDictionary<Derived, Shape>::set_next_enumeration_index(int index) {
36+
DCHECK_LT(0, index);
37+
this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
38+
}
39+
40+
template <typename Derived, typename Shape>
41+
int BaseNameDictionary<Derived, Shape>::next_enumeration_index() {
42+
return Smi::ToInt(this->get(kNextEnumerationIndexIndex));
43+
}
44+
3445
GlobalDictionary::GlobalDictionary(Address ptr)
3546
: BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>(ptr) {
3647
SLOW_DCHECK(IsGlobalDictionary());

‎deps/v8/src/objects/dictionary.h

+7-14
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,6 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) BaseNameDictionary
140140
static const int kObjectHashIndex = kNextEnumerationIndexIndex + 1;
141141
static const int kEntryValueIndex = 1;
142142

143-
// Accessors for next enumeration index.
144-
void SetNextEnumerationIndex(int index) {
145-
DCHECK_NE(0, index);
146-
this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
147-
}
148-
149-
int NextEnumerationIndex() {
150-
return Smi::ToInt(this->get(kNextEnumerationIndexIndex));
151-
}
152-
153143
void SetHash(int hash) {
154144
DCHECK(PropertyArray::HashField::is_valid(hash));
155145
this->set(kObjectHashIndex, Smi::FromInt(hash));
@@ -173,6 +163,13 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) BaseNameDictionary
173163
V8_WARN_UNUSED_RESULT static ExceptionStatus CollectKeysTo(
174164
Handle<Derived> dictionary, KeyAccumulator* keys);
175165

166+
// Allocate the next enumeration index. Possibly updates all enumeration
167+
// indices in the table.
168+
static int NextEnumerationIndex(Isolate* isolate, Handle<Derived> dictionary);
169+
// Accessors for next enumeration index.
170+
inline int next_enumeration_index();
171+
inline void set_next_enumeration_index(int index);
172+
176173
// Return the key indices sorted by its enumeration index.
177174
static Handle<FixedArray> IterationIndices(Isolate* isolate,
178175
Handle<Derived> dictionary);
@@ -184,10 +181,6 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) BaseNameDictionary
184181
Handle<FixedArray> storage, KeyCollectionMode mode,
185182
KeyAccumulator* accumulator);
186183

187-
// Ensure enough space for n additional elements.
188-
static Handle<Derived> EnsureCapacity(Isolate* isolate,
189-
Handle<Derived> dictionary, int n);
190-
191184
V8_WARN_UNUSED_RESULT static Handle<Derived> AddNoUpdateNextEnumerationIndex(
192185
Isolate* isolate, Handle<Derived> dictionary, Key key,
193186
Handle<Object> value, PropertyDetails details, int* entry_out = nullptr);

‎deps/v8/src/objects/hash-table.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
205205

206206
// Ensure enough space for n additional elements.
207207
V8_WARN_UNUSED_RESULT static Handle<Derived> EnsureCapacity(
208-
Isolate* isolate, Handle<Derived> table, int n,
208+
Isolate* isolate, Handle<Derived> table, int n = 1,
209209
AllocationType allocation = AllocationType::kYoung);
210210

211211
// Returns true if this table has sufficient capacity for adding n elements.

‎deps/v8/src/objects/js-objects.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2885,7 +2885,7 @@ void MigrateFastToSlow(Isolate* isolate, Handle<JSObject> object,
28852885
}
28862886

28872887
// Copy the next enumeration index from instance descriptor.
2888-
dictionary->SetNextEnumerationIndex(real_size + 1);
2888+
dictionary->set_next_enumeration_index(real_size + 1);
28892889

28902890
// From here on we cannot fail and we shouldn't GC anymore.
28912891
DisallowHeapAllocation no_allocation;

‎deps/v8/src/objects/literal-objects.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ class ObjectDescriptor {
363363

364364
void Finalize(Isolate* isolate) {
365365
if (HasDictionaryProperties()) {
366-
properties_dictionary_template_->SetNextEnumerationIndex(
366+
properties_dictionary_template_->set_next_enumeration_index(
367367
next_enumeration_index_);
368368
computed_properties_ = FixedArray::ShrinkOrEmpty(
369369
isolate, computed_properties_, current_computed_index_);

‎deps/v8/src/objects/lookup.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -634,8 +634,8 @@ void LookupIterator::PrepareTransitionToDataProperty(
634634
transition_ = cell;
635635
// Assign an enumeration index to the property and update
636636
// SetNextEnumerationIndex.
637-
int index = dictionary->NextEnumerationIndex();
638-
dictionary->SetNextEnumerationIndex(index + 1);
637+
int index = GlobalDictionary::NextEnumerationIndex(isolate_, dictionary);
638+
dictionary->set_next_enumeration_index(index + 1);
639639
property_details_ = PropertyDetails(
640640
kData, attributes, PropertyCellType::kUninitialized, index);
641641
PropertyCellType new_type =

‎deps/v8/src/objects/objects.cc

+24-22
Original file line numberDiff line numberDiff line change
@@ -6663,7 +6663,7 @@ void StringTable::EnsureCapacityForDeserialization(Isolate* isolate,
66636663
int expected) {
66646664
Handle<StringTable> table = isolate->factory()->string_table();
66656665
// We need a key instance for the virtual hash function.
6666-
table = StringTable::EnsureCapacity(isolate, table, expected);
6666+
table = EnsureCapacity(isolate, table, expected);
66676667
isolate->heap()->SetRootStringTable(*table);
66686668
}
66696669

@@ -6715,7 +6715,7 @@ Handle<String> StringTable::LookupKey(Isolate* isolate, StringTableKey* key) {
67156715

67166716
table = StringTable::CautiousShrink(isolate, table);
67176717
// Adding new string. Grow table if needed.
6718-
table = StringTable::EnsureCapacity(isolate, table, 1);
6718+
table = EnsureCapacity(isolate, table);
67196719
isolate->heap()->SetRootStringTable(*table);
67206720

67216721
return AddKeyNoResize(isolate, key);
@@ -6856,7 +6856,7 @@ Handle<StringSet> StringSet::New(Isolate* isolate) {
68566856
Handle<StringSet> StringSet::Add(Isolate* isolate, Handle<StringSet> stringset,
68576857
Handle<String> name) {
68586858
if (!stringset->Has(isolate, name)) {
6859-
stringset = EnsureCapacity(isolate, stringset, 1);
6859+
stringset = EnsureCapacity(isolate, stringset);
68606860
uint32_t hash = ShapeT::Hash(isolate, *name);
68616861
int entry = stringset->FindInsertionEntry(hash);
68626862
stringset->set(EntryToIndex(entry), *name);
@@ -6874,7 +6874,7 @@ Handle<ObjectHashSet> ObjectHashSet::Add(Isolate* isolate,
68746874
Handle<Object> key) {
68756875
int32_t hash = key->GetOrCreateHash(isolate).value();
68766876
if (!set->Has(isolate, key, hash)) {
6877-
set = EnsureCapacity(isolate, set, 1);
6877+
set = EnsureCapacity(isolate, set);
68786878
int entry = set->FindInsertionEntry(hash);
68796879
set->set(EntryToIndex(entry), *key);
68806880
set->ElementAdded();
@@ -7070,7 +7070,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
70707070
src = String::Flatten(isolate, src);
70717071
StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
70727072
Handle<Object> k = key.AsHandle(isolate);
7073-
cache = EnsureCapacity(isolate, cache, 1);
7073+
cache = EnsureCapacity(isolate, cache);
70747074
int entry = cache->FindInsertionEntry(key.Hash());
70757075
cache->set(EntryToIndex(entry), *k);
70767076
cache->set(EntryToIndex(entry) + 1, *value);
@@ -7102,7 +7102,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
71027102
}
71037103
}
71047104

7105-
cache = EnsureCapacity(isolate, cache, 1);
7105+
cache = EnsureCapacity(isolate, cache);
71067106
int entry = cache->FindInsertionEntry(key.Hash());
71077107
Handle<Object> k =
71087108
isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
@@ -7116,7 +7116,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
71167116
Isolate* isolate, Handle<CompilationCacheTable> cache, Handle<String> src,
71177117
JSRegExp::Flags flags, Handle<FixedArray> value) {
71187118
RegExpKey key(src, flags);
7119-
cache = EnsureCapacity(isolate, cache, 1);
7119+
cache = EnsureCapacity(isolate, cache);
71207120
int entry = cache->FindInsertionEntry(key.Hash());
71217121
// We store the value in the key slot, and compare the search key
71227122
// to the stored value with a custon IsMatch function during lookups.
@@ -7178,15 +7178,16 @@ Handle<Derived> BaseNameDictionary<Derived, Shape>::New(
71787178
Handle<Derived> dict = Dictionary<Derived, Shape>::New(
71797179
isolate, at_least_space_for, allocation, capacity_option);
71807180
dict->SetHash(PropertyArray::kNoHashSentinel);
7181-
dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
7181+
dict->set_next_enumeration_index(PropertyDetails::kInitialIndex);
71827182
return dict;
71837183
}
71847184

71857185
template <typename Derived, typename Shape>
7186-
Handle<Derived> BaseNameDictionary<Derived, Shape>::EnsureCapacity(
7187-
Isolate* isolate, Handle<Derived> dictionary, int n) {
7188-
// Check whether there are enough enumeration indices to add n elements.
7189-
if (!PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
7186+
int BaseNameDictionary<Derived, Shape>::NextEnumerationIndex(
7187+
Isolate* isolate, Handle<Derived> dictionary) {
7188+
int index = dictionary->next_enumeration_index();
7189+
// Check whether the next enumeration index is valid.
7190+
if (!PropertyDetails::IsValidIndex(index)) {
71907191
// If not, we generate new indices for the properties.
71917192
int length = dictionary->NumberOfElements();
71927193

@@ -7207,11 +7208,12 @@ Handle<Derived> BaseNameDictionary<Derived, Shape>::EnsureCapacity(
72077208
dictionary->DetailsAtPut(isolate, index, new_details);
72087209
}
72097210

7210-
// Set the next enumeration index.
7211-
dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex +
7212-
length);
7211+
index = PropertyDetails::kInitialIndex + length;
72137212
}
7214-
return HashTable<Derived, Shape>::EnsureCapacity(isolate, dictionary, n);
7213+
7214+
// Don't update the next enumeration index here, since we might be looking at
7215+
// an immutable empty dictionary.
7216+
return index;
72157217
}
72167218

72177219
template <typename Derived, typename Shape>
@@ -7260,13 +7262,13 @@ Handle<Derived> BaseNameDictionary<Derived, Shape>::Add(
72607262
DCHECK_EQ(0, details.dictionary_index());
72617263
// Assign an enumeration index to the property and update
72627264
// SetNextEnumerationIndex.
7263-
int index = dictionary->NextEnumerationIndex();
7265+
int index = Derived::NextEnumerationIndex(isolate, dictionary);
72647266
details = details.set_index(index);
72657267
dictionary = AddNoUpdateNextEnumerationIndex(isolate, dictionary, key, value,
72667268
details, entry_out);
72677269
// Update enumeration index here in order to avoid potential modification of
72687270
// the canonical empty dictionary which lives in read only space.
7269-
dictionary->SetNextEnumerationIndex(index + 1);
7271+
dictionary->set_next_enumeration_index(index + 1);
72707272
return dictionary;
72717273
}
72727274

@@ -7280,7 +7282,7 @@ Handle<Derived> Dictionary<Derived, Shape>::Add(Isolate* isolate,
72807282
// Valdate key is absent.
72817283
SLOW_DCHECK((dictionary->FindEntry(isolate, key) == Dictionary::kNotFound));
72827284
// Check whether the dictionary should be extended.
7283-
dictionary = Derived::EnsureCapacity(isolate, dictionary, 1);
7285+
dictionary = Derived::EnsureCapacity(isolate, dictionary);
72847286

72857287
// Compute the key object.
72867288
Handle<Object> k = Shape::AsHandle(isolate, key);
@@ -7625,7 +7627,7 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
76257627
}
76267628

76277629
// Check whether the hash table should be extended.
7628-
table = Derived::EnsureCapacity(isolate, table, 1);
7630+
table = Derived::EnsureCapacity(isolate, table);
76297631
table->AddEntry(table->FindInsertionEntry(hash), *key, *value);
76307632
return table;
76317633
}
@@ -7873,8 +7875,8 @@ Handle<PropertyCell> PropertyCell::PrepareForValue(
78737875
// Preserve the enumeration index unless the property was deleted or never
78747876
// initialized.
78757877
if (cell->value().IsTheHole(isolate)) {
7876-
index = dictionary->NextEnumerationIndex();
7877-
dictionary->SetNextEnumerationIndex(index + 1);
7878+
index = GlobalDictionary::NextEnumerationIndex(isolate, dictionary);
7879+
dictionary->set_next_enumeration_index(index + 1);
78787880
} else {
78797881
index = original_details.dictionary_index();
78807882
}

0 commit comments

Comments
 (0)
Please sign in to comment.