Commit e8fd58ee authored by Marja Hölttä's avatar Marja Hölttä Committed by V8 LUCI CQ

[web snap] Support functions from multiple scripts

Bug: v8:11525
Change-Id: I6db629c1ecd082162433787a0f5864acd201a91d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3647840Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80598}
parent 87b4acd3
......@@ -662,9 +662,14 @@ void WebSnapshotSerializer::SerializeFunctionInfo(ValueSerializer* serializer,
}
serializer->WriteUint32(source_id_);
Handle<Script> script =
handle(Script::cast(function->shared().script()), isolate_);
int start = function->shared().StartPosition();
int end = function->shared().EndPosition();
serializer->WriteUint32(source_offset_to_compacted_source_offset_[start]);
int final_offset =
source_offset_to_compacted_source_offset_[script_offsets_[script->id()] +
start];
serializer->WriteUint32(final_offset);
serializer->WriteUint32(end - start);
serializer->WriteUint32(
......@@ -915,16 +920,42 @@ void WebSnapshotSerializer::DiscoverSource(Handle<JSFunction> function) {
Throw("Function without source code");
return;
}
source_intervals_.emplace(function->shared().StartPosition(),
function->shared().EndPosition());
// There might be multiple scripts where functions are coming from. Construct
// a combined source code for them by simply concatenating the sources (and
// keep track which script source is where); the source code will be later
// optimized by ConstructSource.
Handle<Script> script =
handle(Script::cast(function->shared().script()), isolate_);
Handle<String> function_script_source =
handle(String::cast(Script::cast(function->shared().script()).source()),
isolate_);
handle(String::cast(script->source()), isolate_);
int script_offset_int;
if (full_source_.is_null()) {
// This is the first script.
script_offset_int = 0;
full_source_ = function_script_source;
} else if (!full_source_->Equals(*function_script_source)) {
Throw("Cannot include functions from multiple scripts");
script_offsets_.insert({script->id(), script_offset_int});
} else {
auto it = script_offsets_.find(script->id());
if (it == script_offsets_.end()) {
// This script hasn't been encountered yet and its source code has to be
// added to full_source_.
DCHECK(!full_source_.is_null());
script_offset_int = full_source_->length();
script_offsets_.insert({script->id(), script_offset_int});
if (!factory()
->NewConsString(full_source_, function_script_source)
.ToHandle(&full_source_)) {
Throw("Can't construct source");
return;
}
} else {
// The script source is already somewhere in full_source_.
script_offset_int = it->second;
}
}
source_intervals_.emplace(
script_offset_int + function->shared().StartPosition(),
script_offset_int + function->shared().EndPosition());
}
void WebSnapshotSerializer::DiscoverArray(Handle<JSArray> array) {
......
......@@ -323,6 +323,9 @@ class V8_EXPORT WebSnapshotSerializer
// 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.
......@@ -330,6 +333,7 @@ class V8_EXPORT WebSnapshotSerializer
// 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
......
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