Commit bff24112 authored by jgruber's avatar jgruber Committed by Commit bot

[csa] Remove StringIndexOfChar

The StringIndexOf stub does the same thing but better (it uses memchr
instead of a manual loop).

Review-Url: https://codereview.chromium.org/2667963002
Cr-Commit-Position: refs/heads/master@{#42923}
parent b963cb23
......@@ -2463,11 +2463,12 @@ TF_BUILTIN(RegExpReplace, RegExpBuiltinsAssembler) {
Node* const replace_string =
CallStub(tostring_callable, context, replace_value);
Node* const dollar_char = Int32Constant('$');
GotoUnless(SmiEqual(StringIndexOfChar(context, replace_string, dollar_char,
SmiConstant(0)),
SmiConstant(-1)),
&runtime);
Callable indexof_callable = CodeFactory::StringIndexOf(isolate());
Node* const dollar_string = HeapConstant(
isolate()->factory()->LookupSingleCharacterStringFromCode('$'));
Node* const dollar_ix = CallStub(indexof_callable, context, replace_string,
dollar_string, SmiConstant(0));
GotoUnless(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime);
Return(
ReplaceSimpleStringFastPath(context, regexp, string, replace_string));
......
......@@ -1180,6 +1180,8 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
// Convert {receiver} and {search} to strings.
Callable tostring_callable = CodeFactory::ToString(isolate());
Callable indexof_callable = CodeFactory::StringIndexOf(isolate());
Node* const subject_string = CallStub(tostring_callable, context, receiver);
Node* const search_string = CallStub(tostring_callable, context, search);
......@@ -1196,10 +1198,11 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
GotoIf(TaggedIsSmi(replace), &next);
GotoUnless(IsString(replace), &next);
Node* const dollar_char = Int32Constant('$');
Node* const index_of_dollar =
StringIndexOfChar(context, replace, dollar_char, smi_zero);
GotoUnless(SmiIsNegative(index_of_dollar), &next);
Node* const dollar_string = HeapConstant(
isolate()->factory()->LookupSingleCharacterStringFromCode('$'));
Node* const dollar_ix =
CallStub(indexof_callable, context, replace, dollar_string, smi_zero);
GotoUnless(SmiIsNegative(dollar_ix), &next);
// Searching by traversing a cons string tree and replace with cons of
// slices works only when the replaced string is a single character, being
......@@ -1211,13 +1214,12 @@ TF_BUILTIN(StringPrototypeReplace, StringBuiltinsAssembler) {
Bind(&next);
}
// TODO(jgruber): Extend StringIndexOfChar to handle two-byte strings and
// TODO(jgruber): Extend StringIndexOf to handle two-byte strings and
// longer substrings - we can handle up to 8 chars (one-byte) / 4 chars
// (2-byte).
Callable indexof_stub = CodeFactory::StringIndexOf(isolate());
Node* const match_start_index =
CallStub(indexof_stub, context, subject_string, search_string, smi_zero);
Node* const match_start_index = CallStub(
indexof_callable, context, subject_string, search_string, smi_zero);
CSA_ASSERT(this, TaggedIsSmi(match_start_index));
// Early exit if no match found.
......
......@@ -3732,73 +3732,6 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
return result.value();
}
Node* CodeStubAssembler::StringIndexOfChar(Node* context, Node* string,
Node* needle_char, Node* from) {
CSA_ASSERT(this, IsString(string));
Variable var_result(this, MachineRepresentation::kTagged);
Label out(this), runtime(this, Label::kDeferred);
// Let runtime handle non-one-byte {needle_char}.
Node* const one_byte_char_mask = Int32Constant(0xFF);
GotoUnless(
Word32Equal(Word32And(needle_char, one_byte_char_mask), needle_char),
&runtime);
// TODO(jgruber): Handle external and two-byte strings.
Node* const one_byte_seq_mask = Int32Constant(
kIsIndirectStringMask | kExternalStringTag | kStringEncodingMask);
Node* const expected_masked = Int32Constant(kOneByteStringTag);
Node* const string_instance_type = LoadInstanceType(string);
GotoUnless(Word32Equal(Word32And(string_instance_type, one_byte_seq_mask),
expected_masked),
&runtime);
// If we reach this, {string} is a non-indirect, non-external one-byte string.
Node* const length = LoadStringLength(string);
Node* const search_range_length = SmiUntag(SmiSub(length, from));
const int offset = SeqOneByteString::kHeaderSize - kHeapObjectTag;
Node* const begin = IntPtrConstant(offset);
Node* const cursor = IntPtrAdd(begin, SmiUntag(from));
Node* const end = IntPtrAdd(cursor, search_range_length);
var_result.Bind(SmiConstant(Smi::FromInt(-1)));
BuildFastLoop(
cursor, end,
[this, string, needle_char, begin, &var_result, &out](Node* cursor) {
Label next(this);
Node* value = Load(MachineType::Uint8(), string, cursor);
GotoUnless(Word32Equal(value, needle_char), &next);
// Found a match.
Node* index = SmiTag(IntPtrSub(cursor, begin));
var_result.Bind(index);
Goto(&out);
Bind(&next);
},
1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
Goto(&out);
Bind(&runtime);
{
Node* const pattern = StringFromCharCode(needle_char);
Node* const result =
CallRuntime(Runtime::kStringIndexOf, context, string, pattern, from);
var_result.Bind(result);
Goto(&out);
}
Bind(&out);
return var_result.value();
}
Node* CodeStubAssembler::StringFromCodePoint(Node* codepoint,
UnicodeEncoding encoding) {
Variable var_result(this, MachineRepresentation::kTagged,
......
......@@ -727,13 +727,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Variable* var_right, Node* right_instance_type,
Label* did_something);
// Return the first index >= {from} at which {needle_char} was found in
// {string}, or -1 if such an index does not exist. The returned value is
// a Smi, {string} is expected to be a String, {needle_char} is an intptr,
// and {from} is expected to be tagged.
Node* StringIndexOfChar(Node* context, Node* string, Node* needle_char,
Node* from);
Node* StringFromCodePoint(Node* codepoint, UnicodeEncoding encoding);
// Type conversion helpers.
......
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