Commit 96a42ce5 authored by jameslahm's avatar jameslahm Committed by V8 LUCI CQ

[web snapshot] Support BigInt

Bug: v8:11525
Change-Id: I69c08f3cc4ee6b391e462a5d49de750f34bbc8cf
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3815487Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: 王澳 <wangao.james@bytedance.com>
Cr-Commit-Position: refs/heads/main@{#82345}
parent 45a74f3a
......@@ -488,6 +488,7 @@ class RuntimeCallTimer final {
V(WebSnapshotDeserialize) \
V(WebSnapshotDeserialize_Arrays) \
V(WebSnapshotDeserialize_ArrayBuffers) \
V(WebSnapshotDeserialize_BigInts) \
V(WebSnapshotDeserialize_BuiltinObjects) \
V(WebSnapshotDeserialize_Classes) \
V(WebSnapshotDeserialize_Contexts) \
......
......@@ -32,6 +32,9 @@ bool MutableBigInt_AbsoluteMulAndCanonicalize(Address result_addr,
class BigInt;
class ValueDeserializer;
class ValueSerializer;
class WebSnapshotSerializerDeserializer;
class WebSnapshotSerializer;
class WebSnapshotDeserializer;
#include "torque-generated/src/objects/bigint-tq.inc"
......@@ -254,6 +257,9 @@ class BigInt : public BigIntBase {
friend class StringToBigIntHelper;
friend class ValueDeserializer;
friend class ValueSerializer;
friend class WebSnapshotSerializerDeserializer;
friend class WebSnapshotSerializer;
friend class WebSnapshotDeserializer;
// Special functions for StringToBigIntHelper:
template <typename IsolateT>
......
This diff is collapsed.
......@@ -8,6 +8,7 @@
#include <queue>
#include "src/handles/handles.h"
#include "src/objects/bigint.h"
#include "src/objects/value-serializer.h"
#include "src/snapshot/serializer.h" // For ObjectCacheIndexMap
......@@ -61,7 +62,8 @@ class WebSnapshotSerializerDeserializer {
IN_PLACE_STRING_ID,
ARRAY_BUFFER_ID,
TYPED_ARRAY_ID,
DATA_VIEW_ID
DATA_VIEW_ID,
BIGINT_ID
};
enum SymbolType : uint8_t {
......@@ -111,6 +113,8 @@ class WebSnapshotSerializerDeserializer {
uint8_t ArrayBufferKindToFlags(Handle<JSArrayBuffer> array_buffer);
uint32_t BigIntSignAndLengthToFlags(Handle<BigInt> bigint);
uint32_t BigIntFlagsToBitField(uint32_t flags);
// The maximum count of items for each value type (strings, objects etc.)
static constexpr uint32_t kMaxItemCount =
static_cast<uint32_t>(FixedArray::kMaxLength - 1);
......@@ -150,6 +154,12 @@ class WebSnapshotSerializerDeserializer {
// constructed without the specified length argument.
using LengthTrackingBitField = base::BitField<bool, 0, 1, uint8_t>;
// Encode BigInt's sign and digits length.
using BigIntSignBitField = base::BitField<bool, 0, 1>;
using BigIntLengthBitField =
BigIntSignBitField::Next<int, BigInt::kLengthFieldBits>;
static_assert(BigIntLengthBitField::kSize == BigInt::LengthBits::kSize);
private:
WebSnapshotSerializerDeserializer(const WebSnapshotSerializerDeserializer&) =
delete;
......@@ -193,6 +203,10 @@ class V8_EXPORT WebSnapshotSerializer
return static_cast<uint32_t>(symbol_ids_.size());
}
uint32_t bigint_count() const {
return static_cast<uint32_t>(bigint_ids_.size());
}
uint32_t map_count() const { return static_cast<uint32_t>(map_ids_.size()); }
uint32_t builtin_object_count() const {
......@@ -261,6 +275,7 @@ class V8_EXPORT WebSnapshotSerializer
void DiscoverString(Handle<String> string,
AllowInPlace can_be_in_place = AllowInPlace::No);
void DiscoverSymbol(Handle<Symbol> symbol);
void DiscoverBigInt(Handle<BigInt> bigint);
void DiscoverMap(Handle<Map> map, bool allow_property_in_descriptor = false);
void DiscoverPropertyKey(Handle<Name> key);
void DiscoverMapForFunction(Handle<JSFunction> function);
......@@ -287,6 +302,7 @@ class V8_EXPORT WebSnapshotSerializer
ValueSerializer& serializer);
void SerializeString(Handle<String> string, ValueSerializer& serializer);
void SerializeSymbol(Handle<Symbol> symbol);
void SerializeBigInt(Handle<BigInt> bigint);
void SerializeMap(Handle<Map> map);
void SerializeBuiltinObject(uint32_t name_id);
void SerializeObjectPrototype(Handle<Map> map, ValueSerializer& serializer);
......@@ -313,6 +329,7 @@ class V8_EXPORT WebSnapshotSerializer
uint32_t GetStringId(Handle<String> string, bool& in_place);
uint32_t GetSymbolId(Symbol symbol);
uint32_t GetBigIntId(BigInt bigint);
uint32_t GetMapId(Map map);
uint32_t GetFunctionId(JSFunction function);
uint32_t GetClassId(JSFunction function);
......@@ -329,6 +346,7 @@ class V8_EXPORT WebSnapshotSerializer
ValueSerializer string_serializer_;
ValueSerializer symbol_serializer_;
ValueSerializer bigint_serializer_;
ValueSerializer map_serializer_;
ValueSerializer builtin_object_serializer_;
ValueSerializer context_serializer_;
......@@ -344,6 +362,7 @@ class V8_EXPORT WebSnapshotSerializer
// These are needed for being able to serialize items in order.
Handle<ArrayList> strings_;
Handle<ArrayList> symbols_;
Handle<ArrayList> bigints_;
Handle<ArrayList> maps_;
Handle<ArrayList> contexts_;
Handle<ArrayList> functions_;
......@@ -364,6 +383,7 @@ class V8_EXPORT WebSnapshotSerializer
// have a lower ID and will be deserialized first.
ObjectCacheIndexMap string_ids_;
ObjectCacheIndexMap symbol_ids_;
ObjectCacheIndexMap bigint_ids_;
ObjectCacheIndexMap map_ids_;
ObjectCacheIndexMap context_ids_;
ObjectCacheIndexMap function_ids_;
......@@ -467,6 +487,7 @@ class V8_EXPORT WebSnapshotDeserializer
void DeserializeStrings();
void DeserializeSymbols();
void DeserializeBigInts();
void DeserializeMaps();
void DeserializeBuiltinObjects();
void DeserializeContexts();
......@@ -516,6 +537,7 @@ class V8_EXPORT WebSnapshotDeserializer
String ReadInPlaceString(
InternalizeStrings internalize_strings = InternalizeStrings::kNo);
Object ReadSymbol();
Object ReadBigInt();
std::tuple<Object, bool> ReadArray(Handle<HeapObject> container,
uint32_t container_index);
std::tuple<Object, bool> ReadArrayBuffer(Handle<HeapObject> container,
......@@ -559,6 +581,9 @@ class V8_EXPORT WebSnapshotDeserializer
Handle<FixedArray> symbols_handle_;
FixedArray symbols_;
Handle<FixedArray> bigints_handle_;
FixedArray bigints_;
Handle<FixedArray> builtin_objects_handle_;
FixedArray builtin_objects_;
......@@ -610,6 +635,7 @@ class V8_EXPORT WebSnapshotDeserializer
uint32_t string_count_ = 0;
uint32_t symbol_count_ = 0;
uint32_t bigint_count_ = 0;
uint32_t map_count_ = 0;
uint32_t builtin_object_count_ = 0;
uint32_t context_count_ = 0;
......
// Copyright 2022 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: --experimental-d8-web-snapshot-api --allow-natives-syntax
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestBigInt() {
function createObjects() {
const b = 100n;
const c = 2n ** 222n;
globalThis.foo = { bar: b, bar1: c };
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(100n, foo.bar);
assertEquals(2n ** 222n , foo.bar1)
})();
(function TestBigIntInArray() {
function createObjects() {
const b = 100n;
const c = 2n ** 222n;
globalThis.foo = [b, c];
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([100n, 2n ** 222n], foo)
})();
(function TestBigIntInFunctionContext() {
function createObjects() {
globalThis.foo = {
key: (function () {
const b = 100n;
const c = 2n ** 222n;
function inner() {
return [b, c];
}
return inner;
})()
};
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([100n, 2n**222n], foo.key());
})();
(function TestBigIntInFunctionContextWithParentContext() {
function createObjects() {
globalThis.foo = {
key: (function () {
const b = 100n;
function inner() {
const c = 2n ** 222n;
function innerinner() {
return [b, c]
}
return innerinner
}
return inner();
})()
};
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([100n, 2n**222n], foo.key());
})();
(function TestBigIntInTopLevelFunctionWithContext() {
function createObjects() {
globalThis.foo = (function () {
const b = 100n;
const c = 2n ** 222n;
function inner() { return [b, c]; }
return inner;
})();
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([100n, 2n**222n], foo());
})();
(function TestBigIntInClassStaticProperty() {
function createObjects() {
globalThis.foo = class Foo {
static b = 100n;
static c = 2n ** 222n;
};
}
const { foo: Foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([100n, 2n**222n], [Foo.b, Foo.c]);
})();
(function TestBigIntInClassWithConstructor() {
function createObjects() {
globalThis.foo = class Foo {
constructor() {
this.b = 100n;
this.c = 2n ** 222n;
}
};
}
const { foo: Foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
const foo = new Foo()
assertEquals([100n, 2n**222n], [foo.b, foo.c]);
})();
(async function TestBigIntInClassWithMethods() {
function createObjects() {
globalThis.foo = class Foo {
b() {
return 100n;
}
async c() {
return 2n ** 222n;
}
};
}
const { foo: Foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
const foo = new Foo()
assertEquals([100n, 2n**222n], [foo.b(), await foo.c()]);
})();
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