[web snapshots] Remove web snapshots

Bug: v8:11525
Change-Id: I0931408eefa4f55b0c9e8c0973787edfb903083a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4205917
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85559}
This commit is contained in:
Marja Hölttä 2023-01-31 12:47:53 +01:00 committed by V8 LUCI CQ
parent 9bc6586712
commit 1f349da554
57 changed files with 23 additions and 9396 deletions

View File

@ -1164,7 +1164,6 @@ filegroup(
"src/builtins/builtins-utils-inl.h",
"src/builtins/builtins-utils.h",
"src/builtins/builtins-weak-refs.cc",
"src/builtins/builtins-web-snapshots.cc",
"src/builtins/builtins.cc",
"src/builtins/builtins.h",
"src/builtins/constants-table-builder.cc",
@ -2207,8 +2206,6 @@ filegroup(
"src/utils/utils.h",
"src/utils/version.cc",
"src/utils/version.h",
"src/web-snapshot/web-snapshot.h",
"src/web-snapshot/web-snapshot.cc",
"src/zone/accounting-allocator.cc",
"src/zone/accounting-allocator.h",
"src/zone/compressed-zone-ptr.h",

View File

@ -4562,7 +4562,6 @@ v8_source_set("v8_base_without_compiler") {
"src/builtins/builtins-trace.cc",
"src/builtins/builtins-typed-array.cc",
"src/builtins/builtins-weak-refs.cc",
"src/builtins/builtins-web-snapshots.cc",
"src/builtins/builtins.cc",
"src/builtins/constants-table-builder.cc",
"src/codegen/aligned-slot-allocator.cc",
@ -4955,8 +4954,6 @@ v8_source_set("v8_base_without_compiler") {
"src/utils/sha-256.cc",
"src/utils/utils.cc",
"src/utils/version.cc",
"src/web-snapshot/web-snapshot.cc",
"src/web-snapshot/web-snapshot.h",
"src/zone/accounting-allocator.cc",
"src/zone/type-stats.cc",
"src/zone/zone-segment.cc",

View File

@ -128,7 +128,6 @@
#include "src/tracing/trace-event.h"
#include "src/utils/detachable-vector.h"
#include "src/utils/version.h"
#include "src/web-snapshot/web-snapshot.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/trap-handler/trap-handler.h"
@ -2225,22 +2224,6 @@ MaybeLocal<Value> Script::Run(Local<Context> context,
}
#endif
auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
if (V8_UNLIKELY(i::v8_flags.experimental_web_snapshots)) {
i::Handle<i::HeapObject> maybe_script =
handle(fun->shared().script(), i_isolate);
if (maybe_script->IsScript() &&
i::Script::cast(*maybe_script).type() == i::Script::TYPE_WEB_SNAPSHOT) {
i::WebSnapshotDeserializer deserializer(
reinterpret_cast<i::Isolate*>(v8_isolate),
i::Handle<i::Script>::cast(maybe_script));
deserializer.Deserialize();
RETURN_ON_FAILED_EXECUTION(Value);
Local<Value> result = v8::Undefined(v8_isolate);
RETURN_ESCAPED(result);
}
}
i::Handle<i::Object> receiver = i_isolate->global_proxy();
// TODO(cbruni, chromium:1244145): Remove once migrated to the context.
i::Handle<i::Object> options(

View File

@ -626,10 +626,6 @@ namespace internal {
CPP(JsonRawJson) \
CPP(JsonIsRawJson) \
\
/* Web snapshots */ \
CPP(WebSnapshotSerialize) \
CPP(WebSnapshotDeserialize) \
\
/* ICs */ \
TFH(LoadIC, LoadWithVector) \
TFH(LoadIC_Megamorphic, LoadWithVector) \

View File

@ -1,119 +0,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.
#include "src/builtins/builtins-utils-inl.h"
#include "src/builtins/builtins.h"
#include "src/logging/counters.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/objects-inl.h"
#include "src/web-snapshot/web-snapshot.h"
namespace v8 {
namespace internal {
BUILTIN(WebSnapshotSerialize) {
HandleScope scope(isolate);
if (args.length() < 2 || args.length() > 3) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
}
Handle<Object> object = args.at(1);
Handle<FixedArray> block_list = isolate->factory()->empty_fixed_array();
Handle<JSArray> block_list_js_array;
if (args.length() == 3) {
if (!args[2].IsJSArray()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
}
block_list_js_array = args.at<JSArray>(2);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, block_list,
JSReceiver::GetOwnValues(isolate, block_list_js_array,
PropertyFilter::ENUMERABLE_STRINGS));
}
auto snapshot_data = std::make_shared<WebSnapshotData>();
WebSnapshotSerializer serializer(isolate);
if (!serializer.TakeSnapshot(object, block_list, *snapshot_data)) {
DCHECK(isolate->has_pending_exception());
return ReadOnlyRoots(isolate).exception();
}
if (!block_list_js_array.is_null() &&
static_cast<uint32_t>(block_list->length()) <
serializer.external_object_count()) {
Handle<FixedArray> externals = serializer.GetExternals();
Handle<Map> map = JSObject::GetElementsTransitionMap(block_list_js_array,
PACKED_ELEMENTS);
block_list_js_array->set_elements(*externals);
block_list_js_array->set_length(Smi::FromInt(externals->length()));
block_list_js_array->set_map(*map);
}
MaybeHandle<JSArrayBuffer> maybe_result =
isolate->factory()->NewJSArrayBufferAndBackingStore(
snapshot_data->buffer_size, InitializedFlag::kUninitialized);
Handle<JSArrayBuffer> result;
if (!maybe_result.ToHandle(&result)) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kOutOfMemory,
isolate->factory()->NewStringFromAsciiChecked(
"WebSnapshotSerialize")));
}
uint8_t* data =
reinterpret_cast<uint8_t*>(result->GetBackingStore()->buffer_start());
memcpy(data, snapshot_data->buffer, snapshot_data->buffer_size);
return *result;
}
BUILTIN(WebSnapshotDeserialize) {
HandleScope scope(isolate);
if (args.length() < 2 || args.length() > 3) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
}
if (!args[1].IsJSArrayBuffer()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
}
auto buffer = args.at<JSArrayBuffer>(1);
std::shared_ptr<BackingStore> backing_store = buffer->GetBackingStore();
if (backing_store.get() == nullptr) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
}
const uint8_t* data =
reinterpret_cast<uint8_t*>(backing_store->buffer_start());
Handle<FixedArray> injected_references =
isolate->factory()->empty_fixed_array();
if (args.length() == 3) {
if (!args[2].IsJSArray()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
}
auto js_array = args.at<JSArray>(2);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, injected_references,
JSReceiver::GetOwnValues(isolate, js_array,
PropertyFilter::ENUMERABLE_STRINGS));
}
WebSnapshotDeserializer deserializer(reinterpret_cast<v8::Isolate*>(isolate),
data, backing_store->byte_length());
if (!deserializer.Deserialize(injected_references)) {
DCHECK(isolate->has_pending_exception());
return ReadOnlyRoots(isolate).exception();
}
Handle<Object> object;
if (!deserializer.value().ToHandle(&object)) {
return ReadOnlyRoots(isolate).undefined_value();
}
return *object;
}
} // namespace internal
} // namespace v8

View File

@ -62,7 +62,6 @@
#include "src/parsing/scanner-character-streams.h"
#include "src/snapshot/code-serializer.h"
#include "src/utils/ostreams.h"
#include "src/web-snapshot/web-snapshot.h"
#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
#ifdef V8_ENABLE_MAGLEV
@ -3451,29 +3450,6 @@ MaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForScriptImpl(
DCHECK_NULL(deserialize_task);
}
if (V8_UNLIKELY(
v8_flags.experimental_web_snapshots &&
(source->IsExternalOneByteString() || source->IsSeqOneByteString() ||
source->IsExternalTwoByteString() || source->IsSeqTwoByteString()) &&
source->length() > 4)) {
// Experimental: Treat the script as a web snapshot if it starts with the
// magic byte sequence. TODO(v8:11525): Remove this once proper embedder
// integration is done.
bool magic_matches = true;
for (size_t i = 0;
i < sizeof(WebSnapshotSerializerDeserializer::kMagicNumber); ++i) {
if (source->Get(static_cast<int>(i)) !=
WebSnapshotSerializerDeserializer::kMagicNumber[i]) {
magic_matches = false;
break;
}
}
if (magic_matches) {
return Compiler::GetSharedFunctionInfoForWebSnapshot(
isolate, source, script_details.name_obj);
}
}
LanguageMode language_mode = construct_language_mode(v8_flags.use_strict);
CompilationCache* compilation_cache = isolate->compilation_cache();
@ -3801,30 +3777,6 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
return maybe_result;
} // namespace internal
// static
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForWebSnapshot(
Isolate* isolate, Handle<String> source,
MaybeHandle<Object> maybe_script_name) {
// This script won't hold the functions created from the web snapshot;
// reserving space only for the top-level SharedFunctionInfo is enough.
Handle<WeakFixedArray> shared_function_infos =
isolate->factory()->NewWeakFixedArray(1, AllocationType::kOld);
Handle<Script> script = isolate->factory()->NewScript(source);
script->set_type(Script::TYPE_WEB_SNAPSHOT);
script->set_shared_function_infos(*shared_function_infos);
Handle<Object> script_name;
if (maybe_script_name.ToHandle(&script_name) && script_name->IsString()) {
script->set_name(String::cast(*script_name));
} else {
script->set_name(*isolate->factory()->empty_string());
}
Handle<SharedFunctionInfo> shared =
isolate->factory()->NewSharedFunctionInfoForWebSnapshot();
shared->SetScript(isolate->factory()->read_only_roots(), *script, 0, false);
return shared;
}
// static
template <typename IsolateT>
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(

View File

@ -224,9 +224,6 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
Isolate* isolate, Handle<String> source,
const ScriptDetails& script_details, ScriptStreamingData* streaming_data);
static Handle<SharedFunctionInfo> GetSharedFunctionInfoForWebSnapshot(
Isolate* isolate, Handle<String> source, MaybeHandle<Object> script_name);
// Create a shared function info object for the given function literal
// node (the code may be lazily compiled).
template <typename IsolateT>

View File

