[web snap] Fix context tree serialization
Enforce the parent context has a smaller id, this time more forcefully. Bug: v8:11525,v8:12820 Change-Id: I05bf675545b81b818eebfcaa40ee6bb93f5bcf9e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3652792 Commit-Queue: Marja Hölttä <marja@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/main@{#80666}
This commit is contained in:
parent
67aff19c27
commit
0d57c9a863
@ -412,14 +412,15 @@ void WebSnapshotSerializer::SerializePendingItems() {
|
|||||||
SerializeBuiltinObject(name_id);
|
SerializeBuiltinObject(name_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize the items in the reverse order. The items at the end of the
|
for (int i = 0; i < contexts_->Length(); ++i) {
|
||||||
// contexts_ etc get lower IDs and vice versa. IDs which items use for
|
|
||||||
// referring to each other are reversed by Get<item>Id functions().
|
|
||||||
for (int i = contexts_->Length() - 1; i >= 0; --i) {
|
|
||||||
Handle<Context> context =
|
Handle<Context> context =
|
||||||
handle(Context::cast(contexts_->Get(i)), isolate_);
|
handle(Context::cast(contexts_->Get(i)), isolate_);
|
||||||
SerializeContext(context);
|
SerializeContext(context, static_cast<uint32_t>(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Serialize the items in the reverse order. The items at the end of the
|
||||||
|
// functions_ etc get lower IDs and vice versa. IDs which items use for
|
||||||
|
// referring to each other are reversed by Get<item>Id() functions.
|
||||||
for (int i = functions_->Length() - 1; i >= 0; --i) {
|
for (int i = functions_->Length() - 1; i >= 0; --i) {
|
||||||
Handle<JSFunction> function =
|
Handle<JSFunction> function =
|
||||||
handle(JSFunction::cast(functions_->Get(i)), isolate_);
|
handle(JSFunction::cast(functions_->Get(i)), isolate_);
|
||||||
@ -942,6 +943,13 @@ void WebSnapshotSerializer::DiscoverContextAndPrototype(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WebSnapshotSerializer::DiscoverContext(Handle<Context> context) {
|
void WebSnapshotSerializer::DiscoverContext(Handle<Context> context) {
|
||||||
|
// Make sure the parent context (if any), gets a smaller ID. This ensures the
|
||||||
|
// parent context references in the snapshot are not deferred.
|
||||||
|
if (!context->previous().IsNativeContext() &&
|
||||||
|
!context->previous().IsScriptContext()) {
|
||||||
|
DiscoverContext(handle(context->previous(), isolate_));
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
if (InsertIntoIndexMap(context_ids_, *context, id)) return;
|
if (InsertIntoIndexMap(context_ids_, *context, id)) return;
|
||||||
|
|
||||||
@ -1235,11 +1243,14 @@ void WebSnapshotSerializer::SerializeClass(Handle<JSFunction> function) {
|
|||||||
// - String id (name)
|
// - String id (name)
|
||||||
// - For each variable:
|
// - For each variable:
|
||||||
// - Serialized value
|
// - Serialized value
|
||||||
void WebSnapshotSerializer::SerializeContext(Handle<Context> context) {
|
void WebSnapshotSerializer::SerializeContext(Handle<Context> context,
|
||||||
|
uint32_t id) {
|
||||||
uint32_t parent_context_id = 0;
|
uint32_t parent_context_id = 0;
|
||||||
if (!context->previous().IsNativeContext() &&
|
if (!context->previous().IsNativeContext() &&
|
||||||
!context->previous().IsScriptContext()) {
|
!context->previous().IsScriptContext()) {
|
||||||
parent_context_id = GetContextId(context->previous()) + 1;
|
parent_context_id = GetContextId(context->previous());
|
||||||
|
DCHECK_LT(parent_context_id, id);
|
||||||
|
++parent_context_id; // 0 is reserved for "no parent context".
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(v8:11525): Use less space for encoding the context type.
|
// TODO(v8:11525): Use less space for encoding the context type.
|
||||||
@ -1662,7 +1673,7 @@ uint32_t WebSnapshotSerializer::GetContextId(Context context) {
|
|||||||
bool return_value = context_ids_.Lookup(context, &id);
|
bool return_value = context_ids_.Lookup(context, &id);
|
||||||
DCHECK(return_value);
|
DCHECK(return_value);
|
||||||
USE(return_value);
|
USE(return_value);
|
||||||
return static_cast<uint32_t>(context_ids_.size() - 1 - id);
|
return static_cast<uint32_t>(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t WebSnapshotSerializer::GetArrayId(JSArray array) {
|
uint32_t WebSnapshotSerializer::GetArrayId(JSArray array) {
|
||||||
|
@ -234,7 +234,7 @@ class V8_EXPORT WebSnapshotSerializer
|
|||||||
void SerializeObjectPropertiesWithDictionaryMap(T dict);
|
void SerializeObjectPropertiesWithDictionaryMap(T dict);
|
||||||
void SerializeFunction(Handle<JSFunction> function);
|
void SerializeFunction(Handle<JSFunction> function);
|
||||||
void SerializeClass(Handle<JSFunction> function);
|
void SerializeClass(Handle<JSFunction> function);
|
||||||
void SerializeContext(Handle<Context> context);
|
void SerializeContext(Handle<Context> context, uint32_t id);
|
||||||
void SerializeArray(Handle<JSArray> array);
|
void SerializeArray(Handle<JSArray> array);
|
||||||
void SerializeObject(Handle<JSObject> object);
|
void SerializeObject(Handle<JSObject> object);
|
||||||
|
|
||||||
|
@ -123,3 +123,23 @@ d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|||||||
assertSame(newAsyncGeneratorFunction.prototype.__proto__,
|
assertSame(newAsyncGeneratorFunction.prototype.__proto__,
|
||||||
asyncGeneratorFunction.prototype.__proto__);
|
asyncGeneratorFunction.prototype.__proto__);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
(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());
|
||||||
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user