Index: src/ia32/codegen-ia32.cc |
=================================================================== |
--- src/ia32/codegen-ia32.cc (revision 2186) |
+++ src/ia32/codegen-ia32.cc (working copy) |
@@ -1806,6 +1806,12 @@ |
return (static_cast<int>(cc_) << 1) | (strict_ ? 1 : 0); |
} |
+ // Branch to the label if the given object isn't a symbol. |
+ void BranchIfNonSymbol(MacroAssembler* masm, |
+ Label* label, |
+ Register object, |
+ Register scratch); |
+ |
#ifdef DEBUG |
void Print() { |
PrintF("CompareStub (cc %d), (strict %s)\n", |
@@ -6992,17 +6998,16 @@ |
__ bind(&slow); |
} |
- // Save the return address (and get it off the stack). |
+ // Push arguments below the return address. |
__ pop(ecx); |
- |
- // Push arguments. |
__ push(eax); |
__ push(edx); |
__ push(ecx); |
// Inlined floating point compare. |
// Call builtin if operands are not floating point or smi. |
- FloatingPointHelper::CheckFloatOperands(masm, &call_builtin, ebx); |
+ Label check_for_symbols; |
+ FloatingPointHelper::CheckFloatOperands(masm, &check_for_symbols, ebx); |
FloatingPointHelper::LoadFloatOperands(masm, ecx); |
__ FCmp(); |
@@ -7026,6 +7031,18 @@ |
__ mov(eax, 1); |
__ ret(2 * kPointerSize); // eax, edx were pushed |
+ // Fast negative check for symbol-to-symbol equality. |
+ __ bind(&check_for_symbols); |
+ if (cc_ == equal) { |
+ BranchIfNonSymbol(masm, &call_builtin, eax, ecx); |
+ BranchIfNonSymbol(masm, &call_builtin, edx, ecx); |
+ |
+ // We've already checked for object identity, so if both operands |
+ // are symbols they aren't equal. Register eax already holds a |
+ // non-zero value, which indicates not equal, so just return. |
+ __ ret(2 * kPointerSize); |
+ } |
+ |
__ bind(&call_builtin); |
// must swap argument order |
__ pop(ecx); |
@@ -7059,6 +7076,20 @@ |
} |
+void CompareStub::BranchIfNonSymbol(MacroAssembler* masm, |
+ Label* label, |
+ Register object, |
+ Register scratch) { |
+ __ test(object, Immediate(kSmiTagMask)); |
+ __ j(zero, label); |
+ __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset)); |
+ __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
+ __ and_(scratch, kIsSymbolMask | kIsNotStringMask); |
+ __ cmp(scratch, kSymbolTag | kStringTag); |
+ __ j(not_equal, label); |
+} |
+ |
+ |
void StackCheckStub::Generate(MacroAssembler* masm) { |
// Because builtins always remove the receiver from the stack, we |
// have to fake one to avoid underflowing the stack. The receiver |