Commit e711ff38 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Inline inequality compares of strings into CompareICStub instead of jumping...

Inline inequality compares of strings into CompareICStub instead of jumping into the CompareStub that handles the generic case.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9649027

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10988 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent cb2f2a23
...@@ -6661,6 +6661,8 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { ...@@ -6661,6 +6661,8 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
ASSERT(state_ == CompareIC::STRINGS); ASSERT(state_ == CompareIC::STRINGS);
Label miss; Label miss;
bool equality = Token::IsEqualityOp(op_);
// Registers containing left and right operands respectively. // Registers containing left and right operands respectively.
Register left = r1; Register left = r1;
Register right = r0; Register right = r0;
...@@ -6694,28 +6696,39 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { ...@@ -6694,28 +6696,39 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
// Check that both strings are symbols. If they are, we're done // Check that both strings are symbols. If they are, we're done
// because we already know they are not identical. // because we already know they are not identical.
ASSERT(GetCondition() == eq); if (equality) {
STATIC_ASSERT(kSymbolTag != 0); ASSERT(GetCondition() == eq);
__ and_(tmp3, tmp1, Operand(tmp2)); STATIC_ASSERT(kSymbolTag != 0);
__ tst(tmp3, Operand(kIsSymbolMask)); __ and_(tmp3, tmp1, Operand(tmp2));
// Make sure r0 is non-zero. At this point input operands are __ tst(tmp3, Operand(kIsSymbolMask));
// guaranteed to be non-zero. // Make sure r0 is non-zero. At this point input operands are
ASSERT(right.is(r0)); // guaranteed to be non-zero.
__ Ret(ne); ASSERT(right.is(r0));
__ Ret(ne);
}
// Check that both strings are sequential ASCII. // Check that both strings are sequential ASCII.
Label runtime; Label runtime;
__ JumpIfBothInstanceTypesAreNotSequentialAscii(tmp1, tmp2, tmp3, tmp4, __ JumpIfBothInstanceTypesAreNotSequentialAscii(
&runtime); tmp1, tmp2, tmp3, tmp4, &runtime);
// Compare flat ASCII strings. Returns when done. // Compare flat ASCII strings. Returns when done.
StringCompareStub::GenerateFlatAsciiStringEquals( if (equality) {
masm, left, right, tmp1, tmp2, tmp3); StringCompareStub::GenerateFlatAsciiStringEquals(
masm, left, right, tmp1, tmp2, tmp3);
} else {
StringCompareStub::GenerateCompareFlatAsciiStrings(
masm, left, right, tmp1, tmp2, tmp3, tmp4);
}
// Handle more complex cases in runtime. // Handle more complex cases in runtime.
__ bind(&runtime); __ bind(&runtime);
__ Push(left, right); __ Push(left, right);
__ TailCallRuntime(Runtime::kStringEquals, 2, 1); if (equality) {
__ TailCallRuntime(Runtime::kStringEquals, 2, 1);
} else {
__ TailCallRuntime(Runtime::kStringCompare, 2, 1);
}
__ bind(&miss); __ bind(&miss);
GenerateMiss(masm); GenerateMiss(masm);
......
...@@ -6462,7 +6462,7 @@ void StringCompareStub::GenerateAsciiCharsCompareLoop( ...@@ -6462,7 +6462,7 @@ void StringCompareStub::GenerateAsciiCharsCompareLoop(
__ mov_b(scratch, Operand(left, index, times_1, 0)); __ mov_b(scratch, Operand(left, index, times_1, 0));
__ cmpb(scratch, Operand(right, index, times_1, 0)); __ cmpb(scratch, Operand(right, index, times_1, 0));
__ j(not_equal, chars_not_equal, chars_not_equal_near); __ j(not_equal, chars_not_equal, chars_not_equal_near);
__ add(index, Immediate(1)); __ inc(index);
__ j(not_zero, &loop); __ j(not_zero, &loop);
} }
...@@ -6645,9 +6645,10 @@ void ICCompareStub::GenerateSymbols(MacroAssembler* masm) { ...@@ -6645,9 +6645,10 @@ void ICCompareStub::GenerateSymbols(MacroAssembler* masm) {
void ICCompareStub::GenerateStrings(MacroAssembler* masm) { void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
ASSERT(state_ == CompareIC::STRINGS); ASSERT(state_ == CompareIC::STRINGS);
ASSERT(GetCondition() == equal);
Label miss; Label miss;
bool equality = Token::IsEqualityOp(op_);
// Registers containing left and right operands respectively. // Registers containing left and right operands respectively.
Register left = edx; Register left = edx;
Register right = eax; Register right = eax;
...@@ -6686,25 +6687,33 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { ...@@ -6686,25 +6687,33 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
__ bind(&not_same); __ bind(&not_same);
// Check that both strings are symbols. If they are, we're done // Check that both strings are symbols. If they are, we're done
// because we already know they are not identical. // because we already know they are not identical. But in the case of
Label do_compare; // non-equality compare, we still need to determine the order.
STATIC_ASSERT(kSymbolTag != 0); if (equality) {
__ and_(tmp1, tmp2); Label do_compare;
__ test(tmp1, Immediate(kIsSymbolMask)); STATIC_ASSERT(kSymbolTag != 0);
__ j(zero, &do_compare, Label::kNear); __ and_(tmp1, tmp2);
// Make sure eax is non-zero. At this point input operands are __ test(tmp1, Immediate(kIsSymbolMask));
// guaranteed to be non-zero. __ j(zero, &do_compare, Label::kNear);
ASSERT(right.is(eax)); // Make sure eax is non-zero. At this point input operands are
__ ret(0); // guaranteed to be non-zero.
ASSERT(right.is(eax));
__ ret(0);
__ bind(&do_compare);
}
// Check that both strings are sequential ASCII. // Check that both strings are sequential ASCII.
Label runtime; Label runtime;
__ bind(&do_compare);
__ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime);
// Compare flat ASCII strings. Returns when done. // Compare flat ASCII strings. Returns when done.
StringCompareStub::GenerateFlatAsciiStringEquals( if (equality) {
masm, left, right, tmp1, tmp2); StringCompareStub::GenerateFlatAsciiStringEquals(
masm, left, right, tmp1, tmp2);
} else {
StringCompareStub::GenerateCompareFlatAsciiStrings(
masm, left, right, tmp1, tmp2, tmp3);
}
// Handle more complex cases in runtime. // Handle more complex cases in runtime.
__ bind(&runtime); __ bind(&runtime);
...@@ -6712,7 +6721,11 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { ...@@ -6712,7 +6721,11 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
__ push(left); __ push(left);
__ push(right); __ push(right);
__ push(tmp1); __ push(tmp1);
__ TailCallRuntime(Runtime::kStringEquals, 2, 1); if (equality) {
__ TailCallRuntime(Runtime::kStringEquals, 2, 1);
} else {
__ TailCallRuntime(Runtime::kStringCompare, 2, 1);
}
__ bind(&miss); __ bind(&miss);
GenerateMiss(masm); GenerateMiss(masm);
......
...@@ -2490,9 +2490,13 @@ CompareIC::State CompareIC::TargetState(State state, ...@@ -2490,9 +2490,13 @@ CompareIC::State CompareIC::TargetState(State state,
return HEAP_NUMBERS; return HEAP_NUMBERS;
} }
} }
if (!Token::IsEqualityOp(op_)) return GENERIC; if (x->IsSymbol() && y->IsSymbol()) {
if (x->IsSymbol() && y->IsSymbol()) return SYMBOLS; // We compare symbols as strings if we need to determine
// the order in a non-equality compare.
return Token::IsEqualityOp(op_) ? SYMBOLS : STRINGS;
}
if (x->IsString() && y->IsString()) return STRINGS; if (x->IsString() && y->IsString()) return STRINGS;
if (!Token::IsEqualityOp(op_)) return GENERIC;
if (x->IsJSObject() && y->IsJSObject()) { if (x->IsJSObject() && y->IsJSObject()) {
if (Handle<JSObject>::cast(x)->map() == if (Handle<JSObject>::cast(x)->map() ==
Handle<JSObject>::cast(y)->map() && Handle<JSObject>::cast(y)->map() &&
......
...@@ -5454,7 +5454,7 @@ void StringCompareStub::GenerateAsciiCharsCompareLoop( ...@@ -5454,7 +5454,7 @@ void StringCompareStub::GenerateAsciiCharsCompareLoop(
__ movb(scratch, Operand(left, index, times_1, 0)); __ movb(scratch, Operand(left, index, times_1, 0));
__ cmpb(scratch, Operand(right, index, times_1, 0)); __ cmpb(scratch, Operand(right, index, times_1, 0));
__ j(not_equal, chars_not_equal, near_jump); __ j(not_equal, chars_not_equal, near_jump);
__ addq(index, Immediate(1)); __ incq(index);
__ j(not_zero, &loop); __ j(not_zero, &loop);
} }
...@@ -5625,9 +5625,10 @@ void ICCompareStub::GenerateSymbols(MacroAssembler* masm) { ...@@ -5625,9 +5625,10 @@ void ICCompareStub::GenerateSymbols(MacroAssembler* masm) {
void ICCompareStub::GenerateStrings(MacroAssembler* masm) { void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
ASSERT(state_ == CompareIC::STRINGS); ASSERT(state_ == CompareIC::STRINGS);
ASSERT(GetCondition() == equal);
Label miss; Label miss;
bool equality = Token::IsEqualityOp(op_);
// Registers containing left and right operands respectively. // Registers containing left and right operands respectively.
Register left = rdx; Register left = rdx;
Register right = rax; Register right = rax;
...@@ -5665,24 +5666,31 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { ...@@ -5665,24 +5666,31 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
// Check that both strings are symbols. If they are, we're done // Check that both strings are symbols. If they are, we're done
// because we already know they are not identical. // because we already know they are not identical.
Label do_compare; if (equality) {
STATIC_ASSERT(kSymbolTag != 0); Label do_compare;
__ and_(tmp1, tmp2); STATIC_ASSERT(kSymbolTag != 0);
__ testb(tmp1, Immediate(kIsSymbolMask)); __ and_(tmp1, tmp2);
__ j(zero, &do_compare, Label::kNear); __ testb(tmp1, Immediate(kIsSymbolMask));
// Make sure rax is non-zero. At this point input operands are __ j(zero, &do_compare, Label::kNear);
// guaranteed to be non-zero. // Make sure rax is non-zero. At this point input operands are
ASSERT(right.is(rax)); // guaranteed to be non-zero.
__ ret(0); ASSERT(right.is(rax));
__ ret(0);
__ bind(&do_compare);
}
// Check that both strings are sequential ASCII. // Check that both strings are sequential ASCII.
Label runtime; Label runtime;
__ bind(&do_compare);
__ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime); __ JumpIfNotBothSequentialAsciiStrings(left, right, tmp1, tmp2, &runtime);
// Compare flat ASCII strings. Returns when done. // Compare flat ASCII strings. Returns when done.
StringCompareStub::GenerateFlatAsciiStringEquals( if (equality) {
masm, left, right, tmp1, tmp2); StringCompareStub::GenerateFlatAsciiStringEquals(
masm, left, right, tmp1, tmp2);
} else {
StringCompareStub::GenerateCompareFlatAsciiStrings(
masm, left, right, tmp1, tmp2, tmp3, kScratchRegister);
}
// Handle more complex cases in runtime. // Handle more complex cases in runtime.
__ bind(&runtime); __ bind(&runtime);
...@@ -5690,7 +5698,11 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) { ...@@ -5690,7 +5698,11 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
__ push(left); __ push(left);
__ push(right); __ push(right);
__ push(tmp1); __ push(tmp1);
__ TailCallRuntime(Runtime::kStringEquals, 2, 1); if (equality) {
__ TailCallRuntime(Runtime::kStringEquals, 2, 1);
} else {
__ TailCallRuntime(Runtime::kStringCompare, 2, 1);
}
__ bind(&miss); __ bind(&miss);
GenerateMiss(masm); GenerateMiss(masm);
......
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