Commit d48558e6 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

Revert "[web snapshot] Recognize builtins"

This reverts commit 71dbb03e.

Reason for revert: gc-stress failures: https://ci.chromium.org/p/v8/builders/ci/V8%20Linux%20-%20gc%20stress/38357

Original change's description:
> [web snapshot] Recognize builtins
>
> Builtins are not snapshotted, but instead we insert "builtin wrappers"
> into the snapshot, and create references to the corresponding builtin
> when deserializing.
>
> Subclassing builtins will be implemented in a follow-up CL.
>
> Bug: v8:11525,v8:12820
> Change-Id: If72695d46bdfc8bf7e477471be1264b668551854
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3630080
> Reviewed-by: Camillo Bruni <cbruni@chromium.org>
> Commit-Queue: Marja Hölttä <marja@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#80419}

Bug: v8:11525,v8:12820
Change-Id: I49f65103ad7b367c5bccb498f698e9afb29b1fec
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3634799
Auto-Submit: Clemens Backes <clemensb@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Owners-Override: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80422}
parent 4fb91a0f
...@@ -42,7 +42,7 @@ BUILTIN(WebSnapshotSerialize) { ...@@ -42,7 +42,7 @@ BUILTIN(WebSnapshotSerialize) {
} }
if (!block_list_js_array.is_null() && if (!block_list_js_array.is_null() &&
static_cast<uint32_t>(block_list->length()) < static_cast<uint32_t>(block_list->length()) <
serializer.external_object_count()) { serializer.external_objects_count()) {
Handle<FixedArray> externals = serializer.GetExternals(); Handle<FixedArray> externals = serializer.GetExternals();
Handle<Map> map = JSObject::GetElementsTransitionMap(block_list_js_array, Handle<Map> map = JSObject::GetElementsTransitionMap(block_list_js_array,
PACKED_ELEMENTS); PACKED_ELEMENTS);
......
...@@ -483,7 +483,6 @@ class RuntimeCallTimer final { ...@@ -483,7 +483,6 @@ class RuntimeCallTimer final {
V(UpdateProtector) \ V(UpdateProtector) \
V(WebSnapshotDeserialize) \ V(WebSnapshotDeserialize) \
V(WebSnapshotDeserialize_Arrays) \ V(WebSnapshotDeserialize_Arrays) \
V(WebSnapshotDeserialize_BuiltinObjects) \
V(WebSnapshotDeserialize_Classes) \ V(WebSnapshotDeserialize_Classes) \
V(WebSnapshotDeserialize_Contexts) \ V(WebSnapshotDeserialize_Contexts) \
V(WebSnapshotDeserialize_Exports) \ V(WebSnapshotDeserialize_Exports) \
......
...@@ -23,7 +23,6 @@ namespace v8 { ...@@ -23,7 +23,6 @@ namespace v8 {
namespace internal { namespace internal {
constexpr uint8_t WebSnapshotSerializerDeserializer::kMagicNumber[4]; constexpr uint8_t WebSnapshotSerializerDeserializer::kMagicNumber[4];
constexpr int WebSnapshotSerializerDeserializer::kBuiltinObjectCount;
// When encountering an error during deserializing, we note down the error but // When encountering an error during deserializing, we note down the error but
// don't bail out from processing the snapshot further. This is to speed up // don't bail out from processing the snapshot further. This is to speed up
...@@ -48,16 +47,6 @@ void WebSnapshotSerializerDeserializer::Throw(const char* message) { ...@@ -48,16 +47,6 @@ void WebSnapshotSerializerDeserializer::Throw(const char* message) {
} }
} }
void WebSnapshotSerializerDeserializer::IterateBuiltinObjects(
std::function<void(String, HeapObject)> func) {
// TODO(v8:11525): Add more builtins.
auto roots = ReadOnlyRoots(isolate_);
func(roots.Error_string(), isolate_->context().error_function());
func(*factory()->NewStringFromAsciiChecked("Error.prototype"),
isolate_->context().error_function().instance_prototype());
STATIC_ASSERT(kBuiltinObjectCount == 2);
}
uint32_t WebSnapshotSerializerDeserializer::FunctionKindToFunctionFlags( uint32_t WebSnapshotSerializerDeserializer::FunctionKindToFunctionFlags(
FunctionKind kind) { FunctionKind kind) {
// TODO(v8:11525): Support more function kinds. // TODO(v8:11525): Support more function kinds.
...@@ -210,14 +199,13 @@ WebSnapshotSerializer::WebSnapshotSerializer(Isolate* isolate) ...@@ -210,14 +199,13 @@ WebSnapshotSerializer::WebSnapshotSerializer(Isolate* isolate)
string_serializer_(isolate_, nullptr), string_serializer_(isolate_, nullptr),
symbol_serializer_(isolate_, nullptr), symbol_serializer_(isolate_, nullptr),
map_serializer_(isolate_, nullptr), map_serializer_(isolate_, nullptr),
builtin_object_serializer_(isolate_, nullptr),
context_serializer_(isolate_, nullptr), context_serializer_(isolate_, nullptr),
function_serializer_(isolate_, nullptr), function_serializer_(isolate_, nullptr),
class_serializer_(isolate_, nullptr), class_serializer_(isolate_, nullptr),
array_serializer_(isolate_, nullptr), array_serializer_(isolate_, nullptr),
object_serializer_(isolate_, nullptr), object_serializer_(isolate_, nullptr),
export_serializer_(isolate_, nullptr), export_serializer_(isolate_, nullptr),
external_object_ids_(isolate_->heap()), external_objects_ids_(isolate_->heap()),
string_ids_(isolate_->heap()), string_ids_(isolate_->heap()),
symbol_ids_(isolate_->heap()), symbol_ids_(isolate_->heap()),
map_ids_(isolate_->heap()), map_ids_(isolate_->heap()),
...@@ -226,8 +214,6 @@ WebSnapshotSerializer::WebSnapshotSerializer(Isolate* isolate) ...@@ -226,8 +214,6 @@ WebSnapshotSerializer::WebSnapshotSerializer(Isolate* isolate)
class_ids_(isolate_->heap()), class_ids_(isolate_->heap()),
array_ids_(isolate_->heap()), array_ids_(isolate_->heap()),
object_ids_(isolate_->heap()), object_ids_(isolate_->heap()),
builtin_object_to_name_(isolate_->heap()),
builtin_object_ids_(isolate_->heap()),
all_strings_(isolate_->heap()) { all_strings_(isolate_->heap()) {
auto empty_array_list = factory()->empty_array_list(); auto empty_array_list = factory()->empty_array_list();
strings_ = empty_array_list; strings_ = empty_array_list;
...@@ -253,10 +239,6 @@ bool WebSnapshotSerializer::TakeSnapshot( ...@@ -253,10 +239,6 @@ bool WebSnapshotSerializer::TakeSnapshot(
ShallowDiscoverExternals(*maybe_externals.ToHandleChecked()); ShallowDiscoverExternals(*maybe_externals.ToHandleChecked());
} }
v8::Local<v8::Context> context =
reinterpret_cast<v8::Isolate*>(isolate_)->GetCurrentContext();
ShallowDiscoverBuiltinObjects(context);
if (object->IsHeapObject()) Discover(Handle<HeapObject>::cast(object)); if (object->IsHeapObject()) Discover(Handle<HeapObject>::cast(object));
ConstructSource(); ConstructSource();
...@@ -283,10 +265,8 @@ bool WebSnapshotSerializer::TakeSnapshot(v8::Local<v8::Context> context, ...@@ -283,10 +265,8 @@ bool WebSnapshotSerializer::TakeSnapshot(v8::Local<v8::Context> context,
} }
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_);
ShallowDiscoverBuiltinObjects(context); std::unique_ptr<Handle<JSObject>[]> export_objects(
new Handle<JSObject>[exports->Length()]);
Handle<FixedArray> export_objects =
isolate_->factory()->NewFixedArray(exports->Length());
for (int i = 0, length = exports->Length(); i < length; ++i) { for (int i = 0, length = exports->Length(); i < length; ++i) {
v8::Local<v8::String> str = v8::Local<v8::String> str =
exports->Get(v8_isolate, i)->ToString(context).ToLocalChecked(); exports->Get(v8_isolate, i)->ToString(context).ToLocalChecked();
...@@ -305,15 +285,8 @@ bool WebSnapshotSerializer::TakeSnapshot(v8::Local<v8::Context> context, ...@@ -305,15 +285,8 @@ bool WebSnapshotSerializer::TakeSnapshot(v8::Local<v8::Context> context,
Throw("Exported object not found"); Throw("Exported object not found");
return false; return false;
} }
auto object = Handle<JSObject>::cast(Utils::OpenHandle(*v8_object)); export_objects[i] = Handle<JSObject>::cast(Utils::OpenHandle(*v8_object));
export_objects->set(i, *object); Discover(export_objects[i]);
Discover(object);
// The error messages will be confusing if we continue running code when
// already in the error state.
if (has_error()) {
isolate_->ReportPendingMessages();
return false;
}
} }
ConstructSource(); ConstructSource();
...@@ -324,7 +297,7 @@ bool WebSnapshotSerializer::TakeSnapshot(v8::Local<v8::Context> context, ...@@ -324,7 +297,7 @@ bool WebSnapshotSerializer::TakeSnapshot(v8::Local<v8::Context> context,
if (str->Length() == 0) { if (str->Length() == 0) {
continue; continue;
} }
SerializeExport(handle(export_objects->get(i), isolate_), SerializeExport(export_objects[i],
Handle<String>::cast(Utils::OpenHandle(*str))); Handle<String>::cast(Utils::OpenHandle(*str)));
} }
...@@ -355,9 +328,6 @@ void WebSnapshotSerializer::SerializePendingItems() { ...@@ -355,9 +328,6 @@ void WebSnapshotSerializer::SerializePendingItems() {
Handle<Map> map = handle(Map::cast(maps_->Get(i)), isolate_); Handle<Map> map = handle(Map::cast(maps_->Get(i)), isolate_);
SerializeMap(map); SerializeMap(map);
} }
for (auto name_id : builtin_objects_) {
SerializeBuiltinObject(name_id);
}
// Serialize the items in the reverse order. The items at the end of the // Serialize the items in the reverse order. The items at the end of the
// contexts_ etc get lower IDs and vice versa. IDs which items use for // contexts_ etc get lower IDs and vice versa. IDs which items use for
...@@ -396,9 +366,6 @@ void WebSnapshotSerializer::SerializePendingItems() { ...@@ -396,9 +366,6 @@ void WebSnapshotSerializer::SerializePendingItems() {
// - Symbol count // - Symbol count
// - For each symbol: // - For each symbol:
// - Serialized symbol // - Serialized symbol
// - Builtin object count
// - For each builtin object:
// - Id of the builtin object name string
// - Shape count // - Shape count
// - For each shape: // - For each shape:
// - Serialized shape // - Serialized shape
...@@ -424,8 +391,7 @@ void WebSnapshotSerializer::WriteSnapshot(uint8_t*& buffer, ...@@ -424,8 +391,7 @@ void WebSnapshotSerializer::WriteSnapshot(uint8_t*& buffer,
ValueSerializer total_serializer(isolate_, nullptr); ValueSerializer total_serializer(isolate_, nullptr);
size_t needed_size = size_t needed_size =
sizeof(kMagicNumber) + string_serializer_.buffer_size_ + sizeof(kMagicNumber) + string_serializer_.buffer_size_ +
symbol_serializer_.buffer_size_ + symbol_serializer_.buffer_size_ + map_serializer_.buffer_size_ +
builtin_object_serializer_.buffer_size_ + map_serializer_.buffer_size_ +
context_serializer_.buffer_size_ + function_serializer_.buffer_size_ + context_serializer_.buffer_size_ + function_serializer_.buffer_size_ +
class_serializer_.buffer_size_ + array_serializer_.buffer_size_ + class_serializer_.buffer_size_ + array_serializer_.buffer_size_ +
object_serializer_.buffer_size_ + export_serializer_.buffer_size_ + object_serializer_.buffer_size_ + export_serializer_.buffer_size_ +
...@@ -438,8 +404,6 @@ void WebSnapshotSerializer::WriteSnapshot(uint8_t*& buffer, ...@@ -438,8 +404,6 @@ void WebSnapshotSerializer::WriteSnapshot(uint8_t*& buffer,
total_serializer.WriteRawBytes(kMagicNumber, 4); total_serializer.WriteRawBytes(kMagicNumber, 4);
WriteObjects(total_serializer, string_count(), string_serializer_, "strings"); WriteObjects(total_serializer, string_count(), string_serializer_, "strings");
WriteObjects(total_serializer, symbol_count(), symbol_serializer_, "symbols"); WriteObjects(total_serializer, symbol_count(), symbol_serializer_, "symbols");
WriteObjects(total_serializer, builtin_object_count(),
builtin_object_serializer_, "builtin_objects");
WriteObjects(total_serializer, map_count(), map_serializer_, "maps"); WriteObjects(total_serializer, map_count(), map_serializer_, "maps");
WriteObjects(total_serializer, context_count(), context_serializer_, WriteObjects(total_serializer, context_count(), context_serializer_,
"contexts"); "contexts");
...@@ -474,6 +438,9 @@ bool WebSnapshotSerializer::InsertIntoIndexMap(ObjectCacheIndexMap& map, ...@@ -474,6 +438,9 @@ bool WebSnapshotSerializer::InsertIntoIndexMap(ObjectCacheIndexMap& map,
uint32_t& id) { uint32_t& id) {
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
int index_out; int index_out;
if (external_objects_ids_.Lookup(heap_object, &index_out)) {
return true;
}
bool found = map.LookupOrInsert(heap_object, &index_out); bool found = map.LookupOrInsert(heap_object, &index_out);
id = static_cast<uint32_t>(index_out); id = static_cast<uint32_t>(index_out);
return found; return found;
...@@ -598,10 +565,6 @@ void WebSnapshotSerializer::SerializeMap(Handle<Map> map) { ...@@ -598,10 +565,6 @@ void WebSnapshotSerializer::SerializeMap(Handle<Map> map) {
} }
} }
void WebSnapshotSerializer::SerializeBuiltinObject(uint32_t name_id) {
builtin_object_serializer_.WriteUint32(name_id);
}
// Construct the minimal source string to be included in the snapshot. Maintain // Construct the minimal source string to be included in the snapshot. Maintain
// the "inner function is textually inside its outer function" relationship. // the "inner function is textually inside its outer function" relationship.
// Example: // Example:
...@@ -699,32 +662,11 @@ void WebSnapshotSerializer::ShallowDiscoverExternals(FixedArray externals) { ...@@ -699,32 +662,11 @@ void WebSnapshotSerializer::ShallowDiscoverExternals(FixedArray externals) {
Object object = externals.get(i); Object object = externals.get(i);
if (!object.IsHeapObject()) continue; if (!object.IsHeapObject()) continue;
uint32_t unused_id = 0; uint32_t unused_id = 0;
InsertIntoIndexMap(external_object_ids_, HeapObject::cast(object), InsertIntoIndexMap(external_objects_ids_, HeapObject::cast(object),
unused_id); unused_id);
} }
} }
void WebSnapshotSerializer::ShallowDiscoverBuiltinObjects(
v8::Local<v8::Context> context) {
// Fill in builtin_object_to_name_. Don't discover them or their
// names, so that they won't be included in the snapshot unless needed.
builtin_object_name_strings_ =
isolate_->factory()->NewFixedArray(kBuiltinObjectCount);
int i = 0;
IterateBuiltinObjects([&](String name, HeapObject object) {
builtin_object_name_strings_->set(i, name);
uint32_t id;
bool already_exists =
InsertIntoIndexMap(builtin_object_to_name_, object, id);
CHECK(!already_exists);
CHECK_EQ(static_cast<int>(id), i);
++i;
});
DCHECK_EQ(i, kBuiltinObjectCount);
}
void WebSnapshotSerializer::Discover(Handle<HeapObject> start_object) { void WebSnapshotSerializer::Discover(Handle<HeapObject> start_object) {
// The object discovery phase assigns IDs for objects / functions / classes / // The object discovery phase assigns IDs for objects / functions / classes /
// arrays and discovers outgoing references from them. This is needed so that // arrays and discovers outgoing references from them. This is needed so that
...@@ -779,9 +721,9 @@ void WebSnapshotSerializer::Discover(Handle<HeapObject> start_object) { ...@@ -779,9 +721,9 @@ void WebSnapshotSerializer::Discover(Handle<HeapObject> start_object) {
// strings. // strings.
DiscoverString(Handle<String>::cast(object), AllowInPlace::Yes); DiscoverString(Handle<String>::cast(object), AllowInPlace::Yes);
break; break;
} else if (external_object_ids_.size() > 0) { } else if (external_objects_ids_.size() > 0) {
int unused_id; int unused_id;
external_object_ids_.LookupOrInsert(*object, &unused_id); external_objects_ids_.LookupOrInsert(*object, &unused_id);
} else { } else {
Throw("Unsupported object"); Throw("Unsupported object");
} }
...@@ -843,10 +785,6 @@ void WebSnapshotSerializer::DiscoverString(Handle<String> string, ...@@ -843,10 +785,6 @@ void WebSnapshotSerializer::DiscoverString(Handle<String> string,
} }
void WebSnapshotSerializer::DiscoverFunction(Handle<JSFunction> function) { void WebSnapshotSerializer::DiscoverFunction(Handle<JSFunction> function) {
if (DiscoverIfBuiltinObject(function)) {
return;
}
uint32_t id; uint32_t id;
if (InsertIntoIndexMap(function_ids_, *function, id)) { if (InsertIntoIndexMap(function_ids_, *function, id)) {
return; return;
...@@ -995,13 +933,6 @@ void WebSnapshotSerializer::DiscoverObjectPropertiesWithDictionaryMap(T dict) { ...@@ -995,13 +933,6 @@ void WebSnapshotSerializer::DiscoverObjectPropertiesWithDictionaryMap(T dict) {
} }
void WebSnapshotSerializer::DiscoverObject(Handle<JSObject> object) { void WebSnapshotSerializer::DiscoverObject(Handle<JSObject> object) {
if (GetExternalId(*object)) {
return;
}
if (DiscoverIfBuiltinObject(object)) {
return;
}
uint32_t id; uint32_t id;
if (InsertIntoIndexMap(object_ids_, *object, id)) return; if (InsertIntoIndexMap(object_ids_, *object, id)) return;
...@@ -1055,32 +986,6 @@ void WebSnapshotSerializer::DiscoverObject(Handle<JSObject> object) { ...@@ -1055,32 +986,6 @@ void WebSnapshotSerializer::DiscoverObject(Handle<JSObject> object) {
} }
} }
bool WebSnapshotSerializer::DiscoverIfBuiltinObject(Handle<HeapObject> object) {
uint32_t name_index;
if (!GetBuiltinObjectNameIndex(*object, name_index)) {
return false;
}
CHECK_LT(name_index, builtin_object_name_strings_->length());
Handle<String> name_string = handle(
String::cast(builtin_object_name_strings_->get(name_index)), isolate_);
DiscoverString(name_string, AllowInPlace::No);
// Ensure the builtin object reference gets included in the snapshot.
uint32_t id;
if (InsertIntoIndexMap(builtin_object_ids_, *object, id)) {
// The builtin object is already referred to by something else.
return true;
}
DCHECK_EQ(id, builtin_objects_.size());
bool in_place = false;
uint32_t name_id = GetStringId(name_string, in_place);
DCHECK(!in_place);
USE(in_place);
builtin_objects_.push_back(name_id);
return true;
}
void WebSnapshotSerializer::DiscoverSymbol(Handle<Symbol> symbol) { void WebSnapshotSerializer::DiscoverSymbol(Handle<Symbol> symbol) {
if (symbol->is_well_known_symbol()) { if (symbol->is_well_known_symbol()) {
// TODO(v8:11525): Support well-known Symbols. // TODO(v8:11525): Support well-known Symbols.
...@@ -1352,16 +1257,10 @@ void WebSnapshotSerializer::WriteValue(Handle<Object> object, ...@@ -1352,16 +1257,10 @@ void WebSnapshotSerializer::WriteValue(Handle<Object> object,
return; return;
} }
uint32_t id; int external_id;
if (GetExternalId(HeapObject::cast(*object), &id)) { if (external_objects_ids_.Lookup(HeapObject::cast(*object), &external_id)) {
serializer.WriteUint32(ValueType::EXTERNAL_ID); serializer.WriteUint32(ValueType::EXTERNAL_ID);
serializer.WriteUint32(id); serializer.WriteUint32(static_cast<uint32_t>(external_id));
return;
}
if (GetBuiltinObjectId(HeapObject::cast(*object), id)) {
serializer.WriteUint32(ValueType::BUILTIN_OBJECT_ID);
serializer.WriteUint32(id);
return; return;
} }
...@@ -1532,33 +1431,16 @@ uint32_t WebSnapshotSerializer::GetObjectId(JSObject object) { ...@@ -1532,33 +1431,16 @@ uint32_t WebSnapshotSerializer::GetObjectId(JSObject object) {
return static_cast<uint32_t>(object_ids_.size() - 1 - id); return static_cast<uint32_t>(object_ids_.size() - 1 - id);
} }
bool WebSnapshotSerializer::GetExternalId(HeapObject object, uint32_t* id) { uint32_t WebSnapshotSerializer::GetExternalId(HeapObject object) {
int id_int; int id;
bool return_value = external_object_ids_.Lookup(object, &id_int); bool return_value = external_objects_ids_.Lookup(object, &id);
if (id != nullptr) { DCHECK(return_value);
*id = static_cast<uint32_t>(id_int); USE(return_value);
} return static_cast<uint32_t>(id);
return return_value;
}
bool WebSnapshotSerializer::GetBuiltinObjectNameIndex(HeapObject object,
uint32_t& index) {
int index_int = 0;
bool return_value = builtin_object_to_name_.Lookup(object, &index_int);
index = static_cast<uint32_t>(index_int);
return return_value;
}
bool WebSnapshotSerializer::GetBuiltinObjectId(HeapObject object,
uint32_t& id) {
int id_int;
bool return_value = builtin_object_ids_.Lookup(object, &id_int);
id = static_cast<uint32_t>(id_int);
return return_value;
} }
Handle<FixedArray> WebSnapshotSerializer::GetExternals() { Handle<FixedArray> WebSnapshotSerializer::GetExternals() {
return external_object_ids_.Values(isolate_); return external_objects_ids_.Values(isolate_);
} }
WebSnapshotDeserializer::WebSnapshotDeserializer(v8::Isolate* isolate, WebSnapshotDeserializer::WebSnapshotDeserializer(v8::Isolate* isolate,
...@@ -1601,7 +1483,6 @@ WebSnapshotDeserializer::~WebSnapshotDeserializer() { ...@@ -1601,7 +1483,6 @@ WebSnapshotDeserializer::~WebSnapshotDeserializer() {
void WebSnapshotDeserializer::UpdatePointers() { void WebSnapshotDeserializer::UpdatePointers() {
strings_ = *strings_handle_; strings_ = *strings_handle_;
symbols_ = *symbols_handle_; symbols_ = *symbols_handle_;
builtin_objects_ = *builtin_objects_handle_;
maps_ = *maps_handle_; maps_ = *maps_handle_;
contexts_ = *contexts_handle_; contexts_ = *contexts_handle_;
functions_ = *functions_handle_; functions_ = *functions_handle_;
...@@ -1668,7 +1549,6 @@ void WebSnapshotDeserializer::Throw(const char* message) { ...@@ -1668,7 +1549,6 @@ void WebSnapshotDeserializer::Throw(const char* message) {
string_count_ = 0; string_count_ = 0;
symbol_count_ = 0; symbol_count_ = 0;
map_count_ = 0; map_count_ = 0;
builtin_object_count_ = 0;
context_count_ = 0; context_count_ = 0;
class_count_ = 0; class_count_ = 0;
function_count_ = 0; function_count_ = 0;
...@@ -1717,8 +1597,6 @@ bool WebSnapshotDeserializer::Deserialize( ...@@ -1717,8 +1597,6 @@ bool WebSnapshotDeserializer::Deserialize(
} }
bool WebSnapshotDeserializer::DeserializeSnapshot(bool skip_exports) { bool WebSnapshotDeserializer::DeserializeSnapshot(bool skip_exports) {
CollectBuiltinObjects();
deferred_references_ = ArrayList::New(isolate_, 30); deferred_references_ = ArrayList::New(isolate_, 30);
const void* magic_bytes; const void* magic_bytes;
...@@ -1730,7 +1608,6 @@ bool WebSnapshotDeserializer::DeserializeSnapshot(bool skip_exports) { ...@@ -1730,7 +1608,6 @@ bool WebSnapshotDeserializer::DeserializeSnapshot(bool skip_exports) {
DeserializeStrings(); DeserializeStrings();
DeserializeSymbols(); DeserializeSymbols();
DeserializeBuiltinObjects();
DeserializeMaps(); DeserializeMaps();
DeserializeContexts(); DeserializeContexts();
DeserializeFunctions(); DeserializeFunctions();
...@@ -1744,28 +1621,6 @@ bool WebSnapshotDeserializer::DeserializeSnapshot(bool skip_exports) { ...@@ -1744,28 +1621,6 @@ bool WebSnapshotDeserializer::DeserializeSnapshot(bool skip_exports) {
return !has_error(); return !has_error();
} }
void WebSnapshotDeserializer::CollectBuiltinObjects() {
// TODO(v8:11525): Look up the builtin objects from the global object.
builtin_object_name_to_object_ =
ObjectHashTable::New(isolate_, kBuiltinObjectCount);
#if DEBUG
int i = 0;
#endif
IterateBuiltinObjects([&](String name, HeapObject object) {
auto new_builtin_object_name_to_object =
ObjectHashTable::Put(builtin_object_name_to_object_,
handle(name, isolate_), handle(object, isolate_));
USE(new_builtin_object_name_to_object);
// We preallocated the correct size, so the hash table doesn't grow.
DCHECK_EQ(*new_builtin_object_name_to_object,
*builtin_object_name_to_object_);
#if DEBUG
++i;
#endif
});
DCHECK_EQ(i, kBuiltinObjectCount);
}
bool WebSnapshotDeserializer::DeserializeScript() { bool WebSnapshotDeserializer::DeserializeScript() {
// If there is more data, treat it as normal JavaScript. // If there is more data, treat it as normal JavaScript.
DCHECK_LE(deserializer_.position_, deserializer_.end_); DCHECK_LE(deserializer_.position_, deserializer_.end_);
...@@ -1985,24 +1840,6 @@ void WebSnapshotDeserializer::DeserializeMaps() { ...@@ -1985,24 +1840,6 @@ void WebSnapshotDeserializer::DeserializeMaps() {
} }
} }
void WebSnapshotDeserializer::DeserializeBuiltinObjects() {
RCS_SCOPE(isolate_,
RuntimeCallCounterId::kWebSnapshotDeserialize_BuiltinObjects);
if (!deserializer_.ReadUint32(&builtin_object_count_) ||
builtin_object_count_ > kMaxItemCount) {
Throw("Malformed builtin object table");
return;
}
STATIC_ASSERT(kMaxItemCount <= FixedArray::kMaxLength);
builtin_objects_handle_ = factory()->NewFixedArray(builtin_object_count_);
builtin_objects_ = *builtin_objects_handle_;
for (uint32_t i = 0; i < builtin_object_count_; ++i) {
Handle<String> name = handle(ReadString(), isolate_);
builtin_objects_.set(static_cast<int>(i),
builtin_object_name_to_object_->Lookup(name));
}
}
void WebSnapshotDeserializer::DeserializeContexts() { void WebSnapshotDeserializer::DeserializeContexts() {
RCS_SCOPE(isolate_, RuntimeCallCounterId::kWebSnapshotDeserialize_Contexts); RCS_SCOPE(isolate_, RuntimeCallCounterId::kWebSnapshotDeserialize_Contexts);
if (!deserializer_.ReadUint32(&context_count_) || if (!deserializer_.ReadUint32(&context_count_) ||
...@@ -2721,8 +2558,6 @@ Object WebSnapshotDeserializer::ReadValue( ...@@ -2721,8 +2558,6 @@ Object WebSnapshotDeserializer::ReadValue(
return ReadSymbol(); return ReadSymbol();
case ValueType::EXTERNAL_ID: case ValueType::EXTERNAL_ID:
return ReadExternalReference(); return ReadExternalReference();
case ValueType::BUILTIN_OBJECT_ID:
return ReadBuiltinObjectReference();
case ValueType::IN_PLACE_STRING_ID: case ValueType::IN_PLACE_STRING_ID:
return ReadInPlaceString(internalize_strings); return ReadInPlaceString(internalize_strings);
default: default:
...@@ -2836,16 +2671,6 @@ Object WebSnapshotDeserializer::ReadExternalReference() { ...@@ -2836,16 +2671,6 @@ Object WebSnapshotDeserializer::ReadExternalReference() {
return external_references_.get(ref_id); return external_references_.get(ref_id);
} }
Object WebSnapshotDeserializer::ReadBuiltinObjectReference() {
uint32_t ref_id;
if (!deserializer_.ReadUint32(&ref_id) ||
ref_id >= static_cast<uint32_t>(builtin_objects_.length())) {
Throw("Invalid builtin object reference");
return Smi::zero();
}
return builtin_objects_.get(ref_id);
}
void WebSnapshotDeserializer::ReadFunctionPrototype( void WebSnapshotDeserializer::ReadFunctionPrototype(
Handle<JSFunction> function) { Handle<JSFunction> function) {
uint32_t object_id; uint32_t object_id;
......
...@@ -57,7 +57,6 @@ class WebSnapshotSerializerDeserializer { ...@@ -57,7 +57,6 @@ class WebSnapshotSerializerDeserializer {
CLASS_ID, CLASS_ID,
SYMBOL_ID, SYMBOL_ID,
EXTERNAL_ID, EXTERNAL_ID,
BUILTIN_OBJECT_ID,
IN_PLACE_STRING_ID IN_PLACE_STRING_ID
}; };
...@@ -95,10 +94,6 @@ class WebSnapshotSerializerDeserializer { ...@@ -95,10 +94,6 @@ class WebSnapshotSerializerDeserializer {
// Not virtual, on purpose (because it doesn't need to be). // Not virtual, on purpose (because it doesn't need to be).
void Throw(const char* message); void Throw(const char* message);
void IterateBuiltinObjects(std::function<void(String, HeapObject)> func);
static constexpr int kBuiltinObjectCount = 2;
inline Factory* factory() const { return isolate_->factory(); } inline Factory* factory() const { return isolate_->factory(); }
Isolate* isolate_; Isolate* isolate_;
...@@ -151,10 +146,6 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -151,10 +146,6 @@ class V8_EXPORT WebSnapshotSerializer
uint32_t map_count() const { return static_cast<uint32_t>(map_ids_.size()); } uint32_t map_count() const { return static_cast<uint32_t>(map_ids_.size()); }
uint32_t builtin_object_count() const {
return static_cast<uint32_t>(builtin_object_ids_.size());
}
uint32_t context_count() const { uint32_t context_count() const {
return static_cast<uint32_t>(context_ids_.size()); return static_cast<uint32_t>(context_ids_.size());
} }
...@@ -175,8 +166,8 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -175,8 +166,8 @@ class V8_EXPORT WebSnapshotSerializer
return static_cast<uint32_t>(object_ids_.size()); return static_cast<uint32_t>(object_ids_.size());
} }
uint32_t external_object_count() const { uint32_t external_objects_count() const {
return static_cast<uint32_t>(external_object_ids_.size()); return static_cast<uint32_t>(external_objects_ids_.size());
} }
Handle<FixedArray> GetExternals(); Handle<FixedArray> GetExternals();
...@@ -200,7 +191,6 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -200,7 +191,6 @@ class V8_EXPORT WebSnapshotSerializer
uint32_t& id); uint32_t& id);
void ShallowDiscoverExternals(FixedArray externals); void ShallowDiscoverExternals(FixedArray externals);
void ShallowDiscoverBuiltinObjects(v8::Local<v8::Context> context);
void Discover(Handle<HeapObject> object); void Discover(Handle<HeapObject> object);
void DiscoverString(Handle<String> string, void DiscoverString(Handle<String> string,
AllowInPlace can_be_in_place = AllowInPlace::No); AllowInPlace can_be_in_place = AllowInPlace::No);
...@@ -212,7 +202,6 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -212,7 +202,6 @@ class V8_EXPORT WebSnapshotSerializer
void DiscoverContext(Handle<Context> context); void DiscoverContext(Handle<Context> context);
void DiscoverArray(Handle<JSArray> array); void DiscoverArray(Handle<JSArray> array);
void DiscoverObject(Handle<JSObject> object); void DiscoverObject(Handle<JSObject> object);
bool DiscoverIfBuiltinObject(Handle<HeapObject> object);
void DiscoverSource(Handle<JSFunction> function); void DiscoverSource(Handle<JSFunction> function);
template <typename T> template <typename T>
void DiscoverObjectPropertiesWithDictionaryMap(T dict); void DiscoverObjectPropertiesWithDictionaryMap(T dict);
...@@ -224,7 +213,6 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -224,7 +213,6 @@ class V8_EXPORT WebSnapshotSerializer
void SerializeString(Handle<String> string, ValueSerializer& serializer); void SerializeString(Handle<String> string, ValueSerializer& serializer);
void SerializeSymbol(Handle<Symbol> symbol); void SerializeSymbol(Handle<Symbol> symbol);
void SerializeMap(Handle<Map> map); void SerializeMap(Handle<Map> map);
void SerializeBuiltinObject(uint32_t name_id);
void SerializeObjectPrototype(Handle<Map> map, ValueSerializer& serializer); void SerializeObjectPrototype(Handle<Map> map, ValueSerializer& serializer);
template <typename T> template <typename T>
...@@ -249,15 +237,11 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -249,15 +237,11 @@ class V8_EXPORT WebSnapshotSerializer
uint32_t GetContextId(Context context); uint32_t GetContextId(Context context);
uint32_t GetArrayId(JSArray array); uint32_t GetArrayId(JSArray array);
uint32_t GetObjectId(JSObject object); uint32_t GetObjectId(JSObject object);
bool GetExternalId(HeapObject object, uint32_t* id = nullptr); uint32_t GetExternalId(HeapObject object);
// 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 string_serializer_;
ValueSerializer symbol_serializer_; ValueSerializer symbol_serializer_;
ValueSerializer map_serializer_; ValueSerializer map_serializer_;
ValueSerializer builtin_object_serializer_;
ValueSerializer context_serializer_; ValueSerializer context_serializer_;
ValueSerializer function_serializer_; ValueSerializer function_serializer_;
ValueSerializer class_serializer_; ValueSerializer class_serializer_;
...@@ -277,7 +261,7 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -277,7 +261,7 @@ class V8_EXPORT WebSnapshotSerializer
// IndexMap to keep track of explicitly blocked external objects and // IndexMap to keep track of explicitly blocked external objects and
// non-serializable/not-supported objects (e.g. API Objects). // non-serializable/not-supported objects (e.g. API Objects).
ObjectCacheIndexMap external_object_ids_; ObjectCacheIndexMap external_objects_ids_;
// ObjectCacheIndexMap implements fast lookup item -> id. Some items (context, // ObjectCacheIndexMap implements fast lookup item -> id. Some items (context,
// function, class, array, object) can point to other items and we serialize // function, class, array, object) can point to other items and we serialize
...@@ -293,24 +277,6 @@ class V8_EXPORT WebSnapshotSerializer ...@@ -293,24 +277,6 @@ class V8_EXPORT WebSnapshotSerializer
ObjectCacheIndexMap object_ids_; ObjectCacheIndexMap object_ids_;
uint32_t export_count_ = 0; 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_; std::queue<Handle<HeapObject>> discovery_queue_;
// For keeping track of which strings have exactly one reference. Strings are // For keeping track of which strings have exactly one reference. Strings are
...@@ -344,7 +310,6 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -344,7 +310,6 @@ class V8_EXPORT WebSnapshotDeserializer
uint32_t string_count() const { return string_count_; } uint32_t string_count() const { return string_count_; }
uint32_t symbol_count() const { return symbol_count_; } uint32_t symbol_count() const { return symbol_count_; }
uint32_t map_count() const { return map_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 context_count() const { return context_count_; }
uint32_t function_count() const { return function_count_; } uint32_t function_count() const { return function_count_; }
uint32_t class_count() const { return class_count_; } uint32_t class_count() const { return class_count_; }
...@@ -372,7 +337,6 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -372,7 +337,6 @@ class V8_EXPORT WebSnapshotDeserializer
base::Vector<const uint8_t> ExtractScriptBuffer( base::Vector<const uint8_t> ExtractScriptBuffer(
Isolate* isolate, Handle<Script> snapshot_as_script); Isolate* isolate, Handle<Script> snapshot_as_script);
bool DeserializeSnapshot(bool skip_exports); bool DeserializeSnapshot(bool skip_exports);
void CollectBuiltinObjects();
bool DeserializeScript(); bool DeserializeScript();
WebSnapshotDeserializer(const WebSnapshotDeserializer&) = delete; WebSnapshotDeserializer(const WebSnapshotDeserializer&) = delete;
...@@ -381,7 +345,6 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -381,7 +345,6 @@ class V8_EXPORT WebSnapshotDeserializer
void DeserializeStrings(); void DeserializeStrings();
void DeserializeSymbols(); void DeserializeSymbols();
void DeserializeMaps(); void DeserializeMaps();
void DeserializeBuiltinObjects();
void DeserializeContexts(); void DeserializeContexts();
Handle<ScopeInfo> CreateScopeInfo(uint32_t variable_count, bool has_parent, Handle<ScopeInfo> CreateScopeInfo(uint32_t variable_count, bool has_parent,
ContextType context_type, ContextType context_type,
...@@ -418,7 +381,6 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -418,7 +381,6 @@ class V8_EXPORT WebSnapshotDeserializer
Object ReadFunction(Handle<HeapObject> container, uint32_t container_index); Object ReadFunction(Handle<HeapObject> container, uint32_t container_index);
Object ReadClass(Handle<HeapObject> container, uint32_t container_index); Object ReadClass(Handle<HeapObject> container, uint32_t container_index);
Object ReadRegexp(); Object ReadRegexp();
Object ReadBuiltinObjectReference();
Object ReadExternalReference(); Object ReadExternalReference();
bool ReadMapType(); bool ReadMapType();
...@@ -438,9 +400,6 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -438,9 +400,6 @@ class V8_EXPORT WebSnapshotDeserializer
Handle<FixedArray> symbols_handle_; Handle<FixedArray> symbols_handle_;
FixedArray symbols_; FixedArray symbols_;
Handle<FixedArray> builtin_objects_handle_;
FixedArray builtin_objects_;
Handle<FixedArray> maps_handle_; Handle<FixedArray> maps_handle_;
FixedArray maps_; FixedArray maps_;
...@@ -462,9 +421,6 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -462,9 +421,6 @@ class V8_EXPORT WebSnapshotDeserializer
Handle<FixedArray> external_references_handle_; Handle<FixedArray> external_references_handle_;
FixedArray external_references_; FixedArray external_references_;
// Map: String -> builtin object.
Handle<ObjectHashTable> builtin_object_name_to_object_;
Handle<ArrayList> deferred_references_; Handle<ArrayList> deferred_references_;
Handle<WeakFixedArray> shared_function_infos_handle_; Handle<WeakFixedArray> shared_function_infos_handle_;
...@@ -480,7 +436,6 @@ class V8_EXPORT WebSnapshotDeserializer ...@@ -480,7 +436,6 @@ class V8_EXPORT WebSnapshotDeserializer
uint32_t string_count_ = 0; uint32_t string_count_ = 0;
uint32_t symbol_count_ = 0; uint32_t symbol_count_ = 0;
uint32_t map_count_ = 0; uint32_t map_count_ = 0;
uint32_t builtin_object_count_ = 0;
uint32_t context_count_ = 0; uint32_t context_count_ = 0;
uint32_t function_count_ = 0; uint32_t function_count_ = 0;
uint32_t current_function_count_ = 0; uint32_t current_function_count_ = 0;
......
...@@ -16,9 +16,9 @@ namespace { ...@@ -16,9 +16,9 @@ namespace {
void TestWebSnapshotExtensive( void TestWebSnapshotExtensive(
const char* snapshot_source, const char* test_source, const char* snapshot_source, const char* test_source,
std::function<void(v8::Isolate*, v8::Local<v8::Context>)> tester, std::function<void(v8::Isolate*, v8::Local<v8::Context>)> tester,
uint32_t string_count, uint32_t symbol_count, uint32_t builtin_object_count, uint32_t string_count, uint32_t symbol_count, uint32_t map_count,
uint32_t map_count, uint32_t context_count, uint32_t function_count, uint32_t context_count, uint32_t function_count, uint32_t object_count,
uint32_t object_count, uint32_t array_count) { uint32_t array_count) {
CcTest::InitializeVM(); CcTest::InitializeVM();
v8::Isolate* isolate = CcTest::isolate(); v8::Isolate* isolate = CcTest::isolate();
...@@ -40,7 +40,6 @@ void TestWebSnapshotExtensive( ...@@ -40,7 +40,6 @@ void TestWebSnapshotExtensive(
CHECK_EQ(string_count, serializer.string_count()); CHECK_EQ(string_count, serializer.string_count());
CHECK_EQ(symbol_count, serializer.symbol_count()); CHECK_EQ(symbol_count, serializer.symbol_count());
CHECK_EQ(map_count, serializer.map_count()); CHECK_EQ(map_count, serializer.map_count());
CHECK_EQ(builtin_object_count, serializer.builtin_object_count());
CHECK_EQ(context_count, serializer.context_count()); CHECK_EQ(context_count, serializer.context_count());
CHECK_EQ(function_count, serializer.function_count()); CHECK_EQ(function_count, serializer.function_count());
CHECK_EQ(object_count, serializer.object_count()); CHECK_EQ(object_count, serializer.object_count());
...@@ -59,7 +58,6 @@ void TestWebSnapshotExtensive( ...@@ -59,7 +58,6 @@ void TestWebSnapshotExtensive(
CHECK_EQ(string_count, deserializer.string_count()); CHECK_EQ(string_count, deserializer.string_count());
CHECK_EQ(symbol_count, deserializer.symbol_count()); CHECK_EQ(symbol_count, deserializer.symbol_count());
CHECK_EQ(map_count, deserializer.map_count()); CHECK_EQ(map_count, deserializer.map_count());
CHECK_EQ(builtin_object_count, deserializer.builtin_object_count());
CHECK_EQ(context_count, deserializer.context_count()); CHECK_EQ(context_count, deserializer.context_count());
CHECK_EQ(function_count, deserializer.function_count()); CHECK_EQ(function_count, deserializer.function_count());
CHECK_EQ(object_count, deserializer.object_count()); CHECK_EQ(object_count, deserializer.object_count());
...@@ -70,9 +68,8 @@ void TestWebSnapshotExtensive( ...@@ -70,9 +68,8 @@ void TestWebSnapshotExtensive(
void TestWebSnapshot(const char* snapshot_source, const char* test_source, void TestWebSnapshot(const char* snapshot_source, const char* test_source,
const char* expected_result, uint32_t string_count, const char* expected_result, uint32_t string_count,
uint32_t symbol_count, uint32_t map_count, uint32_t symbol_count, uint32_t map_count,
uint32_t builtin_object_count, uint32_t context_count, uint32_t context_count, uint32_t function_count,
uint32_t function_count, uint32_t object_count, uint32_t object_count, uint32_t array_count) {
uint32_t array_count) {
TestWebSnapshotExtensive( TestWebSnapshotExtensive(
snapshot_source, test_source, snapshot_source, test_source,
[test_source, expected_result](v8::Isolate* isolate, [test_source, expected_result](v8::Isolate* isolate,
...@@ -80,8 +77,8 @@ void TestWebSnapshot(const char* snapshot_source, const char* test_source, ...@@ -80,8 +77,8 @@ void TestWebSnapshot(const char* snapshot_source, const char* test_source,
v8::Local<v8::String> result = CompileRun(test_source).As<v8::String>(); v8::Local<v8::String> result = CompileRun(test_source).As<v8::String>();
CHECK(result->Equals(new_context, v8_str(expected_result)).FromJust()); CHECK(result->Equals(new_context, v8_str(expected_result)).FromJust());
}, },
string_count, symbol_count, map_count, builtin_object_count, string_count, symbol_count, map_count, context_count, function_count,
context_count, function_count, object_count, array_count); object_count, array_count);
} }
} // namespace } // namespace
...@@ -92,15 +89,14 @@ TEST(Minimal) { ...@@ -92,15 +89,14 @@ TEST(Minimal) {
const char* expected_result = "lol"; const char* expected_result = "lol";
uint32_t kStringCount = 1; // 'foo'; 'key' is in-place. uint32_t kStringCount = 1; // 'foo'; 'key' is in-place.
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
uint32_t kObjectCount = 1; uint32_t kObjectCount = 1;
uint32_t kArrayCount = 0; uint32_t kArrayCount = 0;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount, TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount, kSymbolCount, kMapCount, kContextCount, kFunctionCount,
kFunctionCount, kObjectCount, kArrayCount); kObjectCount, kArrayCount);
} }
TEST(EmptyObject) { TEST(EmptyObject) {
...@@ -108,7 +104,6 @@ TEST(EmptyObject) { ...@@ -108,7 +104,6 @@ TEST(EmptyObject) {
const char* test_source = "foo"; const char* test_source = "foo";
uint32_t kStringCount = 1; // 'foo' uint32_t kStringCount = 1; // 'foo'
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
...@@ -123,9 +118,8 @@ TEST(EmptyObject) { ...@@ -123,9 +118,8 @@ TEST(EmptyObject) {
i_isolate->native_context()->object_function().initial_map()); i_isolate->native_context()->object_function().initial_map());
}; };
TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount, TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kSymbolCount, kMapCount, kContextCount,
kContextCount, kFunctionCount, kObjectCount, kFunctionCount, kObjectCount, kArrayCount);
kArrayCount);
} }
TEST(Numbers) { TEST(Numbers) {
...@@ -140,7 +134,6 @@ TEST(Numbers) { ...@@ -140,7 +134,6 @@ TEST(Numbers) {
const char* test_source = "foo"; const char* test_source = "foo";
uint32_t kStringCount = 1; // 'foo'; 'a'...'f' are in-place. uint32_t kStringCount = 1; // 'foo'; 'a'...'f' are in-place.
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
...@@ -182,9 +175,8 @@ TEST(Numbers) { ...@@ -182,9 +175,8 @@ TEST(Numbers) {
CHECK_EQ(f, -std::numeric_limits<double>::infinity()); CHECK_EQ(f, -std::numeric_limits<double>::infinity());
}; };
TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount, TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kSymbolCount, kMapCount, kContextCount,
kContextCount, kFunctionCount, kObjectCount, kFunctionCount, kObjectCount, kArrayCount);
kArrayCount);
} }
TEST(Oddballs) { TEST(Oddballs) {
...@@ -197,7 +189,6 @@ TEST(Oddballs) { ...@@ -197,7 +189,6 @@ TEST(Oddballs) {
const char* test_source = "foo"; const char* test_source = "foo";
uint32_t kStringCount = 1; // 'foo'; 'a'...'d' are in-place. uint32_t kStringCount = 1; // 'foo'; 'a'...'d' are in-place.
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
...@@ -216,9 +207,8 @@ TEST(Oddballs) { ...@@ -216,9 +207,8 @@ TEST(Oddballs) {
CHECK(d->IsUndefined()); CHECK(d->IsUndefined());
}; };
TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount, TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kSymbolCount, kMapCount, kContextCount,
kContextCount, kFunctionCount, kObjectCount, kFunctionCount, kObjectCount, kArrayCount);
kArrayCount);
} }
TEST(Function) { TEST(Function) {
...@@ -228,15 +218,14 @@ TEST(Function) { ...@@ -228,15 +218,14 @@ TEST(Function) {
const char* expected_result = "11525"; const char* expected_result = "11525";
uint32_t kStringCount = 2; // 'foo', function source code. 'key' is in-place. uint32_t kStringCount = 2; // 'foo', function source code. 'key' is in-place.
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 1; uint32_t kFunctionCount = 1;
uint32_t kObjectCount = 1; uint32_t kObjectCount = 1;
uint32_t kArrayCount = 0; uint32_t kArrayCount = 0;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount, TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount, kSymbolCount, kMapCount, kContextCount, kFunctionCount,
kFunctionCount, kObjectCount, kArrayCount); kObjectCount, kArrayCount);
} }
TEST(InnerFunctionWithContext) { TEST(InnerFunctionWithContext) {
...@@ -251,15 +240,14 @@ TEST(InnerFunctionWithContext) { ...@@ -251,15 +240,14 @@ TEST(InnerFunctionWithContext) {
// Strings: 'foo', 'result', function source code (inner). 'key' is in-place. // Strings: 'foo', 'result', function source code (inner). 'key' is in-place.
uint32_t kStringCount = 3; uint32_t kStringCount = 3;
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 1; uint32_t kContextCount = 1;
uint32_t kFunctionCount = 1; uint32_t kFunctionCount = 1;
uint32_t kObjectCount = 1; uint32_t kObjectCount = 1;
uint32_t kArrayCount = 0; uint32_t kArrayCount = 0;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount, TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount, kSymbolCount, kMapCount, kContextCount, kFunctionCount,
kFunctionCount, kObjectCount, kArrayCount); kObjectCount, kArrayCount);
} }
TEST(InnerFunctionWithContextAndParentContext) { TEST(InnerFunctionWithContextAndParentContext) {
...@@ -280,15 +268,14 @@ TEST(InnerFunctionWithContextAndParentContext) { ...@@ -280,15 +268,14 @@ TEST(InnerFunctionWithContextAndParentContext) {
// Strings: 'foo', function source code (innerinner), 'part1', 'part2'. // Strings: 'foo', function source code (innerinner), 'part1', 'part2'.
uint32_t kStringCount = 4; uint32_t kStringCount = 4;
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 2; uint32_t kContextCount = 2;
uint32_t kFunctionCount = 1; uint32_t kFunctionCount = 1;
uint32_t kObjectCount = 1; uint32_t kObjectCount = 1;
uint32_t kArrayCount = 0; uint32_t kArrayCount = 0;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount, TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount, kSymbolCount, kMapCount, kContextCount, kFunctionCount,
kFunctionCount, kObjectCount, kArrayCount); kObjectCount, kArrayCount);
} }
TEST(RegExp) { TEST(RegExp) {
...@@ -296,7 +283,6 @@ TEST(RegExp) { ...@@ -296,7 +283,6 @@ TEST(RegExp) {
const char* test_source = "foo"; const char* test_source = "foo";
uint32_t kStringCount = 3; // 'foo', RegExp pattern, RegExp flags uint32_t kStringCount = 3; // 'foo', RegExp pattern, RegExp flags
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
...@@ -319,9 +305,8 @@ TEST(RegExp) { ...@@ -319,9 +305,8 @@ TEST(RegExp) {
CHECK(no_match->IsNull()); CHECK(no_match->IsNull());
}; };
TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount, TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kSymbolCount, kMapCount, kContextCount,
kContextCount, kFunctionCount, kObjectCount, kFunctionCount, kObjectCount, kArrayCount);
kArrayCount);
} }
TEST(RegExpNoFlags) { TEST(RegExpNoFlags) {
...@@ -329,7 +314,6 @@ TEST(RegExpNoFlags) { ...@@ -329,7 +314,6 @@ TEST(RegExpNoFlags) {
const char* test_source = "foo"; const char* test_source = "foo";
uint32_t kStringCount = 3; // 'foo', RegExp pattern, RegExp flags uint32_t kStringCount = 3; // 'foo', RegExp pattern, RegExp flags
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
...@@ -352,9 +336,8 @@ TEST(RegExpNoFlags) { ...@@ -352,9 +336,8 @@ TEST(RegExpNoFlags) {
CHECK(no_match->IsNull()); CHECK(no_match->IsNull());
}; };
TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount, TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kSymbolCount, kMapCount, kContextCount,
kContextCount, kFunctionCount, kObjectCount, kFunctionCount, kObjectCount, kArrayCount);
kArrayCount);
} }
TEST(SFIDeduplication) { TEST(SFIDeduplication) {
...@@ -721,7 +704,6 @@ TEST(FunctionKinds) { ...@@ -721,7 +704,6 @@ TEST(FunctionKinds) {
const char* test_source = "foo"; const char* test_source = "foo";
uint32_t kStringCount = 2; // 'foo', source code. 'a'...'f' in-place. uint32_t kStringCount = 2; // 'foo', source code. 'a'...'f' in-place.
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 6; uint32_t kFunctionCount = 6;
...@@ -745,9 +727,8 @@ TEST(FunctionKinds) { ...@@ -745,9 +727,8 @@ TEST(FunctionKinds) {
FunctionKind::kAsyncGeneratorFunction); FunctionKind::kAsyncGeneratorFunction);
}; };
TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount, TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kSymbolCount, kMapCount, kContextCount,
kContextCount, kFunctionCount, kObjectCount, kFunctionCount, kObjectCount, kArrayCount);
kArrayCount);
} }
// Test that concatenating JS code to the snapshot works. // Test that concatenating JS code to the snapshot works.
...@@ -899,15 +880,14 @@ TEST(InPlaceStringsInArrays) { ...@@ -899,15 +880,14 @@ TEST(InPlaceStringsInArrays) {
const char* expected_result = "onetwothree"; const char* expected_result = "onetwothree";
uint32_t kStringCount = 1; // 'foo'; Other strings are in-place. uint32_t kStringCount = 1; // 'foo'; Other strings are in-place.
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 0; uint32_t kMapCount = 0;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
uint32_t kObjectCount = 0; uint32_t kObjectCount = 0;
uint32_t kArrayCount = 1; uint32_t kArrayCount = 1;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount, TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount, kSymbolCount, kMapCount, kContextCount, kFunctionCount,
kFunctionCount, kObjectCount, kArrayCount); kObjectCount, kArrayCount);
} }
TEST(RepeatedInPlaceStringsInArrays) { TEST(RepeatedInPlaceStringsInArrays) {
...@@ -916,15 +896,14 @@ TEST(RepeatedInPlaceStringsInArrays) { ...@@ -916,15 +896,14 @@ TEST(RepeatedInPlaceStringsInArrays) {
const char* expected_result = "onetwoone"; const char* expected_result = "onetwoone";
uint32_t kStringCount = 2; // 'foo', 'one'; Other strings are in-place. uint32_t kStringCount = 2; // 'foo', 'one'; Other strings are in-place.
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 0; uint32_t kMapCount = 0;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
uint32_t kObjectCount = 0; uint32_t kObjectCount = 0;
uint32_t kArrayCount = 1; uint32_t kArrayCount = 1;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount, TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount, kSymbolCount, kMapCount, kContextCount, kFunctionCount,
kFunctionCount, kObjectCount, kArrayCount); kObjectCount, kArrayCount);
} }
TEST(InPlaceStringsInObjects) { TEST(InPlaceStringsInObjects) {
...@@ -934,15 +913,14 @@ TEST(InPlaceStringsInObjects) { ...@@ -934,15 +913,14 @@ TEST(InPlaceStringsInObjects) {
// 'foo'. Other strings are in-place. // 'foo'. Other strings are in-place.
uint32_t kStringCount = 1; uint32_t kStringCount = 1;
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
uint32_t kObjectCount = 1; uint32_t kObjectCount = 1;
uint32_t kArrayCount = 0; uint32_t kArrayCount = 0;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount, TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount, kSymbolCount, kMapCount, kContextCount, kFunctionCount,
kFunctionCount, kObjectCount, kArrayCount); kObjectCount, kArrayCount);
} }
TEST(RepeatedInPlaceStringsInObjects) { TEST(RepeatedInPlaceStringsInObjects) {
...@@ -952,52 +930,14 @@ TEST(RepeatedInPlaceStringsInObjects) { ...@@ -952,52 +930,14 @@ TEST(RepeatedInPlaceStringsInObjects) {
// 'foo', 'one'. Other strings are in-place. // 'foo', 'one'. Other strings are in-place.
uint32_t kStringCount = 2; uint32_t kStringCount = 2;
uint32_t kSymbolCount = 0; uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 0;
uint32_t kMapCount = 1; uint32_t kMapCount = 1;
uint32_t kContextCount = 0; uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0; uint32_t kFunctionCount = 0;
uint32_t kObjectCount = 1; uint32_t kObjectCount = 1;
uint32_t kArrayCount = 0; uint32_t kArrayCount = 0;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount, TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount, kSymbolCount, kMapCount, kContextCount, kFunctionCount,
kFunctionCount, kObjectCount, kArrayCount); kObjectCount, kArrayCount);
}
TEST(builtin_objects) {
const char* snapshot_source = "var foo = {a: Error.prototype};";
const char* test_source = "foo.a == Error.prototype ? \"pass\" : \"fail\"";
const char* expected_result = "pass";
// 'foo', 'Error.prototype'. Other strings are in-place.
uint32_t kStringCount = 2;
uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 1;
uint32_t kMapCount = 1;
uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0;
uint32_t kObjectCount = 1;
uint32_t kArrayCount = 0;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount,
kFunctionCount, kObjectCount, kArrayCount);
}
TEST(builtin_objectsDeduplicated) {
const char* snapshot_source =
"var foo = {a: Error.prototype, b: Error.prototype}";
const char* test_source = "foo.a === Error.prototype ? \"pass\" : \"fail\"";
const char* expected_result = "pass";
// 'foo', 'Error.prototype'. Other strings are in-place.
uint32_t kStringCount = 2;
uint32_t kSymbolCount = 0;
uint32_t kBuiltinObjectCount = 1;
uint32_t kMapCount = 1;
uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0;
uint32_t kObjectCount = 1;
uint32_t kArrayCount = 0;
TestWebSnapshot(snapshot_source, test_source, expected_result, kStringCount,
kSymbolCount, kBuiltinObjectCount, kMapCount, kContextCount,
kFunctionCount, kObjectCount, kArrayCount);
} }
} // namespace internal } // namespace internal
......
// 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 TestBuiltin() {
function createObjects() {
globalThis.obj1 = {'a': Error};
globalThis.obj2 = {'b': Error.prototype};
}
const realm = Realm.create();
const {obj1, obj2} = takeAndUseWebSnapshot(
createObjects, ['obj1', 'obj2'], realm);
assertTrue(obj1.a === Realm.eval(realm, "Error"));
assertTrue(obj2.b === Realm.eval(realm, "Error.prototype"));
})();
...@@ -8,14 +8,13 @@ function use(exports) { ...@@ -8,14 +8,13 @@ function use(exports) {
return result; return result;
} }
function takeAndUseWebSnapshot(createObjects, exports, realmForDeserializing) { function takeAndUseWebSnapshot(createObjects, exports) {
// Take a snapshot in Realm r1. // Take a snapshot in Realm r1.
const r1 = Realm.create(); const r1 = Realm.create();
Realm.eval(r1, createObjects, { type: 'function' }); Realm.eval(r1, createObjects, { type: 'function' });
const snapshot = Realm.takeWebSnapshot(r1, exports); const snapshot = Realm.takeWebSnapshot(r1, exports);
// Use the snapshot in Realm r2. // Use the snapshot in Realm r2.
const r2 = realmForDeserializing != undefined ? const r2 = Realm.create();
realmForDeserializing : Realm.create();
const success = Realm.useWebSnapshot(r2, snapshot); const success = Realm.useWebSnapshot(r2, snapshot);
assertTrue(success); assertTrue(success);
const result = const result =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment