Skip to content

Commit

Permalink
deps: V8: cherry-pick 1a7d55a9a427
Browse files Browse the repository at this point in the history
Original commit message:

    Merged: [runtime] Fix sorted order of DescriptorArray entries

    Revision: 518d67ad652fc24b7eb03e48bb342f952d4ccf74

    This is a reland of the previous merge which addresses the cctest link
    failure in component build mode.

    BUG=chromium:1133527
    NOTRY=true
    NOPRESUBMIT=true
    NOTREECHECKS=true
    R=verwaest@chromium.org

    Change-Id: Icbbc69fd5403fd0c2ab6d07d4340292b2b8c72b9
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2504264
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Cr-Commit-Position: refs/branch-heads/8.6@{#40}
    Cr-Branched-From: a64aed2333abf49e494d2a5ce24bbd14fff19f60-refs/heads/8.6.395@{#1}
    Cr-Branched-From: a626bc036236c9bf92ac7b87dc40c9e538b087e3-refs/heads/master@{#69472}

Refs: v8/v8@1a7d55a

PR-URL: #38275
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Shelley Vohr <codebytere@gmail.com>
  • Loading branch information
targos committed Apr 30, 2021
1 parent 7dd68ac commit c5fe3a2
Show file tree
Hide file tree
Showing 16 changed files with 490 additions and 38 deletions.
2 changes: 1 addition & 1 deletion common.gypi
Expand Up @@ -36,7 +36,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.52',
'v8_embedder_string': '-node.53',

##### V8 defaults for Node.js #####

Expand Down
19 changes: 10 additions & 9 deletions deps/v8/src/codegen/code-stub-assembler.cc
Expand Up @@ -1801,12 +1801,13 @@ TNode<IntPtrT> CodeStubAssembler::LoadJSReceiverIdentityHash(
return var_hash.value();
}

TNode<Uint32T> CodeStubAssembler::LoadNameHashField(SloppyTNode<Name> name) {
CSA_ASSERT(this, IsName(name));
return LoadObjectField<Uint32T>(name, Name::kHashFieldOffset);
TNode<Uint32T> CodeStubAssembler::LoadNameHashAssumeComputed(TNode<Name> name) {
TNode<Uint32T> hash_field = LoadNameHashField(name);
CSA_ASSERT(this, IsClearWord32(hash_field, Name::kHashNotComputedMask));
return Unsigned(Word32Shr(hash_field, Int32Constant(Name::kHashShift)));
}

TNode<Uint32T> CodeStubAssembler::LoadNameHash(SloppyTNode<Name> name,
TNode<Uint32T> CodeStubAssembler::LoadNameHash(TNode<Name> name,
Label* if_hash_not_computed) {
TNode<Uint32T> hash_field = LoadNameHashField(name);
if (if_hash_not_computed != nullptr) {
Expand Down Expand Up @@ -1994,13 +1995,13 @@ TNode<T> CodeStubAssembler::LoadArrayElement(TNode<Array> array,
}
}

template TNode<MaybeObject>
template V8_EXPORT_PRIVATE TNode<MaybeObject>
CodeStubAssembler::LoadArrayElement<TransitionArray>(TNode<TransitionArray>,
int, Node*, int,
ParameterMode,
LoadSensitivity);

template TNode<MaybeObject>
template V8_EXPORT_PRIVATE TNode<MaybeObject>
CodeStubAssembler::LoadArrayElement<DescriptorArray>(TNode<DescriptorArray>,
int, Node*, int,
ParameterMode,
Expand Down Expand Up @@ -8063,7 +8064,7 @@ void CodeStubAssembler::LookupBinary(TNode<Name> unique_name,
TNode<Uint32T> limit =
Unsigned(Int32Sub(NumberOfEntries<Array>(array), Int32Constant(1)));
TVARIABLE(Uint32T, var_high, limit);
TNode<Uint32T> hash = LoadNameHashField(unique_name);
TNode<Uint32T> hash = LoadNameHashAssumeComputed(unique_name);
CSA_ASSERT(this, Word32NotEqual(hash, Int32Constant(0)));

// Assume non-empty array.
Expand All @@ -8081,7 +8082,7 @@ void CodeStubAssembler::LookupBinary(TNode<Name> unique_name,
TNode<Uint32T> sorted_key_index = GetSortedKeyIndex<Array>(array, mid);
TNode<Name> mid_name = GetKey<Array>(array, sorted_key_index);

TNode<Uint32T> mid_hash = LoadNameHashField(mid_name);
TNode<Uint32T> mid_hash = LoadNameHashAssumeComputed(mid_name);

Label mid_greater(this), mid_less(this), merge(this);
Branch(Uint32GreaterThanOrEqual(mid_hash, hash), &mid_greater, &mid_less);
Expand All @@ -8108,7 +8109,7 @@ void CodeStubAssembler::LookupBinary(TNode<Name> unique_name,
TNode<Uint32T> sort_index =
GetSortedKeyIndex<Array>(array, var_low.value());
TNode<Name> current_name = GetKey<Array>(array, sort_index);
TNode<Uint32T> current_hash = LoadNameHashField(current_name);
TNode<Uint32T> current_hash = LoadNameHashAssumeComputed(current_name);
GotoIf(Word32NotEqual(current_hash, hash), if_not_found);
Label next(this);
GotoIf(TaggedNotEqual(current_name, unique_name), &next);
Expand Down
7 changes: 3 additions & 4 deletions deps/v8/src/codegen/code-stub-assembler.h
Expand Up @@ -1353,13 +1353,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// Check if the map is set for slow properties.
TNode<BoolT> IsDictionaryMap(SloppyTNode<Map> map);

// Load the hash field of a name as an uint32 value.
TNode<Uint32T> LoadNameHashField(SloppyTNode<Name> name);
// Load the hash value of a name as an uint32 value.
// Load the Name::hash() value of a name as an uint32 value.
// If {if_hash_not_computed} label is specified then it also checks if
// hash is actually computed.
TNode<Uint32T> LoadNameHash(SloppyTNode<Name> name,
TNode<Uint32T> LoadNameHash(TNode<Name> name,
Label* if_hash_not_computed = nullptr);
TNode<Uint32T> LoadNameHashAssumeComputed(TNode<Name> name);

// Load length field of a String object as Smi value.
TNode<Smi> LoadStringLengthAsSmi(TNode<String> string);
Expand Down
6 changes: 4 additions & 2 deletions deps/v8/src/diagnostics/objects-debug.cc
Expand Up @@ -1667,12 +1667,13 @@ bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
uint32_t current = 0;
for (int i = 0; i < number_of_descriptors(); i++) {
Name key = GetSortedKey(i);
CHECK(key.HasHashCode());
if (key == current_key) {
Print();
return false;
}
current_key = key;
uint32_t hash = GetSortedKey(i).Hash();
uint32_t hash = key.hash();
if (hash < current) {
Print();
return false;
Expand All @@ -1691,7 +1692,8 @@ bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {

for (int i = 0; i < number_of_transitions(); i++) {
Name key = GetSortedKey(i);
uint32_t hash = key.Hash();
CHECK(key.HasHashCode());
uint32_t hash = key.hash();
PropertyKind kind = kData;
PropertyAttributes attributes = NONE;
if (!TransitionsAccessor::IsSpecialTransition(key.GetReadOnlyRoots(),
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/objects/descriptor-array-inl.h
Expand Up @@ -226,7 +226,7 @@ void DescriptorArray::Append(Descriptor* desc) {

for (insertion = descriptor_number; insertion > 0; --insertion) {
Name key = GetSortedKey(insertion - 1);
if (key.Hash() <= hash) break;
if (key.hash() <= hash) break;
SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
}

Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/objects/descriptor-array.h
Expand Up @@ -113,7 +113,7 @@ class DescriptorArray
int slack = 0);

// Sort the instance descriptors by the hash codes of their keys.
void Sort();
V8_EXPORT_PRIVATE void Sort();

// Search the instance descriptors for given name.
V8_INLINE InternalIndex Search(Name name, int number_of_own_descriptors);
Expand Down
10 changes: 5 additions & 5 deletions deps/v8/src/objects/fixed-array-inl.h
Expand Up @@ -212,15 +212,15 @@ int BinarySearch(T* array, Name name, int valid_entries,
DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == nullptr);
int low = 0;
int high = array->number_of_entries() - 1;
uint32_t hash = name.hash_field();
uint32_t hash = name.hash();
int limit = high;

DCHECK(low <= high);

while (low != high) {
int mid = low + (high - low) / 2;
Name mid_name = array->GetSortedKey(mid);
uint32_t mid_hash = mid_name.hash_field();
uint32_t mid_hash = mid_name.hash();

if (mid_hash >= hash) {
high = mid;
Expand All @@ -232,7 +232,7 @@ int BinarySearch(T* array, Name name, int valid_entries,
for (; low <= limit; ++low) {
int sort_index = array->GetSortedKeyIndex(low);
Name entry = array->GetKey(InternalIndex(sort_index));
uint32_t current_hash = entry.hash_field();
uint32_t current_hash = entry.hash();
if (current_hash != hash) {
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
*out_insertion_index = sort_index + (current_hash > hash ? 0 : 1);
Expand All @@ -259,12 +259,12 @@ template <SearchMode search_mode, typename T>
int LinearSearch(T* array, Name name, int valid_entries,
int* out_insertion_index) {
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
uint32_t hash = name.hash_field();
uint32_t hash = name.hash();
int len = array->number_of_entries();
for (int number = 0; number < len; number++) {
int sorted_index = array->GetSortedKeyIndex(number);
Name entry = array->GetKey(InternalIndex(sorted_index));
uint32_t current_hash = entry.hash_field();
uint32_t current_hash = entry.hash();
if (current_hash > hash) {
*out_insertion_index = sorted_index;
return T::kNotFound;
Expand Down
6 changes: 6 additions & 0 deletions deps/v8/src/objects/name-inl.h
Expand Up @@ -94,6 +94,12 @@ uint32_t Name::Hash() {
return String::cast(*this).ComputeAndSetHash();
}

uint32_t Name::hash() const {
uint32_t field = hash_field();
DCHECK(IsHashFieldComputed(field));
return field >> kHashShift;
}

DEF_GETTER(Name, IsInterestingSymbol, bool) {
return IsSymbol(isolate) && Symbol::cast(*this).is_interesting_symbol();
}
Expand Down
8 changes: 7 additions & 1 deletion deps/v8/src/objects/name.h
Expand Up @@ -23,9 +23,15 @@ class Name : public TorqueGeneratedName<Name, PrimitiveHeapObject> {
// Tells whether the hash code has been computed.
inline bool HasHashCode();

// Returns a hash value used for the property table
// Returns a hash value used for the property table. Ensures that the hash
// value is computed.
// TODO(ishell): rename to EnsureHash().
inline uint32_t Hash();

// Returns a hash value used for the property table (same as Hash()), assumes
// the hash is already computed.
inline uint32_t hash() const;

// Equality operations.
inline bool Equals(Name other);
inline static bool Equals(Isolate* isolate, Handle<Name> one,
Expand Down
14 changes: 7 additions & 7 deletions deps/v8/src/objects/objects.cc
Expand Up @@ -4355,16 +4355,16 @@ void DescriptorArray::Sort() {
// Reset sorting since the descriptor array might contain invalid pointers.
for (int i = 0; i < len; ++i) SetSortedKey(i, i);
// Bottom-up max-heap construction.
// Index of the last node with children
// Index of the last node with children.
const int max_parent_index = (len / 2) - 1;
for (int i = max_parent_index; i >= 0; --i) {
int parent_index = i;
const uint32_t parent_hash = GetSortedKey(i).Hash();
const uint32_t parent_hash = GetSortedKey(i).hash();
while (parent_index <= max_parent_index) {
int child_index = 2 * parent_index + 1;
uint32_t child_hash = GetSortedKey(child_index).Hash();
uint32_t child_hash = GetSortedKey(child_index).hash();
if (child_index + 1 < len) {
uint32_t right_child_hash = GetSortedKey(child_index + 1).Hash();
uint32_t right_child_hash = GetSortedKey(child_index + 1).hash();
if (right_child_hash > child_hash) {
child_index++;
child_hash = right_child_hash;
Expand All @@ -4383,13 +4383,13 @@ void DescriptorArray::Sort() {
SwapSortedKeys(0, i);
// Shift down the new top element.
int parent_index = 0;
const uint32_t parent_hash = GetSortedKey(parent_index).Hash();
const uint32_t parent_hash = GetSortedKey(parent_index).hash();
const int max_parent_index = (i / 2) - 1;
while (parent_index <= max_parent_index) {
int child_index = parent_index * 2 + 1;
uint32_t child_hash = GetSortedKey(child_index).Hash();
uint32_t child_hash = GetSortedKey(child_index).hash();
if (child_index + 1 < i) {
uint32_t right_child_hash = GetSortedKey(child_index + 1).Hash();
uint32_t right_child_hash = GetSortedKey(child_index + 1).hash();
if (right_child_hash > child_hash) {
child_index++;
child_hash = right_child_hash;
Expand Down
8 changes: 8 additions & 0 deletions deps/v8/src/objects/transitions-inl.h
Expand Up @@ -169,12 +169,20 @@ int TransitionArray::SearchNameForTesting(Name name, int* out_insertion_index) {
return SearchName(name, out_insertion_index);
}

Map TransitionArray::SearchAndGetTargetForTesting(
PropertyKind kind, Name name, PropertyAttributes attributes) {
return SearchAndGetTarget(kind, name, attributes);
}

int TransitionArray::SearchSpecial(Symbol symbol, int* out_insertion_index) {
return SearchName(symbol, out_insertion_index);
}

int TransitionArray::SearchName(Name name, int* out_insertion_index) {
DCHECK(name.IsUniqueName());
// The name is taken from DescriptorArray, so it must already has a computed
// hash.
DCHECK(name.HasHashCode());
return internal::Search<ALL_ENTRIES>(this, name, number_of_entries(),
out_insertion_index);
}
Expand Down
4 changes: 2 additions & 2 deletions deps/v8/src/objects/transitions.cc
Expand Up @@ -619,8 +619,8 @@ void TransitionArray::Sort() {
temp_kind = details.kind();
temp_attributes = details.attributes();
}
int cmp = CompareKeys(temp_key, temp_key.Hash(), temp_kind,
temp_attributes, key, key.Hash(), kind, attributes);
int cmp = CompareKeys(temp_key, temp_key.hash(), temp_kind,
temp_attributes, key, key.hash(), kind, attributes);
if (cmp > 0) {
SetKey(j + 1, temp_key);
SetRawTarget(j + 1, temp_target);
Expand Down
13 changes: 8 additions & 5 deletions deps/v8/src/objects/transitions.h
Expand Up @@ -143,6 +143,8 @@ class V8_EXPORT_PRIVATE TransitionsAccessor {
return encoding_;
}

inline TransitionArray transitions();

private:
friend class MarkCompactCollector; // For HasSimpleTransitionTo.
friend class TransitionArray;
Expand Down Expand Up @@ -175,8 +177,6 @@ class V8_EXPORT_PRIVATE TransitionsAccessor {
void TraverseTransitionTreeInternal(TraverseCallback callback, void* data,
DisallowHeapAllocation* no_gc);

inline TransitionArray transitions();

Isolate* isolate_;
Handle<Map> map_handle_;
Map map_;
Expand Down Expand Up @@ -231,7 +231,7 @@ class TransitionArray : public WeakFixedArray {
V8_EXPORT_PRIVATE bool IsSortedNoDuplicates(int valid_entries = -1);
#endif

void Sort();
V8_EXPORT_PRIVATE void Sort();

void PrintInternal(std::ostream& os);

Expand Down Expand Up @@ -260,6 +260,9 @@ class TransitionArray : public WeakFixedArray {
inline int SearchNameForTesting(Name name,
int* out_insertion_index = nullptr);

inline Map SearchAndGetTargetForTesting(PropertyKind kind, Name name,
PropertyAttributes attributes);

private:
friend class Factory;
friend class MarkCompactCollector;
Expand Down Expand Up @@ -296,8 +299,8 @@ class TransitionArray : public WeakFixedArray {
int Search(PropertyKind kind, Name name, PropertyAttributes attributes,
int* out_insertion_index = nullptr);

Map SearchAndGetTarget(PropertyKind kind, Name name,
PropertyAttributes attributes);
V8_EXPORT_PRIVATE Map SearchAndGetTarget(PropertyKind kind, Name name,
PropertyAttributes attributes);

// Search a non-property transition (like elements kind, observe or frozen
// transitions).
Expand Down
1 change: 1 addition & 0 deletions deps/v8/test/cctest/BUILD.gn
Expand Up @@ -204,6 +204,7 @@ v8_source_set("cctest_sources") {
"test-debug.cc",
"test-decls.cc",
"test-deoptimization.cc",
"test-descriptor-array.cc",
"test-dictionary.cc",
"test-diy-fp.cc",
"test-double.cc",
Expand Down

0 comments on commit c5fe3a2

Please sign in to comment.