Commit 088de5d3 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by V8 LUCI CQ

[inspector] Speed up inspection of large BigInts.

For large BigInts, computing the decimal representation can take a
very long time, so send them as hexadecimal strings instead. Also
make sure to abbreviate the RemoteObject description for bigints
appropriately always.

Also-By: jarin@chromium.org
Fixed: chromium:1068663
Change-Id: I2f7e4e1cbd2f66ce45be307fb787e101d9a8e2a7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3578653
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79872}
parent 989c6641
......@@ -50,6 +50,40 @@ v8_inspector::V8Inspector* GetInspector(Isolate* isolate) {
return reinterpret_cast<i::Isolate*>(isolate)->inspector();
}
Local<String> GetBigIntDescription(Isolate* isolate, Local<BigInt> bigint) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::BigInt> i_bigint = Utils::OpenHandle(*bigint);
// For large BigInts computing the decimal string representation
// can take a long time, so we go with hexadecimal in that case.
int radix = (i_bigint->Words64Count() > 100 * 1000) ? 16 : 10;
i::Handle<i::String> string =
i::BigInt::ToString(i_isolate, i_bigint, radix, i::kDontThrow)
.ToHandleChecked();
if (radix == 16) {
if (i_bigint->IsNegative()) {
string = i_isolate->factory()
->NewConsString(
i_isolate->factory()->NewStringFromAsciiChecked("-0x"),
i_isolate->factory()->NewProperSubString(
string, 1, string->length() - 1))
.ToHandleChecked();
} else {
string =
i_isolate->factory()
->NewConsString(
i_isolate->factory()->NewStringFromAsciiChecked("0x"), string)
.ToHandleChecked();
}
}
i::Handle<i::String> description =
i_isolate->factory()
->NewConsString(
string,
i_isolate->factory()->LookupSingleCharacterStringFromCode('n'))
.ToHandleChecked();
return Utils::ToLocal(description);
}
Local<String> GetDateDescription(Local<Date> date) {
auto receiver = Utils::OpenHandle(*date);
i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(receiver);
......
......@@ -50,6 +50,9 @@ int GetContextId(Local<Context> context);
void SetInspector(Isolate* isolate, v8_inspector::V8Inspector*);
v8_inspector::V8Inspector* GetInspector(Isolate* isolate);
// Returns a debug string representation of the bigint.
Local<String> GetBigIntDescription(Isolate* isolate, Local<BigInt> bigint);
// Returns a debug string representation of the date.
Local<String> GetDateDescription(Local<Date> date);
......
......@@ -209,10 +209,9 @@ String16 descriptionForSymbol(v8::Local<v8::Context> context,
String16 descriptionForBigInt(v8::Local<v8::Context> context,
v8::Local<v8::BigInt> value) {
v8::Isolate* isolate = context->GetIsolate();
v8::TryCatch tryCatch(isolate);
v8::Local<v8::String> description;
if (!value->ToString(context).ToLocal(&description)) return String16();
return toProtocolString(isolate, description) + "n";
v8::Local<v8::String> description =
v8::debug::GetBigIntDescription(isolate, value);
return toProtocolString(isolate, description);
}
String16 descriptionForPrimitiveType(v8::Local<v8::Context> context,
......@@ -516,7 +515,7 @@ class BigIntMirror final : public ValueMirror {
*result = RemoteObject::create()
.setType(RemoteObject::TypeEnum::Bigint)
.setUnserializableValue(description)
.setDescription(description)
.setDescription(abbreviateString(description, kMiddle))
.build();
return Response::Success();
}
......@@ -540,7 +539,8 @@ class BigIntMirror final : public ValueMirror {
*preview =
ObjectPreview::create()
.setType(RemoteObject::TypeEnum::Bigint)
.setDescription(descriptionForBigInt(context, m_value))
.setDescription(abbreviateString(
descriptionForBigInt(context, m_value), kMiddle))
.setOverflow(false)
.setProperties(std::make_unique<protocol::Array<PropertyPreview>>())
.build();
......
......@@ -395,6 +395,23 @@ Running test: testBigInt
unserializableValue : -5n
}
}
'1n << 9_999_999n', returnByValue: false, generatePreview: false
{
result : {
description : 0x800000000000000000000000000000000000000000000000…000000000000000000000000000000000000000000000000n
type : bigint
unserializableValue : <expected unserializableValue>
}
}
'-1n << 9_999_999n', returnByValue: false, generatePreview: false
100
{
result : {
description : -0x80000000000000000000000000000000000000000000000…000000000000000000000000000000000000000000000000n
type : bigint
unserializableValue : <expected unserializableValue>
}
}
Running test: testRegExp
'/w+/d', returnByValue: false, generatePreview: false
......
......@@ -198,6 +198,19 @@ InspectorTest.runAsyncTestSuite([
expression: '-5n',
generatePreview: true
})).result);
let result = (await evaluate({
expression: '1n << 9_999_999n'
})).result;
if (result.result.unserializableValue === '0x8' + '0'.repeat(2_499_999) + 'n')
result.result.unserializableValue = '<expected unserializableValue>';
InspectorTest.logMessage(result);
result = (await evaluate({
expression: '-1n << 9_999_999n'
})).result;
InspectorTest.logMessage(result.result.description.length);
if (result.result.unserializableValue === '-0x8' + '0'.repeat(2_499_998) + 'n')
result.result.unserializableValue = '<expected unserializableValue>';
InspectorTest.logMessage(result);
},
async function testRegExp() {
InspectorTest.logMessage((await evaluate({
......
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