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