From 01216a069be410cf0c403446ab2a06cff0a4dbd9 Mon Sep 17 00:00:00 2001 From: "kasperl@chromium.org" Date: Tue, 16 Jun 2009 12:54:07 +0000 Subject: [PATCH] Add fast negative checks for symbol equality: If we're comparing two symbols, they're only equal if the objects are identical. Review URL: http://codereview.chromium.org/125184 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2188 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/date-delay.js | 5 ++++- src/ia32/codegen-ia32.cc | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/date-delay.js b/src/date-delay.js index 9aecadb..0a89783 100644 --- a/src/date-delay.js +++ b/src/date-delay.js @@ -150,6 +150,8 @@ var DST_offset_cache = { }; +// NOTE: The implementation relies on the fact that no time zones have +// more than one daylight savings offset change per month. function DaylightSavingsOffset(t) { // Load the cache object from the builtins object. var cache = DST_offset_cache; @@ -530,7 +532,8 @@ function GetUTCHoursFrom(aDate) { function GetFullYearFrom(aDate) { var t = GetTimeFrom(aDate); if ($isNaN(t)) return t; - return YearFromTime(LocalTimeNoCheck(t)); + // Ignore the DST offset for year computations. + return YearFromTime(t + local_time_offset); } diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 42fe9da..01caa9a 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -1806,6 +1806,12 @@ class CompareStub: public CodeStub { return (static_cast(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 @@ void CompareStub::Generate(MacroAssembler* masm) { __ 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 @@ void CompareStub::Generate(MacroAssembler* masm) { __ 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::Generate(MacroAssembler* masm) { } +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 -- 2.7.4