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 { ...@@ -46,49 +46,59 @@ class CollectionsBuiltinsAssembler : public CodeStubAssembler {
std::tuple<Node*, Node*, Node*> NextSkipHoles(Node* table, Node* index, std::tuple<Node*, Node*, Node*> NextSkipHoles(Node* table, Node* index,
Label* if_end); 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 // {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 // 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 // was not found. In the {entry_found} branch, the variable
// entry_start_position will be bound to the index of the entry (relative to // entry_start_position will be bound to the index of the entry (relative to
// OrderedHashMap::kHashTableStartIndex). // OrderedHashTable::kHashTableStartIndex).
void FindOrderedHashMapEntry( //
// 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, Node* table, Node* hash,
std::function<void(Node* other, Label* if_same, Label* if_not_same)> std::function<void(Node* other, Label* if_same, Label* if_not_same)>
key_compare, key_compare,
Variable* entry_start_position, Label* entry_found, Label* not_found); Variable* entry_start_position, Label* entry_found, Label* not_found);
// Specialization for Smi. // Specialization for Smi.
void FindOrderedHashMapEntryForSmiKey(Node* table, Node* key_tagged, template <typename CollectionType>
Variable* entry_start_position, void FindOrderedHashTableEntryForSmiKey(Node* table, Node* key_tagged,
Label* entry_found, Label* not_found); Variable* entry_start_position,
Label* entry_found, Label* not_found);
void SameValueZeroSmi(Node* key_smi, Node* candidate_key, Label* if_same, void SameValueZeroSmi(Node* key_smi, Node* candidate_key, Label* if_same,
Label* if_not_same); Label* if_not_same);
// Specialization for heap numbers. // Specialization for heap numbers.
void SameValueZeroHeapNumber(Node* key_string, Node* candidate_key, void SameValueZeroHeapNumber(Node* key_string, Node* candidate_key,
Label* if_same, Label* if_not_same); Label* if_same, Label* if_not_same);
void FindOrderedHashMapEntryForHeapNumberKey(Node* context, Node* table, template <typename CollectionType>
Node* key_heap_number, void FindOrderedHashTableEntryForHeapNumberKey(Node* context, Node* table,
Variable* entry_start_position, Node* key_heap_number,
Label* entry_found, Variable* entry_start_position,
Label* not_found); Label* entry_found,
Label* not_found);
// Specialization for string. // Specialization for string.
void FindOrderedHashMapEntryForStringKey(Node* context, Node* table, template <typename CollectionType>
Node* key_tagged, void FindOrderedHashTableEntryForStringKey(Node* context, Node* table,
Variable* entry_start_position, Node* key_tagged,
Label* entry_found, Variable* entry_start_position,
Label* not_found); Label* entry_found,
Label* not_found);
Node* ComputeIntegerHashForString(Node* context, Node* string_key); Node* ComputeIntegerHashForString(Node* context, Node* string_key);
void SameValueZeroString(Node* context, Node* key_string, Node* candidate_key, void SameValueZeroString(Node* context, Node* key_string, Node* candidate_key,
Label* if_same, Label* if_not_same); Label* if_same, Label* if_not_same);
// Specialization for non-strings, non-numbers. For those we only need // Specialization for non-strings, non-numbers. For those we only need
// reference equality to compare the keys. // reference equality to compare the keys.
void FindOrderedHashMapEntryForOtherKey(Node* context, Node* table, Node* key, template <typename CollectionType>
Variable* entry_start_position, void FindOrderedHashTableEntryForOtherKey(Node* context, Node* table,
Label* entry_found, Label* not_found); Node* key,
Variable* entry_start_position,
Label* entry_found,
Label* not_found);
}; };
template <typename CollectionType> template <typename CollectionType>
...@@ -412,27 +422,6 @@ Node* CollectionsBuiltinsAssembler::CallGetHashRaw(Node* const key) { ...@@ -412,27 +422,6 @@ Node* CollectionsBuiltinsAssembler::CallGetHashRaw(Node* const key) {
return result; 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, void CollectionsBuiltinsAssembler::SameValueZeroSmi(Node* key_smi,
Node* candidate_key, Node* candidate_key,
Label* if_same, Label* if_same,
...@@ -456,13 +445,14 @@ void CollectionsBuiltinsAssembler::SameValueZeroSmi(Node* key_smi, ...@@ -456,13 +445,14 @@ void CollectionsBuiltinsAssembler::SameValueZeroSmi(Node* key_smi,
Goto(if_not_same); Goto(if_not_same);
} }
void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForSmiKey( template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForSmiKey(
Node* table, Node* smi_key, Variable* entry_start_position, Node* table, Node* smi_key, Variable* entry_start_position,
Label* entry_found, Label* not_found) { Label* entry_found, Label* not_found) {
Node* const key_untagged = SmiUntag(smi_key); Node* const key_untagged = SmiUntag(smi_key);
Node* const hash = Node* const hash =
ChangeInt32ToIntPtr(ComputeIntegerHash(key_untagged, Int32Constant(0))); ChangeInt32ToIntPtr(ComputeIntegerHash(key_untagged, Int32Constant(0)));
FindOrderedHashMapEntry( FindOrderedHashTableEntry<CollectionType>(
table, hash, table, hash,
[&](Node* other_key, Label* if_same, Label* if_not_same) { [&](Node* other_key, Label* if_same, Label* if_not_same) {
SameValueZeroSmi(smi_key, other_key, if_same, if_not_same); SameValueZeroSmi(smi_key, other_key, if_same, if_not_same);
...@@ -470,11 +460,12 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForSmiKey( ...@@ -470,11 +460,12 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForSmiKey(
entry_start_position, entry_found, not_found); entry_start_position, entry_found, not_found);
} }
void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForStringKey( template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForStringKey(
Node* context, Node* table, Node* key_tagged, Node* context, Node* table, Node* key_tagged,
Variable* entry_start_position, Label* entry_found, Label* not_found) { Variable* entry_start_position, Label* entry_found, Label* not_found) {
Node* const hash = ComputeIntegerHashForString(context, key_tagged); Node* const hash = ComputeIntegerHashForString(context, key_tagged);
FindOrderedHashMapEntry( FindOrderedHashTableEntry<CollectionType>(
table, hash, table, hash,
[&](Node* other_key, Label* if_same, Label* if_not_same) { [&](Node* other_key, Label* if_same, Label* if_not_same) {
SameValueZeroString(context, key_tagged, other_key, if_same, SameValueZeroString(context, key_tagged, other_key, if_same,
...@@ -483,13 +474,14 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForStringKey( ...@@ -483,13 +474,14 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForStringKey(
entry_start_position, entry_found, not_found); entry_start_position, entry_found, not_found);
} }
void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForHeapNumberKey( template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForHeapNumberKey(
Node* context, Node* table, Node* key_heap_number, Node* context, Node* table, Node* key_heap_number,
Variable* entry_start_position, Label* entry_found, Label* not_found) { Variable* entry_start_position, Label* entry_found, Label* not_found) {
Node* tagged_hash = CallGetHashRaw(key_heap_number); Node* tagged_hash = CallGetHashRaw(key_heap_number);
CSA_ASSERT(this, TaggedIsSmi(tagged_hash)); CSA_ASSERT(this, TaggedIsSmi(tagged_hash));
Node* const key_float = LoadHeapNumberValue(key_heap_number); Node* const key_float = LoadHeapNumberValue(key_heap_number);
FindOrderedHashMapEntry( FindOrderedHashTableEntry<CollectionType>(
table, SmiUntag(tagged_hash), table, SmiUntag(tagged_hash),
[&](Node* other_key, Label* if_same, Label* if_not_same) { [&](Node* other_key, Label* if_same, Label* if_not_same) {
SameValueZeroHeapNumber(key_float, other_key, if_same, if_not_same); SameValueZeroHeapNumber(key_float, other_key, if_same, if_not_same);
...@@ -497,12 +489,13 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForHeapNumberKey( ...@@ -497,12 +489,13 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntryForHeapNumberKey(
entry_start_position, entry_found, not_found); 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, Node* context, Node* table, Node* key, Variable* entry_start_position,
Label* entry_found, Label* not_found) { Label* entry_found, Label* not_found) {
Node* tagged_hash = CallGetHashRaw(key); Node* tagged_hash = CallGetHashRaw(key);
CSA_ASSERT(this, TaggedIsSmi(tagged_hash)); CSA_ASSERT(this, TaggedIsSmi(tagged_hash));
FindOrderedHashMapEntry( FindOrderedHashTableEntry<CollectionType>(
table, SmiUntag(tagged_hash), table, SmiUntag(tagged_hash),
[&](Node* other_key, Label* if_same, Label* if_not_same) { [&](Node* other_key, Label* if_same, Label* if_not_same) {
Branch(WordEqual(key, other_key), if_same, if_not_same); Branch(WordEqual(key, other_key), if_same, if_not_same);
...@@ -579,17 +572,18 @@ void CollectionsBuiltinsAssembler::SameValueZeroHeapNumber(Node* key_float, ...@@ -579,17 +572,18 @@ void CollectionsBuiltinsAssembler::SameValueZeroHeapNumber(Node* key_float,
} }
} }
void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry( template <typename CollectionType>
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntry(
Node* table, Node* hash, Node* table, Node* hash,
std::function<void(Node*, Label*, Label*)> key_compare, std::function<void(Node*, Label*, Label*)> key_compare,
Variable* entry_start_position, Label* entry_found, Label* not_found) { Variable* entry_start_position, Label* entry_found, Label* not_found) {
// Get the index of the bucket. // Get the index of the bucket.
Node* const number_of_buckets = SmiUntag( Node* const number_of_buckets = SmiUntag(
LoadFixedArrayElement(table, OrderedHashMap::kNumberOfBucketsIndex)); LoadFixedArrayElement(table, CollectionType::kNumberOfBucketsIndex));
Node* const bucket = Node* const bucket =
WordAnd(hash, IntPtrSub(number_of_buckets, IntPtrConstant(1))); WordAnd(hash, IntPtrSub(number_of_buckets, IntPtrConstant(1)));
Node* const first_entry = SmiUntag(LoadFixedArrayElement( Node* const first_entry = SmiUntag(LoadFixedArrayElement(
table, bucket, OrderedHashMap::kHashTableStartIndex * kPointerSize)); table, bucket, CollectionType::kHashTableStartIndex * kPointerSize));
// Walk the bucket chain. // Walk the bucket chain.
{ {
...@@ -601,7 +595,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry( ...@@ -601,7 +595,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry(
// If the entry index is the not-found sentinel, we are done. // If the entry index is the not-found sentinel, we are done.
GotoIf( GotoIf(
WordEqual(var_entry.value(), IntPtrConstant(OrderedHashMap::kNotFound)), WordEqual(var_entry.value(), IntPtrConstant(CollectionType::kNotFound)),
not_found); not_found);
// Make sure the entry index is within range. // Make sure the entry index is within range.
...@@ -611,21 +605,21 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry( ...@@ -611,21 +605,21 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry(
var_entry.value(), var_entry.value(),
SmiUntag(SmiAdd( SmiUntag(SmiAdd(
LoadFixedArrayElement(table, LoadFixedArrayElement(table,
OrderedHashMap::kNumberOfElementsIndex), CollectionType::kNumberOfElementsIndex),
LoadFixedArrayElement( LoadFixedArrayElement(
table, OrderedHashMap::kNumberOfDeletedElementsIndex))))); table, CollectionType::kNumberOfDeletedElementsIndex)))));
// Compute the index of the entry relative to kHashTableStartIndex. // Compute the index of the entry relative to kHashTableStartIndex.
Node* entry_start = Node* entry_start =
IntPtrAdd(IntPtrMul(var_entry.value(), IntPtrAdd(IntPtrMul(var_entry.value(),
IntPtrConstant(OrderedHashMap::kEntrySize)), IntPtrConstant(CollectionType::kEntrySize)),
number_of_buckets); number_of_buckets);
entry_start_position->Bind(entry_start); entry_start_position->Bind(entry_start);
// Load the key from the entry. // Load the key from the entry.
Node* const candidate_key = LoadFixedArrayElement( Node* const candidate_key = LoadFixedArrayElement(
table, entry_start, table, entry_start,
OrderedHashMap::kHashTableStartIndex * kPointerSize); CollectionType::kHashTableStartIndex * kPointerSize);
key_compare(candidate_key, entry_found, &continue_next_entry); key_compare(candidate_key, entry_found, &continue_next_entry);
...@@ -633,7 +627,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry( ...@@ -633,7 +627,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry(
// Load the index of the next entry in the bucket chain. // Load the index of the next entry in the bucket chain.
var_entry.Bind(SmiUntag(LoadFixedArrayElement( var_entry.Bind(SmiUntag(LoadFixedArrayElement(
table, entry_start, table, entry_start,
(OrderedHashMap::kHashTableStartIndex + OrderedHashMap::kChainOffset) * (CollectionType::kHashTableStartIndex + CollectionType::kChainOffset) *
kPointerSize))); kPointerSize)));
Goto(&loop); Goto(&loop);
...@@ -992,7 +986,43 @@ TF_BUILTIN(SetHas, CollectionsBuiltinsAssembler) { ...@@ -992,7 +986,43 @@ TF_BUILTIN(SetHas, CollectionsBuiltinsAssembler) {
ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, "Set.prototype.has"); ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, "Set.prototype.has");
Node* const table = LoadObjectField(receiver, JSMap::kTableOffset); 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) { TF_BUILTIN(SetPrototypeEntries, CollectionsBuiltinsAssembler) {
...@@ -1159,24 +1189,24 @@ TF_BUILTIN(MapLookupHashIndex, CollectionsBuiltinsAssembler) { ...@@ -1159,24 +1189,24 @@ TF_BUILTIN(MapLookupHashIndex, CollectionsBuiltinsAssembler) {
GotoIf(IsString(key), &if_key_string); GotoIf(IsString(key), &if_key_string);
GotoIf(IsHeapNumber(key), &if_key_heap_number); GotoIf(IsHeapNumber(key), &if_key_heap_number);
FindOrderedHashMapEntryForOtherKey(context, table, key, &entry_start_position, FindOrderedHashTableEntryForOtherKey<OrderedHashMap>(
&entry_found, &not_found); context, table, key, &entry_start_position, &entry_found, &not_found);
BIND(&if_key_smi); BIND(&if_key_smi);
{ {
FindOrderedHashMapEntryForSmiKey(table, key, &entry_start_position, FindOrderedHashTableEntryForSmiKey<OrderedHashMap>(
&entry_found, &not_found); table, key, &entry_start_position, &entry_found, &not_found);
} }
BIND(&if_key_string); BIND(&if_key_string);
{ {
FindOrderedHashMapEntryForStringKey( FindOrderedHashTableEntryForStringKey<OrderedHashMap>(
context, table, key, &entry_start_position, &entry_found, &not_found); context, table, key, &entry_start_position, &entry_found, &not_found);
} }
BIND(&if_key_heap_number); BIND(&if_key_heap_number);
{ {
FindOrderedHashMapEntryForHeapNumberKey( FindOrderedHashTableEntryForHeapNumberKey<OrderedHashMap>(
context, table, key, &entry_start_position, &entry_found, &not_found); 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