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