From 925364f5b447b42c5af748896e552d6e918adca3 Mon Sep 17 00:00:00 2001 From: arv Date: Fri, 20 Feb 2015 13:02:40 -0800 Subject: [PATCH] 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 Review URL: https://codereview.chromium.org/947443005 Cr-Commit-Position: refs/heads/master@{#26787} --- src/objects.cc | 14 ++++++++--- test/mjsunit/es6/map-minus-zero.js | 51 ++++++++++++++++++++++++++++++++++++++ test/mjsunit/es6/set-minus-zero.js | 51 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 test/mjsunit/es6/map-minus-zero.js create mode 100644 test/mjsunit/es6/set-minus-zero.js diff --git a/src/objects.cc b/src/objects.cc index 56c3771..ea4b664 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(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()) { diff --git a/test/mjsunit/es6/map-minus-zero.js b/test/mjsunit/es6/map-minus-zero.js new file mode 100644 index 0000000..f9f397e --- /dev/null +++ b/test/mjsunit/es6/map-minus-zero.js @@ -0,0 +1,51 @@ +// 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 map = 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(map.size, 0); + +map.set(objectKey, 'aaa'); +map.set(stringKey, 'bbb'); +map.set(numberKey, 'ccc'); +map.set(booleanKey, 'ddd'); +map.set(undefinedKey, 'eee'); +map.set(nullKey, 'fff'); +map.set(nanKey, 'ggg'); +map.set(zeroKey, 'hhh'); + +assertEquals(8, map.size); + +assertEquals('aaa', map.get(objectKey)); +assertEquals('bbb', map.get(stringKey)); +assertEquals('ccc', map.get(numberKey)); +assertEquals('ddd', map.get(booleanKey)); +assertEquals('eee', map.get(undefinedKey)); +assertEquals('fff', map.get(nullKey)); +assertEquals('ggg', map.get(nanKey)); +assertEquals('hhh', map.get(zeroKey)); + +assertEquals(undefined, map.get({})); +assertEquals('bbb', map.get('keykeykey')); +assertEquals('ccc', map.get(42.24)); +assertEquals('ddd', map.get(true)); +assertEquals('eee', map.get(undefined)); +assertEquals('fff', map.get(null)); +assertEquals('ggg', map.get(NaN)); +assertEquals('hhh', map.get(0)); +assertEquals('hhh', map.get(-0)); +assertEquals('hhh', map.get(1 / Infinity)); +assertEquals('hhh', map.get(-1 / Infinity)); diff --git a/test/mjsunit/es6/set-minus-zero.js b/test/mjsunit/es6/set-minus-zero.js new file mode 100644 index 0000000..792332c --- /dev/null +++ b/test/mjsunit/es6/set-minus-zero.js @@ -0,0 +1,51 @@ +// Copyright 2015 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 set = new Set(); + +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(set.size, 0); + +set.add(objectKey); +set.add(stringKey); +set.add(numberKey); +set.add(booleanKey); +set.add(undefinedKey); +set.add(nullKey); +set.add(nanKey); +set.add(zeroKey); + +assertEquals(8, set.size); + +assertTrue(set.has(objectKey)); +assertTrue(set.has(stringKey)); +assertTrue(set.has(numberKey)); +assertTrue(set.has(booleanKey)); +assertTrue(set.has(undefinedKey)); +assertTrue(set.has(nullKey)); +assertTrue(set.has(nanKey)); +assertTrue(set.has(zeroKey)); + +assertFalse(set.has({})); +assertTrue(set.has('keykeykey')); +assertTrue(set.has(42.24)); +assertTrue(set.has(true)); +assertTrue(set.has(undefined)); +assertTrue(set.has(null)); +assertTrue(set.has(NaN)); +assertTrue(set.has(0)); +assertTrue(set.has(-0)); +assertTrue(set.has(1 / Infinity)); +assertTrue(set.has(-1 / Infinity)); -- 2.7.4