Commit 4aa97de1 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[conversions] Speed up double to CString conversion

This addresses most of the regression in of
Kraken's json-stringify-tinderbox-orig with
31bit Smis: Many object properties become heap
numbers, and printing an integer which is
represented as a double is slower than printing
the integer directly.

Change-Id: I9a14c4da61721b6c3f22e88145acc6a61ed4a419
Bug: v8:8344
Reviewed-on: https://chromium-review.googlesource.com/c/1382741Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58358}
parent 89a64f04
......@@ -936,6 +936,11 @@ const char* DoubleToCString(double v, Vector<char> buffer) {
case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity");
case FP_ZERO: return "0";
default: {
if (IsInt32Double(v)) {
// This will trigger if v is -0 and -0.0 is stringified to "0".
// (see ES section 7.1.12.1 #sec-tostring-applied-to-the-number-type)
return IntToCString(FastD2I(v), buffer);
}
SimpleStringBuilder builder(buffer.start(), buffer.length());
int decimal_point;
int sign;
......@@ -986,18 +991,17 @@ const char* DoubleToCString(double v, Vector<char> buffer) {
const char* IntToCString(int n, Vector<char> buffer) {
bool negative = false;
if (n < 0) {
// We must not negate the most negative int.
if (n == kMinInt) return DoubleToCString(n, buffer);
negative = true;
bool negative = true;
if (n >= 0) {
n = -n;
negative = false;
}
// Build the string backwards from the least significant digit.
int i = buffer.length();
buffer[--i] = '\0';
do {
buffer[--i] = '0' + (n % 10);
// We ensured n <= 0, so the subtraction does the right addition.
buffer[--i] = '0' - (n % 10);
n /= 10;
} while (n);
if (negative) buffer[--i] = '-';
......
......@@ -115,11 +115,12 @@ const int kDoubleToCStringMinBufferSize = 100;
// Converts a double to a string value according to ECMA-262 9.8.1.
// The buffer should be large enough for any floating point number.
// 100 characters is enough.
const char* DoubleToCString(double value, Vector<char> buffer);
V8_EXPORT_PRIVATE const char* DoubleToCString(double value,
Vector<char> buffer);
// Convert an int to a null-terminated string. The returned string is
// located inside the buffer, but not necessarily at the start.
const char* IntToCString(int n, Vector<char> buffer);
V8_EXPORT_PRIVATE const char* IntToCString(int n, Vector<char> buffer);
// Additional number to string conversions for the number type.
// The caller is responsible for calling free on the returned pointer.
......
......@@ -144,6 +144,7 @@ v8_source_set("unittests_sources") {
"compiler/typer-unittest.cc",
"compiler/value-numbering-reducer-unittest.cc",
"compiler/zone-stats-unittest.cc",
"conversions-unittest.cc",
"counters-unittest.cc",
"detachable-vector-unittest.cc",
"eh-frame-iterator-unittest.cc",
......
// Copyright 2016 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.
#include "src/v8.h"
#include "src/conversions.h"
#include "test/unittests/test-utils.h"
namespace v8 {
namespace internal {
namespace interpreter {
class ConversionsTest : public ::testing::Test {
public:
ConversionsTest() = default;
~ConversionsTest() override = default;
SourcePosition toPos(int offset) {
return SourcePosition(offset, offset % 10 - 1);
}
};
// Some random offsets, mostly at 'suspicious' bit boundaries.
struct IntStringPair {
int integer;
std::string string;
};
static IntStringPair int_pairs[] = {{0, "0"},
{101, "101"},
{-1, "-1"},
{1024, "1024"},
{200000, "200000"},
{-1024, "-1024"},
{-200000, "-200000"},
{kMinInt, "-2147483648"},
{kMaxInt, "2147483647"}};
TEST_F(ConversionsTest, IntToCString) {
std::unique_ptr<char[]> buf(new char[4096]);
for (size_t i = 0; i < arraysize(int_pairs); i++) {
ASSERT_STREQ(IntToCString(int_pairs[i].integer, {buf.get(), 4096}),
int_pairs[i].string.c_str());
}
}
struct DoubleStringPair {
double number;
std::string string;
};
static DoubleStringPair double_pairs[] = {
{0.0, "0"},
{kMinInt, "-2147483648"},
{kMaxInt, "2147483647"},
// ES section 7.1.12.1 #sec-tostring-applied-to-the-number-type:
// -0.0 is stringified to "0".
{-0.0, "0"},
{1.1, "1.1"},
{0.1, "0.1"}};
TEST_F(ConversionsTest, DoubleToCString) {
std::unique_ptr<char[]> buf(new char[4096]);
for (size_t i = 0; i < arraysize(double_pairs); i++) {
ASSERT_STREQ(DoubleToCString(double_pairs[i].number, {buf.get(), 4096}),
double_pairs[i].string.c_str());
}
}
} // namespace interpreter
} // namespace internal
} // namespace v8
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