[csa] Relax bailout condition for integer indexed exotic

GetProperty CSA implementation bailouts prototype lookup when the
holder is a typed array, which is to handle integer indexed exotic
cases. However, this strict condition made too much overheads for
search of common names such as "constructor". This CL checks the
first character of a name, and do not bailout if we are sure that
the name cannot be a special index.

Bug: v8:4911, v8:7161
Change-Id: I2229ff3bebe14a452718e0b1f8354bb05437c09c
Reviewed-on: https://chromium-review.googlesource.com/842963
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50414}
This commit is contained in:
Choongwoo Han 2018-01-09 00:22:59 +09:00 committed by Commit Bot
parent a3baa35372
commit 2ca420e46c
2 changed files with 50 additions and 6 deletions

View File

@ -7047,6 +7047,35 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
}
}
void CodeStubAssembler::BranchIfMaybeSpecialIndex(TNode<String> name_string,
Label* if_maybe_special_index,
Label* if_not_special_index) {
// TODO(cwhan.tunz): Implement fast cases more.
// If a name is empty or too long, it's not a special index
// Max length of canonical double: -X.XXXXXXXXXXXXXXXXX-eXXX
const int kBufferSize = 24;
TNode<Smi> string_length = LoadStringLengthAsSmi(name_string);
GotoIf(SmiEqual(string_length, SmiConstant(0)), if_not_special_index);
GotoIf(SmiGreaterThan(string_length, SmiConstant(kBufferSize)),
if_not_special_index);
// If the first character of name is not a digit or '-', or we can't match it
// to Infinity or NaN, then this is not a special index.
TNode<Uint32T> first_char = StringCharCodeAt(name_string, IntPtrConstant(0));
// If the name starts with '-', it can be a negative index.
GotoIf(Word32Equal(first_char, Int32Constant('-')), if_maybe_special_index);
// If the name starts with 'I', it can be "Infinity".
GotoIf(Word32Equal(first_char, Int32Constant('I')), if_maybe_special_index);
// If the name starts with 'N', it can be "NaN".
GotoIf(Word32Equal(first_char, Int32Constant('N')), if_maybe_special_index);
// Finally, if the first character is not a digit either, then we are sure
// that the name is not a special index.
GotoIf(Uint32LessThan(first_char, Int32Constant('0')), if_not_special_index);
GotoIf(Uint32LessThan(Int32Constant('9'), first_char), if_not_special_index);
Goto(if_maybe_special_index);
}
void CodeStubAssembler::TryPrototypeChainLookup(
Node* receiver, Node* key, const LookupInHolder& lookup_property_in_holder,
const LookupInHolder& lookup_element_in_holder, Label* if_end,
@ -7094,15 +7123,21 @@ void CodeStubAssembler::TryPrototypeChainLookup(
Node* holder_map = var_holder_map.value();
Node* holder_instance_type = var_holder_instance_type.value();
Label next_proto(this);
Label next_proto(this), check_integer_indexed_exotic(this);
lookup_property_in_holder(receiver, var_holder.value(), holder_map,
holder_instance_type, var_unique.value(),
&next_proto, if_bailout);
BIND(&next_proto);
&check_integer_indexed_exotic, if_bailout);
// Bailout if it can be an integer indexed exotic case.
GotoIf(InstanceTypeEqual(holder_instance_type, JS_TYPED_ARRAY_TYPE),
if_bailout);
BIND(&check_integer_indexed_exotic);
{
// Bailout if it can be an integer indexed exotic case.
GotoIfNot(InstanceTypeEqual(holder_instance_type, JS_TYPED_ARRAY_TYPE),
&next_proto);
GotoIfNot(IsString(var_unique.value()), &next_proto);
BranchIfMaybeSpecialIndex(CAST(key), if_bailout, &next_proto);
}
BIND(&next_proto);
Node* proto = LoadMapPrototype(holder_map);

View File

@ -1613,6 +1613,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Label* if_bailout)>
LookupInHolder;
// For integer indexed exotic cases, check if the given string cannot be a
// special index. If we are not sure that the given string is not a special
// index with a simple check, return False. Note that "False" return value
// does not mean that the name_string is a special index in the current
// implementation.
void BranchIfMaybeSpecialIndex(TNode<String> name_string,
Label* if_maybe_special_index,
Label* if_not_special_index);
// Generic property prototype chain lookup generator.
// For properties it generates lookup using given {lookup_property_in_holder}
// and for elements it uses {lookup_element_in_holder}.