[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);
|
||||
}
|
||||
|
||||
// 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
|
||||
// referring to each other are reversed by Get<item>Id functions().
|
||||
for (int i = contexts_->Length() - 1; i >= 0; --i) {
|
||||
for (int i = 0; i < contexts_->Length(); ++i) {
|
||||
Handle<Context> context =
|
||||
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) {
|
||||
Handle<JSFunction> function =
|
||||
handle(JSFunction::cast(functions_->Get(i)), isolate_);
|
||||
@ -942,6 +943,13 @@ void WebSnapshotSerializer::DiscoverContextAndPrototype(
|
||||
}
|
||||
|
||||
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;
|
||||
if (InsertIntoIndexMap(context_ids_, *context, id)) return;
|
||||
|
||||
@ -1235,11 +1243,14 @@ void WebSnapshotSerializer::SerializeClass(Handle<JSFunction> function) {
|
||||
// - String id (name)
|
||||
// - For each variable:
|
||||
// - Serialized value
|
||||
void WebSnapshotSerializer::SerializeContext(Handle<Context> context) {
|
||||
void WebSnapshotSerializer::SerializeContext(Handle<Context> context,
|
||||
uint32_t id) {
|
||||
uint32_t parent_context_id = 0;
|
||||
if (!context->previous().IsNativeContext() &&
|
||||
!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.
|
||||
@ -1662,7 +1673,7 @@ uint32_t WebSnapshotSerializer::GetContextId(Context context) {
|
||||
bool return_value = context_ids_.Lookup(context, &id);
|
||||
DCHECK(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) {
|
||||
|
@ -234,7 +234,7 @@ class V8_EXPORT WebSnapshotSerializer
|
||||
void SerializeObjectPropertiesWithDictionaryMap(T dict);
|
||||
void SerializeFunction(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 SerializeObject(Handle<JSObject> object);
|
||||
|
||||
|
@ -123,3 +123,23 @@ d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
||||
assertSame(newAsyncGeneratorFunction.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