Commit 2d26a268 authored by Nico Hartmann's avatar Nico Hartmann Committed by Commit Bot

[TurboFan] Fix max double string length in JSNativeContextSpecialization

Some string constant optimizations in JSNativeContextSpecialization
assumed an incorrect maximal string length of double values.

Bug: chromium:1189077, chromium:1178718
Change-Id: Iae531f0e323679a4490e666a971b66655c25c757
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2843361
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74101}
parent c4113c47
......@@ -5,7 +5,6 @@
#include "src/codegen/string-constants.h"
#include "src/base/functional.h"
#include "src/numbers/dtoa.h"
#include "src/objects/objects.h"
#include "src/objects/string-inl.h"
......@@ -176,7 +175,7 @@ size_t StringConstantBase::GetMaxStringConstantLength() const {
size_t StringLiteral::GetMaxStringConstantLength() const { return length_; }
size_t NumberToStringConstant::GetMaxStringConstantLength() const {
return kBase10MaximalLength + 1;
return kMaxDoubleStringLength;
}
size_t StringCons::GetMaxStringConstantLength() const {
......
......@@ -210,6 +210,15 @@ constexpr int kElidedFrameSlots = 0;
#endif
constexpr int kDoubleSizeLog2 = 3;
// The maximal length of the string representation for a double value
// (e.g. "-2.2250738585072020E-308"). It is composed as follows:
// - 17 decimal digits, see kBase10MaximalLength (dtoa.h)
// - 1 sign
// - 1 decimal point
// - 1 E or e
// - 1 exponent sign
// - 3 exponent
constexpr int kMaxDoubleStringLength = 24;
// Total wasm code space per engine (i.e. per process) is limited to make
// certain attacks that rely on heap spraying harder.
......
......@@ -21,7 +21,6 @@
#include "src/compiler/property-access-builder.h"
#include "src/compiler/type-cache.h"
#include "src/execution/isolate-inl.h"
#include "src/numbers/dtoa.h"
#include "src/objects/feedback-vector.h"
#include "src/objects/field-index-inl.h"
#include "src/objects/heap-number.h"
......@@ -140,7 +139,7 @@ base::Optional<size_t> JSNativeContextSpecialization::GetMaxStringLength(
NumberMatcher number_matcher(node);
if (number_matcher.HasResolvedValue()) {
return kBase10MaximalLength + 1;
return kMaxDoubleStringLength;
}
// We don't support objects with possibly monkey-patched prototype.toString
......
......@@ -23,9 +23,14 @@ enum DtoaMode {
DTOA_PRECISION
};
// The maximal length of digits a double can have in base 10.
// Note that DoubleToAscii null-terminates its input. So the given buffer should
// be at least kBase10MaximalLength + 1 characters long.
// The maximal length of digits a double can have in base 10 as returned by
// 'DoubleToAscii'. This does neither include sign, decimal point nor exponent.
// For example DoubleToAscii(-3.5844466002796428e+298, ..., buffer, ...) will
// fill buffer with the string "35844466002796428", while sign and decimal point
// position will be provided through additional output arguments.
// kBase10MaximalLength refers to the maximal length of this string. Note that
// DoubleToAscii null-terminates its input. So the given buffer should be at
// least kBase10MaximalLength + 1 characters long.
const int kBase10MaximalLength = 17;
// Converts the given double 'v' to ASCII.
......
// Copyright 2021 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 string_max_length = %StringMaxLength();
const longest_double = -2.2250738585105353E-308;
const s18 = "A".repeat(string_max_length - 18);
const s23 = "A".repeat(string_max_length - 23);
const s24 = "A".repeat(string_max_length - 24);
const s25 = "A".repeat(string_max_length - 25);
(function() {
function f() {
return s18 + longest_double;
}
%PrepareFunctionForOptimization(f);
assertThrows(f, RangeError);
%OptimizeFunctionOnNextCall(f);
assertThrows(f, RangeError);
})();
(function() {
function f() {
return s23 + longest_double;
}
%PrepareFunctionForOptimization(f);
assertThrows(f, RangeError);
%OptimizeFunctionOnNextCall(f);
assertThrows(f, RangeError);
})();
(function() {
function f() {
return s24 + longest_double;
}
%PrepareFunctionForOptimization(f);
assertEquals(string_max_length, f().length);
%OptimizeFunctionOnNextCall(f);
assertEquals(string_max_length, f().length);
})();
(function() {
function f() {
return s25 + longest_double;
}
%PrepareFunctionForOptimization(f);
assertEquals(string_max_length - 1, f().length);
%OptimizeFunctionOnNextCall(f);
assertEquals(string_max_length - 1, f().length);
})();
......@@ -8,7 +8,6 @@
#include "src/compiler/js-operator.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/simplified-operator.h"
#include "src/numbers/dtoa.h"
namespace v8 {
namespace internal {
......@@ -30,7 +29,7 @@ class JSNativeContextSpecializationTest : public GraphTest {
TEST_F(JSNativeContextSpecializationTest, GetMaxStringLengthOfString) {
const size_t str_len = 3;
const size_t num_len = kBase10MaximalLength + 1;
const size_t num_len = kMaxDoubleStringLength;
Node* const str_node = graph()->NewNode(
common()->HeapConstant(factory()->InternalizeUtf8String("str")));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment