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

Unified Diff: src/code-stubs.cc

Issue 2363333003: [turbofan] Lower StringEqual and friends in EffectControlLinearizer. (Closed)
Patch Set: Preinitialize interface descriptors and drop TODO. Created 4 years, 3 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-stubs.h ('k') | src/compiler/effect-control-linearizer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stubs.cc
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 46d9c4df84fb75ea39c72b26c5728e23e70d70c0..b4562f41b8feabffa9a444244539f14f3e516007 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -4188,365 +4188,6 @@ compiler::Node* GenerateStrictEqual(CodeStubAssembler* assembler,
return result.value();
}
-void GenerateStringRelationalComparison(CodeStubAssembler* assembler,
- RelationalComparisonMode mode) {
- typedef CodeStubAssembler::Label Label;
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Variable Variable;
-
- Node* lhs = assembler->Parameter(0);
- Node* rhs = assembler->Parameter(1);
- Node* context = assembler->Parameter(2);
-
- Label if_less(assembler), if_equal(assembler), if_greater(assembler);
-
- // Fast check to see if {lhs} and {rhs} refer to the same String object.
- Label if_same(assembler), if_notsame(assembler);
- assembler->Branch(assembler->WordEqual(lhs, rhs), &if_same, &if_notsame);
-
- assembler->Bind(&if_same);
- assembler->Goto(&if_equal);
-
- assembler->Bind(&if_notsame);
- {
- // Load instance types of {lhs} and {rhs}.
- Node* lhs_instance_type = assembler->LoadInstanceType(lhs);
- Node* rhs_instance_type = assembler->LoadInstanceType(rhs);
-
- // Combine the instance types into a single 16-bit value, so we can check
- // both of them at once.
- Node* both_instance_types = assembler->Word32Or(
- lhs_instance_type,
- assembler->Word32Shl(rhs_instance_type, assembler->Int32Constant(8)));
-
- // Check that both {lhs} and {rhs} are flat one-byte strings.
- int const kBothSeqOneByteStringMask =
- kStringEncodingMask | kStringRepresentationMask |
- ((kStringEncodingMask | kStringRepresentationMask) << 8);
- int const kBothSeqOneByteStringTag =
- kOneByteStringTag | kSeqStringTag |
- ((kOneByteStringTag | kSeqStringTag) << 8);
- Label if_bothonebyteseqstrings(assembler),
- if_notbothonebyteseqstrings(assembler);
- assembler->Branch(assembler->Word32Equal(
- assembler->Word32And(both_instance_types,
- assembler->Int32Constant(
- kBothSeqOneByteStringMask)),
- assembler->Int32Constant(kBothSeqOneByteStringTag)),
- &if_bothonebyteseqstrings, &if_notbothonebyteseqstrings);
-
- assembler->Bind(&if_bothonebyteseqstrings);
- {
- // Load the length of {lhs} and {rhs}.
- Node* lhs_length = assembler->LoadStringLength(lhs);
- Node* rhs_length = assembler->LoadStringLength(rhs);
-
- // Determine the minimum length.
- Node* length = assembler->SmiMin(lhs_length, rhs_length);
-
- // Compute the effective offset of the first character.
- Node* begin = assembler->IntPtrConstant(SeqOneByteString::kHeaderSize -
- kHeapObjectTag);
-
- // Compute the first offset after the string from the length.
- Node* end = assembler->IntPtrAdd(begin, assembler->SmiUntag(length));
-
- // Loop over the {lhs} and {rhs} strings to see if they are equal.
- Variable var_offset(assembler, MachineType::PointerRepresentation());
- Label loop(assembler, &var_offset);
- var_offset.Bind(begin);
- assembler->Goto(&loop);
- assembler->Bind(&loop);
- {
- // Check if {offset} equals {end}.
- Node* offset = var_offset.value();
- Label if_done(assembler), if_notdone(assembler);
- assembler->Branch(assembler->WordEqual(offset, end), &if_done,
- &if_notdone);
-
- assembler->Bind(&if_notdone);
- {
- // Load the next characters from {lhs} and {rhs}.
- Node* lhs_value = assembler->Load(MachineType::Uint8(), lhs, offset);
- Node* rhs_value = assembler->Load(MachineType::Uint8(), rhs, offset);
-
- // Check if the characters match.
- Label if_valueissame(assembler), if_valueisnotsame(assembler);
- assembler->Branch(assembler->Word32Equal(lhs_value, rhs_value),
- &if_valueissame, &if_valueisnotsame);
-
- assembler->Bind(&if_valueissame);
- {
- // Advance to next character.
- var_offset.Bind(
- assembler->IntPtrAdd(offset, assembler->IntPtrConstant(1)));
- }
- assembler->Goto(&loop);
-
- assembler->Bind(&if_valueisnotsame);
- assembler->BranchIf(assembler->Uint32LessThan(lhs_value, rhs_value),
- &if_less, &if_greater);
- }
-
- assembler->Bind(&if_done);
- {
- // All characters up to the min length are equal, decide based on
- // string length.
- Label if_lengthisequal(assembler), if_lengthisnotequal(assembler);
- assembler->Branch(assembler->SmiEqual(lhs_length, rhs_length),
- &if_lengthisequal, &if_lengthisnotequal);
-
- assembler->Bind(&if_lengthisequal);
- assembler->Goto(&if_equal);
-
- assembler->Bind(&if_lengthisnotequal);
- assembler->BranchIfSmiLessThan(lhs_length, rhs_length, &if_less,
- &if_greater);
- }
- }
- }
-
- assembler->Bind(&if_notbothonebyteseqstrings);
- {
- // TODO(bmeurer): Add fast case support for flattened cons strings;
- // also add support for two byte string relational comparisons.
- switch (mode) {
- case kLessThan:
- assembler->TailCallRuntime(Runtime::kStringLessThan, context, lhs,
- rhs);
- break;
- case kLessThanOrEqual:
- assembler->TailCallRuntime(Runtime::kStringLessThanOrEqual, context,
- lhs, rhs);
- break;
- case kGreaterThan:
- assembler->TailCallRuntime(Runtime::kStringGreaterThan, context, lhs,
- rhs);
- break;
- case kGreaterThanOrEqual:
- assembler->TailCallRuntime(Runtime::kStringGreaterThanOrEqual,
- context, lhs, rhs);
- break;
- }
- }
- }
-
- assembler->Bind(&if_less);
- switch (mode) {
- case kLessThan:
- case kLessThanOrEqual:
- assembler->Return(assembler->BooleanConstant(true));
- break;
-
- case kGreaterThan:
- case kGreaterThanOrEqual:
- assembler->Return(assembler->BooleanConstant(false));
- break;
- }
-
- assembler->Bind(&if_equal);
- switch (mode) {
- case kLessThan:
- case kGreaterThan:
- assembler->Return(assembler->BooleanConstant(false));
- break;
-
- case kLessThanOrEqual:
- case kGreaterThanOrEqual:
- assembler->Return(assembler->BooleanConstant(true));
- break;
- }
-
- assembler->Bind(&if_greater);
- switch (mode) {
- case kLessThan:
- case kLessThanOrEqual:
- assembler->Return(assembler->BooleanConstant(false));
- break;
-
- case kGreaterThan:
- case kGreaterThanOrEqual:
- assembler->Return(assembler->BooleanConstant(true));
- break;
- }
-}
-
-void GenerateStringEqual(CodeStubAssembler* assembler, ResultMode mode) {
- // Here's pseudo-code for the algorithm below in case of kDontNegateResult
- // mode; for kNegateResult mode we properly negate the result.
- //
- // if (lhs == rhs) return true;
- // if (lhs->length() != rhs->length()) return false;
- // if (lhs->IsInternalizedString() && rhs->IsInternalizedString()) {
- // return false;
- // }
- // if (lhs->IsSeqOneByteString() && rhs->IsSeqOneByteString()) {
- // for (i = 0; i != lhs->length(); ++i) {
- // if (lhs[i] != rhs[i]) return false;
- // }
- // return true;
- // }
- // return %StringEqual(lhs, rhs);
-
- typedef CodeStubAssembler::Label Label;
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Variable Variable;
-
- Node* lhs = assembler->Parameter(0);
- Node* rhs = assembler->Parameter(1);
- Node* context = assembler->Parameter(2);
-
- Label if_equal(assembler), if_notequal(assembler);
-
- // Fast check to see if {lhs} and {rhs} refer to the same String object.
- Label if_same(assembler), if_notsame(assembler);
- assembler->Branch(assembler->WordEqual(lhs, rhs), &if_same, &if_notsame);
-
- assembler->Bind(&if_same);
- assembler->Goto(&if_equal);
-
- assembler->Bind(&if_notsame);
- {
- // The {lhs} and {rhs} don't refer to the exact same String object.
-
- // Load the length of {lhs} and {rhs}.
- Node* lhs_length = assembler->LoadStringLength(lhs);
- Node* rhs_length = assembler->LoadStringLength(rhs);
-
- // Check if the lengths of {lhs} and {rhs} are equal.
- Label if_lengthisequal(assembler), if_lengthisnotequal(assembler);
- assembler->Branch(assembler->WordEqual(lhs_length, rhs_length),
- &if_lengthisequal, &if_lengthisnotequal);
-
- assembler->Bind(&if_lengthisequal);
- {
- // Load instance types of {lhs} and {rhs}.
- Node* lhs_instance_type = assembler->LoadInstanceType(lhs);
- Node* rhs_instance_type = assembler->LoadInstanceType(rhs);
-
- // Combine the instance types into a single 16-bit value, so we can check
- // both of them at once.
- Node* both_instance_types = assembler->Word32Or(
- lhs_instance_type,
- assembler->Word32Shl(rhs_instance_type, assembler->Int32Constant(8)));
-
- // Check if both {lhs} and {rhs} are internalized.
- int const kBothInternalizedMask =
- kIsNotInternalizedMask | (kIsNotInternalizedMask << 8);
- int const kBothInternalizedTag =
- kInternalizedTag | (kInternalizedTag << 8);
- Label if_bothinternalized(assembler), if_notbothinternalized(assembler);
- assembler->Branch(assembler->Word32Equal(
- assembler->Word32And(both_instance_types,
- assembler->Int32Constant(
- kBothInternalizedMask)),
- assembler->Int32Constant(kBothInternalizedTag)),
- &if_bothinternalized, &if_notbothinternalized);
-
- assembler->Bind(&if_bothinternalized);
- {
- // Fast negative check for internalized-to-internalized equality.
- assembler->Goto(&if_notequal);
- }
-
- assembler->Bind(&if_notbothinternalized);
- {
- // Check that both {lhs} and {rhs} are flat one-byte strings.
- int const kBothSeqOneByteStringMask =
- kStringEncodingMask | kStringRepresentationMask |
- ((kStringEncodingMask | kStringRepresentationMask) << 8);
- int const kBothSeqOneByteStringTag =
- kOneByteStringTag | kSeqStringTag |
- ((kOneByteStringTag | kSeqStringTag) << 8);
- Label if_bothonebyteseqstrings(assembler),
- if_notbothonebyteseqstrings(assembler);
- assembler->Branch(
- assembler->Word32Equal(
- assembler->Word32And(
- both_instance_types,
- assembler->Int32Constant(kBothSeqOneByteStringMask)),
- assembler->Int32Constant(kBothSeqOneByteStringTag)),
- &if_bothonebyteseqstrings, &if_notbothonebyteseqstrings);
-
- assembler->Bind(&if_bothonebyteseqstrings);
- {
- // Compute the effective offset of the first character.
- Node* begin = assembler->IntPtrConstant(
- SeqOneByteString::kHeaderSize - kHeapObjectTag);
-
- // Compute the first offset after the string from the length.
- Node* end =
- assembler->IntPtrAdd(begin, assembler->SmiUntag(lhs_length));
-
- // Loop over the {lhs} and {rhs} strings to see if they are equal.
- Variable var_offset(assembler, MachineType::PointerRepresentation());
- Label loop(assembler, &var_offset);
- var_offset.Bind(begin);
- assembler->Goto(&loop);
- assembler->Bind(&loop);
- {
- // Check if {offset} equals {end}.
- Node* offset = var_offset.value();
- Label if_done(assembler), if_notdone(assembler);
- assembler->Branch(assembler->WordEqual(offset, end), &if_done,
- &if_notdone);
-
- assembler->Bind(&if_notdone);
- {
- // Load the next characters from {lhs} and {rhs}.
- Node* lhs_value =
- assembler->Load(MachineType::Uint8(), lhs, offset);
- Node* rhs_value =
- assembler->Load(MachineType::Uint8(), rhs, offset);
-
- // Check if the characters match.
- Label if_valueissame(assembler), if_valueisnotsame(assembler);
- assembler->Branch(assembler->Word32Equal(lhs_value, rhs_value),
- &if_valueissame, &if_valueisnotsame);
-
- assembler->Bind(&if_valueissame);
- {
- // Advance to next character.
- var_offset.Bind(
- assembler->IntPtrAdd(offset, assembler->IntPtrConstant(1)));
- }
- assembler->Goto(&loop);
-
- assembler->Bind(&if_valueisnotsame);
- assembler->Goto(&if_notequal);
- }
-
- assembler->Bind(&if_done);
- assembler->Goto(&if_equal);
- }
- }
-
- assembler->Bind(&if_notbothonebyteseqstrings);
- {
- // TODO(bmeurer): Add fast case support for flattened cons strings;
- // also add support for two byte string equality checks.
- Runtime::FunctionId function_id = (mode == kDontNegateResult)
- ? Runtime::kStringEqual
- : Runtime::kStringNotEqual;
- assembler->TailCallRuntime(function_id, context, lhs, rhs);
- }
- }
- }
-
- assembler->Bind(&if_lengthisnotequal);
- {
- // Mismatch in length of {lhs} and {rhs}, cannot be equal.
- assembler->Goto(&if_notequal);
- }
- }
-
- assembler->Bind(&if_equal);
- assembler->Return(assembler->BooleanConstant(mode == kDontNegateResult));
-
- assembler->Bind(&if_notequal);
- assembler->Return(assembler->BooleanConstant(mode == kNegateResult));
-}
-
} // namespace
void LoadApiGetterStub::GenerateAssembly(CodeStubAssembler* assembler) const {
@@ -4845,33 +4486,6 @@ compiler::Node* StrictNotEqualStub::Generate(CodeStubAssembler* assembler,
return GenerateStrictEqual(assembler, kNegateResult, lhs, rhs, context);
}
-void StringEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
- GenerateStringEqual(assembler, kDontNegateResult);
-}
-
-void StringNotEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
- GenerateStringEqual(assembler, kNegateResult);
-}
-
-void StringLessThanStub::GenerateAssembly(CodeStubAssembler* assembler) const {
- GenerateStringRelationalComparison(assembler, kLessThan);
-}
-
-void StringLessThanOrEqualStub::GenerateAssembly(
- CodeStubAssembler* assembler) const {
- GenerateStringRelationalComparison(assembler, kLessThanOrEqual);
-}
-
-void StringGreaterThanStub::GenerateAssembly(
- CodeStubAssembler* assembler) const {
- GenerateStringRelationalComparison(assembler, kGreaterThan);
-}
-
-void StringGreaterThanOrEqualStub::GenerateAssembly(
- CodeStubAssembler* assembler) const {
- GenerateStringRelationalComparison(assembler, kGreaterThanOrEqual);
-}
-
void ToLengthStub::GenerateAssembly(CodeStubAssembler* assembler) const {
typedef CodeStubAssembler::Label Label;
typedef compiler::Node Node;
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/effect-control-linearizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698