Reviewers: adamk,

Message:
PTAL


https://codereview.chromium.org/947443005/diff/1/src/objects.cc
File src/objects.cc (right):

https://codereview.chromium.org/947443005/diff/1/src/objects.cc#newcode801
src/objects.cc:801: if (IsSmi()) {
IsNumber() checked IsSmi() || IsHeapNumber()

If it is a Smi it cannot be a NaN or -0.

https://codereview.chromium.org/947443005/diff/1/src/objects.cc#newcode803
src/objects.cc:803: uint32_t hash =
ComputeLongHash(double_to_uint64(static_cast<double>(num)));
I tried a few other approaches here but it is important that we compute
the same hash code here as in the heap number case.

Description:
Fix issue with -0 in Maps

Because we generated a different hash code for 0 and -0 we ended up
not even getting to the SameValueZero check.

BUG=v8:3906
LOG=N
R=adamk

Please review this at https://codereview.chromium.org/947443005/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+62, -4 lines):
  M src/objects.cc
  A test/mjsunit/es6/map-set-minus-zero.js


Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 100cbf90b3493860d8bd0c5c5b4246d8f57e495d..99b0ab70de998065185c0d504ba487f31b6a08a7 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -798,10 +798,16 @@ Map* Object::GetRootMap(Isolate* isolate) {
 Object* Object::GetHash() {
   // The object is either a number, a name, an odd-ball,
   // a real JS object, or a Harmony proxy.
-  if (IsNumber()) {
-    uint32_t hash = std::isnan(Number())
-                        ? Smi::kMaxValue
-                        : ComputeLongHash(double_to_uint64(Number()));
+  if (IsSmi()) {
+    int num = Smi::cast(this)->value();
+ uint32_t hash = ComputeLongHash(double_to_uint64(static_cast<double>(num)));
+    return Smi::FromInt(hash & Smi::kMaxValue);
+  }
+  if (IsHeapNumber()) {
+    double num = HeapNumber::cast(this)->value();
+    if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue);
+    if (i::IsMinusZero(num)) num = 0;
+    uint32_t hash = ComputeLongHash(double_to_uint64(num));
     return Smi::FromInt(hash & Smi::kMaxValue);
   }
   if (IsName()) {
Index: test/mjsunit/es6/map-set-minus-zero.js
diff --git a/test/mjsunit/es6/map-set-minus-zero.js b/test/mjsunit/es6/map-set-minus-zero.js
new file mode 100644
index 0000000000000000000000000000000000000000..a12121effc6ceff6274c7291e7008bc96d7c5477
--- /dev/null
+++ b/test/mjsunit/es6/map-set-minus-zero.js
@@ -0,0 +1,52 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+var t = new Map();
+
+var objectKey = {};
+var stringKey = 'keykeykey';
+var numberKey = 42.24;
+var booleanKey = true;
+var undefinedKey = undefined;
+var nullKey = null;
+var nanKey = NaN;
+var zeroKey = 0;
+var minusZeroKey = -0;
+
+
+assertEquals(t.size, 0);
+
+t.set(undefinedKey, 'value8');
+t.set(nullKey, 'value9');
+t.set(stringKey, 'value5');
+t.set(numberKey, 'value6');
+t.set(booleanKey, 'value7');
+t.set(objectKey, 'value1');
+t.set(nanKey, 'value10');
+t.set(zeroKey, 'value11');
+
+assertEquals(t.size, 8);
+
+assertEquals(t.get(objectKey), 'value1');
+assertEquals(t.get(stringKey), 'value5');
+assertEquals(t.get(numberKey), 'value6');
+assertEquals(t.get(booleanKey), 'value7');
+assertEquals(t.get(undefinedKey), 'value8');
+assertEquals(t.get(nullKey), 'value9');
+assertEquals(t.get(nanKey), 'value10');
+assertEquals(t.get(zeroKey), 'value11');
+
+assertEquals(t.get({}), undefined);
+assertEquals(t.get('keykeykey'), 'value5');
+assertEquals(t.get(42.24), 'value6');
+assertEquals(t.get(true), 'value7');
+assertEquals(t.get(undefined), 'value8');
+assertEquals(t.get(null), 'value9');
+assertEquals(t.get(NaN), 'value10');
+assertEquals(t.get(0), 'value11');
+assertEquals(t.get(-0), 'value11');
+assertEquals(t.get(1 / Infinity), 'value11');
+assertEquals(t.get(-1 / Infinity), 'value11');


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to