Don't attempt to create source positions for unfinalized scripts

For streaming compilation, scripts don't have a source string attached
until finalization, but the Script and SharedFunctionInfo objects are
already on the heap and may be picked up by heap walks.

This happens e.g. in CollectSourcePositionsForAllBytecodeArrays, where
we then try to reparse and recompile the SFI. This is invalid, since
the source string is not yet set.

Avoid this by checking for the empty source string (and leaving a TODO
for a nicer future solution).

Bug: v8:12051
Change-Id: Ib4f40cd218151120e5aff8558dd5df5c8834412e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3071403
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76104}
This commit is contained in:
Jakob Gruber 2021-08-05 07:14:02 +02:00 committed by V8 LUCI CQ
parent d589411f72
commit 4371d88d9d
3 changed files with 18 additions and 0 deletions

View File

@ -1711,6 +1711,13 @@ bool Compiler::CollectSourcePositions(Isolate* isolate,
return false;
}
// Unfinalized scripts don't yet have the proper source string attached and
// thus can't be reparsed.
if (Script::cast(shared_info->script()).IsMaybeUnfinalized(isolate)) {
bytecode->SetSourcePositionsFailedToCollect();
return false;
}
DCHECK(AllowCompilation::IsAllowed(isolate));
DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
DCHECK(!isolate->has_pending_exception());

View File

@ -179,6 +179,12 @@ bool Script::HasSourceURLComment() const {
return source_url().IsString() && String::cast(source_url()).length() != 0;
}
bool Script::IsMaybeUnfinalized(Isolate* isolate) const {
// TODO(v8:12051): A more robust detection, e.g. with a dedicated sentinel
// value.
return source().IsUndefined(isolate) || String::cast(source()).length() == 0;
}
} // namespace internal
} // namespace v8

View File

@ -145,6 +145,11 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
// If the script has a non-empty sourceURL comment.
inline bool HasSourceURLComment() const;
// Streaming compilation only attaches the source to the Script upon
// finalization. This predicate returns true, if this script may still be
// unfinalized.
inline bool IsMaybeUnfinalized(Isolate* isolate) const;
Object GetNameOrSourceURL();
// Retrieve source position from where eval was called.