Revision: 6399
Author: [email protected]
Date: Wed Jan 19 05:52:08 2011
Log: X64: Fix bug in DoBranch that miss detecting NaN as falsy.

Review URL: http://codereview.chromium.org/6369005
http://code.google.com/p/v8/source/detail?r=6399

Modified:
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h

=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Jan 19 02:17:18 2011 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Jan 19 05:52:08 2011
@@ -977,25 +977,27 @@
       Label* true_label = chunk_->GetAssemblyLabel(true_block);
       Label* false_label = chunk_->GetAssemblyLabel(false_block);

-      __ Cmp(reg, Factory::undefined_value());
+      __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
       __ j(equal, false_label);
-      __ Cmp(reg, Factory::true_value());
+      __ CompareRoot(reg, Heap::kTrueValueRootIndex);
       __ j(equal, true_label);
-      __ Cmp(reg, Factory::false_value());
+      __ CompareRoot(reg, Heap::kFalseValueRootIndex);
       __ j(equal, false_label);
       __ SmiCompare(reg, Smi::FromInt(0));
       __ j(equal, false_label);
       __ JumpIfSmi(reg, true_label);

-      // Test for double values. Plus/minus zero are false. NaN is handled
-      // in the stub.
+      // Test for double values. Plus/minus zero and NaN are false.
       NearLabel call_stub;
-      __ Cmp(FieldOperand(reg, HeapObject::kMapOffset),
-             Factory::heap_number_map());
+      __ CompareRoot(FieldOperand(reg, HeapObject::kMapOffset),
+                     Heap::kHeapNumberMapRootIndex);
       __ j(not_equal, &call_stub);
- __ movq(kScratchRegister, FieldOperand(reg, HeapNumber::kValueOffset));
-      __ shl(kScratchRegister, Immediate(1));  // Shift out the sign bit.
-      __ j(zero, false_label);  // Zero or negative zero.
+
+      // HeapNumber => false iff +0, -0, or NaN. These three cases set the
+      // zero flag when compared to zero using ucomisd.
+      __ xorpd(xmm0, xmm0);
+      __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset));
+      __ j(zero, false_label);
       __ jmp(true_label);

       // The conversion stub doesn't cause garbage collections so it's
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Wed Jan 19 02:17:18 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Wed Jan 19 05:52:08 2011
@@ -1326,10 +1326,10 @@
 };


-class LCallKeyed: public LTemplateInstruction<1, 0, 1> {
+class LCallKeyed: public LTemplateInstruction<1, 1, 0> {
  public:
-  explicit LCallKeyed(LOperand* temp) {
-    temps_[0] = temp;
+  explicit LCallKeyed(LOperand* key) {
+    inputs_[0] = key;
   }

   DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
@@ -1898,30 +1898,30 @@
   MUST_USE_RESULT LOperand* UseRegister(HValue* value);
   MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);

-  // A value in a register that may be trashed.
+  // An input operand in a register that may be trashed.
   MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);

-  // An operand value in a register or stack slot.
+  // An input operand in a register or stack slot.
   MUST_USE_RESULT LOperand* Use(HValue* value);
   MUST_USE_RESULT LOperand* UseAtStart(HValue* value);

-  // An operand value in a register, stack slot or a constant operand.
+  // An input operand in a register, stack slot or a constant operand.
   MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
   MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);

-  // An operand value in a register or a constant operand.
+  // An input operand in a register or a constant operand.
   MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
   MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);

+  // An input operand in register, stack slot or a constant operand.
+  // Will not be moved to a register even if one is freely available.
+  MUST_USE_RESULT LOperand* UseAny(HValue* value);
+
   // Temporary operand that must be in a register.
   MUST_USE_RESULT LUnallocated* TempRegister();
   MUST_USE_RESULT LOperand* FixedTemp(Register reg);
   MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg);

-  // An operand value in register, stack slot or a constant operand.
-  // Will not be moved to a register even if one is freely available.
-  LOperand* UseAny(HValue* value);
-
   // Methods for setting up define-use relationships.
   // Return the same instruction that they are passed.
   template<int I, int T>

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to