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 { ...@@ -488,6 +488,7 @@ class RuntimeCallTimer final {
V(WebSnapshotDeserialize) \ V(WebSnapshotDeserialize) \
V(WebSnapshotDeserialize_Arrays) \ V(WebSnapshotDeserialize_Arrays) \
V(WebSnapshotDeserialize_ArrayBuffers) \ V(WebSnapshotDeserialize_ArrayBuffers) \
V(WebSnapshotDeserialize_BigInts) \
V(WebSnapshotDeserialize_BuiltinObjects) \ V(WebSnapshotDeserialize_BuiltinObjects) \
V(WebSnapshotDeserialize_Classes) \ V(WebSnapshotDeserialize_Classes) \
V(WebSnapshotDeserialize_Contexts) \ V(WebSnapshotDeserialize_Contexts) \
......
...@@ -32,6 +32,9 @@ bool MutableBigInt_AbsoluteMulAndCanonicalize(Address result_addr, ...@@ -32,6 +32,9 @@ bool MutableBigInt_AbsoluteMulAndCanonicalize(Address result_addr,
class BigInt; class BigInt;
class ValueDeserializer; class ValueDeserializer;
class ValueSerializer; class ValueSerializer;
class WebSnapshotSerializerDeserializer;
class WebSnapshotSerializer;
class WebSnapshotDeserializer;
#include "torque-generated/src/objects/bigint-tq.inc" #include "torque-generated/src/objects/bigint-tq.inc"
...@@ -254,6 +257,9 @@ class BigInt : public BigIntBase { ...@@ -254,6 +257,9 @@ class BigInt : public BigIntBase {
friend class StringToBigIntHelper; friend class StringToBigIntHelper;
friend class ValueDeserializer; friend class ValueDeserializer;
friend class ValueSerializer; friend class ValueSerializer;
friend class WebSnapshotSerializerDeserializer;
friend class WebSnapshotSerializer;
friend class WebSnapshotDeserializer;
// Special functions for StringToBigIntHelper: // Special functions for StringToBigIntHelper:
template <typename IsolateT> template <typename IsolateT>
......
This diff is collapsed.
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <queue> #include <queue>
#include "src/handles/handles.h" #include "src/handles/handles.h"
#include "src/objects/bigint.h"
#include "src/objects/value-serializer.h" #include "src/objects/value-serializer.h"
#include "src/snapshot/serializer.h" // For ObjectCacheIndexMap #include "src/snapshot/serializer.h" // For ObjectCacheIndexMap
...@@ -61,7 +62,8 @@ class WebSnapshotSerializerDeserializer { ...@@ -61,7 +62,8 @@ class WebSnapshotSerializerDeserializer {
IN_PLACE_STRING_ID, IN_PLACE_STRING_ID,
ARRAY_BUFFER_ID, ARRAY_BUFFER_ID,
TYPED_ARRAY_ID, TYPED_ARRAY_ID,
DATA_VIEW_ID DATA_VIEW_ID,
BIGINT_ID
}; };
enum SymbolType : uint8_t { enum SymbolType : uint8_t {
...@@ -111,6 +113,8 @@ class WebSnapshotSerializerDeserializer { ...@@ -111,6 +113,8 @@ class WebSnapshotSerializerDeserializer {
uint8_t ArrayBufferKindToFlags(Handle<JSArrayBuffer> array_buffer); 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.) // The maximum count of items for each value type (strings, objects etc.)
static constexpr uint32_t kMaxItemCount = static constexpr uint32_t kMaxItemCount =
static_cast<uint32_t>(FixedArray::kMaxLength - 1); static_cast<uint32_t>(FixedArray::kMaxLength - 1);
...@@ -150,6 +154,12 @@ class WebSnapshotSerializerDeserializer { ...@@ -150,6 +154,12 @@ class WebSnapshotSerializerDeserializer {
// constructed without the specified length argument. // constructed without the specified length argument.
using LengthTrackingBitField = base::BitField<bool, 0, 1, uint8_t>; 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: private:
WebSnapshotSerializerDeserializer(const WebSnapshotSerializerDeserializer&) = WebSnapshotSerializerDeserializer(const WebSnapshotSerializerDeserializer&) =
delete; delete;
...@@ -193,6 +203,10 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -193,6 +203,10 @@ class V8_EXPORT WebSnapshotSerializer
return static_cast<uint32_t>(symbol_ids_.size()); 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 map_count() const { return static_cast<uint32_t>(map_ids_.size()); }
uint32_t builtin_object_count() const { uint32_t builtin_object_count() const {
...@@ -261,6 +275,7 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -261,6 +275,7 @@ class V8_EXPORT WebSnapshotSerializer
void DiscoverString(Handle<String> string, void DiscoverString(Handle<String> string,
AllowInPlace can_be_in_place = AllowInPlace::No); AllowInPlace can_be_in_place = AllowInPlace::No);
void DiscoverSymbol(Handle<Symbol> symbol); void DiscoverSymbol(Handle<Symbol> symbol);
void DiscoverBigInt(Handle<BigInt> bigint);
void DiscoverMap(Handle<Map> map, bool allow_property_in_descriptor = false); void DiscoverMap(Handle<Map> map, bool allow_property_in_descriptor = false);
void DiscoverPropertyKey(Handle<Name> key); void DiscoverPropertyKey(Handle<Name> key);
void DiscoverMapForFunction(Handle<JSFunction> function); void DiscoverMapForFunction(Handle<JSFunction> function);
...@@ -287,6 +302,7 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -287,6 +302,7 @@ class V8_EXPORT WebSnapshotSerializer
ValueSerializer& serializer); ValueSerializer& serializer);
void SerializeString(Handle<String> string, ValueSerializer& serializer); void SerializeString(Handle<String> string, ValueSerializer& serializer);
void SerializeSymbol(Handle<Symbol> symbol); void SerializeSymbol(Handle<Symbol> symbol);
void SerializeBigInt(Handle<BigInt> bigint);
void SerializeMap(Handle<Map> map); void SerializeMap(Handle<Map> map);
void SerializeBuiltinObject(uint32_t name_id); void SerializeBuiltinObject(uint32_t name_id);
void SerializeObjectPrototype(Handle<Map> map, ValueSerializer& serializer); void SerializeObjectPrototype(Handle<Map> map, ValueSerializer& serializer);
...@@ -313,6 +329,7 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -313,6 +329,7 @@ class V8_EXPORT WebSnapshotSerializer
uint32_t GetStringId(Handle<String> string, bool& in_place); uint32_t GetStringId(Handle<String> string, bool& in_place);
uint32_t GetSymbolId(Symbol symbol); uint32_t GetSymbolId(Symbol symbol);
uint32_t GetBigIntId(BigInt bigint);
uint32_t GetMapId(Map map); uint32_t GetMapId(Map map);
uint32_t GetFunctionId(JSFunction function); uint32_t GetFunctionId(JSFunction function);
uint32_t GetClassId(JSFunction function); uint32_t GetClassId(JSFunction function);
...@@ -329,6 +346,7 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -329,6 +346,7 @@ class V8_EXPORT WebSnapshotSerializer
ValueSerializer string_serializer_; ValueSerializer string_serializer_;
ValueSerializer symbol_serializer_; ValueSerializer symbol_serializer_;
ValueSerializer bigint_serializer_;
ValueSerializer map_serializer_; ValueSerializer map_serializer_;
ValueSerializer builtin_object_serializer_; ValueSerializer builtin_object_serializer_;
ValueSerializer context_serializer_; ValueSerializer context_serializer_;
...@@ -344,6 +362,7 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -344,6 +362,7 @@ class V8_EXPORT WebSnapshotSerializer
// These are needed for being able to serialize items in order. // These are needed for being able to serialize items in order.
Handle<ArrayList> strings_; Handle<ArrayList> strings_;
Handle<ArrayList> symbols_; Handle<ArrayList> symbols_;
Handle<ArrayList> bigints_;
Handle<ArrayList> maps_; Handle<ArrayList> maps_;
Handle<ArrayList> contexts_; Handle<ArrayList> contexts_;
Handle<ArrayList> functions_; Handle<ArrayList> functions_;
...@@ -364,6 +383,7 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -364,6 +383,7 @@ class V8_EXPORT WebSnapshotSerializer
// have a lower ID and will be deserialized first. // have a lower ID and will be deserialized first.
ObjectCacheIndexMap string_ids_; ObjectCacheIndexMap string_ids_;
ObjectCacheIndexMap symbol_ids_; ObjectCacheIndexMap symbol_ids_;
ObjectCacheIndexMap bigint_ids_;
ObjectCacheIndexMap map_ids_; ObjectCacheIndexMap map_ids_;
ObjectCacheIndexMap context_ids_; ObjectCacheIndexMap context_ids_;
ObjectCacheIndexMap function_ids_; ObjectCacheIndexMap function_ids_;
...@@ -467,6 +487,7 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -467,6 +487,7 @@ class V8_EXPORT WebSnapshotDeserializer
void DeserializeStrings(); void DeserializeStrings();
void DeserializeSymbols(); void DeserializeSymbols();
void DeserializeBigInts();
void DeserializeMaps(); void DeserializeMaps();
void DeserializeBuiltinObjects(); void DeserializeBuiltinObjects();
void DeserializeContexts(); void DeserializeContexts();
...@@ -516,6 +537,7 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -516,6 +537,7 @@ class V8_EXPORT WebSnapshotDeserializer
String ReadInPlaceString( String ReadInPlaceString(
InternalizeStrings internalize_strings = InternalizeStrings::kNo); InternalizeStrings internalize_strings = InternalizeStrings::kNo);
Object ReadSymbol(); Object ReadSymbol();
Object ReadBigInt();
std::tuple<Object, bool> ReadArray(Handle<HeapObject> container, std::tuple<Object, bool> ReadArray(Handle<HeapObject> container,
uint32_t container_index); uint32_t container_index);
std::tuple<Object, bool> ReadArrayBuffer(Handle<HeapObject> container, std::tuple<Object, bool> ReadArrayBuffer(Handle<HeapObject> container,
...@@ -559,6 +581,9 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -559,6 +581,9 @@ class V8_EXPORT WebSnapshotDeserializer
Handle<FixedArray> symbols_handle_; Handle<FixedArray> symbols_handle_;
FixedArray symbols_; FixedArray symbols_;
Handle<FixedArray> bigints_handle_;
FixedArray bigints_;
Handle<FixedArray> builtin_objects_handle_; Handle<FixedArray> builtin_objects_handle_;
FixedArray builtin_objects_; FixedArray builtin_objects_;
...@@ -610,6 +635,7 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -610,6 +635,7 @@ class V8_EXPORT WebSnapshotDeserializer
uint32_t string_count_ = 0; uint32_t string_count_ = 0;
uint32_t symbol_count_ = 0; uint32_t symbol_count_ = 0;
uint32_t bigint_count_ = 0;
uint32_t map_count_ = 0; uint32_t map_count_ = 0;
uint32_t builtin_object_count_ = 0; uint32_t builtin_object_count_ = 0;
uint32_t context_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