[strings] Fix hash for exactly 512MB long strings

Bug: chromium:1016237
Change-Id: Idda1e44b5d578d1213aa54927ca68289bcdce8ac
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1878487
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64552}
This commit is contained in:
Jakob Kummerow 2019-10-24 17:49:23 +02:00 committed by Commit Bot
parent 7228ef8040
commit 556f44c494
2 changed files with 21 additions and 3 deletions

View File

@ -33,9 +33,18 @@ uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
uint32_t StringHasher::GetTrivialHash(int length) {
DCHECK_GT(length, String::kMaxHashCalcLength);
// String hash of a large string is simply the length.
return (static_cast<uint32_t>(length) << String::kHashShift) |
String::kIsNotArrayIndexMask | String::kIsNotIntegerIndexMask;
// The hash of a large string is simply computed from the length. We don't
// have quite enough bits, so we drop the least significant bit.
// TODO(9904): Free up one bit, so we don't have to drop anything here.
constexpr int kDroppedBits = 1;
// Ensure that the max length after dropping bits is small enough to be
// shifted without losing information.
STATIC_ASSERT(base::bits::CountLeadingZeros32(String::kMaxLength) +
kDroppedBits >=
String::kHashShift);
uint32_t hash = static_cast<uint32_t>(length) >> kDroppedBits;
return (hash << String::kHashShift) | String::kIsNotArrayIndexMask |
String::kIsNotIntegerIndexMask;
}
template <typename schar>

View File

@ -0,0 +1,9 @@
// Copyright 2019 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.
// Flags: --allow-natives-syntax
const kLength = Math.min(536870912, %StringMaxLength());
const v2 = "foo".padEnd(kLength);
delete v2[v2];