@ -709,10 +709,7 @@ namespace internal {
T(OptionalChainingNoSuper, "Invalid optional chain from super property") \
T(OptionalChainingNoTemplate, "Invalid tagged template on optional chain") \
/* AggregateError */ \
T(AllPromisesRejected, "All promises were rejected") \
/* Web snapshots */ \
T(WebSnapshotError, "Web snapshot failed: %")
T(AllPromisesRejected, "All promises were rejected")
enum class MessageTemplate {
#define TEMPLATE(NAME, STRING) k##NAME,
MESSAGE_TEMPLATES(TEMPLATE)

View File

@ -69,7 +69,6 @@
#include "src/tasks/cancelable-task.h"
#include "src/utils/ostreams.h"
#include "src/utils/utils.h"
#include "src/web-snapshot/web-snapshot.h"
#if V8_OS_POSIX
#include <signal.h>
@ -914,52 +913,6 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
return success;
}
bool Shell::TakeWebSnapshot(Isolate* isolate) {
PerIsolateData* data = PerIsolateData::Get(isolate);
Local<Context> realm =
Local<Context>::New(isolate, data->realms_[data->realm_current_]);
Context::Scope context_scope(realm);
Local<Context> context(isolate->GetCurrentContext());
v8::TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
const char* web_snapshot_output_file_name = "web.snap";
if (options.web_snapshot_output) {
web_snapshot_output_file_name = options.web_snapshot_output;
}
if (!options.web_snapshot_config) {
isolate->ThrowError(
"Web snapshots: --web-snapshot-config is needed when "
"--web-snapshot-output is passed");
CHECK(try_catch.HasCaught());
ReportException(isolate, &try_catch);
return false;
}
MaybeLocal<PrimitiveArray> maybe_exports =
ReadLines(isolate, options.web_snapshot_config);
Local<PrimitiveArray> exports;
if (!maybe_exports.ToLocal(&exports)) {
isolate->ThrowError("Web snapshots: unable to read config");
CHECK(try_catch.HasCaught());
ReportException(isolate, &try_catch);
return false;
}
i::WebSnapshotSerializer serializer(isolate);
i::WebSnapshotData snapshot_data;
if (serializer.TakeSnapshot(context, exports, snapshot_data)) {
DCHECK_NOT_NULL(snapshot_data.buffer);
WriteChars(web_snapshot_output_file_name, snapshot_data.buffer,
snapshot_data.buffer_size);
} else {
CHECK(try_catch.HasCaught());
return false;
}
return true;
}
namespace {
bool IsAbsolutePath(const std::string& path) {
@ -1499,44 +1452,6 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
return true;
}
bool Shell::ExecuteWebSnapshot(Isolate* isolate, const char* file_name) {
HandleScope handle_scope(isolate);
PerIsolateData* data = PerIsolateData::Get(isolate);
Local<Context> realm = data->realms_[data->realm_current_].Get(isolate);
Context::Scope context_scope(realm);
std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory());
int length = 0;
std::unique_ptr<uint8_t[]> snapshot_data(
reinterpret_cast<uint8_t*>(ReadChars(absolute_path.c_str(), &length)));
if (length == 0) {
TryCatch try_catch(isolate);
isolate->ThrowError("Could not read the web snapshot file");
CHECK(try_catch.HasCaught());
ReportException(isolate, &try_catch);
return false;
} else {
for (int r = 0; r < DeserializationRunCount(); ++r) {
bool skip_exports = r > 0;
i::WebSnapshotDeserializer deserializer(isolate, snapshot_data.get(),
static_cast<size_t>(length));
if (!deserializer.Deserialize({}, skip_exports)) {
// d8 is calling into the internal APIs which won't do
// ReportPendingMessages in all error paths (it's supposed to be done at
// the API boundary). Call it here.
auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
if (i_isolate->has_pending_exception()) {
i_isolate->ReportPendingMessages();
}
return false;
}
}
}
return true;
}
// Treat every line as a JSON value and parse it.
bool Shell::LoadJSON(Isolate* isolate, const char* file_name) {
HandleScope handle_scope(isolate);
@ -1579,10 +1494,6 @@ PerIsolateData::PerIsolateData(Isolate* isolate)
async_hooks_wrapper_ = new AsyncHooks(isolate);
}
ignore_unhandled_promises_ = false;
// TODO(v8:11525): Use methods on global Snapshot objects with
// signature checks.
HandleScope scope(isolate);
Shell::CreateSnapshotTemplate(isolate);
}
PerIsolateData::~PerIsolateData() {
@ -1678,14 +1589,6 @@ void PerIsolateData::SetTestApiObjectCtor(Local<FunctionTemplate> ctor) {
test_api_object_ctor_.Reset(isolate_, ctor);
}
Local<FunctionTemplate> PerIsolateData::GetSnapshotObjectCtor() const {
return snapshot_object_ctor_.Get(isolate_);
}
void PerIsolateData::SetSnapshotObjectCtor(Local<FunctionTemplate> ctor) {
snapshot_object_ctor_.Reset(isolate_, ctor);
}
Local<FunctionTemplate> PerIsolateData::GetDomNodeCtor() const {
return dom_node_ctor_.Get(isolate_);
}
@ -2168,100 +2071,6 @@ void Shell::RealmSharedSet(Local<String> property, Local<Value> value,
data->realm_shared_.Reset(isolate, value);
}
// Realm.takeWebSnapshot(index, exports) takes a snapshot of the list of exports
// in the realm with the specified index and returns the result.
void Shell::RealmTakeWebSnapshot(
const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();
if (args.Length() < 2 || !args[1]->IsArray()) {
isolate->ThrowError("Invalid argument");
return;
}
PerIsolateData* data = PerIsolateData::Get(isolate);
int index = data->RealmIndexOrThrow(args, 0);
if (index == -1) return;
// Create a Local<PrimitiveArray> from the exports array.
Local<Context> current_context = isolate->GetCurrentContext();
Local<Array> exports_array = args[1].As<Array>();
int length = exports_array->Length();
Local<PrimitiveArray> exports = PrimitiveArray::New(isolate, length);
for (int i = 0; i < length; ++i) {
Local<Value> value;
Local<String> str;
if (!exports_array->Get(current_context, i).ToLocal(&value) ||
!value->ToString(current_context).ToLocal(&str) || str.IsEmpty()) {
isolate->ThrowError("Invalid argument");
return;
}
exports->Set(isolate, i, str);
}
// Take the snapshot in the specified Realm.
auto snapshot_data_shared = std::make_shared<i::WebSnapshotData>();
{
TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
PerIsolateData::ExplicitRealmScope realm_scope(data, index);
i::WebSnapshotSerializer serializer(isolate);
if (!serializer.TakeSnapshot(realm_scope.context(), exports,
*snapshot_data_shared)) {
CHECK(try_catch.HasCaught());
args.GetReturnValue().Set(Undefined(isolate));
return;
}
}
// Create a snapshot object and store the WebSnapshotData as an embedder
// field. TODO(v8:11525): Use methods on global Snapshot objects with
// signature checks.
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::Object> snapshot_data_managed =
i::Managed<i::WebSnapshotData>::FromSharedPtr(
i_isolate, snapshot_data_shared->buffer_size, snapshot_data_shared);
v8::Local<v8::Value> shapshot_data = Utils::ToLocal(snapshot_data_managed);
Local<ObjectTemplate> snapshot_template =
data->GetSnapshotObjectCtor()->InstanceTemplate();
Local<Object> snapshot_instance =
snapshot_template->NewInstance(isolate->GetCurrentContext())
.ToLocalChecked();
snapshot_instance->SetInternalField(0, shapshot_data);
args.GetReturnValue().Set(snapshot_instance);
}
// Realm.useWebSnapshot(index, snapshot) deserializes the snapshot in the realm
// with the specified index.
void Shell::RealmUseWebSnapshot(
const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();
if (args.Length() < 2 || !args[1]->IsObject()) {
isolate->ThrowError("Invalid argument");
return;
}
PerIsolateData* data = PerIsolateData::Get(isolate);
int index = data->RealmIndexOrThrow(args, 0);
if (index == -1) return;
// Restore the snapshot data from the snapshot object.
Local<Object> snapshot_instance = args[1].As<Object>();
Local<FunctionTemplate> snapshot_template = data->GetSnapshotObjectCtor();
if (!snapshot_template->HasInstance(snapshot_instance)) {
isolate->ThrowError("Invalid argument");
return;
}
v8::Local<v8::Value> snapshot_data = snapshot_instance->GetInternalField(0);
i::Handle<i::Object> snapshot_data_handle = Utils::OpenHandle(*snapshot_data);
auto snapshot_data_managed =
i::Handle<i::Managed<i::WebSnapshotData>>::cast(snapshot_data_handle);
std::shared_ptr<i::WebSnapshotData> snapshot_data_shared =
snapshot_data_managed->get();
// Deserialize the snapshot in the specified Realm.
{
PerIsolateData::ExplicitRealmScope realm_scope(data, index);
i::WebSnapshotDeserializer deserializer(isolate,
snapshot_data_shared->buffer,
snapshot_data_shared->buffer_size);
bool success = deserializer.Deserialize();
args.GetReturnValue().Set(success);
}
}
void Shell::LogGetAndStop(const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
@ -3569,21 +3378,9 @@ Local<ObjectTemplate> Shell::CreateRealmTemplate(Isolate* isolate) {
FunctionTemplate::New(isolate, RealmEval));
realm_template->SetAccessor(String::NewFromUtf8Literal(isolate, "shared"),
RealmSharedGet, RealmSharedSet);
if (options.d8_web_snapshot_api) {
realm_template->Set(isolate, "takeWebSnapshot",
FunctionTemplate::New(isolate, RealmTakeWebSnapshot));
realm_template->Set(isolate, "useWebSnapshot",
FunctionTemplate::New(isolate, RealmUseWebSnapshot));
}
return realm_template;
}
Local<FunctionTemplate> Shell::CreateSnapshotTemplate(Isolate* isolate) {
Local<FunctionTemplate> snapshot_template = FunctionTemplate::New(isolate);
snapshot_template->InstanceTemplate()->SetInternalFieldCount(1);
PerIsolateData::Get(isolate)->SetSnapshotObjectCtor(snapshot_template);
return snapshot_template;
}
Local<ObjectTemplate> Shell::CreateD8Template(Isolate* isolate) {
Local<ObjectTemplate> d8_template = ObjectTemplate::New(isolate);
{
@ -4464,15 +4261,6 @@ bool SourceGroup::Execute(Isolate* isolate) {
break;
}
continue;
} else if (strcmp(arg, "--web-snapshot") == 0 && i + 1 < end_offset_) {
// Treat the next file as a web snapshot.
arg = argv_[++i];
Shell::set_script_executed();
if (!Shell::ExecuteWebSnapshot(isolate, arg)) {
success = false;
break;
}
continue;
} else if (strcmp(arg, "--json") == 0 && i + 1 < end_offset_) {
// Treat the next file as a JSON file.
arg = argv_[++i];
@ -4505,13 +4293,6 @@ bool SourceGroup::Execute(Isolate* isolate) {
break;
}
}
if (!success) {
return false;
}
if (Shell::options.web_snapshot_config ||
Shell::options.web_snapshot_output) {
success = Shell::TakeWebSnapshot(isolate);
}
return success;
}
@ -5067,15 +4848,6 @@ bool Shell::SetOptions(int argc, char* argv[]) {
} else if (strcmp(argv[i], "--stress-deserialize") == 0) {
options.stress_deserialize = true;
argv[i] = nullptr;
} else if (strncmp(argv[i], "--web-snapshot-config=", 22) == 0) {
options.web_snapshot_config = argv[i] + 22;
argv[i] = nullptr;
} else if (strncmp(argv[i], "--web-snapshot-output=", 22) == 0) {
options.web_snapshot_output = argv[i] + 22;
argv[i] = nullptr;
} else if (strcmp(argv[i], "--experimental-d8-web-snapshot-api") == 0) {
options.d8_web_snapshot_api = true;
argv[i] = nullptr;
} else if (strcmp(argv[i], "--compile-only") == 0) {
options.compile_only = true;
argv[i] = nullptr;
@ -5154,12 +4926,11 @@ bool Shell::SetOptions(int argc, char* argv[]) {
const char* usage =
"Synopsis:\n"
" shell [options] [--shell] [<file>...]\n"
" d8 [options] [-e <string>] [--shell] [[--module|--web-snapshot]"
" d8 [options] [-e <string>] [--shell] [--module|]"
" <file>...]\n\n"
" -e execute a string in V8\n"
" --shell run an interactive JavaScript shell\n"
" --module execute a file as a JavaScript module\n"
" --web-snapshot execute a file as a web snapshot\n\n";
" --module execute a file as a JavaScript module\n";
using HelpOptions = i::FlagList::HelpOptions;
i::v8_flags.abort_on_contradictory_flags = true;
i::FlagList::SetFlagsFromCommandLine(&argc, argv, true,
@ -5186,9 +4957,7 @@ bool Shell::SetOptions(int argc, char* argv[]) {
current->End(i);
current++;
current->Begin(argv, i + 1);
} else if (strcmp(str, "--module") == 0 ||
strcmp(str, "--web-snapshot") == 0 ||
strcmp(str, "--json") == 0) {
} else if (strcmp(str, "--module") == 0 || strcmp(str, "--json") == 0) {
// Pass on to SourceGroup, which understands these options.
} else if (strncmp(str, "--", 2) == 0) {
if (!i::v8_flags.correctness_fuzzer_suppressions) {
@ -5222,7 +4991,6 @@ int Shell::RunMain(Isolate* isolate, bool last_run) {
}
HandleScope scope(isolate);
Local<Context> context = CreateEvaluationContext(isolate);
CreateSnapshotTemplate(isolate);
bool use_existing_context = last_run && use_interactive_shell();
if (use_existing_context) {
// Keep using the same context in the interactive shell.

View File

@ -319,9 +319,6 @@ class PerIsolateData {
Local<FunctionTemplate> GetTestApiObjectCtor() const;
void SetTestApiObjectCtor(Local<FunctionTemplate> ctor);
Local<FunctionTemplate> GetSnapshotObjectCtor() const;
void SetSnapshotObjectCtor(Local<FunctionTemplate> ctor);
Local<FunctionTemplate> GetDomNodeCtor() const;
void SetDomNodeCtor(Local<FunctionTemplate> ctor);
@ -344,7 +341,6 @@ class PerIsolateData {
std::unordered_set<DynamicImportData*> import_data_;
#endif
Global<FunctionTemplate> test_api_object_ctor_;
Global<FunctionTemplate> snapshot_object_ctor_;
Global<FunctionTemplate> dom_node_ctor_;
int RealmIndexOrThrow(const v8::FunctionCallbackInfo<v8::Value>& args,
@ -464,13 +460,7 @@ class ShellOptions {
"enable-system-instrumentation", false};
DisallowReassignment<bool> enable_etw_stack_walking = {
"enable-etw-stack-walking", false};
DisallowReassignment<const char*> web_snapshot_config = {
"web-snapshot-config", nullptr};
DisallowReassignment<const char*> web_snapshot_output = {
"web-snapshot-output", nullptr};
DisallowReassignment<bool> d8_web_snapshot_api = {
"experimental-d8-web-snapshot-api", false};
// Applies to web snapshot and JSON deserialization.
// Applies to JSON deserialization.
DisallowReassignment<bool> stress_deserialize = {"stress-deserialize", false};
DisallowReassignment<bool> compile_only = {"compile-only", false};
DisallowReassignment<int> repeat_compile = {"repeat-compile", 1};
@ -508,8 +498,6 @@ class Shell : public i::AllStatic {
ReportExceptions report_exceptions,
ProcessMessageQueue process_message_queue);
static bool ExecuteModule(Isolate* isolate, const char* file_name);
static bool TakeWebSnapshot(Isolate* isolate);
static bool ExecuteWebSnapshot(Isolate* isolate, const char* file_name);
static bool LoadJSON(Isolate* isolate, const char* file_name);
static void ReportException(Isolate* isolate, Local<Message> message,
Local<Value> exception);
@ -569,10 +557,6 @@ class Shell : public i::AllStatic {
const PropertyCallbackInfo<Value>& info);
static void RealmSharedSet(Local<String> property, Local<Value> value,
const PropertyCallbackInfo<void>& info);
static void RealmTakeWebSnapshot(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void RealmUseWebSnapshot(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void LogGetAndStop(const v8::FunctionCallbackInfo<v8::Value>& args);
static void TestVerifySourcePositions(
@ -737,8 +721,6 @@ class Shell : public i::AllStatic {
static void PromiseRejectCallback(v8::PromiseRejectMessage reject_message);
static Local<FunctionTemplate> CreateSnapshotTemplate(Isolate* isolate);
private:
static inline int DeserializationRunCount() {
return options.stress_deserialize ? 1000 : 1;

View File

@ -1898,12 +1898,6 @@ void AllocationSite::AllocationSiteVerify(Isolate* isolate) {
void Script::ScriptVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::ScriptVerify(*this, isolate);
if (V8_UNLIKELY(type() == Script::TYPE_WEB_SNAPSHOT)) {
CHECK_LE(shared_function_info_count(), shared_function_infos().length());
} else {
// No overallocating shared_function_infos.
CHECK_EQ(shared_function_info_count(), shared_function_infos().length());
}
for (int i = 0; i < shared_function_info_count(); ++i) {
MaybeObject maybe_object = shared_function_infos().Get(i);
HeapObject heap_object;

View File

@ -2374,9 +2374,6 @@ void Script::ScriptPrint(std::ostream& os) {
os << "\n - eval from shared: " << Brief(eval_from_shared());
} else if (is_wrapped()) {
os << "\n - wrapped arguments: " << Brief(wrapped_arguments());
} else if (type() == TYPE_WEB_SNAPSHOT) {
os << "\n - shared function info table: "
<< Brief(shared_function_info_table());
}
os << "\n - eval from position: " << eval_from_position();
}

View File

@ -589,7 +589,6 @@ DEFINE_BOOL(trace_block_coverage, false,
"trace collected block coverage information")
DEFINE_BOOL(trace_protector_invalidation, false,
"trace protector cell invalidations")
DEFINE_BOOL(trace_web_snapshot, false, "trace web snapshot deserialization")
DEFINE_BOOL(feedback_normalization, false,
"feed back normalization to constructors")
@ -2392,12 +2391,6 @@ DEFINE_NEG_IMPLICATION(single_threaded_gc, concurrent_array_buffer_sweeping)
DEFINE_NEG_IMPLICATION(single_threaded_gc, stress_concurrent_allocation)
DEFINE_NEG_IMPLICATION(single_threaded_gc, cppheap_concurrent_marking)
// Web snapshots: 1) expose WebSnapshot.* API 2) interpret scripts as web
// snapshots if they start with a magic number.
// TODO(v8:11525): Remove this flag once proper embedder integration is done.
DEFINE_BOOL(experimental_web_snapshots, false, "enable Web Snapshots")
DEFINE_NEG_IMPLICATION(experimental_web_snapshots, script_streaming)
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
DEFINE_BOOL(use_libm_trig_functions, true, "use libm trig functions")
#endif

View File

@ -280,8 +280,8 @@ Handle<Script> FactoryBase<Impl>::NewScriptWithId(
raw.set_context_data(roots.undefined_value(), SKIP_WRITE_BARRIER);
raw.set_type(Script::TYPE_NORMAL);
raw.set_line_ends(roots.undefined_value(), SKIP_WRITE_BARRIER);
raw.set_eval_from_shared_or_wrapped_arguments_or_sfi_table(
roots.undefined_value(), SKIP_WRITE_BARRIER);
raw.set_eval_from_shared_or_wrapped_arguments(roots.undefined_value(),
SKIP_WRITE_BARRIER);
raw.set_eval_from_position(0);
raw.set_shared_function_infos(roots.empty_weak_fixed_array(),
SKIP_WRITE_BARRIER);

View File

@ -338,7 +338,6 @@ class FactoryBase : public TorqueGeneratedFactory<Impl> {
AllocationType allocation);
private:
friend class WebSnapshotDeserializer;
Impl* impl() { return static_cast<Impl*>(this); }
auto isolate() { return impl()->isolate(); }
ReadOnlyRoots read_only_roots() { return impl()->read_only_roots(); }

View File

@ -1512,8 +1512,8 @@ Handle<Script> Factory::CloneScript(Handle<Script> script) {
new_script.set_context_data(old_script.context_data());
new_script.set_type(old_script.type());
new_script.set_line_ends(*undefined_value(), SKIP_WRITE_BARRIER);
new_script.set_eval_from_shared_or_wrapped_arguments_or_sfi_table(
script->eval_from_shared_or_wrapped_arguments_or_sfi_table());
new_script.set_eval_from_shared_or_wrapped_arguments(
script->eval_from_shared_or_wrapped_arguments());
new_script.set_shared_function_infos(*empty_weak_fixed_array(),
SKIP_WRITE_BARRIER);
new_script.set_eval_from_position(old_script.eval_from_position());
@ -3366,12 +3366,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForBuiltin(
return shared;
}
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForWebSnapshot() {
return NewSharedFunctionInfo(empty_string(), MaybeHandle<InstructionStream>(),
Builtin::kNoBuiltinId,
FunctionKind::kNormalFunction);
}
int Factory::NumberToStringCacheHash(Smi number) {
int mask = (number_string_cache()->length() >> 1) - 1;
return number.value() & mask;

View File

@ -809,8 +809,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
MaybeHandle<String> name, Builtin builtin,
FunctionKind kind = FunctionKind::kNormalFunction);
Handle<SharedFunctionInfo> NewSharedFunctionInfoForWebSnapshot();
static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
return (function_mode & kWithPrototypeBits) != 0;
}
@ -1054,7 +1052,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
private:
friend class FactoryBase<Factory>;
friend class WebSnapshotDeserializer;
// ------
// Customization points for FactoryBase

View File

@ -246,8 +246,6 @@ class Genesis {
#undef DECLARE_FEATURE_INITIALIZATION
void InitializeGlobal_regexp_linear_flag();
void InitializeGlobal_experimental_web_snapshots();
enum ArrayBufferKind { ARRAY_BUFFER, SHARED_ARRAY_BUFFER };
Handle<JSFunction> CreateArrayBuffer(Handle<String> name,
ArrayBufferKind array_buffer_kind);
@ -4150,7 +4148,6 @@ void Genesis::InitializeExperimentalGlobal() {
HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
#undef FEATURE_INITIALIZE_GLOBAL
InitializeGlobal_regexp_linear_flag();
InitializeGlobal_experimental_web_snapshots();
}
bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
@ -5556,21 +5553,6 @@ void Genesis::InitializeGlobal_harmony_intl_number_format_v3() {
#endif // V8_INTL_SUPPORT
void Genesis::InitializeGlobal_experimental_web_snapshots() {
if (!v8_flags.experimental_web_snapshots) return;
Handle<JSGlobalObject> global(native_context()->global_object(), isolate());
Handle<JSObject> web_snapshot_object =
factory()->NewJSObject(isolate_->object_function(), AllocationType::kOld);
JSObject::AddProperty(isolate_, global, "WebSnapshot", web_snapshot_object,
DONT_ENUM);
InstallToStringTag(isolate_, web_snapshot_object, "WebSnapshot");
SimpleInstallFunction(isolate_, web_snapshot_object, "serialize",
Builtin::kWebSnapshotSerialize, 2, false);
SimpleInstallFunction(isolate_, web_snapshot_object, "deserialize",
Builtin::kWebSnapshotDeserialize, 2, false);
}
#ifdef V8_INTL_SUPPORT
void Genesis::InitializeGlobal_harmony_intl_duration_format() {
if (!v8_flags.harmony_intl_duration_format) return;

View File

@ -494,21 +494,6 @@ class RuntimeCallTimer final {
V(TestCounter2) \
V(TestCounter3) \
V(UpdateProtector) \
V(WebSnapshotDeserialize) \
V(WebSnapshotDeserialize_Arrays) \
V(WebSnapshotDeserialize_ArrayBuffers) \
V(WebSnapshotDeserialize_BigInts) \
V(WebSnapshotDeserialize_BuiltinObjects) \
V(WebSnapshotDeserialize_Classes) \
V(WebSnapshotDeserialize_Contexts) \
V(WebSnapshotDeserialize_DataViews) \
V(WebSnapshotDeserialize_Exports) \
V(WebSnapshotDeserialize_Functions) \
V(WebSnapshotDeserialize_Maps) \
V(WebSnapshotDeserialize_Objects) \
V(WebSnapshotDeserialize_Strings) \
V(WebSnapshotDeserialize_Symbols) \
V(WebSnapshotDeserialize_TypedArrays) \
V(WrappedFunctionLengthGetter) \
V(WrappedFunctionNameGetter)

View File

@ -73,9 +73,6 @@ void MutableBigInt_RightShiftAndCanonicalize(Address result_addr,
class BigInt;
class ValueDeserializer;
class ValueSerializer;
class WebSnapshotSerializerDeserializer;
class WebSnapshotSerializer;
class WebSnapshotDeserializer;
#include "torque-generated/src/objects/bigint-tq.inc"
@ -304,9 +301,6 @@ 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>

View File

@ -233,7 +233,6 @@ class DescriptorArray
using EntryValueField = TaggedField<MaybeObject, kEntryValueOffset>;
private:
friend class WebSnapshotDeserializer;
DECL_INT16_ACCESSORS(filler16bits)
inline void SetKey(InternalIndex descriptor_number, Name key);

View File

@ -391,7 +391,6 @@ class JSTypedArray
template <typename IsolateT>
friend class Deserializer;
friend class Factory;
friend class WebSnapshotDeserializer;
DECL_PRIMITIVE_SETTER(length, size_t)
// Reads the "length" field, doesn't assert the TypedArray is not RAB / GSAB

View File

@ -5123,11 +5123,6 @@ MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
Handle<Script> script, IsolateT* isolate,
FunctionLiteral* function_literal) {
int function_literal_id = function_literal->function_literal_id();
if (V8_UNLIKELY(script->type() == Script::TYPE_WEB_SNAPSHOT &&
function_literal_id >=
script->shared_function_info_count())) {
return FindWebSnapshotSharedFunctionInfo(script, isolate, function_literal);
}
CHECK_NE(function_literal_id, kFunctionLiteralIdInvalid);
// If this check fails, the problem is most probably the function id
@ -5149,77 +5144,6 @@ template MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
Handle<Script> script, LocalIsolate* isolate,
FunctionLiteral* function_literal);
MaybeHandle<SharedFunctionInfo> Script::FindWebSnapshotSharedFunctionInfo(
Handle<Script> script, Isolate* isolate,
FunctionLiteral* function_literal) {
// We might be able to de-dupe the SFI against a SFI that was
// created when deserializing the snapshot (or when calling a function which
// was included in the snapshot). In that case, we can find it based on the
// start position in shared_function_info_table.
Handle<ObjectHashTable> shared_function_info_table = handle(
ObjectHashTable::cast(script->shared_function_info_table()), isolate);
{
DisallowHeapAllocation no_gc;
Object index_object = shared_function_info_table->Lookup(
handle(Smi::FromInt(function_literal->start_position()), isolate));
if (!index_object.IsTheHole()) {
int index = Smi::cast(index_object).value();
DCHECK_LT(index, script->shared_function_info_count());
MaybeObject maybe_shared = script->shared_function_infos().Get(index);
HeapObject heap_object;
if (!maybe_shared->GetHeapObject(&heap_object)) {
// We found the correct location but it's not filled in (e.g., the weak
// pointer to the SharedFunctionInfo has been cleared). Record the
// location in the FunctionLiteral, so that it will be refilled later.
// SharedFunctionInfo::SetScript will write the SharedFunctionInfo in
// the shared_function_infos.
function_literal->set_function_literal_id(index);
return MaybeHandle<SharedFunctionInfo>();
}
SharedFunctionInfo shared = SharedFunctionInfo::cast(heap_object);
DCHECK_EQ(shared.StartPosition(), function_literal->start_position());
DCHECK_EQ(shared.EndPosition(), function_literal->end_position());
return handle(shared, isolate);
}
}
// It's possible that FunctionLiterals which were processed before this one
// were deduplicated against existing ones. Decrease function_literal_id to
// avoid holes in shared_function_infos.
int old_length = script->shared_function_info_count();
int function_literal_id = old_length;
function_literal->set_function_literal_id(function_literal_id);
// Also add to shared_function_info_table.
shared_function_info_table = ObjectHashTable::Put(
shared_function_info_table,
handle(Smi::FromInt(function_literal->start_position()), isolate),
handle(Smi::FromInt(function_literal_id), isolate));
script->set_shared_function_info_table(*shared_function_info_table);
// Grow shared_function_infos if needed (we don't know the correct amount of
// space needed upfront).
int new_length = old_length + 1;
Handle<WeakFixedArray> old_infos =
handle(script->shared_function_infos(), isolate);
if (new_length > old_infos->length()) {
int capacity = WeakArrayList::CapacityForLength(new_length);
Handle<WeakFixedArray> new_infos(
isolate->factory()->NewWeakFixedArray(capacity, AllocationType::kOld));
new_infos->CopyElements(isolate, 0, *old_infos, 0, old_length,
WriteBarrierMode::UPDATE_WRITE_BARRIER);
script->set_shared_function_infos(*new_infos);
}
return MaybeHandle<SharedFunctionInfo>();
}
MaybeHandle<SharedFunctionInfo> Script::FindWebSnapshotSharedFunctionInfo(
Handle<Script> script, LocalIsolate* isolate,
FunctionLiteral* function_literal) {
// Off-thread serialization of web snapshots is not implemented.
UNREACHABLE();
}
Script::Iterator::Iterator(Isolate* isolate)
: iterator_(isolate->heap()->script_list()) {}

View File

@ -316,8 +316,6 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
V8_EXPORT_PRIVATE uint32_t Hash();
private:
friend class WebSnapshotDeserializer;
int InlinedLocalNamesLookup(String name);
int ContextLocalNamesIndex() const;

View File

@ -25,7 +25,7 @@ NEVER_READ_ONLY_SPACE_IMPL(Script)
#if V8_ENABLE_WEBASSEMBLY
ACCESSORS_CHECKED(Script, wasm_breakpoint_infos, FixedArray,
kEvalFromSharedOrWrappedArgumentsOrSfiTableOffset,
kEvalFromSharedOrWrappedArgumentsOffset,
this->type() == TYPE_WASM)
ACCESSORS_CHECKED(Script, wasm_managed_native_module, Object,
kEvalFromPositionOffset, this->type() == TYPE_WASM)
@ -37,8 +37,8 @@ ACCESSORS_CHECKED(Script, wasm_weak_instance_list, WeakArrayList,
#endif // V8_ENABLE_WEBASSEMBLY
SMI_ACCESSORS(Script, type, kScriptTypeOffset)
ACCESSORS_CHECKED(Script, eval_from_shared_or_wrapped_arguments_or_sfi_table,
Object, kEvalFromSharedOrWrappedArgumentsOrSfiTableOffset,
ACCESSORS_CHECKED(Script, eval_from_shared_or_wrapped_arguments, Object,
kEvalFromSharedOrWrappedArgumentsOffset,
CHECK_SCRIPT_NOT_WASM)
SMI_ACCESSORS_CHECKED(Script, eval_from_position, kEvalFromPositionOffset,
CHECK_SCRIPT_NOT_WASM)
@ -48,51 +48,32 @@ ACCESSORS(Script, compiled_lazy_function_positions, Object,
kCompiledLazyFunctionPositionsOffset)
bool Script::is_wrapped() const {
return eval_from_shared_or_wrapped_arguments_or_sfi_table().IsFixedArray() &&
type() != TYPE_WEB_SNAPSHOT;
return eval_from_shared_or_wrapped_arguments().IsFixedArray();
}
bool Script::has_eval_from_shared() const {
return eval_from_shared_or_wrapped_arguments_or_sfi_table()
.IsSharedFunctionInfo();
return eval_from_shared_or_wrapped_arguments().IsSharedFunctionInfo();
}
void Script::set_eval_from_shared(SharedFunctionInfo shared,
WriteBarrierMode mode) {
DCHECK(!is_wrapped());
DCHECK_NE(type(), TYPE_WEB_SNAPSHOT);
set_eval_from_shared_or_wrapped_arguments_or_sfi_table(shared, mode);
set_eval_from_shared_or_wrapped_arguments(shared, mode);
}
SharedFunctionInfo Script::eval_from_shared() const {
DCHECK(has_eval_from_shared());
return SharedFunctionInfo::cast(
eval_from_shared_or_wrapped_arguments_or_sfi_table());
return SharedFunctionInfo::cast(eval_from_shared_or_wrapped_arguments());
}
void Script::set_wrapped_arguments(FixedArray value, WriteBarrierMode mode) {
DCHECK(!has_eval_from_shared());
DCHECK_NE(type(), TYPE_WEB_SNAPSHOT);
set_eval_from_shared_or_wrapped_arguments_or_sfi_table(value, mode);
set_eval_from_shared_or_wrapped_arguments(value, mode);
}
FixedArray Script::wrapped_arguments() const {
DCHECK(is_wrapped());
return FixedArray::cast(eval_from_shared_or_wrapped_arguments_or_sfi_table());
}
void Script::set_shared_function_info_table(ObjectHashTable value,
WriteBarrierMode mode) {
DCHECK(!has_eval_from_shared());
DCHECK(!is_wrapped());
DCHECK_EQ(type(), TYPE_WEB_SNAPSHOT);
set_eval_from_shared_or_wrapped_arguments_or_sfi_table(value, mode);
}
ObjectHashTable Script::shared_function_info_table() const {
DCHECK_EQ(type(), TYPE_WEB_SNAPSHOT);
return ObjectHashTable::cast(
eval_from_shared_or_wrapped_arguments_or_sfi_table());
return FixedArray::cast(eval_from_shared_or_wrapped_arguments());
}
DEF_GETTER(Script, shared_function_infos, WeakFixedArray) {
@ -114,11 +95,6 @@ void Script::set_shared_function_infos(WeakFixedArray value,
}
int Script::shared_function_info_count() const {
if (V8_UNLIKELY(type() == TYPE_WEB_SNAPSHOT)) {
// +1 because the 0th element in shared_function_infos is reserved for the
// top-level SharedFunctionInfo which doesn't exist.
return shared_function_info_table().NumberOfElements() + 1;
}
return shared_function_infos().length();
}

View File

@ -46,8 +46,7 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
#if V8_ENABLE_WEBASSEMBLY
TYPE_WASM = 3,
#endif // V8_ENABLE_WEBASSEMBLY
TYPE_INSPECTOR = 4,
TYPE_WEB_SNAPSHOT = 5
TYPE_INSPECTOR = 4
};
// Script compilation types.
@ -62,7 +61,7 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
// [type]: the script type.
DECL_INT_ACCESSORS(type)
DECL_ACCESSORS(eval_from_shared_or_wrapped_arguments_or_sfi_table, Object)
DECL_ACCESSORS(eval_from_shared_or_wrapped_arguments, Object)
// [eval_from_shared]: for eval scripts the shared function info for the
// function from which eval was called.
@ -71,12 +70,6 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
// [wrapped_arguments]: for the list of arguments in a wrapped script.
DECL_ACCESSORS(wrapped_arguments, FixedArray)
// For web snapshots: a hash table mapping function positions to indices in
// shared_function_infos.
// TODO(v8:11525): Replace with a more efficient data structure mapping
// function positions to weak pointers to SharedFunctionInfos directly.
DECL_ACCESSORS(shared_function_info_table, ObjectHashTable)
// Whether the script is implicitly wrapped in a function.
inline bool is_wrapped() const;
@ -221,14 +214,6 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
Handle<Script> script, IsolateT* isolate,
FunctionLiteral* function_literal);
static MaybeHandle<SharedFunctionInfo> FindWebSnapshotSharedFunctionInfo(
Handle<Script> script, Isolate* isolate,
FunctionLiteral* function_literal);
static MaybeHandle<SharedFunctionInfo> FindWebSnapshotSharedFunctionInfo(
Handle<Script> script, LocalIsolate* isolate,
FunctionLiteral* function_literal);
// Iterate over all script objects on the heap.
class V8_EXPORT_PRIVATE Iterator {
public:

View File

@ -42,10 +42,9 @@ extern class Script extends Struct {
// For scripts originating from eval: the SharedFunctionInfo contains the SFI
// for the script. For scripts wrapped as functions: the FixedArray contains
// the arguments. For web snapshots: the ObjectHashTable maps function start
// position to SFI index in shared_function_infos.
eval_from_shared_or_wrapped_arguments_or_sfi_table: SharedFunctionInfo|
FixedArray|ObjectHashTable|Undefined;
// the arguments.
eval_from_shared_or_wrapped_arguments: SharedFunctionInfo|FixedArray|
Undefined;
eval_from_position: Smi|Foreign; // Smi or Managed<wasm::NativeModule>
shared_function_infos: WeakFixedArray|WeakArrayList;

View File

@ -689,8 +689,6 @@ class SharedFunctionInfo
Isolate* isolate);
private:
friend class WebSnapshotDeserializer;
#ifdef VERIFY_HEAP
void SharedFunctionInfoVerify(ReadOnlyRoots roots);
#endif

View File

@ -98,8 +98,6 @@ class ValueSerializer {
void SetTreatArrayBufferViewsAsHostObjects(bool mode);
private:
friend class WebSnapshotSerializer;
// Managing allocations of the internal buffer.
Maybe<bool> ExpandBuffer(size_t required_capacity);
@ -249,8 +247,6 @@ class ValueDeserializer {
bool ReadByte(uint8_t* value) V8_WARN_UNUSED_RESULT;
private:
friend class WebSnapshotDeserializer;
// Reading the wire format.
Maybe<SerializationTag> PeekTag() const V8_WARN_UNUSED_RESULT;
void ConsumeTag(SerializationTag peeked_tag);

View File

@ -889,15 +889,6 @@ void Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
}
int function_literal_id = shared_info->function_literal_id();
if (V8_UNLIKELY(script->type() == Script::TYPE_WEB_SNAPSHOT)) {
// Function literal IDs for inner functions haven't been allocated when
// deserializing. Put the inner function SFIs to the end of the list;
// they'll be deduplicated later (if the corresponding SFIs exist already)
// in Script::FindSharedFunctionInfo. (-1 here because function_literal_id
// is the parent's id. The inner function will get ids starting from
// function_literal_id + 1.)
function_literal_id = script->shared_function_info_count() - 1;
}
// Initialize parser state.
info->set_function_name(ast_value_factory()->GetString(

View File

@ -36,7 +36,6 @@
#include "src/profiler/heap-snapshot-generator.h"
#include "src/regexp/regexp.h"
#include "src/snapshot/snapshot.h"
#include "src/web-snapshot/web-snapshot.h"
#ifdef V8_ENABLE_MAGLEV
#include "src/maglev/maglev.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,669 +0,0 @@
// 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.
#ifndef V8_WEB_SNAPSHOT_WEB_SNAPSHOT_H_
#define V8_WEB_SNAPSHOT_WEB_SNAPSHOT_H_
#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
namespace v8 {
class Context;
class Isolate;
template <typename T>
class Local;
namespace internal {
class Context;
class Map;
class Object;
class String;
struct WebSnapshotData : public std::enable_shared_from_this<WebSnapshotData> {
uint8_t* buffer = nullptr;
size_t buffer_size = 0;
WebSnapshotData() = default;
WebSnapshotData(const WebSnapshotData&) = delete;
WebSnapshotData& operator=(const WebSnapshotData&) = delete;
~WebSnapshotData() { free(buffer); }
};
class WebSnapshotSerializerDeserializer {
public:
inline bool has_error() const { return error_message_ != nullptr; }
const char* error_message() const { return error_message_; }
enum ValueType : uint8_t {
FALSE_CONSTANT,
TRUE_CONSTANT,
NULL_CONSTANT,
UNDEFINED_CONSTANT,
// It corresponds to the hole value.
NO_ELEMENT_CONSTANT,
INTEGER,
DOUBLE,
REGEXP,
STRING_ID,
ARRAY_ID,
OBJECT_ID,
FUNCTION_ID,
CLASS_ID,
SYMBOL_ID,
EXTERNAL_ID,
BUILTIN_OBJECT_ID,
IN_PLACE_STRING_ID,
ARRAY_BUFFER_ID,
TYPED_ARRAY_ID,
DATA_VIEW_ID,
BIGINT_ID
};
enum SymbolType : uint8_t {
kNonGlobalNoDesription = 0,
kNonGlobal = 1,
kGlobal = 2
};
enum ElementsType : uint8_t { kDense = 0, kSparse = 1 };
enum TypedArrayType : uint8_t {
kInt8Array,
kUint8Array,
kUint8ClampedArray,
kInt16Array,
kUint16Array,
kInt32Array,
kUint32Array,
kFloat32Array,
kFloat64Array,
kBigInt64Array,
kBigUint64Array,
};
static inline ExternalArrayType TypedArrayTypeToExternalArrayType(
TypedArrayType type);
static inline TypedArrayType ExternalArrayTypeToTypedArrayType(
ExternalArrayType type);
static constexpr uint8_t kMagicNumber[4] = {'+', '+', '+', ';'};
enum ContextType : uint8_t { FUNCTION, BLOCK };
enum PropertyAttributesType : uint8_t { DEFAULT, CUSTOM };
uint8_t FunctionKindToFunctionFlags(FunctionKind kind);
FunctionKind FunctionFlagsToFunctionKind(uint8_t flags);
bool IsFunctionOrMethod(uint8_t flags);
bool IsConstructor(uint8_t flags);
uint8_t GetDefaultAttributeFlags();
uint8_t AttributesToFlags(PropertyDetails details);
PropertyAttributes FlagsToAttributes(uint8_t flags);
uint8_t ArrayBufferViewKindToFlags(
Handle<JSArrayBufferView> array_buffer_view);
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);
// This ensures indices and lengths can be converted between uint32_t and int
// without problems:
static_assert(kMaxItemCount <
static_cast<uint32_t>(std::numeric_limits<int32_t>::max()));
protected:
explicit WebSnapshotSerializerDeserializer(Isolate* isolate)
: isolate_(isolate) {}
// Not virtual, on purpose (because it doesn't need to be).
void Throw(const char* message);
void IterateBuiltinObjects(
std::function<void(Handle<String>, Handle<HeapObject>)> func);
static constexpr int kBuiltinObjectCount = 12;
inline Factory* factory() const { return isolate_->factory(); }
Isolate* isolate_;
const char* error_message_ = nullptr;
// Encode JSArrayBufferFlags, including was_detached, is_shared, is_resizable.
// DetachedBitField indicates whether the ArrayBuffer was detached.
using DetachedBitField = base::BitField<bool, 0, 1, uint8_t>;
// SharedBitField indicates whether the ArrayBuffer is SharedArrayBuffer.
using SharedBitField = DetachedBitField::Next<bool, 1>;
// ResizableBitField indicates whether the ArrayBuffer is ResizableArrayBuffer
// or GrowableSharedArrayBuffer.
using ResizableBitField = SharedBitField::Next<bool, 1>;
// Encode JSArrayBufferViewFlags, including is_length_tracking, see
// https://github.com/tc39/proposal-resizablearraybuffer.
// LengthTrackingBitField indicates whether the ArrayBufferView should track
// the length of the backing buffer, that is whether the ArrayBufferView is
// 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;
WebSnapshotSerializerDeserializer& operator=(
const WebSnapshotSerializerDeserializer&) = delete;
using AsyncFunctionBitField = base::BitField<bool, 0, 1, uint8_t>;
using GeneratorFunctionBitField = AsyncFunctionBitField::Next<bool, 1>;
using ArrowFunctionBitField = GeneratorFunctionBitField::Next<bool, 1>;
using MethodBitField = ArrowFunctionBitField::Next<bool, 1>;
using StaticBitField = MethodBitField::Next<bool, 1>;
using ClassConstructorBitField = StaticBitField::Next<bool, 1>;
using DefaultConstructorBitField = ClassConstructorBitField::Next<bool, 1>;
using DerivedConstructorBitField = DefaultConstructorBitField::Next<bool, 1>;
using ReadOnlyBitField = base::BitField<bool, 0, 1, uint8_t>;
using ConfigurableBitField = ReadOnlyBitField::Next<bool, 1>;
using EnumerableBitField = ConfigurableBitField::Next<bool, 1>;
};
class V8_EXPORT WebSnapshotSerializer
: public WebSnapshotSerializerDeserializer {
public:
explicit WebSnapshotSerializer(v8::Isolate* isolate);
explicit WebSnapshotSerializer(Isolate* isolate);
~WebSnapshotSerializer();
bool TakeSnapshot(v8::Local<v8::Context> context,
v8::Local<v8::PrimitiveArray> exports,
WebSnapshotData& data_out);
bool TakeSnapshot(Handle<Object> object, MaybeHandle<FixedArray> block_list,
WebSnapshotData& data_out);
// For inspecting the state after taking a snapshot.
uint32_t string_count() const {
return static_cast<uint32_t>(string_ids_.size());
}
uint32_t symbol_count() const {
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 {
return static_cast<uint32_t>(builtin_object_ids_.size());
}
uint32_t context_count() const {
return static_cast<uint32_t>(context_ids_.size());
}
uint32_t function_count() const {
return static_cast<uint32_t>(function_ids_.size());
}
uint32_t class_count() const {
return static_cast<uint32_t>(class_ids_.size());
}
uint32_t array_count() const {
return static_cast<uint32_t>(array_ids_.size());
}
uint32_t array_buffer_count() const {
return static_cast<uint32_t>(array_buffer_ids_.size());
}
uint32_t typed_array_count() const {
return static_cast<uint32_t>(typed_array_ids_.size());
}
uint32_t data_view_count() const {
return static_cast<uint32_t>(data_view_ids_.size());
}
uint32_t object_count() const {
return static_cast<uint32_t>(object_ids_.size());
}
uint32_t external_object_count() const {
return static_cast<uint32_t>(external_object_ids_.size());
}
Handle<FixedArray> GetExternals();
private:
WebSnapshotSerializer(const WebSnapshotSerializer&) = delete;
WebSnapshotSerializer& operator=(const WebSnapshotSerializer&) = delete;
enum class AllowInPlace {
No, // This reference cannot be replace with an in-place item.
Yes, // This reference can be replaced with an in-place item.
};
void SerializePendingItems();
void WriteSnapshot(uint8_t*& buffer, size_t& buffer_size);
void WriteObjects(ValueSerializer& destination, size_t count,
ValueSerializer& source, const char* name);
// Returns true if the object was already in the map, false if it was added.
bool InsertIntoIndexMap(ObjectCacheIndexMap& map, HeapObject heap_object,
uint32_t& id);
void ShallowDiscoverExternals(FixedArray externals);
void ShallowDiscoverBuiltinObjects(v8::Local<v8::Context> context);
void Discover(Handle<HeapObject> object);
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);
void DiscoverFunction(Handle<JSFunction> function);
void DiscoverClass(Handle<JSFunction> function);
void DiscoverContextAndPrototype(Handle<JSFunction> function);
void DiscoverContext(Handle<Context> context);
void DiscoverArray(Handle<JSArray> array);
void DiscoverTypedArray(Handle<JSTypedArray> typed_array);
void DiscoverDataView(Handle<JSDataView> data_view);
void DiscoverArrayBuffer(Handle<JSArrayBuffer> array_buffer);
void DiscoverElements(Handle<JSObject> object);
void DiscoverObject(Handle<JSObject> object);
bool DiscoverIfBuiltinObject(Handle<HeapObject> object);
void DiscoverSource(Handle<JSFunction> function);
template <typename T>
void DiscoverObjectPropertiesWithDictionaryMap(T dict);
bool ShouldBeSerialized(Handle<Name> key);
void ConstructSource();
void SerializeFunctionInfo(Handle<JSFunction> function,
ValueSerializer& serializer);
void SerializeFunctionProperties(Handle<JSFunction> function,
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);
template <typename T>
void SerializeObjectPropertiesWithDictionaryMap(T dict);
void SerializeFunction(Handle<JSFunction> function);
void SerializeClass(Handle<JSFunction> function);
void SerializeContext(Handle<Context> context, uint32_t id);
void SerializeArray(Handle<JSArray> array);
void SerializeElements(Handle<JSObject> object, ValueSerializer& serializer,
Maybe<uint32_t> length);
void SerializeObject(Handle<JSObject> object);
void SerializeArrayBufferView(Handle<JSArrayBufferView> array_buffer_view,
ValueSerializer& serializer);
void SerializeArrayBuffer(Handle<JSArrayBuffer> array_buffer);
void SerializeTypedArray(Handle<JSTypedArray> typed_array);
void SerializeDataView(Handle<JSDataView> data_view);
void SerializeExport(Handle<Object> object, Handle<String> export_name);
void WriteValue(Handle<Object> object, ValueSerializer& serializer);
void WriteStringMaybeInPlace(Handle<String> string,
ValueSerializer& serializer);
void WriteStringId(Handle<String> string, ValueSerializer& serializer);
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);
uint32_t GetContextId(Context context);
uint32_t GetArrayId(JSArray array);
uint32_t GetTypedArrayId(JSTypedArray typed_array);
uint32_t GetDataViewId(JSDataView data_view);
uint32_t GetArrayBufferId(JSArrayBuffer array_buffer);
uint32_t GetObjectId(JSObject object);
bool GetExternalId(HeapObject object, uint32_t* id = nullptr);
// Returns index into builtin_object_name_strings_.
bool GetBuiltinObjectNameIndex(HeapObject object, uint32_t& index);
bool GetBuiltinObjectId(HeapObject object, uint32_t& id);
ValueSerializer string_serializer_;
ValueSerializer symbol_serializer_;
ValueSerializer bigint_serializer_;
ValueSerializer map_serializer_;
ValueSerializer builtin_object_serializer_;
ValueSerializer context_serializer_;
ValueSerializer function_serializer_;
ValueSerializer class_serializer_;
ValueSerializer array_serializer_;
ValueSerializer typed_array_serializer_;
ValueSerializer array_buffer_serializer_;
ValueSerializer data_view_serializer_;
ValueSerializer object_serializer_;
ValueSerializer export_serializer_;
// 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_;
Handle<ArrayList> classes_;
Handle<ArrayList> arrays_;
Handle<ArrayList> typed_arrays_;
Handle<ArrayList> array_buffers_;
Handle<ArrayList> data_views_;
Handle<ArrayList> objects_;
// IndexMap to keep track of explicitly blocked external objects and
// non-serializable/not-supported objects (e.g. API Objects).
ObjectCacheIndexMap external_object_ids_;
// ObjectCacheIndexMap implements fast lookup item -> id. Some items (context,
// function, class, array, object) can point to other items and we serialize
// them in the reverse order. This ensures that the items this item points to
// 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_;
ObjectCacheIndexMap class_ids_;
ObjectCacheIndexMap array_ids_;
ObjectCacheIndexMap typed_array_ids_;
ObjectCacheIndexMap array_buffer_ids_;
ObjectCacheIndexMap data_view_ids_;
ObjectCacheIndexMap object_ids_;
uint32_t export_count_ = 0;
// For handling references to builtin objects:
// --------------------------------
// String objects for the names of all known builtins.
Handle<FixedArray> builtin_object_name_strings_;
// Map object -> index in builtin_name_strings_ for all known builtins.
ObjectCacheIndexMap builtin_object_to_name_;
// Map object -> index in builtins_. Includes only builtins which will be
// incluced in the snapshot.
ObjectCacheIndexMap builtin_object_ids_;
// For creating the Builtin wrappers in the snapshot. Includes only builtins
// which will be incluced in the snapshot. Each element is the id of the
// builtin name string in the snapshot.
std::vector<uint32_t> builtin_objects_;
// --------------------------------
std::queue<Handle<HeapObject>> discovery_queue_;
// For keeping track of which strings have exactly one reference. Strings are
// inserted here when the first reference is discovered, and never removed.
// Strings which have more than one reference get an ID and are inserted to
// strings_.
IdentityMap<int, base::DefaultAllocationPolicy> all_strings_;
// For constructing the minimal, "compacted", source string to cover all
// function bodies.
// --------------------------------
// Script id -> offset of the script source code in full_source_.
std::map<int, int> script_offsets_;
Handle<String> full_source_;
uint32_t source_id_;
// Ordered set of (start, end) pairs of all functions we've discovered.
std::set<std::pair<int, int>> source_intervals_;
// Maps function positions in the real source code into the function positions
// in the constructed source code (which we'll include in the web snapshot).
std::unordered_map<int, int> source_offset_to_compacted_source_offset_;
// --------------------------------
};
class V8_EXPORT WebSnapshotDeserializer
: public WebSnapshotSerializerDeserializer {
public:
WebSnapshotDeserializer(v8::Isolate* v8_isolate, const uint8_t* data,
size_t buffer_size);
WebSnapshotDeserializer(Isolate* isolate, Handle<Script> snapshot_as_script);
~WebSnapshotDeserializer();
bool Deserialize(MaybeHandle<FixedArray> external_references = {},
bool skip_exports = false);
// For inspecting the state after deserializing a snapshot.
uint32_t string_count() const { return string_count_; }
uint32_t symbol_count() const { return symbol_count_; }
uint32_t map_count() const { return map_count_; }
uint32_t builtin_object_count() const { return builtin_object_count_; }
uint32_t context_count() const { return context_count_; }
uint32_t function_count() const { return function_count_; }
uint32_t class_count() const { return class_count_; }
uint32_t array_count() const { return array_count_; }
uint32_t object_count() const { return object_count_; }
static void UpdatePointersCallback(v8::Isolate* isolate, v8::GCType type,
v8::GCCallbackFlags flags,
void* deserializer) {
reinterpret_cast<WebSnapshotDeserializer*>(deserializer)->UpdatePointers();
}
void UpdatePointers();
MaybeHandle<Object> value() const { return return_value_; }
private:
enum class InternalizeStrings {
kNo,
kYes,
};
WebSnapshotDeserializer(Isolate* isolate, Handle<Object> script_name,
base::Vector<const uint8_t> buffer);
// Return value: {data, length, data_owned}.
std::tuple<const uint8_t*, uint32_t, bool> ExtractScriptBuffer(
Isolate* isolate, Handle<Script> snapshot_as_script);
bool DeserializeSnapshot(bool skip_exports);
void CollectBuiltinObjects();
bool DeserializeScript();
WebSnapshotDeserializer(const WebSnapshotDeserializer&) = delete;
WebSnapshotDeserializer& operator=(const WebSnapshotDeserializer&) = delete;
void DeserializeStrings();
void DeserializeSymbols();
void DeserializeBigInts();
void DeserializeMaps();
void DeserializeBuiltinObjects();
void DeserializeContexts();
Handle<ScopeInfo> CreateScopeInfo(uint32_t variable_count, bool has_parent,
ContextType context_type,
bool has_inlined_local_names);
Handle<JSFunction> CreateJSFunction(int index, uint32_t start,
uint32_t length, uint32_t parameter_count,
uint8_t flags, uint32_t context_id);
void DeserializeFunctionData(uint32_t count, uint32_t current_count);
void DeserializeFunctions();
void DeserializeClasses();
void DeserializeArrays();
void DeserializeArrayBuffers();
void DeserializeTypedArrays();
void DeserializeDataViews();
void DeserializeObjects();
void DeserializeObjectElements(Handle<JSObject> object,
bool map_from_snapshot);
void DeserializeExports(bool skip_exports);
void DeserializeObjectPrototype(Handle<Map> map);
Handle<Map> DeserializeObjectPrototypeAndCreateEmptyMap();
void DeserializeObjectPrototypeForFunction(Handle<JSFunction> function);
void SetPrototype(Handle<Map> map, Handle<Object> prototype);
void DeserializeFunctionProperties(Handle<JSFunction> function);
bool ReadCount(uint32_t& count);
bool IsInitialFunctionPrototype(Object prototype);
template <typename T>
void DeserializeObjectPropertiesWithDictionaryMap(
T dict, uint32_t property_count, bool has_custom_property_attributes);
Handle<PropertyArray> DeserializePropertyArray(
Handle<DescriptorArray> descriptors, int no_properties);
// Return value: (object, was_deferred)
std::tuple<Object, bool> ReadValue(
Handle<HeapObject> object_for_deferred_reference = Handle<HeapObject>(),
uint32_t index_for_deferred_reference = 0,
InternalizeStrings internalize_strings = InternalizeStrings::kNo);
Object ReadInteger();
Object ReadNumber();
String ReadString(
InternalizeStrings internalize_strings = InternalizeStrings::kNo);
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,
uint32_t container_index);
std::tuple<Object, bool> ReadTypedArray(Handle<HeapObject> container,
uint32_t container_index);
std::tuple<Object, bool> ReadDataView(Handle<HeapObject> container,
uint32_t container_index);
std::tuple<Object, bool> ReadObject(Handle<HeapObject> container,
uint32_t container_index);
std::tuple<Object, bool> ReadFunction(Handle<HeapObject> container,
uint32_t container_index);
std::tuple<Object, bool> ReadClass(Handle<HeapObject> container,
uint32_t container_index);
Object ReadRegexp();
Object ReadBuiltinObjectReference();
Object ReadExternalReference();
bool ReadMapType();
std::tuple<Handle<FixedArrayBase>, ElementsKind, uint32_t>
DeserializeElements();
ElementsType ReadElementsType();
std::tuple<Handle<FixedArrayBase>, ElementsKind, uint32_t> ReadDenseElements(
uint32_t length);
std::tuple<Handle<FixedArrayBase>, ElementsKind, uint32_t> ReadSparseElements(
uint32_t length);
void ReadFunctionPrototype(Handle<JSFunction> function);
bool SetFunctionPrototype(JSFunction function, JSReceiver prototype);
HeapObject AddDeferredReference(Handle<HeapObject> container, uint32_t index,
ValueType target_type,
uint32_t target_object_index);
void ProcessDeferredReferences();
// Not virtual, on purpose (because it doesn't need to be).
void Throw(const char* message);
void VerifyObjects();
Handle<FixedArray> strings_handle_;
FixedArray strings_;
Handle<FixedArray> symbols_handle_;
FixedArray symbols_;
Handle<FixedArray> bigints_handle_;
FixedArray bigints_;
Handle<FixedArray> builtin_objects_handle_;
FixedArray builtin_objects_;
Handle<FixedArray> maps_handle_;
FixedArray maps_;
std::map<int, Handle<Map>> deserialized_function_maps_;
Handle<FixedArray> contexts_handle_;
FixedArray contexts_;
Handle<FixedArray> functions_handle_;
FixedArray functions_;
Handle<FixedArray> classes_handle_;
FixedArray classes_;
Handle<FixedArray> arrays_handle_;
FixedArray arrays_;
Handle<FixedArray> array_buffers_handle_;
FixedArray array_buffers_;
Handle<FixedArray> typed_arrays_handle_;
FixedArray typed_arrays_;
Handle<FixedArray> data_views_handle_;
FixedArray data_views_;
Handle<FixedArray> objects_handle_;
FixedArray objects_;
Handle<FixedArray> external_references_handle_;
FixedArray external_references_;
// Map: String -> builtin object.
Handle<ObjectHashTable> builtin_object_name_to_object_;
Handle<ArrayList> deferred_references_;
Handle<WeakFixedArray> shared_function_infos_handle_;
WeakFixedArray shared_function_infos_;
Handle<ObjectHashTable> shared_function_info_table_;
Handle<Script> script_;
Handle<Object> script_name_;
Handle<Object> return_value_;
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;
uint32_t function_count_ = 0;
uint32_t current_function_count_ = 0;
uint32_t class_count_ = 0;
uint32_t current_class_count_ = 0;
uint32_t array_count_ = 0;
uint32_t current_array_count_ = 0;
uint32_t array_buffer_count_ = 0;
uint32_t current_array_buffer_count_ = 0;
uint32_t typed_array_count_ = 0;
uint32_t current_typed_array_count_ = 0;
uint32_t data_view_count_ = 0;
uint32_t current_data_view_count_ = 0;
uint32_t object_count_ = 0;
uint32_t current_object_count_ = 0;
std::unique_ptr<ValueDeserializer> deserializer_;
std::unique_ptr<const uint8_t[]> owned_data_;
ReadOnlyRoots roots_;
bool deserialized_ = false;
};
} // namespace internal
} // namespace v8
#endif // V8_WEB_SNAPSHOT_WEB_SNAPSHOT_H_

View File

@ -39,7 +39,6 @@
'wasm/wasm-module-builder': [SKIP],
'compiler/fast-api-helpers': [SKIP],
'typedarray-helpers': [SKIP],
'web-snapshot/web-snapshot-helpers': [SKIP],
# All tests in the bug directory are expected to fail.
'bugs/*': [FAIL],

View File

@ -1,85 +0,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 --harmony-rab-gsab --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestSharedArrayBuffer() {
function createObjects() {
const growableArrayBuffer = new SharedArrayBuffer(5, { maxByteLength: 10 });
globalThis.growableArrayBuffer = growableArrayBuffer;
const array1 = new Uint8Array(growableArrayBuffer);
for (let i = 0; i < 5; i++) {
array1[i] = i;
}
const arrayBuffer = new SharedArrayBuffer(5);
globalThis.arrayBuffer = arrayBuffer;
const array2 = new Uint8Array(arrayBuffer);
for (let i = 0; i < 5; i++) {
array2[i] = i;
}
}
const { growableArrayBuffer, arrayBuffer } = takeAndUseWebSnapshot(createObjects, ['growableArrayBuffer', 'arrayBuffer']);
assertEquals(5, growableArrayBuffer.byteLength);
assertEquals(10, growableArrayBuffer.maxByteLength);
assertTrue(growableArrayBuffer.growable);
const array1 = new Uint8Array(growableArrayBuffer);
for (let i = 0; i < 5; i++) {
assertEquals(array1[i], i);
}
assertEquals(arrayBuffer.byteLength, 5);
assertEquals(arrayBuffer.maxByteLength, 5);
assertFalse(arrayBuffer.growable, false);
const array2 = new Uint8Array(arrayBuffer);
for (let i = 0; i < 5; i++) {
assertEquals(array2[i], i);
}
})();
(function TestArrayBuffer() {
function createObjects() {
const resizableArrayBuffer = new ArrayBuffer(5, {maxByteLength: 10});
globalThis.resizableArrayBuffer = resizableArrayBuffer;
const array1 = new Uint8Array(resizableArrayBuffer);
for (let i = 0; i < 5; i++) {
array1[i] = i;
}
const arrayBuffer = new ArrayBuffer(5);
globalThis.arrayBuffer = arrayBuffer;
const array2 = new Uint8Array(arrayBuffer);
for (let i = 0; i < 5; i++) {
array2[i] = i;
}
const detachedArrayBuffer = new ArrayBuffer(5);
%ArrayBufferDetach(detachedArrayBuffer);
globalThis.detachedArrayBuffer = detachedArrayBuffer;
}
const { resizableArrayBuffer, arrayBuffer, detachedArrayBuffer } = takeAndUseWebSnapshot(createObjects, ['resizableArrayBuffer', 'arrayBuffer', 'detachedArrayBuffer']);
assertEquals(5, resizableArrayBuffer.byteLength);
assertEquals(10, resizableArrayBuffer.maxByteLength);
assertTrue(resizableArrayBuffer.resizable)
const array1 = new Uint8Array(resizableArrayBuffer);
for (let i = 0; i < 5; i++) {
assertEquals(array1[i], i);
}
assertEquals(5, arrayBuffer.byteLength);
assertEquals(5, arrayBuffer.maxByteLength);
assertFalse(arrayBuffer.resizable)
const array2 = new Uint8Array(arrayBuffer);
for (let i = 0; i < 5; i++) {
assertEquals(array2[i], i);
}
assertEquals(0, detachedArrayBuffer.byteLength);
assertEquals(0, detachedArrayBuffer.maxByteLength);
})()

View File

@ -1,133 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestArray() {
function createObjects() {
globalThis.foo = {
array: [5, 6, 7]
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([5, 6, 7], foo.array);
})();
(function TestPackedDoubleElementsArray() {
function createObjects() {
globalThis.foo = [1.2, 2.3];
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([1.2, 2.3], foo);
})();
(function TestArrayContainingDoubleAndSmi() {
function createObjects() {
globalThis.foo = [1.2, 1];
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([1.2, 1], foo);
})();
(function TestArrayContainingDoubleAndObject() {
function createObjects() {
globalThis.foo = [1.2, {'key': 'value'}];
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([1.2, {'key': 'value'}], foo);
})();
(function TestEmptyArray() {
function createObjects() {
globalThis.foo = {
array: []
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(0, foo.array.length);
assertEquals([], foo.array);
})();
(function TestArrayContainingArray() {
function createObjects() {
globalThis.foo = {
array: [[2, 3], [4, 5]]
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([[2, 3], [4, 5]], foo.array);
})();
(function TestArrayContainingObject() {
function createObjects() {
globalThis.foo = {
array: [{ a: 1 }, { b: 2 }]
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(1, foo.array[0].a);
assertEquals(2, foo.array[1].b);
})();
(function TestArrayContainingFunction() {
function createObjects() {
globalThis.foo = {
array: [function () { return 5; }]
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(5, foo.array[0]());
})();
(function TestInPlaceStringsInArray() {
function createObjects() {
globalThis.foo = {
array: ['foo', 'bar', 'baz']
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
// We cannot test that the strings are really in-place; that's covered by
// cctests.
assertEquals('foobarbaz', foo.array.join(''));
})();
(function TestRepeatedInPlaceStringsInArray() {
function createObjects() {
globalThis.foo = {
array: ['foo', 'bar', 'foo']
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
// We cannot test that the strings are really in-place; that's covered by
// cctests.
assertEquals('foobarfoo', foo.array.join(''));
})();
(function TestArrayWithSlackElements() {
function createObjects() {
globalThis.foo = {
array: [],
doubleArray: [],
objectArray: []
};
for (let i = 0; i < 100; ++i) {
globalThis.foo.array.push(i);
globalThis.foo.doubleArray.push(i + 0.1);
globalThis.foo.objectArray.push({});
}
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(100, foo.array.length);
assertEquals(100, foo.doubleArray.length);
assertEquals(100, foo.objectArray.length);
for (let i = 0; i < 100; ++i){
assertEquals(i, foo.array[i]);
assertEquals(i + 0.1, foo.doubleArray[i]);
assertEquals({}, foo.objectArray[i]);
}
})();

View File

@ -1,147 +0,0 @@
// 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: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestMinimal() {
function createObjects() {
globalThis.foo = {
str: 'hello',
n: 42,
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('hello', foo.str);
assertEquals(42, foo.n);
})();
(function TestEmptyObject() {
function createObjects() {
globalThis.foo = {};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([], Object.keys(foo));
})();
(function TestNumbers() {
function createObjects() {
globalThis.foo = {
a: 6,
b: -7,
c: 7.3,
d: NaN,
e: Number.POSITIVE_INFINITY,
f: Number.NEGATIVE_INFINITY,
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(6, foo.a);
assertEquals(-7, foo.b);
assertEquals(7.3, foo.c);
assertEquals(NaN, foo.d);
assertEquals(Number.POSITIVE_INFINITY, foo.e);
assertEquals(Number.NEGATIVE_INFINITY, foo.f);
})();
(function TestTopLevelNumbers() {
function createObjects() {
globalThis.a = 6;
globalThis.b = -7;
}
const { a, b } = takeAndUseWebSnapshot(createObjects, ['a', 'b']);
assertEquals(6, a);
assertEquals(-7, b);
})();
(function TestOddballs() {
function createObjects() {
globalThis.foo = {
a: true,
b: false,
c: null,
d: undefined,
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertTrue(foo.a);
assertFalse(foo.b);
assertEquals(null, foo.c);
assertEquals(undefined, foo.d);
})();
(function TestTopLevelOddballs() {
function createObjects() {
globalThis.a = true;
globalThis.b = false;
}
const { a, b } = takeAndUseWebSnapshot(createObjects, ['a', 'b']);
assertTrue(a);
assertFalse(b);
})();
(function TestStringWithNull() {
function createObjects() {
globalThis.s = 'l\0l';
}
const { s } = takeAndUseWebSnapshot(createObjects, ['s']);
assertEquals(108, s.charCodeAt(0));
assertEquals(0, s.charCodeAt(1));
assertEquals(108, s.charCodeAt(2));
})();
(function TestTwoByteString() {
function createObjects() {
globalThis.s = '\u{1F600}';
}
const { s } = takeAndUseWebSnapshot(createObjects, ['s']);
assertEquals('\u{1F600}', s);
})();
(function TestTwoByteStringWithNull() {
function createObjects() {
globalThis.s = 'l\0l\u{1F600}';
}
const { s } = takeAndUseWebSnapshot(createObjects, ['s']);
assertEquals(108, s.charCodeAt(0));
assertEquals(0, s.charCodeAt(1));
assertEquals(108, s.charCodeAt(2));
})();
(function TestRegExp() {
function createObjects() {
globalThis.foo = {
re: /ab+c/gi,
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('/ab+c/gi', foo.re.toString());
assertTrue(foo.re.test('aBc'));
assertFalse(foo.re.test('ac'));
})();
(function TestRegExpNoFlags() {
function createObjects() {
globalThis.foo = {
re: /ab+c/,
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('/ab+c/', foo.re.toString());
assertTrue(foo.re.test('abc'));
assertFalse(foo.re.test('ac'));
})();
(function TestTopLevelRegExp() {
function createObjects() {
globalThis.re = /ab+c/gi;
}
const { re } = takeAndUseWebSnapshot(createObjects, ['re']);
assertEquals('/ab+c/gi', re.toString());
assertTrue(re.test('aBc'));
assertFalse(re.test('ac'));
})();

View File

@ -1,122 +0,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()]);
})();

View File

@ -1,39 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestBuiltin() {
function createObjects() {
globalThis.obj1 = {'a': Error};
globalThis.obj2 = {'b': Error.prototype};
}
const realm = Realm.create();
const {obj1, obj2} = takeAndUseWebSnapshot(
createObjects, ['obj1', 'obj2'], realm);
assertSame(Realm.eval(realm, 'Error'), obj1.a);
assertSame(Realm.eval(realm, 'Error.prototype'), obj2.b);
})();
(function TestInheritFromBuiltin() {
function createObjects() {
function inherit(subclass, superclass) {
function middle() {}
middle.prototype = superclass.prototype;
subclass.prototype = new middle();
subclass.prototype.constructor = subclass;
};
function MyError() {}
inherit(MyError, Error);
globalThis.MyError = MyError;
}
const realm = Realm.create();
const {MyError} = takeAndUseWebSnapshot(createObjects, ['MyError'], realm);
const obj = new MyError();
assertSame(Realm.eval(realm, 'Error.prototype'), obj.__proto__.__proto__);
})();

View File

@ -1,20 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestCircularObjectReference() {
function createObjects() {
globalThis.foo = {
bar: {}
};
globalThis.foo.bar.circular = globalThis.foo;
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertSame(foo, foo.bar.circular);
})();

View File

@ -1,177 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestEmptyClass() {
function createObjects() {
globalThis.Foo = class Foo { };
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
const x = new Foo();
})();
(function TestClassWithConstructor() {
function createObjects() {
globalThis.Foo = class {
constructor() {
this.n = 42;
}
};
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
const x = new Foo(2);
assertEquals(42, x.n);
})();
(function TestClassWithMethods() {
function createObjects() {
globalThis.Foo = class {
f() { return 7; };
};
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
const x = new Foo();
assertEquals(7, x.f());
})();
(function TestDerivedClass() {
function createObjects() {
globalThis.Base = class { f() { return 8; }};
globalThis.Foo = class extends Base { };
}
const realm = Realm.create();
const { Foo, Base } = takeAndUseWebSnapshot(createObjects, ['Foo', 'Base'], realm);
assertEquals(Base.prototype, Foo.prototype.__proto__);
assertEquals(Base, Foo.__proto__);
const x = new Foo();
assertEquals(8, x.f());
})();
(function TestDerivedClassWithConstructor() {
function createObjects() {
globalThis.Base = class { constructor() {this.m = 43;}};
globalThis.Foo = class extends Base{
constructor() {
super();
this.n = 42;
}
};
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
const x = new Foo();
assertEquals(42, x.n);
assertEquals(43, x.m);
})();
(async function TestClassWithAsyncMethods() {
function createObjects() {
globalThis.Foo = class {
async g() { return 6; };
};
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
const x = new Foo();
assertEquals(6, await x.g());
})();
(function TestClassWithProperties() {
function createObjects() {
globalThis.Foo = class Foo { };
Foo.key1 = 'value1';
Foo.key2 = 1;
Foo.key3 = 2.2;
Foo.key4 = function key4() {
return 'key4';
}
Foo.key5 = [1, 2];
Foo.key6 = {'key':'value'}
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
assertEquals('value1', Foo.key1);
assertEquals(1, Foo.key2);
assertEquals(2.2, Foo.key3);
assertEquals('key4', Foo.key4());
assertEquals([1, 2], Foo.key5);
assertEquals({ 'key': 'value' }, Foo.key6 );
})();
(function TestClassWithStaticProperties() {
function createObjects() {
globalThis.Foo = class Foo {
static key1 = 'value1';
static key2 = 1;
static key3 = 2.2;
static key4 = [1, 2];
static key5 = {'key':'value'}
};
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
assertEquals('value1', Foo.key1);
assertEquals(1, Foo.key2);
assertEquals(2.2, Foo.key3);
assertEquals([1, 2], Foo.key4);
assertEquals({'key': 'value'}, Foo.key5);
})();
(function TestClassWithStaticMethods() {
function createObjects() {
globalThis.Foo = class Foo {
static foo() {
return 'foo'
}
};
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
assertEquals('foo', Foo.foo());
})();
(async function TestClassWithStaticAsyncMethods() {
function createObjects() {
globalThis.Foo = class Foo {
static async foo() {
await Promise.resolve(1);
return 'foo'
}
};
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
assertEquals('foo', await Foo.foo());
})();
(function TestClassWithStaticGeneratorMethods() {
function createObjects() {
globalThis.Foo = class Foo {
static *foo() {
yield 'foo1'
return 'foo2'
}
};
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
const foo = Foo.foo()
assertEquals('foo1', foo.next().value);
assertEquals('foo2', foo.next().value);
assertEquals(true, foo.next().done);
})();
(async function TestClassWithStaticAsyncGeneratorMethods() {
function createObjects() {
globalThis.Foo = class Foo {
static async *foo() {
yield 'foo1'
return 'foo2'
}
};
}
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
const foo = Foo.foo()
assertEquals('foo1', (await foo.next()).value);
assertEquals('foo2', (await foo.next()).value);
assertEquals(true, (await foo.next()).done);
})();

View File

@ -1,127 +0,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 --harmony-rab-gsab --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestDataView() {
function createObjects() {
const buffer = new ArrayBuffer(10);
const array1 = new DataView(buffer, 0, 5);
const array2 = new DataView(buffer, 5, 5);
const array3 = new DataView(buffer, 2, 5);
for (let i = 0; i < 5; i++) {
array1.setUint8(i, i);
array2.setUint8(i, i);
}
globalThis.array1 = array1;
globalThis.array2 = array2;
globalThis.array3 = array3;
}
const {array1, array2, array3} = takeAndUseWebSnapshot(createObjects, [
'array1',
'array2',
'array3'
]);
assertEquals(5, array1.byteLength);
assertEquals(0, array1.byteOffset);
assertEquals(5, array2.byteLength);
assertEquals(5, array2.byteOffset);
assertEquals(5, array3.byteLength);
assertEquals(2, array3.byteOffset);
for (let i = 0; i < 5; i++) {
assertEquals(i, array1.getUint8(i));
assertEquals(i, array2.getUint8(i));
}
assertSame(array1.buffer, array2.buffer);
assertSame(array1.buffer, array3.buffer);
new DataView(array1.buffer).setUint8(2, 10);
assertTrue(array1.getUint8(2) === 10);
assertTrue(array3.getUint8(0) === 10);
})();
(function TestResizableDataView() {
function createObjects() {
let resizableArrayBuffer = new ArrayBuffer(1024, {
maxByteLength: 1024 * 2,
});
// 0 offset, auto length
let array1 = new DataView(resizableArrayBuffer);
globalThis.array1 = array1;
// Non-0 offset, auto length
let array2 = new DataView(resizableArrayBuffer, 256);
globalThis.array2 = array2;
// Non-0 offset, fixed length
let array3 = new DataView(resizableArrayBuffer, 128, 4);
globalThis.array3 = array3;
}
const {array1, array2, array3} = takeAndUseWebSnapshot(createObjects, [
'array1',
'array2',
'array3',
]);
assertTrue(array1.buffer.resizable);
assertEquals(2048, array1.buffer.maxByteLength);
assertEquals(1024, array1.byteLength);
assertEquals(0, array1.byteOffset, 0);
assertEquals(768, array2.byteLength); // 1024 - 256
assertEquals(256, array2.byteOffset);
assertEquals(4, array3.byteLength);
assertEquals(128, array3.byteOffset);
array1.buffer.resize(1024 * 2);
assertEquals(2048, array1.byteLength);
assertEquals(1792, array2.byteLength); // 2048 - 256
assertEquals(4, array3.byteLength);
assertSame(array1.buffer, array2.buffer);
assertSame(array1.buffer, array3.buffer);
})();
(function TestGrowableDataView() {
function createObjects() {
let resizableArrayBuffer = new SharedArrayBuffer(1024, {
maxByteLength: 1024 * 2,
});
// 0 offset, auto length
let array1 = new DataView(resizableArrayBuffer);
globalThis.array1 = array1;
// Non-0 offset, auto length
let array2 = new DataView(resizableArrayBuffer, 256);
globalThis.array2 = array2;
// Non-0 offset, fixed length
let array3 = new DataView(resizableArrayBuffer, 128, 4);
globalThis.array3 = array3;
}
const {array1, array2, array3} = takeAndUseWebSnapshot(createObjects, [
'array1',
'array2',
'array3',
]);
assertTrue(array1.buffer.growable);
assertEquals(2048, array1.buffer.maxByteLength);
assertEquals(1024, array1.byteLength);
assertEquals(0, array1.byteOffset);
assertEquals(768, array2.byteLength); // 1024 - 256
assertEquals(256, array2.byteOffset);
assertEquals(4, array3.byteLength);
assertEquals(128, array3.byteOffset);
array1.buffer.grow(1024 * 2);
assertEquals(2048, array1.byteLength);
assertEquals(1792, array2.byteLength); // 2048 - 256
assertEquals(4, array3.byteLength);
assertSame(array1.buffer, array2.buffer);
assertSame(array1.buffer, array3.buffer);
})();

View File

@ -1,80 +0,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-web-snapshots --allow-natives-syntax --verify-heap
const external_1 = {external: 1};
const external_2 = {external: 2};
const object = {
a: [1,2],
b: external_1,
c: [external_1, external_2],
d: { d_a: external_2 }
};
(function testNoExternals() {
const snapshot = WebSnapshot.serialize(object);
const deserialized = WebSnapshot.deserialize(snapshot);
%HeapObjectVerify(deserialized);
assertEquals(object, deserialized);
assertEquals(external_1, deserialized.b);
assertNotSame(external_1, deserialized.b);
assertEquals(external_2, deserialized.d.d_a);
assertNotSame(external_2, deserialized.d.d_a);
})();
(function testOneExternals() {
const externals = [external_1];
const snapshot = WebSnapshot.serialize(object, externals);
const replaced_externals = [{replacement:1}]
const deserialized = WebSnapshot.deserialize(snapshot, replaced_externals);
%HeapObjectVerify(deserialized);
assertEquals(object.a, deserialized.a);
assertSame(replaced_externals[0], deserialized.b);
assertArrayEquals([replaced_externals[0], external_2], deserialized.c);
assertSame(replaced_externals[0], deserialized.c[0]);
assertNotSame(external_2, deserialized.c[1]);
assertEquals(external_2, deserialized.d.d_a);
assertNotSame(external_2, deserialized.d.d_a);
})();
(function testTwoExternals() {
const externals = [external_1, external_2];
const snapshot = WebSnapshot.serialize(object, externals);
const replaced_externals = [{replacement:1}, {replacement:2}]
const deserialized = WebSnapshot.deserialize(snapshot, replaced_externals);
%HeapObjectVerify(deserialized);
assertEquals(object.a, deserialized.a);
assertSame(deserialized.b, replaced_externals[0]);
assertArrayEquals(replaced_externals, deserialized.c);
assertSame(replaced_externals[0], deserialized.c[0]);
assertSame(replaced_externals[1], deserialized.c[1]);
assertSame(replaced_externals[1], deserialized.d.d_a);
})();
(function testApiObject() {
const api_object = new d8.dom.Div();
const source_1 = [{}, api_object];
assertThrows(() => WebSnapshot.serialize(source_1));
let externals = [external_1]
const source_2 = [{}, external_1, api_object, api_object];
const snapshot_2 = WebSnapshot.serialize(source_2, externals);
%HeapObjectVerify(externals);
// Check that the unhandled api object is added to the externals.
assertArrayEquals([external_1, api_object], externals);
assertThrows(() => WebSnapshot.deserialize(snapshot_2));
assertThrows(() => WebSnapshot.deserialize(snapshot_2, []));
assertThrows(() => WebSnapshot.deserialize(snapshot_2, [external_1]));
const result_2 = WebSnapshot.deserialize(snapshot_2, [external_1, api_object]);
%HeapObjectVerify(externals);
%HeapObjectVerify(result_2);
assertArrayEquals(source_2, result_2);
assertNotSame(source_2[0], result_2[0]);
assertSame(external_1, result_2[1]);
assertSame(api_object, result_2[2]);
assertSame(api_object, result_2[3]);
})();

View File

@ -1,444 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestFunctionWithContext() {
function createObjects() {
globalThis.foo = {
key: (function () {
let result = 'bar';
function inner() { return result; }
return inner;
})(),
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('bar', foo.key());
})();
(function TestInnerFunctionWithContextAndParentContext() {
function createObjects() {
globalThis.foo = {
key: (function () {
let part1 = 'snap';
function inner() {
let part2 = 'shot';
function innerinner() {
return part1 + part2;
}
return innerinner;
}
return inner();
})()
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('snapshot', foo.key());
})();
(function TestTopLevelFunctionWithContext() {
function createObjects() {
globalThis.foo = (function () {
let result = 'bar';
function inner() { return result; }
return inner;
})();
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('bar', foo());
})();
(function TestContextTree() {
function createObjects() {
(function outer() {
let a = 10;
let b = 20;
(function inner1() {
let c = 5;
globalThis.f1 = function() { return a + b + c; };
})();
(function inner2() {
let d = 10;
globalThis.f2 = function() { return a - b - d; };
})();
})();
}
const {f1, f2} = takeAndUseWebSnapshot(createObjects, ['f1', 'f2']);
assertEquals(35, f1());
assertEquals(-20, f2());
})();
(function TestContextReferringToFunction() {
function createObjects() {
(function outer() {
let a = function() { return 10; }
globalThis.f = function() { return a(); };
})();
}
const {f} = takeAndUseWebSnapshot(createObjects, ['f']);
assertEquals(10, f());
})();
(function TestNonInlinedScopeInfoInContext() {
function createObjects() {
globalThis.bar = (function() {
let a1 = 1;
let a2 = 1;
let a3 = 1;
let a4 = 1;
let a5 = 1;
let a6 = 1;
let a7 = 1;
let a8 = 1;
let a9 = 1;
let a10 = 1;
let a11 = 1;
let a12 = 1;
let a13 = 1;
let a14 = 1;
let a15 = 1;
let a16 = 1;
let a17 = 1;
let a18 = 1;
let a19 = 1;
let a20 = 1;
let a21 = 1;
let a22 = 1;
let a23 = 1;
let a24 = 1;
let a25 = 1;
let a26 = 1;
let a27 = 1;
let a28 = 1;
let a29 = 1;
let a30 = 1;
let a31 = 1;
let a32 = 1;
let a33 = 1;
let a34 = 1;
let a35 = 1;
let a36 = 1;
let a37 = 1;
let a38 = 1;
let a39 = 1;
let a40 = 1;
let a41 = 1;
let a42 = 1;
let a43 = 1;
let a44 = 1;
let a45 = 1;
let a46 = 1;
let a47 = 1;
let a48 = 1;
let a49 = 1;
let a50 = 1;
let a51 = 1;
let a52 = 1;
let a53 = 1;
let a54 = 1;
let a55 = 1;
let a56 = 1;
let a57 = 1;
let a58 = 1;
let a59 = 1;
let a60 = 1;
let a61 = 1;
let a62 = 1;
let a63 = 1;
let a64 = 1;
let a65 = 1;
let a66 = 1;
let a67 = 1;
let a68 = 1;
let a69 = 1;
let a70 = 1;
let a71 = 1;
let a72 = 1;
let a73 = 1;
let a74 = 1;
let a75 = 1;
function inner1() {
return a1;
}
function inner2() {
return a2;
}
function inner3() {
return a3;
}
function inner4() {
return a4;
}
function inner5() {
return a5;
}
function inner6() {
return a6;
}
function inner7() {
return a7;
}
function inner8() {
return a8;
}
function inner9() {
return a9;
}
function inner10() {
return a10;
}
function inner11() {
return a11;
}
function inner12() {
return a12;
}
function inner13() {
return a13;
}
function inner14() {
return a14;
}
function inner15() {
return a15;
}
function inner16() {
return a16;
}
function inner17() {
return a17;
}
function inner18() {
return a18;
}
function inner19() {
return a19;
}
function inner20() {
return a20;
}
function inner21() {
return a21;
}
function inner22() {
return a22;
}
function inner23() {
return a23;
}
function inner24() {
return a24;
}
function inner25() {
return a25;
}
function inner26() {
return a26;
}
function inner27() {
return a27;
}
function inner28() {
return a28;
}
function inner29() {
return a29;
}
function inner30() {
return a30;
}
function inner31() {
return a31;
}
function inner32() {
return a32;
}
function inner33() {
return a33;
}
function inner34() {
return a34;
}
function inner35() {
return a35;
}
function inner36() {
return a36;
}
function inner37() {
return a37;
}
function inner38() {
return a38;
}
function inner39() {
return a39;
}
function inner40() {
return a40;
}
function inner41() {
return a41;
}
function inner42() {
return a42;
}
function inner43() {
return a43;
}
function inner44() {
return a44;
}
function inner45() {
return a45;
}
function inner46() {
return a46;
}
function inner47() {
return a47;
}
function inner48() {
return a48;
}
function inner49() {
return a49;
}
function inner50() {
return a50;
}
function inner51() {
return a51;
}
function inner52() {
return a52;
}
function inner53() {
return a53;
}
function inner54() {
return a54;
}
function inner55() {
return a55;
}
function inner56() {
return a56;
}
function inner57() {
return a57;
}
function inner58() {
return a58;
}
function inner59() {
return a59;
}
function inner60() {
return a60;
}
function inner61() {
return a61;
}
function inner62() {
return a62;
}
function inner63() {
return a63;
}
function inner64() {
return a64;
}
function inner65() {
return a65;
}
function inner66() {
return a66;
}
function inner67() {
return a67;
}
function inner68() {
return a68;
}
function inner69() {
return a69;
}
function inner70() {
return a70;
}
function inner71() {
return a71;
}
function inner72() {
return a72;
}
function inner73() {
return a73;
}
function inner74() {
return a74;
}
function inner75() {
return a75;
}
return inner1;
})()
}
const {bar} = takeAndUseWebSnapshot(createObjects, ['bar']);
assertEquals(1, bar());
})();
(function TestMoreThanOneScopeLocalInContext() {
function createObjects() {
globalThis.foo = (function() {
let result = 'bar';
let a = '1';
function inner() {
return result;
}
function inner2() {
return a;
}
return inner;
})();
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('bar', foo());
})();
(function TestContextReferencingArray() {
function createObjects() {
function outer() {
let o = [11525];
function inner() { return o; }
return inner;
}
globalThis.foo = {
func: outer()
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(11525, foo.func()[0]);
})();
(function TestContextReferencingObject() {
function createObjects() {
function outer() {
let o = { value: 11525 };
function inner() { return o; }
return inner;
}
globalThis.foo = {
func: outer()
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(11525, foo.func().value);
})();

View File

@ -1,270 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestFunction() {
function createObjects() {
globalThis.foo = {
key: function () { return 'bar'; },
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('bar', foo.key());
})();
(function TestOptimizingFunctionFromSnapshot() {
function createObjects() {
globalThis.f = function(a, b) { return a + b; }
}
const { f } = takeAndUseWebSnapshot(createObjects, ['f']);
%PrepareFunctionForOptimization(f);
assertEquals(3, f(1, 2));
%OptimizeFunctionOnNextCall(f);
assertEquals(4, f(1, 3));
})();
(function TestOptimizingConstructorFromSnapshot() {
function createObjects() {
globalThis.C = class {
constructor(a, b) {
this.x = a + b;
}
}
}
const { C } = takeAndUseWebSnapshot(createObjects, ['C']);
%PrepareFunctionForOptimization(C);
assertEquals(3, new C(1, 2).x);
%OptimizeFunctionOnNextCall(C);
assertEquals(4, new C(1, 3).x);
})();
(function TestFunctionPrototype() {
function createObjects() {
globalThis.F = function(p1, p2) {
this.x = p1 + p2;
}
globalThis.F.prototype.m = function(p1, p2) {
return this.x + p1 + p2;
}
}
const { F } = takeAndUseWebSnapshot(createObjects, ['F']);
const o = new F(1, 2);
assertEquals(3, o.x);
assertEquals(10, o.m(3, 4));
})();
(function TestFunctionPrototypeBecomesProto() {
function createObjects() {
globalThis.F = function() {}
globalThis.F.prototype.x = 100;
}
const { F } = takeAndUseWebSnapshot(createObjects, ['F']);
const o = new F();
assertEquals(100, Object.getPrototypeOf(o).x);
})();
(function TestFunctionCtorCallsFunctionInPrototype() {
function createObjects() {
globalThis.F = function() {
this.fooCalled = false;
this.foo();
}
globalThis.F.prototype.foo = function() { this.fooCalled = true; };
}
const { F } = takeAndUseWebSnapshot(createObjects, ['F']);
const o = new F();
assertTrue(o.fooCalled);
})();
(function TestFunctionPrototypeConnectedToObjectPrototype() {
function createObjects() {
globalThis.F = function() {}
}
const realm = Realm.create();
const { F } = takeAndUseWebSnapshot(createObjects, ['F'], realm);
const o = new F();
assertSame(Realm.eval(realm, 'Object.prototype'),
Object.getPrototypeOf(Object.getPrototypeOf(o)));
})();
(function TestFunctionInheritance() {
function createObjects() {
globalThis.Super = function() {}
globalThis.Super.prototype.superfunc = function() { return 'superfunc'; };
globalThis.Sub = function() {}
globalThis.Sub.prototype = Object.create(Super.prototype);
globalThis.Sub.prototype.subfunc = function() { return 'subfunc'; };
}
const realm = Realm.create();
const { Sub, Super } =
takeAndUseWebSnapshot(createObjects, ['Sub', 'Super'], realm);
const o = new Sub();
assertEquals('superfunc', o.superfunc());
assertEquals('subfunc', o.subfunc());
assertSame(Super.prototype, Sub.prototype.__proto__);
const realmFunctionPrototype = Realm.eval(realm, 'Function.prototype');
assertSame(realmFunctionPrototype, Super.__proto__);
assertSame(realmFunctionPrototype, Sub.__proto__);
})();
(function TestFunctionKinds() {
function createObjects() {
globalThis.normalFunction = function() {}
globalThis.asyncFunction = async function() {}
globalThis.generatorFunction = function*() {}
globalThis.asyncGeneratorFunction = async function*() {}
}
const realm = Realm.create();
const {normalFunction, asyncFunction, generatorFunction,
asyncGeneratorFunction} =
takeAndUseWebSnapshot(createObjects, ['normalFunction', 'asyncFunction',
'generatorFunction', 'asyncGeneratorFunction'], realm);
const newNormalFunction = Realm.eval(realm, 'f1 = function() {}');
const newAsyncFunction = Realm.eval(realm, 'f2 = async function() {}');
const newGeneratorFunction = Realm.eval(realm, 'f3 = function*() {}');
const newAsyncGeneratorFunction =
Realm.eval(realm, 'f4 = async function*() {}');
assertSame(newNormalFunction.__proto__, normalFunction.__proto__);
assertSame(newNormalFunction.prototype.__proto__,
normalFunction.prototype.__proto__);
assertSame(newAsyncFunction.__proto__, asyncFunction.__proto__);
assertEquals(undefined, asyncFunction.prototype);
assertEquals(undefined, newAsyncFunction.prototype);
assertSame(newGeneratorFunction.__proto__, generatorFunction.__proto__);
assertSame(newGeneratorFunction.prototype.__proto__,
generatorFunction.prototype.__proto__);
assertSame(newAsyncGeneratorFunction.__proto__,
asyncGeneratorFunction.__proto__);
assertSame(newAsyncGeneratorFunction.prototype.__proto__,
asyncGeneratorFunction.prototype.__proto__);
})();
(function TestFunctionWithProperties() {
function createObjects() {
function bar() { return 'bar'; };
bar.key1 = 'value1';
bar.key2 = 1;
bar.key3 = 2.2;
bar.key4 = function key4() {
return 'key4';
}
bar.key5 = [1, 2];
bar.key6 = {'key':'value'}
globalThis.foo = {
bar: bar,
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('bar', foo.bar());
assertEquals('value1', foo.bar.key1);
assertEquals(1, foo.bar.key2);
assertEquals(2.2, foo.bar.key3);
assertEquals('key4', foo.bar.key4());
assertEquals([1, 2], foo.bar.key5);
assertEquals({ 'key': 'value' }, foo.bar.key6 );
})();
(function TestAsyncFunctionWithProperties() {
function createObjects() {
async function bar() { return 'bar'; };
bar.key1 = 'value1';
bar.key2 = 1;
bar.key3 = 2.2;
bar.key4 = function key4() {
return 'key4';
}
bar.key5 = [1, 2];
bar.key6 = {'key':'value'}
globalThis.foo = {
bar: bar,
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('value1', foo.bar.key1);
assertEquals(1, foo.bar.key2);
assertEquals(2.2, foo.bar.key3);
assertEquals('key4', foo.bar.key4());
assertEquals([1, 2], foo.bar.key5);
assertEquals({'key': 'value'}, foo.bar.key6 );
})();
(function TestGeneratorFunctionWithProperties() {
function createObjects() {
function *bar() { return 'bar'; };
bar.key1 = 'value1';
bar.key2 = 1;
bar.key3 = 2.2;
bar.key4 = function key4() {
return 'key4';
};
bar.key5 = [1, 2];
bar.key6 = {'key':'value'};
globalThis.foo = {
bar: bar,
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('value1', foo.bar.key1);
assertEquals(1, foo.bar.key2);
assertEquals(2.2, foo.bar.key3);
assertEquals('key4', foo.bar.key4());
assertEquals([1, 2], foo.bar.key5);
assertEquals({'key': 'value'}, foo.bar.key6 );
})();
(function TestAsyncGeneratorFunctionWithProperties() {
function createObjects() {
async function *bar() { return 'bar'; };
bar.key1 = 'value1';
bar.key2 = 1;
bar.key3 = 2.2;
bar.key4 = function key4() {
return 'key4';
}
bar.key5 = [1, 2];
bar.key6 = {'key':'value'}
globalThis.foo = {
bar: bar,
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('value1', foo.bar.key1);
assertEquals(1, foo.bar.key2);
assertEquals(2.2, foo.bar.key3);
assertEquals('key4', foo.bar.key4());
assertEquals([1, 2], foo.bar.key5);
assertEquals({'key': 'value'}, foo.bar.key6);
})();
(function TestFunctionsWithSameMap() {
function createObjects() {
function bar1() { return 'bar1'; };
bar1.key = 'value';
function bar2() {
return 'bar2';
}
bar2.key = 'value';
globalThis.foo = {
bar1: bar1,
bar2: bar2
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals('bar1', foo.bar1());
assertEquals('value', foo.bar1.key);
assertEquals('bar2', foo.bar2());
assertEquals('value', foo.bar2.key);
assertTrue(%HaveSameMap(foo.bar1, foo.bar2))
})();

View File

@ -1,25 +0,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.
function use(exports) {
const result = Object.create(null);
exports.forEach(x => result[x] = globalThis[x]);
return result;
}
function takeAndUseWebSnapshot(createObjects, exports, realmForDeserializing) {
// Take a snapshot in Realm r1.
const r1 = Realm.create();
Realm.eval(r1, createObjects, { type: 'function' });
const snapshot = Realm.takeWebSnapshot(r1, exports);
// Use the snapshot in Realm r2.
const r2 = realmForDeserializing != undefined ?
realmForDeserializing : Realm.create();
const success = Realm.useWebSnapshot(r2, snapshot);
assertTrue(success);
const result =
Realm.eval(r2, use, { type: 'function', arguments: [exports] });
%HeapObjectVerify(result);
return result;
}

View File

@ -1,49 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestHoleySmiElementsArray() {
function createObjects() {
globalThis.foo = [1,,2];
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([1,,2], foo);
})();
(function TestHoleyElementsArray() {
function createObjects() {
globalThis.foo = [1,,'123'];
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([1,,'123'], foo);
})();
(function TestHoleyArrayContainingDoubleAndSmi() {
function createObjects() {
globalThis.foo = [1.2, , 1];
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([1.2, , 1], foo);
})();
(function TestHoleyArrayContainingDoubleAndObject() {
function createObjects() {
globalThis.foo = [1.2, , {'key': 'value'}];
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([1.2, , {'key': 'value'}], foo);
})();
(function TestHoleyDoubleElementsArray() {
function createObjects() {
globalThis.foo = [1.2, , 2.3];
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals([1.2, , 2.3], foo);
})();

View File

@ -1,204 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestObjectReferencingObject() {
function createObjects() {
globalThis.foo = {
bar: { baz: 11525 }
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(11525, foo.bar.baz);
})();
(function TestInPlaceStringsInObject() {
function createObjects() {
globalThis.foo = {a: 'foo', b: 'bar', c: 'baz'};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
// We cannot test that the strings are really in-place; that's covered by
// cctests.
assertEquals('foobarbaz', foo.a + foo.b + foo.c);
})();
(function TestRepeatedInPlaceStringsInObject() {
function createObjects() {
globalThis.foo = {a: 'foo', b: 'bar', c: 'foo'};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
// We cannot test that the strings are really in-place; that's covered by
// cctests.
assertEquals('foobarfoo', foo.a + foo.b + foo.c);
})();
(function TestObjectWithPackedElements() {
function createObjects() {
globalThis.foo = {
'0': 'zero', '1': 'one', '2': 'two', '3': 'three'
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
// Objects always get HOLEY_ELEMENTS; no PACKED or SMI_ELEMENTS.
const elementsKindTest = {0: 0, 1: 1, 2: 2};
assertFalse(%HasPackedElements(elementsKindTest));
assertFalse(%HasSmiElements(elementsKindTest));
assertFalse(%HasPackedElements(foo));
assertFalse(%HasSmiElements(foo));
assertEquals('zeroonetwothree', foo[0] + foo[1] + foo[2] + foo[3]);
})();
(function TestObjectWithPackedSmiElements() {
function createObjects() {
globalThis.foo = {
'0': 0, '1': 1, '2': 2, '3': 3
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertFalse(%HasPackedElements(foo));
assertFalse(%HasSmiElements(foo));
assertEquals('0123', '' + foo[0] + foo[1] + foo[2] + foo[3]);
})();
(function TestObjectWithHoleyElements() {
function createObjects() {
globalThis.foo = {
'1': 'a', '11': 'b', '111': 'c'
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertFalse(%HasPackedElements(foo));
assertFalse(%HasSmiElements(foo));
assertEquals('abc', foo[1] + foo[11] + foo[111]);
})();
(function TestObjectWithHoleySmiElements() {
function createObjects() {
globalThis.foo = {
'1': 0, '11': 1, '111': 2
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertFalse(%HasPackedElements(foo));
assertFalse(%HasSmiElements(foo));
assertEquals('012', '' + foo[1] + foo[11] + foo[111]);
})();
(function TestObjectWithPropertiesAndElements() {
function createObjects() {
globalThis.foo = {
'prop1': 'value1', '1': 'a', 'prop2': 'value2', '11': 'b', '111': 'c'
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertFalse(%HasPackedElements(foo));
assertFalse(%HasSmiElements(foo));
assertEquals('abc', foo[1] + foo[11] + foo[111]);
assertEquals('value1value2', foo.prop1 + foo.prop2);
})();
(function TestObjectsWithSamePropertiesButDifferentElementsKind() {
function createObjects() {
globalThis.foo = {
'prop1': 'value1', 'prop2': 'value2', '1': 'a', '11': 'b', '111': 'c'
};
globalThis.bar = {
'prop1': 'value1', 'prop2': 'value2', '0': 0, '1': 0
}
}
const { foo, bar } = takeAndUseWebSnapshot(createObjects, ['foo', 'bar']);
assertFalse(%HasPackedElements(foo));
assertFalse(%HasSmiElements(foo));
assertEquals('abc', foo[1] + foo[11] + foo[111]);
assertEquals('value1value2', foo.prop1 + foo.prop2);
assertFalse(%HasPackedElements(bar));
assertFalse(%HasSmiElements(bar));
assertEquals('00', '' + bar[0] + bar[1]);
assertEquals('value1value2', bar.prop1 + bar.prop2);
})();
(function TestObjectWithEmptyMap() {
function createObjects() {
globalThis.foo = [{a:1}, {}, {b: 2}];
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(1, foo[0].a);
assertEquals(2, foo[2].b);
})();
(function TestObjectWithDictionaryMap() {
function createObjects() {
const obj = {};
// Create an object with dictionary map.
for (let i = 0; i < 2000; i++){
obj[`key${i}`] = `value${i}`;
}
globalThis.foo = obj;
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(2000, Object.keys(foo).length);
assertEquals(2000, Object.values(foo).length);
for (let i = 0; i < 2000; i++){
assertEquals(`value${i}`, foo[`key${i}`]);
}
})();
(function TwoExportedObjects() {
function createObjects() {
globalThis.one = {x: 1};
globalThis.two = {x: 2};
}
const { one, two } = takeAndUseWebSnapshot(createObjects, ['one', 'two']);
assertEquals(1, one.x);
assertEquals(2, two.x);
})();
(function TestObjectWithDictionaryElements() {
function createObjects() {
globalThis.obj = {
10: 1,
100: 2,
1000: 3,
10000: 4
};
}
const { obj } = takeAndUseWebSnapshot(createObjects, ['obj']);
assertEquals(['10', '100', '1000', '10000'], Object.getOwnPropertyNames(obj));
assertEquals[1, obj[10]];
assertEquals[2, obj[100]];
assertEquals[3, obj[1000]];
assertEquals[4, obj[10000]];
})();
(function TestObjectWithDictionaryElementsWithLargeIndex() {
function createObjects() {
globalThis.obj = {};
globalThis.obj[4394967296] = 'lol';
}
const { obj } = takeAndUseWebSnapshot(createObjects, ['obj']);
assertEquals(['4394967296'], Object.getOwnPropertyNames(obj));
assertEquals['lol', obj[4394967296]];
})();
(function TestObjectWithSlackElements() {
function createObjects() {
globalThis.foo = {};
globalThis.bar = {};
for (let i = 0; i < 100; ++i) {
globalThis.foo[i] = i;
globalThis.bar[i] = {};
}
}
const { foo, bar } = takeAndUseWebSnapshot(createObjects, ['foo', 'bar']);
for (let i = 0; i < 100; ++i) {
assertEquals(i, foo[i]);
assertEquals({}, bar[i]);
}
})();

View File

@ -1,105 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestObjectPrototype() {
function createObjects() {
globalThis.obj = {a: 1, __proto__: {x: 1}};
}
const realm = Realm.create();
const {obj} = takeAndUseWebSnapshot(createObjects, ['obj'], realm);
assertEquals(1, obj.x);
assertEquals(1, obj.__proto__.x);
assertSame(Realm.eval(realm, 'Object.prototype'), obj.__proto__.__proto__);
})();
(function TestEmptyObjectPrototype() {
function createObjects() {
globalThis.obj = {__proto__: {x: 1}};
}
const realm = Realm.create();
const {obj} = takeAndUseWebSnapshot(createObjects, ['obj'], realm);
assertEquals(1, obj.x);
assertEquals(1, obj.__proto__.x);
assertSame(Realm.eval(realm, 'Object.prototype'), obj.__proto__.__proto__);
})();
(function TestDictionaryObjectPrototype() {
function createObjects() {
const obj = {};
// Create an object with dictionary map.
for (let i = 0; i < 2000; i++){
obj[`key${i}`] = `value${i}`;
}
obj.__proto__ = {x: 1};
globalThis.foo = obj;
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(2000, Object.keys(foo).length);
assertEquals(2000, Object.values(foo).length);
for (let i = 0; i < 2000; i++){
assertEquals(`value${i}`, foo[`key${i}`]);
}
assertEquals(1, foo.x);
assertEquals(1, foo.__proto__.x);
})();
(function TestNullPrototype() {
function createObjects() {
globalThis.foo = Object.create(null);
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(null, Object.getPrototypeOf(foo));
})();
(function TestDefaultObjectProto() {
function createObjects() {
globalThis.foo = {
str: 'hello',
n: 42,
};
}
const realm = Realm.create();
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo'], realm);
assertSame(Realm.eval(realm, 'Object.prototype'), Object.getPrototypeOf(foo));
})();
(function TestEmptyObjectProto() {
function createObjects() {
globalThis.foo = {};
}
const realm = Realm.create();
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo'], realm);
assertSame(Realm.eval(realm, 'Object.prototype'), Object.getPrototypeOf(foo));
})();
(function TestObjectProto() {
function createObjects() {
globalThis.foo = {
__proto__ : {x : 10},
y: 11
};
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertEquals(10, Object.getPrototypeOf(foo).x);
})();
(function TestObjectProtoInSnapshot() {
function createObjects() {
globalThis.o1 = { x: 10};
globalThis.o2 = {
__proto__ : o1,
y: 11
};
}
const realm = Realm.create();
const { o1, o2 } = takeAndUseWebSnapshot(createObjects, ['o1', 'o2'], realm);
assertSame(o1, Object.getPrototypeOf(o2));
assertSame(Realm.eval(realm, 'Object.prototype'), Object.getPrototypeOf(o1));
})();

View File

@ -1,99 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestDictionaryElementsArray() {
function createObjects() {
const array = [];
// Add a large index to force dictionary elements.
array[2 ** 30] = 10;
for (let i = 0; i < 10; i++) {
array[i * 101] = i;
}
globalThis.foo = array;
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertTrue(%HasDictionaryElements(foo));
assertEquals(2 ** 30 + 1, foo.length);
for (let i = 0; i < 10; i++) {
assertEquals(i, foo[i * 101]);
}
})();
(function TestDictionaryElementsArrayContainingArray() {
function createObjects() {
const array = [];
// Add a large index to force dictionary elements.
array[2 ** 30] = 10;
for (let i = 0; i < 10; i++) {
array[i * 101] = [i];
}
globalThis.foo = array;
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertTrue(%HasDictionaryElements(foo));
assertEquals(2 ** 30 + 1, foo.length);
for (let i = 0; i < 10; i++) {
assertEquals([i], foo[i * 101]);
}
})();
(function TestDictionaryElementsArrayContainingObject() {
function createObjects() {
const array = [];
// Add a large index to force dictionary elements.
array[2 ** 30] = 10;
for (let i = 0; i < 10; i++) {
array[i * 101] = {i: i};
}
globalThis.foo = array;
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertTrue(%HasDictionaryElements(foo));
assertEquals(2 ** 30 + 1, foo.length);
for (let i = 0; i < 10; i++) {
assertEquals({i: i}, foo[i * 101]);
}
})();
(function TestDictionaryElementsArrayContainingFunction() {
function createObjects() {
const array = [];
// Add a large index to force dictionary elements.
array[2 ** 30] = 10;
for (let i = 0; i < 10; i++) {
array[i * 101] = function() { return i; };
}
globalThis.foo = array;
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertTrue(%HasDictionaryElements(foo));
assertEquals(2 ** 30 + 1, foo.length);
for (let i = 0; i < 10; i++) {
assertEquals(i, foo[i * 101]());
}
})();
(function TestDictionaryElementsArrayContainingString() {
function createObjects() {
const array = [];
// Add a large index to force dictionary elements.
array[2 ** 30] = 10;
for (let i = 0; i < 10; i++) {
array[i * 101] = `${i}`;
}
globalThis.foo = array;
}
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
assertTrue(%HasDictionaryElements(foo));
assertEquals(2 ** 30 + 1, foo.length);
for (let i = 0; i < 10; i++) {
assertEquals(`${i}`, foo[i * 101]);
}
})();

View File

@ -1,47 +0,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 --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestNonGlobalSymbol() {
function createObjects() {
const s = Symbol('description');
globalThis.foo = {mySymbol: s, innerObject: { symbolHereToo: s}};
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertSame(foo.mySymbol, foo.innerObject.symbolHereToo);
assertEquals('description', foo.mySymbol.description);
assertNotEquals(foo.mySymbol, Symbol('description'));
assertNotEquals(foo.mySymbol, Symbol.for('description'));
})();
(function TestGlobalSymbol() {
function createObjects() {
const s = Symbol.for('this is global');
globalThis.foo = {mySymbol: s, innerObject: { symbolHereToo: s}};
}
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
assertSame(foo.mySymbol, foo.innerObject.symbolHereToo);
assertEquals('this is global', foo.mySymbol.description);
assertEquals(Symbol.for('this is global'), foo.mySymbol);
})();
(function TestSymbolAsMapKey() {
function createObjects() {
globalThis.obj1 = {};
const global_symbol = Symbol.for('this is global');
obj1[global_symbol] = 'global symbol value';
globalThis.obj2 = {};
const nonglobal_symbol = Symbol('this is not global');
obj2[nonglobal_symbol] = 'nonglobal symbol value';
}
const {obj1, obj2} = takeAndUseWebSnapshot(createObjects, ['obj1', 'obj2']);
assertEquals('global symbol value', obj1[Symbol.for('this is global')]);
const nonglobal_symbol = Object.getOwnPropertySymbols(obj2)[0];
assertEquals('nonglobal symbol value', obj2[nonglobal_symbol]);
})();

View File

@ -1,439 +0,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 --harmony-rab-gsab --verify-heap
'use strict';
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
(function TestTypedArray() {
function createObjects() {
const int8Array = new Int8Array(3);
for (let i = 0; i < 3; i++) {
int8Array[i] = i;
}
const uint8Array = new Uint8Array(3);
for (let i = 0; i < 3; i++) {
uint8Array[i] = i;
}
const uint8ClampedArray = new Uint8ClampedArray(3);
for (let i = 0; i < 3; i++) {
uint8ClampedArray[i] = i;
}
const int16Array = new Int16Array(3);
for (let i = 0; i < 3; i++) {
int16Array[i] = i;
}
const uint16Array = new Uint16Array(3);
for (let i = 0; i < 3; i++) {
uint16Array[i] = i;
}
const int32Array = new Int32Array(3);
for (let i = 0; i < 3; i++) {
int32Array[i] = i;
}
const uint32Array = new Uint32Array(3);
for (let i = 0; i < 3; i++) {
uint32Array[i] = i;
}
const float32Array = new Float32Array(3);
for (let i = 0; i < 3; i++) {
float32Array[i] = i + 0.2;
}
const float64Array = new Float64Array(3);
for (let i = 0; i < 3; i++) {
float64Array[i] = i + 0.2;
}
const bigInt64Array = new BigInt64Array(3);
for (let i = 0; i < 3; i++) {
bigInt64Array[i] = BigInt(i);
}
const bigUint64Array = new BigUint64Array(3);
for (let i = 0; i < 3; i++) {
bigUint64Array[i] = BigInt(i);
}
globalThis.int8Array = int8Array;
globalThis.uint8Array = uint8Array;
globalThis.uint8ClampedArray = uint8ClampedArray;
globalThis.int16Array = int16Array;
globalThis.uint16Array = uint16Array;
globalThis.int32Array = int32Array;
globalThis.uint32Array = uint32Array;
globalThis.float32Array = float32Array;
globalThis.float64Array = float64Array;
globalThis.bigInt64Array = bigInt64Array;
globalThis.bigUint64Array = bigUint64Array;
}
const {
int8Array,
uint8Array,
uint8ClampedArray,
int16Array,
uint16Array,
int32Array,
uint32Array,
float32Array,
float64Array,
bigInt64Array,
bigUint64Array,
} =
takeAndUseWebSnapshot(createObjects, [
'int8Array',
'uint8Array',
'uint8ClampedArray',
'int16Array',
'uint16Array',
'int32Array',
'uint32Array',
'float32Array',
'float64Array',
'bigInt64Array',
'bigUint64Array',
]);
assertNotSame(globalThis.int8Array, int8Array);
assertEquals(int8Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEquals(int8Array[i], i);
}
assertNotSame(globalThis.uint8Array, uint8Array);
assertEquals(uint8Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEquals(uint8Array[i], i);
}
assertNotSame(globalThis.uint8ClampedArray, uint8ClampedArray);
assertEquals(uint8ClampedArray.length, 3);
for (let i = 0; i < 3; i++) {
assertEquals(uint8ClampedArray[i], i);
}
assertNotSame(globalThis.int16Array, int16Array);
assertEquals(int16Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEquals(int16Array[i], i);
}
assertNotSame(globalThis.uint16Array, uint16Array);
assertEquals(uint16Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEquals(uint16Array[i], i);
}
assertNotSame(globalThis.int32Array, int32Array);
assertEquals(int32Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEquals(int32Array[i], i);
}
assertNotSame(globalThis.uint32Array, uint32Array);
assertEquals(uint32Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEquals(uint32Array[i], i);
}
assertNotSame(globalThis.float32Array, float32Array);
assertEquals(float32Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEqualsDelta(float32Array[i], i + 0.2);
}
assertNotSame(globalThis.float64Array, float64Array);
assertEquals(float64Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEqualsDelta(float64Array[i], i + 0.2);
}
assertNotSame(globalThis.bigInt64Array, bigInt64Array);
assertEquals(bigInt64Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEquals(bigInt64Array[i], BigInt(i));
}
assertNotSame(globalThis.bigUint64Array, bigUint64Array);
assertEquals(bigUint64Array.length, 3);
for (let i = 0; i < 3; i++) {
assertEquals(bigUint64Array[i], BigInt(i));
}
})();
(function TestInt8Array() {
function createObjects() {
const array = new Int8Array([-129, -128, 1, 127, 128]);
globalThis.array = array;
const array2 = new Int8Array(array.buffer, 1, 2);
globalThis.array2 = array2;
}
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
]);
assertEquals(array.length, 5);
assertEquals(array[0], 127);
assertEquals(array[1], -128);
assertEquals(array[2], 1);
assertEquals(array[3], 127);
assertEquals(array[4], -128);
assertSame(array.buffer, array2.buffer);
assertEquals(array2.length, 2);
assertEquals(array2[0], array[1]);
assertEquals(array2[1], array[2]);
})();
(function TestUint8Array() {
function createObjects() {
const array = new Uint8Array([-1, 0, 2, 255, 256]);
globalThis.array = array;
const array2 = new Uint8Array(array.buffer, 1, 2);
globalThis.array2 = array2;
}
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
]);
assertEquals(array.length, 5);
assertEquals(array[0], 255);
assertEquals(array[1], 0);
assertEquals(array[2], 2);
assertEquals(array[3], 255);
assertEquals(array[4], 0);
assertSame(array.buffer, array2.buffer);
assertEquals(array2.length, 2);
assertEquals(array2[0], array[1]);
assertEquals(array2[1], array[2]);
})();
(function TestUint8ClampedArray() {
function createObjects() {
const array = new Uint8ClampedArray([-1, 0, 2, 255, 256]);
globalThis.array = array;
const array2 = new Uint8ClampedArray(array.buffer, 1, 2);
globalThis.array2 = array2;
}
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
]);
assertEquals(array.length, 5);
assertEquals(array[0], 0);
assertEquals(array[1], 0);
assertEquals(array[2], 2);
assertEquals(array[3], 255);
assertEquals(array[4], 255);
assertSame(array.buffer, array2.buffer);
assertEquals(array2.length, 2);
assertEquals(array2[0], array[1]);
assertEquals(array2[1], array[2]);
})();
(function TestInt16Array() {
function createObjects() {
const array = new Int16Array([-32769, -32768, 1, 32767, 32768]);
globalThis.array = array;
const array2 = new Int16Array(array.buffer, 2, 2);
globalThis.array2 = array2;
}
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
]);
assertEquals(array.length, 5);
assertEquals(array[0], 32767);
assertEquals(array[1], -32768);
assertEquals(array[2], 1);
assertEquals(array[3], 32767);
assertEquals(array[4], -32768);
assertSame(array.buffer, array2.buffer);
assertEquals(array2.length, 2);
assertEquals(array2[0], array[1]);
assertEquals(array2[1], array[2]);
})();
(function TestUint16Array() {
function createObjects() {
const array = new Uint16Array([-1, 0, 2, 65535, 65536]);
globalThis.array = array;
const array2 = new Uint16Array(array.buffer, 2, 2);
globalThis.array2 = array2;
}
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
]);
assertEquals(array.length, 5);
assertEquals(array[0], 65535);
assertEquals(array[1], 0);
assertEquals(array[2], 2);
assertEquals(array[3], 65535);
assertEquals(array[4], 0);
assertSame(array.buffer, array2.buffer);
assertEquals(array2.length, 2);
assertEquals(array2[0], array[1]);
assertEquals(array2[1], array[2]);
})();
(function TestInt32Array() {
function createObjects() {
const array = new Int32Array([
-2147483649,
-2147483648,
1,
2147483647,
2147483648,
]);
globalThis.array = array;
const array2 = new Int32Array(array.buffer, 4, 2);
globalThis.array2 = array2;
}
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
]);
assertEquals(array.length, 5);
assertEquals(array[0], 2147483647);
assertEquals(array[1], -2147483648);
assertEquals(array[2], 1);
assertEquals(array[3], 2147483647);
assertEquals(array[4], -2147483648);
assertSame(array.buffer, array2.buffer);
assertEquals(array2.length, 2);
assertEquals(array2[0], array[1]);
assertEquals(array2[1], array[2]);
})();
(function TestUint32Array() {
function createObjects() {
const array = new Uint32Array([-1, 0, 2, 4294967295, 4294967296]);
globalThis.array = array;
const array2 = new Uint32Array(array.buffer, 4, 2);
globalThis.array2 = array2;
}
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
]);
assertEquals(array.length, 5);
assertEquals(array[0], 4294967295);
assertEquals(array[1], 0);
assertEquals(array[2], 2);
assertEquals(array[3], 4294967295);
assertEquals(array[4], 0);
assertSame(array.buffer, array2.buffer);
assertEquals(array2.length, 2);
assertEquals(array2[0], array[1]);
assertEquals(array2[1], array[2]);
})();
(function TestBigInt64Array() {
function createObjects() {
const array = new BigInt64Array([
BigInt(-(2 ** 63)) - 1n,
BigInt(-(2 ** 63)),
1n,
BigInt(2 ** 63) - 1n,
BigInt(2 ** 63),
]);
globalThis.array = array;
const array2 = new BigInt64Array(array.buffer, 8, 2);
globalThis.array2 = array2;
}
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
]);
assertEquals(array.length, 5);
assertEquals(array[0], BigInt(2 ** 63) - 1n);
assertEquals(array[1], BigInt(-(2 ** 63)));
assertEquals(array[2], 1n);
assertEquals(array[3], BigInt(2 ** 63) - 1n);
assertEquals(array[4], BigInt(-(2 ** 63)));
assertSame(array.buffer, array2.buffer);
assertEquals(array2.length, 2);
assertEquals(array2[0], array[1]);
assertEquals(array2[1], array[2]);
})();
(function TestBigUint32Array() {
function createObjects() {
const array = new BigUint64Array([
-1n,
0n,
2n,
BigInt(2 ** 64) - 1n,
BigInt(2 ** 64),
]);
globalThis.array = array;
const array2 = new BigUint64Array(array.buffer, 8, 2);
globalThis.array2 = array2;
}
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
]);
assertEquals(array.length, 5);
assertEquals(array[0], BigInt(2 ** 64) - 1n);
assertEquals(array[1], 0n);
assertEquals(array[2], 2n);
assertEquals(array[3], BigInt(2 ** 64) - 1n);
assertEquals(array[4], 0n);
assertSame(array.buffer, array2.buffer);
assertEquals(array2.length, 2);
assertEquals(array2[0], array[1]);
assertEquals(array2[1], array[2]);
})();
(function TestResizableTypedArray() {
function createObjects() {
let resizableArrayBuffer = new ArrayBuffer(1024, {
maxByteLength: 1024 * 2,
});
// 0 offset, auto length
let array = new Uint32Array(resizableArrayBuffer);
globalThis.array = array;
// Non-0 offset, auto length
let array2 = new Uint32Array(resizableArrayBuffer, 256);
globalThis.array2 = array2;
// Non-0 offset, fixed length
let array3 = new Uint32Array(resizableArrayBuffer, 128, 4);
globalThis.array3 = array3;
}
const {array, array2, array3} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
'array3',
]);
assertTrue(array.buffer.resizable);
assertEquals(array.length, 256); // (1024 - 0) / 4
assertEquals(array2.length, 192); // (1024 - 256) / 4
assertEquals(array3.length, 4);
array.buffer.resize(1024 * 2);
assertEquals(array.length, 512); // (2048 - 0) / 4
assertEquals(array2.length, 448); // (2048 - 256) / 4
assertEquals(array3.length, 4);
})();
(function TestGrowableTypedArray() {
function createObjects() {
let resizableArrayBuffer = new SharedArrayBuffer(1024, {
maxByteLength: 1024 * 2,
});
// 0 offset, auto length
let array = new Uint32Array(resizableArrayBuffer);
globalThis.array = array;
// Non-0 offset, auto length
let array2 = new Uint32Array(resizableArrayBuffer, 256);
globalThis.array2 = array2;
// Non-0 offset, fixed length
let array3 = new Uint32Array(resizableArrayBuffer, 128, 4);
globalThis.array3 = array3;
}
const {array, array2, array3} = takeAndUseWebSnapshot(createObjects, [
'array',
'array2',
'array3',
]);
assertTrue(array.buffer.growable);
assertEquals(array.length, 256); // (1024 - 0) / 4
assertEquals(array2.length, 192); // (1024 - 256) / 4
assertEquals(array3.length, 4);
array.buffer.grow(1024 * 2);
assertEquals(array.length, 512); // (2048 - 0) / 4
assertEquals(array2.length, 448); // (2048 - 256) / 4
assertEquals(array3.length, 4);
})();

View File

@ -465,7 +465,6 @@ v8_source_set("unittests_sources") {
"utils/sparse-bit-vector-unittest.cc",
"utils/utils-unittest.cc",
"utils/version-unittest.cc",
"web-snapshot/web-snapshot-unittest.cc",
"zone/zone-allocator-unittest.cc",
"zone/zone-chunk-list-unittest.cc",
"zone/zone-unittest.cc",

View File

@ -246,7 +246,6 @@
'WeakMapsTest.WeakMapsWithChainedEntries': [SKIP],
'WeakMapsTest.Weakness': [SKIP],
'WeakSetsTest.WeakSet_Weakness': [SKIP],
'WebSnapshotTest.SFIDeduplicationAfterBytecodeFlushing': [SKIP],
# CodeRange tests
'CodePagesTest.LargeCodeObjectWithSignalHandler': [SKIP],
@ -264,13 +263,6 @@
'FactoryCodeBuilderOOMTest.Factory_CodeBuilder_TryBuildOOM': [SKIP],
}], # third_party_heap
################################################################################
['variant == always_sparkplug', {
# SFI deduplication tests check compilation state, which always_sparkplug
# can break.
'WebSnapshotTest.SFIDeduplication*': [SKIP],
}],
##############################################################################
['byteorder == big', {
# Peephole optimization not supported on big-endian machines.

File diff suppressed because it is too large Load Diff

View File

@ -1945,7 +1945,6 @@ code is governed by a BSD-style license that can be found in the LICENSE file.
Group.groups.get('gc-background').entry(),
Group.groups.get('gc').entry(),
Group.groups.get('javascript').entry(),
Group.groups.get('websnapshot').entry(),
Group.groups.get('runtime').entry(),
this.unclassified
];
@ -2282,7 +2281,6 @@ code is governed by a BSD-style license that can be found in the LICENSE file.
new Group('GC', /GC_.*|AllocateInTargetSpace|GC/, "#00799c"));
Group.add('javascript',
new Group('JavaScript', /JS_Execution|JavaScript/, "#DD4477"));
Group.add('websnapshot', new Group('WebSnapshot', /.*Web.*/, "#E8E11C"));
Group.add('runtime', new Group('V8 C++', /.*/, "#88BB00"));
Group.add('blink',
new Group('Blink RCS', /.*Blink_.*/, "#006600", false, false));

View File

@ -19,5 +19,4 @@ RUNTIME_CALL_STATS_GROUPS = [
('Group-GC-Background', re.compile(".*GC.*BACKGROUND.*")),
('Group-GC', re.compile("GC_.*|AllocateInTargetSpace")),
('Group-JavaScript', re.compile("JS_Execution")),
('Group-WebSnapshot', re.compile("WebSnapshot.*")),
('Group-Runtime', re.compile(".*"))]