Commit 26e835b1 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[builtins] CSA version of Set.prototype.has.

Change-Id: Ie59254ff0790a2db70c1f620f287f8de6387ad23
Bug: v8:5717
Reviewed-on: https://chromium-review.googlesource.com/573543Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46691}
parent 8089fb98
......@@ -46,49 +46,59 @@ class CollectionsBuiltinsAssembler : public CodeStubAssembler {
std::tuple<Node*, Node*, Node*> NextSkipHoles(Node* table, Node* index,
Label* if_end);
// Builds code that finds OrderedHashMap entry for a key with hash code
// 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
// OrderedHashMap::kHashTableStartIndex).
void FindOrderedHashMapEntry(
// 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.
void FindOrderedHashMapEntryForSmiKey(Node* table, Node* key_tagged,
Variable* entry_start_position,
Label* entry_found, Label* not_found);
template <typename CollectionType>
void FindOrderedHashTableEntryForSmiKey(Node* table, Node* key_tagged,
Variable* entry_start_position,
Label* entry_found, Label* not_found);
void SameValueZeroSmi(Node* key_smi, Node* candidate_key, Label* if_same,
Label* if_not_same);
// Specialization for heap numbers.
void SameValueZeroHeapNumber(Node* key_string, Node* candidate_key,
Label* if_same, Label* if_not_same);
void FindOrderedHashMapEntryForHeapNumberKey(Node* context, Node* table,
Node* key_heap_number,
Variable* entry_start_position,
Label* entry_found,
Label* not_found);
template <typename CollectionType>
void FindOrderedHashTableEntryForHeapNumberKey(Node* context, Node* table,
Node* key_heap_number,
Variable* entry_start_position,
Label* entry_found,
Label* not_found);
// Specialization for string.
void FindOrderedHashMapEntryForStringKey(Node* context, Node* table,
Node* key_tagged,
Variable* entry_start_position,
Label* entry_found,
Label* not_found);
template <typename CollectionType>
void FindOrderedHashTableEntryForStringKey(Node* context, Node* table,
Node* key_tagged,
Variable* entry_start_position,
Label* entry_found,
Label* not_found);
Node* ComputeIntegerHashForString(Node* context, Node* string_key);
void SameValueZeroString(Node* context, Node* key_string, Node* candidate_key,
Label* if_same, Label* if_not_same);
// Specialization for non-strings, non-numbers. For those we only need
// reference equality to compare the keys.
void FindOrderedHashMapEntryForOtherKey(Node* context, Node* table, Node* key,
Variable* entry_start_position,
Label* entry_found, Label* not_found);
template <typename CollectionType>
void FindOrderedHashTableEntryForOtherKey(Node* context, Node* table,
Node* key,
Variable* entry_start_position,
Label* entry_found,
Label* not_found);
};
template <typename CollectionType>
......@@ -412,27 +422,6 @@ Node* CollectionsBuiltinsAssembler::CallGetHashRaw(Node* const key) {
return result;
}
template <typename CollectionType, int entrysize>
Node* CollectionsBuiltinsAssembler::CallHasRaw(Node* const table,
Node* const key) {
Node* const function_addr = ExternalConstant(
ExternalReference::orderedhashtable_has_raw<CollectionType, entrysize>(
isolate()));
Node* const isolate_ptr =
ExternalConstant(ExternalReference::isolate_address(isolate()));
MachineType type_uint8 = MachineType::Uint8();
MachineType type_ptr = MachineType::Pointer();
MachineType type_tagged = MachineType::AnyTagged();
Node* const result =
CallCFunction3(type_uint8, type_ptr, type_tagged, type_tagged,
function_addr, isolate_ptr, table, key);
return SelectBooleanConstant(
Word32NotEqual(Word32And(result, Int32Constant(0xFF)), Int32Constant(0)));
}
void CollectionsBuiltinsAssembler::SameValueZeroSmi(Node* key_smi,
Node* candidate_key,
Label* if_same,
......@@ -456,13 +445,14 @@ void CollectionsBuiltinsAssembler::SameValueZeroSmi(Node* key_smi,
Goto(if_not_same);
}
void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForSmiKey(
template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForSmiKey(
Node* table, Node* smi_key, Variable* entry_start_position,
Label* entry_found, Label* not_found) {
Node* const key_untagged = SmiUntag(smi_key);
Node* const hash =
ChangeInt32ToIntPtr(ComputeIntegerHash(key_untagged, Int32Constant(0)));
FindOrderedHashMapEntry(
FindOrderedHashTableEntry<CollectionType>(
table, hash,
[&](Node* other_key, Label* if_same, Label* if_not_same) {
SameValueZeroSmi(smi_key, other_key, if_same, if_not_same);
......@@ -470,11 +460,12 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForSmiKey(
entry_start_position, entry_found, not_found);
}
void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForStringKey(
template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForStringKey(
Node* context, Node* table, Node* key_tagged,
Variable* entry_start_position, Label* entry_found, Label* not_found) {
Node* const hash = ComputeIntegerHashForString(context, key_tagged);
FindOrderedHashMapEntry(
FindOrderedHashTableEntry<CollectionType>(
table, hash,
[&](Node* other_key, Label* if_same, Label* if_not_same) {
SameValueZeroString(context, key_tagged, other_key, if_same,
......@@ -483,13 +474,14 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForStringKey(
entry_start_position, entry_found, not_found);
}
void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForHeapNumberKey(
template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForHeapNumberKey(
Node* context, Node* table, Node* key_heap_number,
Variable* entry_start_position, Label* entry_found, Label* not_found) {
Node* tagged_hash = CallGetHashRaw(key_heap_number);
CSA_ASSERT(this, TaggedIsSmi(tagged_hash));
Node* const key_float = LoadHeapNumberValue(key_heap_number);
FindOrderedHashMapEntry(
FindOrderedHashTableEntry<CollectionType>(
table, SmiUntag(tagged_hash),
[&](Node* other_key, Label* if_same, Label* if_not_same) {
SameValueZeroHeapNumber(key_float, other_key, if_same, if_not_same);
......@@ -497,12 +489,13 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForHeapNumberKey(
entry_start_position, entry_found, not_found);
}
void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForOtherKey(
template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForOtherKey(
Node* context, Node* table, Node* key, Variable* entry_start_position,
Label* entry_found, Label* not_found) {
Node* tagged_hash = CallGetHashRaw(key);
CSA_ASSERT(this, TaggedIsSmi(tagged_hash));
FindOrderedHashMapEntry(
FindOrderedHashTableEntry<CollectionType>(
table, SmiUntag(tagged_hash),
[&](Node* other_key, Label* if_same, Label* if_not_same) {
Branch(WordEqual(key, other_key), if_same, if_not_same);
......@@ -579,17 +572,18 @@ void CollectionsBuiltinsAssembler::SameValueZeroHeapNumber(Node* key_float,
}
}
void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry(
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(
LoadFixedArrayElement(table, OrderedHashMap::kNumberOfBucketsIndex));
LoadFixedArrayElement(table, CollectionType::kNumberOfBucketsIndex));
Node* const bucket =
WordAnd(hash, IntPtrSub(number_of_buckets, IntPtrConstant(1)));
Node* const first_entry = SmiUntag(LoadFixedArrayElement(
table, bucket, OrderedHashMap::kHashTableStartIndex * kPointerSize));
table, bucket, CollectionType::kHashTableStartIndex * kPointerSize));
// Walk the bucket chain.
{
......@@ -601,7 +595,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry(
// If the entry index is the not-found sentinel, we are done.
GotoIf(
WordEqual(var_entry.value(), IntPtrConstant(OrderedHashMap::kNotFound)),
WordEqual(var_entry.value(), IntPtrConstant(CollectionType::kNotFound)),
not_found);
// Make sure the entry index is within range.
......@@ -611,21 +605,21 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry(
var_entry.value(),
SmiUntag(SmiAdd(
LoadFixedArrayElement(table,
OrderedHashMap::kNumberOfElementsIndex),
CollectionType::kNumberOfElementsIndex),
LoadFixedArrayElement(
table, OrderedHashMap::kNumberOfDeletedElementsIndex)))));
table, CollectionType::kNumberOfDeletedElementsIndex)))));
// Compute the index of the entry relative to kHashTableStartIndex.
Node* entry_start =
IntPtrAdd(IntPtrMul(var_entry.value(),
IntPtrConstant(OrderedHashMap::kEntrySize)),
IntPtrConstant(CollectionType::kEntrySize)),
number_of_buckets);
entry_start_position->Bind(entry_start);
// Load the key from the entry.
Node* const candidate_key = LoadFixedArrayElement(
table, entry_start,
OrderedHashMap::kHashTableStartIndex * kPointerSize);
CollectionType::kHashTableStartIndex * kPointerSize);
key_compare(candidate_key, entry_found, &continue_next_entry);
......@@ -633,7 +627,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry(
// Load the index of the next entry in the bucket chain.
var_entry.Bind(SmiUntag(LoadFixedArrayElement(
table, entry_start,
(OrderedHashMap::kHashTableStartIndex + OrderedHashMap::kChainOffset) *
(CollectionType::kHashTableStartIndex + CollectionType::kChainOffset) *
kPointerSize)));
Goto(&loop);
......@@ -992,7 +986,43 @@ TF_BUILTIN(SetHas, CollectionsBuiltinsAssembler) {
ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, "Set.prototype.has");
Node* const table = LoadObjectField(receiver, JSMap::kTableOffset);
Return(CallHasRaw<OrderedHashSet, 1>(table, key));
VARIABLE(entry_start_position, MachineType::PointerRepresentation(),
IntPtrConstant(0));
VARIABLE(result, MachineRepresentation::kTaggedSigned, IntPtrConstant(0));
Label if_key_smi(this), if_key_string(this), if_key_heap_number(this),
entry_found(this), not_found(this), done(this);
GotoIf(TaggedIsSmi(key), &if_key_smi);
GotoIf(IsString(key), &if_key_string);
GotoIf(IsHeapNumber(key), &if_key_heap_number);
FindOrderedHashTableEntryForOtherKey<OrderedHashSet>(
context, table, key, &entry_start_position, &entry_found, &not_found);
BIND(&if_key_smi);
{
FindOrderedHashTableEntryForSmiKey<OrderedHashSet>(
table, key, &entry_start_position, &entry_found, &not_found);
}
BIND(&if_key_string);
{
FindOrderedHashTableEntryForStringKey<OrderedHashSet>(
context, table, key, &entry_start_position, &entry_found, &not_found);
}
BIND(&if_key_heap_number);
{
FindOrderedHashTableEntryForHeapNumberKey<OrderedHashSet>(
context, table, key, &entry_start_position, &entry_found, &not_found);
}
BIND(&entry_found);
Return(TrueConstant());
BIND(&not_found);
Return(FalseConstant());
}
TF_BUILTIN(SetPrototypeEntries, CollectionsBuiltinsAssembler) {
......@@ -1159,24 +1189,24 @@ TF_BUILTIN(MapLookupHashIndex, CollectionsBuiltinsAssembler) {
GotoIf(IsString(key), &if_key_string);
GotoIf(IsHeapNumber(key), &if_key_heap_number);
FindOrderedHashMapEntryForOtherKey(context, table, key, &entry_start_position,
&entry_found, &not_found);
FindOrderedHashTableEntryForOtherKey<OrderedHashMap>(
context, table, key, &entry_start_position, &entry_found, &not_found);
BIND(&if_key_smi);
{
FindOrderedHashMapEntryForSmiKey(table, key, &entry_start_position,
&entry_found, &not_found);
FindOrderedHashTableEntryForSmiKey<OrderedHashMap>(
table, key, &entry_start_position, &entry_found, &not_found);
}
BIND(&if_key_string);
{
FindOrderedHashMapEntryForStringKey(
FindOrderedHashTableEntryForStringKey<OrderedHashMap>(
context, table, key, &entry_start_position, &entry_found, &not_found);
}
BIND(&if_key_heap_number);
{
FindOrderedHashMapEntryForHeapNumberKey(
FindOrderedHashTableEntryForHeapNumberKey<OrderedHashMap>(
context, table, key, &entry_start_position, &entry_found, &not_found);
}
......
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