Commit 238dff26 authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[hashtable] Move FindOrderedHashTableEntry to CSA

... from BaseCollectionsAssembler

Bug: v8:7569
Change-Id: I938257b18372bbe8a43af3f25c85d192950be8fa
Reviewed-on: https://chromium-review.googlesource.com/1026053
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52766}
parent cec16302
......@@ -643,22 +643,6 @@ class CollectionsBuiltinsAssembler : public BaseCollectionsAssembler {
std::tuple<Node*, Node*, Node*> NextSkipHoles(Node* table, Node* index,
Label* if_end);
// Builds code that finds OrderedHashTable entry for a key with hash code
// {hash} with using the comparison code generated by {key_compare}. The code
// jumps to {entry_found} if the key is found, or to {not_found} if the key
// was not found. In the {entry_found} branch, the variable
// entry_start_position will be bound to the index of the entry (relative to
// OrderedHashTable::kHashTableStartIndex).
//
// The {CollectionType} template parameter stands for the particular instance
// of OrderedHashTable, it should be OrderedHashMap or OrderedHashSet.
template <typename CollectionType>
void FindOrderedHashTableEntry(
Node* table, Node* hash,
std::function<void(Node* other, Label* if_same, Label* if_not_same)>
key_compare,
Variable* entry_start_position, Label* entry_found, Label* not_found);
// Specialization for Smi.
// The {result} variable will contain the entry index if the key was found,
// or the hash code otherwise.
......@@ -998,73 +982,6 @@ void CollectionsBuiltinsAssembler::SameValueZeroHeapNumber(Node* key_float,
}
}
template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntry(
Node* table, Node* hash,
std::function<void(Node*, Label*, Label*)> key_compare,
Variable* entry_start_position, Label* entry_found, Label* not_found) {
// Get the index of the bucket.
Node* const number_of_buckets = SmiUntag(CAST(
LoadFixedArrayElement(table, CollectionType::kNumberOfBucketsIndex)));
Node* const bucket =
WordAnd(hash, IntPtrSub(number_of_buckets, IntPtrConstant(1)));
Node* const first_entry = SmiUntag(CAST(LoadFixedArrayElement(
table, bucket, CollectionType::kHashTableStartIndex * kPointerSize)));
// Walk the bucket chain.
Node* entry_start;
Label if_key_found(this);
{
VARIABLE(var_entry, MachineType::PointerRepresentation(), first_entry);
Label loop(this, {&var_entry, entry_start_position}),
continue_next_entry(this);
Goto(&loop);
BIND(&loop);
// If the entry index is the not-found sentinel, we are done.
GotoIf(
WordEqual(var_entry.value(), IntPtrConstant(CollectionType::kNotFound)),
not_found);
// Make sure the entry index is within range.
CSA_ASSERT(
this,
UintPtrLessThan(
var_entry.value(),
SmiUntag(SmiAdd(
CAST(LoadFixedArrayElement(
table, CollectionType::kNumberOfElementsIndex)),
CAST(LoadFixedArrayElement(
table, CollectionType::kNumberOfDeletedElementsIndex))))));
// Compute the index of the entry relative to kHashTableStartIndex.
entry_start =
IntPtrAdd(IntPtrMul(var_entry.value(),
IntPtrConstant(CollectionType::kEntrySize)),
number_of_buckets);
// Load the key from the entry.
Node* const candidate_key = LoadFixedArrayElement(
table, entry_start,
CollectionType::kHashTableStartIndex * kPointerSize);
key_compare(candidate_key, &if_key_found, &continue_next_entry);
BIND(&continue_next_entry);
// Load the index of the next entry in the bucket chain.
var_entry.Bind(SmiUntag(CAST(LoadFixedArrayElement(
table, entry_start,
(CollectionType::kHashTableStartIndex + CollectionType::kChainOffset) *
kPointerSize))));
Goto(&loop);
}
BIND(&if_key_found);
entry_start_position->Bind(entry_start);
Goto(entry_found);
}
TF_BUILTIN(OrderedHashTableHealIndex, CollectionsBuiltinsAssembler) {
Node* table = Parameter(Descriptor::kTable);
Node* index = Parameter(Descriptor::kIndex);
......
......@@ -3008,6 +3008,82 @@ Node* CodeStubAssembler::AllocateOrderedHashTable() {
template Node* CodeStubAssembler::AllocateOrderedHashTable<OrderedHashMap>();
template Node* CodeStubAssembler::AllocateOrderedHashTable<OrderedHashSet>();
template <typename CollectionType>
void CodeStubAssembler::FindOrderedHashTableEntry(
Node* table, Node* hash,
std::function<void(Node*, Label*, Label*)> key_compare,
Variable* entry_start_position, Label* entry_found, Label* not_found) {
// Get the index of the bucket.
Node* const number_of_buckets = SmiUntag(CAST(
LoadFixedArrayElement(table, CollectionType::kNumberOfBucketsIndex)));
Node* const bucket =
WordAnd(hash, IntPtrSub(number_of_buckets, IntPtrConstant(1)));
Node* const first_entry = SmiUntag(CAST(LoadFixedArrayElement(
table, bucket, CollectionType::kHashTableStartIndex * kPointerSize)));
// Walk the bucket chain.
Node* entry_start;
Label if_key_found(this);
{
VARIABLE(var_entry, MachineType::PointerRepresentation(), first_entry);
Label loop(this, {&var_entry, entry_start_position}),
continue_next_entry(this);
Goto(&loop);
BIND(&loop);
// If the entry index is the not-found sentinel, we are done.
GotoIf(
WordEqual(var_entry.value(), IntPtrConstant(CollectionType::kNotFound)),
not_found);
// Make sure the entry index is within range.
CSA_ASSERT(
this,
UintPtrLessThan(
var_entry.value(),
SmiUntag(SmiAdd(
CAST(LoadFixedArrayElement(
table, CollectionType::kNumberOfElementsIndex)),
CAST(LoadFixedArrayElement(
table, CollectionType::kNumberOfDeletedElementsIndex))))));
// Compute the index of the entry relative to kHashTableStartIndex.
entry_start =
IntPtrAdd(IntPtrMul(var_entry.value(),
IntPtrConstant(CollectionType::kEntrySize)),
number_of_buckets);
// Load the key from the entry.
Node* const candidate_key = LoadFixedArrayElement(
table, entry_start,
CollectionType::kHashTableStartIndex * kPointerSize);
key_compare(candidate_key, &if_key_found, &continue_next_entry);
BIND(&continue_next_entry);
// Load the index of the next entry in the bucket chain.
var_entry.Bind(SmiUntag(CAST(LoadFixedArrayElement(
table, entry_start,
(CollectionType::kHashTableStartIndex + CollectionType::kChainOffset) *
kPointerSize))));
Goto(&loop);
}
BIND(&if_key_found);
entry_start_position->Bind(entry_start);
Goto(entry_found);
}
template void CodeStubAssembler::FindOrderedHashTableEntry<OrderedHashMap>(
Node* table, Node* hash,
std::function<void(Node*, Label*, Label*)> key_compare,
Variable* entry_start_position, Label* entry_found, Label* not_found);
template void CodeStubAssembler::FindOrderedHashTableEntry<OrderedHashSet>(
Node* table, Node* hash,
std::function<void(Node*, Label*, Label*)> key_compare,
Variable* entry_start_position, Label* entry_found, Label* not_found);
Node* CodeStubAssembler::AllocateStruct(Node* map, AllocationFlags flags) {
Comment("AllocateStruct");
CSA_ASSERT(this, IsMap(map));
......
......@@ -952,6 +952,21 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
template <typename CollectionType>
Node* AllocateOrderedHashTable();
// Builds code that finds OrderedHashTable entry for a key with hash code
// {hash} with using the comparison code generated by {key_compare}. The code
// jumps to {entry_found} if the key is found, or to {not_found} if the key
// was not found. In the {entry_found} branch, the variable
// entry_start_position will be bound to the index of the entry (relative to
// OrderedHashTable::kHashTableStartIndex).
//
// The {CollectionType} template parameter stands for the particular instance
// of OrderedHashTable, it should be OrderedHashMap or OrderedHashSet.
template <typename CollectionType>
void FindOrderedHashTableEntry(
Node* table, Node* hash,
std::function<void(Node*, Label*, Label*)> key_compare,
Variable* entry_start_position, Label* entry_found, Label* not_found);
Node* AllocateStruct(Node* map, AllocationFlags flags = kNone);
void InitializeStructBody(Node* object, Node* map, Node* size,
int start_offset = Struct::kHeaderSize);
......
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