Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Unified Diff: src/code-stub-assembler.cc

Issue 2680973002: [stubs] Implement binary-search descriptor lookup in CSA (Closed)
Patch Set: rebased Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/ic/accessor-assembler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 358d103997be66d855d0d8b861f7c71d71df7a92..520789cc16fab43bbf3813aed52e9abc0a45c19e 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -4721,6 +4721,7 @@ void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name,
Label* if_found,
Variable* var_name_index,
Label* if_not_found) {
+ Comment("DescriptorLookupLinear");
Node* first_inclusive = IntPtrConstant(DescriptorArray::ToKeyIndex(0));
Node* factor = IntPtrConstant(DescriptorArray::kEntrySize);
Node* last_exclusive = IntPtrAdd(first_inclusive, IntPtrMul(nof, factor));
@@ -4738,6 +4739,136 @@ void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name,
Goto(if_not_found);
}
+Node* CodeStubAssembler::DescriptorArrayNumberOfEntries(Node* descriptors) {
+ return LoadAndUntagToWord32FixedArrayElement(
+ descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex));
+}
+
+namespace {
+
+Node* DescriptorNumberToIndex(CodeStubAssembler* a, Node* descriptor_number) {
+ Node* descriptor_size = a->Int32Constant(DescriptorArray::kEntrySize);
+ Node* index = a->Int32Mul(descriptor_number, descriptor_size);
+ return a->ChangeInt32ToIntPtr(index);
+}
+
+} // namespace
+
+Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) {
+ return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)),
+ DescriptorNumberToIndex(this, descriptor_number));
+}
+
+Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex(
+ Node* descriptors, Node* descriptor_number) {
+ const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize;
+ Node* details = LoadAndUntagToWord32FixedArrayElement(
+ descriptors, DescriptorNumberToIndex(this, descriptor_number),
+ details_offset);
+ return DecodeWord32<PropertyDetails::DescriptorPointer>(details);
+}
+
+Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors,
+ Node* descriptor_number) {
+ const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize;
+ return LoadFixedArrayElement(descriptors,
+ DescriptorNumberToIndex(this, descriptor_number),
+ key_offset);
+}
+
+void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
+ Node* descriptors, Node* nof,
+ Label* if_found,
+ Variable* var_name_index,
+ Label* if_not_found) {
+ Comment("DescriptorLookupBinary");
+ Variable var_low(this, MachineRepresentation::kWord32, Int32Constant(0));
+ Node* limit =
+ Int32Sub(DescriptorArrayNumberOfEntries(descriptors), Int32Constant(1));
+ Variable var_high(this, MachineRepresentation::kWord32, limit);
+ Node* hash = LoadNameHashField(unique_name);
+ CSA_ASSERT(this, Word32NotEqual(hash, Int32Constant(0)));
+
+ // Assume non-empty array.
+ CSA_ASSERT(this, Uint32LessThanOrEqual(var_low.value(), var_high.value()));
+
+ Variable* loop_vars[] = {&var_high, &var_low};
+ Label binary_loop(this, 2, loop_vars);
+ Goto(&binary_loop);
+ Bind(&binary_loop);
+ {
+ // mid = low + (high - low) / 2 (to avoid overflow in "(low + high) / 2").
+ Node* mid =
+ Int32Add(var_low.value(),
+ Word32Shr(Int32Sub(var_high.value(), var_low.value()), 1));
+ // mid_name = descriptors->GetSortedKey(mid).
+ Node* sorted_key_index = DescriptorArrayGetSortedKeyIndex(descriptors, mid);
+ Node* mid_name = DescriptorArrayGetKey(descriptors, sorted_key_index);
+
+ Node* mid_hash = LoadNameHashField(mid_name);
+
+ Label mid_greater(this), mid_less(this), merge(this);
+ Branch(Uint32GreaterThanOrEqual(mid_hash, hash), &mid_greater, &mid_less);
+ Bind(&mid_greater);
+ {
+ var_high.Bind(mid);
+ Goto(&merge);
+ }
+ Bind(&mid_less);
+ {
+ var_low.Bind(Int32Add(mid, Int32Constant(1)));
+ Goto(&merge);
+ }
+ Bind(&merge);
+ GotoIf(Word32NotEqual(var_low.value(), var_high.value()), &binary_loop);
+ }
+
+ Label scan_loop(this, &var_low);
+ Goto(&scan_loop);
+ Bind(&scan_loop);
+ {
+ GotoIf(Int32GreaterThan(var_low.value(), limit), if_not_found);
+
+ Node* sort_index =
+ DescriptorArrayGetSortedKeyIndex(descriptors, var_low.value());
+ Node* current_name = DescriptorArrayGetKey(descriptors, sort_index);
+ Node* current_hash = LoadNameHashField(current_name);
+ GotoIf(Word32NotEqual(current_hash, hash), if_not_found);
+ Label next(this);
+ GotoIf(WordNotEqual(current_name, unique_name), &next);
+ GotoIf(Int32GreaterThanOrEqual(sort_index, nof), if_not_found);
+ var_name_index->Bind(DescriptorArrayToKeyIndex(sort_index));
+ Goto(if_found);
+
+ Bind(&next);
+ var_low.Bind(Int32Add(var_low.value(), Int32Constant(1)));
+ Goto(&scan_loop);
+ }
+}
+
+void CodeStubAssembler::DescriptorLookup(Node* unique_name, Node* descriptors,
+ Node* bitfield3, Label* if_found,
+ Variable* var_name_index,
+ Label* if_not_found) {
+ Comment("DescriptorArrayLookup");
+ Node* nof = DecodeWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3);
+ GotoIf(Word32Equal(nof, Int32Constant(0)), if_not_found);
+ Label linear_search(this), binary_search(this);
+ const int kMaxElementsForLinearSearch = 32;
+ Branch(Int32LessThanOrEqual(nof, Int32Constant(kMaxElementsForLinearSearch)),
+ &linear_search, &binary_search);
+ Bind(&linear_search);
+ {
+ DescriptorLookupLinear(unique_name, descriptors, ChangeInt32ToIntPtr(nof),
+ if_found, var_name_index, if_not_found);
+ }
+ Bind(&binary_search);
+ {
+ DescriptorLookupBinary(unique_name, descriptors, nof, if_found,
+ var_name_index, if_not_found);
+ }
+}
+
void CodeStubAssembler::TryLookupProperty(
Node* object, Node* map, Node* instance_type, Node* unique_name,
Label* if_found_fast, Label* if_found_dict, Label* if_found_global,
@@ -4763,20 +4894,11 @@ void CodeStubAssembler::TryLookupProperty(
&if_isfastmap);
Bind(&if_isfastmap);
{
- Comment("DescriptorArrayLookup");
- Node* nof =
- DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3);
- // Bail out to the runtime for large numbers of own descriptors. The stub
- // only does linear search, which becomes too expensive in that case.
- {
- static const int32_t kMaxLinear = 210;
- GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), if_bailout);
- }
Node* descriptors = LoadMapDescriptors(map);
var_meta_storage->Bind(descriptors);
- DescriptorLookupLinear(unique_name, descriptors, nof, if_found_fast,
- var_name_index, if_not_found);
+ DescriptorLookup(unique_name, descriptors, bit_field3, if_found_fast,
+ var_name_index, if_not_found);
}
Bind(&if_isslowmap);
{
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/ic/accessor-assembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698