Add fast negative checks for symbol equality: If we're comparing
authorkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Jun 2009 12:54:07 +0000 (12:54 +0000)
committerkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Jun 2009 12:54:07 +0000 (12:54 +0000)
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
src/ia32/codegen-ia32.cc

index 9aecadbec6c3b3a45376cb802fb3f730b94389f7..0a89783b4fcaddd412dae39770d704e84fe7f1df 100644 (file)
@@ -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);
 }
 
 
index 42fe9da9f5ee18a3b0c3a4ed484b32b4ec806898..01caa9aae7ee13b37568d142cf2f9a6e0fb2b842 100644 (file)
@@ -1806,6 +1806,12 @@ class CompareStub: public CodeStub {
     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 @@ 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