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