| 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);
|
| {
|
|
|