Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.15',
'v8_embedder_string': '-node.16',

##### V8 defaults for Node.js #####

Expand Down
11 changes: 10 additions & 1 deletion deps/v8/src/codegen/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2022,6 +2022,9 @@ void BackgroundCompileTask::Run(
parser.ParseOnBackground(isolate, &info, script_, start_position_,
end_position_, function_literal_id_);
parser.UpdateStatistics(script_, &use_counts_, &total_preparse_skipped_);
if (toplevel_script_compilation) {
debug_magic_comment_locations_ = parser.debug_magic_comment_locations();
}

TRACE_EVENT(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompileCodeBackground");
Expand Down Expand Up @@ -2766,8 +2769,14 @@ MaybeHandle<SharedFunctionInfo> BackgroundCompileTask::FinalizeScript(
{
DisallowGarbageCollection no_gc;
SetScriptFieldsFromDetails(isolate, *script, script_details, &no_gc);
LOG(isolate, ScriptDetails(*script));
}
// After SetScriptFieldsFromDetails, so that a source map URL provided
// through the API takes precedence. The locations come from the streamed
// source; the embedder is expected to pass the same source here, but an
// out-of-bounds location is ignored.
Parser::SetDebugMagicCommentFields(isolate, script, source,
debug_magic_comment_locations_);
LOG(isolate, ScriptDetails(*script));
}

ReportStatistics(isolate);
Expand Down
4 changes: 4 additions & 0 deletions deps/v8/src/codegen/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "src/objects/debug-objects.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/pending-compilation-error-handler.h"
#include "src/parsing/scanner.h" // For Scanner::DebugMagicCommentLocations.
#include "src/snapshot/code-serializer.h"
#include "src/utils/allocation.h"
#include "src/zone/zone.h"
Expand Down Expand Up @@ -649,6 +650,9 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
DeferredFinalizationJobDataList jobs_to_retry_finalization_on_main_thread_;
base::SmallVector<v8::Isolate::UseCounterFeature, 8> use_counts_;
int total_preparse_skipped_ = 0;
// The source is not available on the background thread, so the debug magic
// comment values are created from these locations when finalizing.
Scanner::DebugMagicCommentLocations debug_magic_comment_locations_;

// Single function data for top-level function compilation.
MaybeIndirectHandle<SharedFunctionInfo> input_shared_info_;
Expand Down
18 changes: 0 additions & 18 deletions deps/v8/src/parsing/literal-buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,11 @@
#include "src/parsing/literal-buffer.h"

#include "src/base/strings.h"
#include "src/execution/isolate.h"
#include "src/execution/local-isolate.h"
#include "src/heap/factory.h"
#include "src/objects/objects.h"
#include "src/objects/string.h"
#include "src/utils/memcopy.h"

namespace v8 {
namespace internal {

template <typename IsolateT>
DirectHandle<String> LiteralBuffer::Internalize(IsolateT* isolate) const {
if (is_one_byte()) {
return isolate->factory()->InternalizeString(one_byte_literal());
}
return isolate->factory()->InternalizeString(two_byte_literal());
}

template DirectHandle<String> LiteralBuffer::Internalize(
Isolate* isolate) const;
template DirectHandle<String> LiteralBuffer::Internalize(
LocalIsolate* isolate) const;

size_t LiteralBuffer::NewCapacity(size_t min_capacity) {
return min_capacity < (kMaxGrowth / (kGrowthFactor - 1))
? min_capacity * kGrowthFactor
Expand Down
3 changes: 0 additions & 3 deletions deps/v8/src/parsing/literal-buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ class LiteralBuffer final {
is_one_byte_ = true;
}

template <typename IsolateT>
DirectHandle<String> Internalize(IsolateT* isolate) const;

private:
static constexpr size_t kInitialCapacity = 256;
static constexpr size_t kGrowthFactor = 4;
Expand Down
47 changes: 30 additions & 17 deletions deps/v8/src/parsing/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "src/common/message-template.h"
#include "src/common/scoped-modification.h"
#include "src/compiler-dispatcher/lazy-compile-dispatcher.h"
#include "src/heap/factory-inl.h"
#include "src/heap/local-heap-inl.h"
#include "src/heap/parked-scope.h"
#include "src/logging/counters.h"
Expand Down Expand Up @@ -3565,32 +3566,47 @@ void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
// ----------------------------------------------------------------------------
// Parser support

template <typename IsolateT>
void Parser::HandleDebugMagicComments(IsolateT* isolate,
void Parser::HandleDebugMagicComments(Isolate* isolate,
DirectHandle<Script> script) {
DirectHandle<String> source_url = scanner_.SourceUrl(isolate);
// On the main thread, the scanned source is the script source.
DirectHandle<String> source(Cast<String>(script->source()), isolate);
SetDebugMagicCommentFields(isolate, script, source,
scanner_.debug_magic_comment_locations());
}

// static
void Parser::SetDebugMagicCommentFields(
Isolate* isolate, DirectHandle<Script> script, DirectHandle<String> source,
const Scanner::DebugMagicCommentLocations& locations) {
// The values can be arbitrarily large (e.g. inline source maps), so they are
// substrings of the source rather than copies.
auto value = [&](Scanner::Location location) -> DirectHandle<String> {
if (!location.IsValid() || location.length() == 0 ||
static_cast<uint32_t>(location.end_pos) > source->length()) {
return {};
}
return isolate->factory()->NewSubString(source, location.beg_pos,
location.end_pos);
};
DirectHandle<String> source_url = value(locations.source_url);
if (!source_url.is_null()) {
script->set_source_url(*source_url);
}
DirectHandle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
// The API can provide a source map URL and the API should take precedence.
// Let's make sure we do not override the API with the magic comment.
if (!source_mapping_url.is_null() &&
IsUndefined(script->source_mapping_url())) {
script->set_source_mapping_url(*source_mapping_url);
if (IsUndefined(script->source_mapping_url())) {
DirectHandle<String> source_mapping_url =
value(locations.source_mapping_url);
if (!source_mapping_url.is_null()) {
script->set_source_mapping_url(*source_mapping_url);
}
}

DirectHandle<String> debug_id = scanner_.DebugId(isolate);
DirectHandle<String> debug_id = value(locations.debug_id);
if (!debug_id.is_null()) {
script->set_debug_id(*debug_id);
}
}

template void Parser::HandleDebugMagicComments(Isolate* isolate,
DirectHandle<Script> script);
template void Parser::HandleDebugMagicComments(LocalIsolate* isolate,
DirectHandle<Script> script);

void Parser::UpdateStatistics(Isolate* isolate, DirectHandle<Script> script) {
CHECK_NOT_NULL(isolate);

Expand Down Expand Up @@ -3693,9 +3709,6 @@ void Parser::ParseOnBackground(LocalIsolate* isolate, ParseInfo* info,
MaybeProcessSourceRanges(info, result, stack_limit_);
});
// We need to unpark by now though, to be able to internalize.
if (flags().is_toplevel()) {
HandleDebugMagicComments(isolate, script);
}
if (result == nullptr) return;
PostProcessParseResult(isolate, info, result);
}
Expand Down
14 changes: 12 additions & 2 deletions deps/v8/src/parsing/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,18 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
DirectHandle<Script> script,
base::SmallVector<v8::Isolate::UseCounterFeature, 8>* use_counters,
int* preparse_skipped);
template <typename IsolateT>
void HandleDebugMagicComments(IsolateT* isolate, DirectHandle<Script> script);
void HandleDebugMagicComments(Isolate* isolate, DirectHandle<Script> script);
const Scanner::DebugMagicCommentLocations& debug_magic_comment_locations()
const {
return scanner_.debug_magic_comment_locations();
}
// Sets the debug magic comment fields of {script} to substrings of {source}
// at the given locations. Locations that are empty, invalid or out of bounds
// are ignored.
static void SetDebugMagicCommentFields(
Isolate* isolate, DirectHandle<Script> script,
DirectHandle<String> source,
const Scanner::DebugMagicCommentLocations& locations);

private:
friend class ParserBase<Parser>;
Expand Down
63 changes: 16 additions & 47 deletions deps/v8/src/parsing/scanner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,15 @@ void Scanner::TryToParseMagicComment(base::uc32 hash_or_at_sign) {
}
if (!name.is_one_byte()) return;
base::Vector<const uint8_t> name_literal = name.one_byte_literal();
LiteralBuffer* value;
// The debug magic comment values are recorded as source locations, so that
// they can be created as substrings of the source instead of being copied.
Location* value_location = nullptr;
bool is_compile_hints = false;
LiteralBuffer per_function_compile_hints_value;
if (name_literal == base::StaticOneByteVector("sourceURL")) {
value = &source_url_;
value_location = &debug_magic_comment_locations_.source_url;
} else if (name_literal == base::StaticOneByteVector("sourceMappingURL")) {
value = &source_mapping_url_;
value_location = &debug_magic_comment_locations_.source_mapping_url;
DCHECK(hash_or_at_sign == '#' || hash_or_at_sign == '@');
saw_source_mapping_url_magic_comment_at_sign_ = hash_or_at_sign == '@';
} else if (!saw_non_comment_ &&
Expand All @@ -309,38 +312,41 @@ void Scanner::TryToParseMagicComment(base::uc32 hash_or_at_sign) {
} else if (name_literal ==
base::StaticOneByteVector("functionsCalledOnLoad") &&
hash_or_at_sign == '#') {
value = &per_function_compile_hints_value;
is_compile_hints = true;
} else if (name_literal == base::StaticOneByteVector("debugId") &&
hash_or_at_sign == '#') {
value = &debug_id_;
value_location = &debug_magic_comment_locations_.debug_id;
} else {
return;
}
if (c0_ != '=') {
return;
}
value->Start();
if (is_compile_hints) per_function_compile_hints_value.Start();
Advance();
while (IsWhiteSpace(c0_)) {
Advance();
}
int value_beg_pos = source_pos();
while (c0_ != kEndOfInput && !unibrow::IsLineTerminator(c0_)) {
if (IsWhiteSpace(c0_)) {
break;
}
value->AddChar(c0_);
if (is_compile_hints) per_function_compile_hints_value.AddChar(c0_);
Advance();
}
Location value_location_in_source(value_beg_pos, source_pos());
// Allow whitespace at the end.
while (c0_ != kEndOfInput && !unibrow::IsLineTerminator(c0_)) {
if (!IsWhiteSpace(c0_)) {
value->Start();
if (is_compile_hints) per_function_compile_hints_value.Start();
value_location_in_source = Location::invalid();
break;
}
Advance();
}
if (value == &per_function_compile_hints_value &&
per_function_compile_hints_value.is_one_byte()) {
if (value_location != nullptr) *value_location = value_location_in_source;
if (is_compile_hints && per_function_compile_hints_value.is_one_byte()) {
base::Vector<const uint8_t> value_literal =
per_function_compile_hints_value.one_byte_literal();
per_function_compile_hint_positions_.clear();
Expand Down Expand Up @@ -689,43 +695,6 @@ Token::Value Scanner::ScanTemplateSpan() {
return result;
}

template <typename IsolateT>
DirectHandle<String> Scanner::SourceUrl(IsolateT* isolate) const {
DirectHandle<String> tmp;
if (source_url_.length() > 0) {
tmp = source_url_.Internalize(isolate);
}
return tmp;
}

template DirectHandle<String> Scanner::SourceUrl(Isolate* isolate) const;
template DirectHandle<String> Scanner::SourceUrl(LocalIsolate* isolate) const;

template <typename IsolateT>
DirectHandle<String> Scanner::SourceMappingUrl(IsolateT* isolate) const {
DirectHandle<String> tmp;
if (source_mapping_url_.length() > 0) {
tmp = source_mapping_url_.Internalize(isolate);
}
return tmp;
}

template DirectHandle<String> Scanner::SourceMappingUrl(Isolate* isolate) const;
template DirectHandle<String> Scanner::SourceMappingUrl(
LocalIsolate* isolate) const;

template <typename IsolateT>
DirectHandle<String> Scanner::DebugId(IsolateT* isolate) const {
DirectHandle<String> tmp;
if (debug_id_.length() > 0) {
tmp = debug_id_.Internalize(isolate);
}
return tmp;
}

template DirectHandle<String> Scanner::DebugId(Isolate* isolate) const;
template DirectHandle<String> Scanner::DebugId(LocalIsolate* isolate) const;

bool Scanner::ScanDigitsWithNumericSeparators(bool (*predicate)(base::uc32 ch),
bool is_check_first_digit) {
// we must have at least one digit after 'x'/'b'/'o'
Expand Down
23 changes: 13 additions & 10 deletions deps/v8/src/parsing/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,18 @@ class V8_EXPORT_PRIVATE Scanner {
return ScanTemplateSpan();
}

template <typename IsolateT>
DirectHandle<String> SourceUrl(IsolateT* isolate) const;
template <typename IsolateT>
DirectHandle<String> SourceMappingUrl(IsolateT* isolate) const;
template <typename IsolateT>
DirectHandle<String> DebugId(IsolateT* isolate) const;
// Source locations of the values of the debug magic comments. A location is
// invalid if there was no such comment, or if the last one was malformed; it
// is empty if the last one had an empty value. In both cases there is no
// value.
struct DebugMagicCommentLocations {
Location source_url = Location::invalid();
Location source_mapping_url = Location::invalid();
Location debug_id = Location::invalid();
};
const DebugMagicCommentLocations& debug_magic_comment_locations() const {
return debug_magic_comment_locations_;
}

bool SawSourceMappingUrlMagicCommentAtSign() const {
return saw_source_mapping_url_magic_comment_at_sign_;
Expand Down Expand Up @@ -802,10 +808,7 @@ class V8_EXPORT_PRIVATE Scanner {
// Whether this scanner encountered an HTML comment.
bool found_html_comment_;

// Values parsed from magic comments.
LiteralBuffer source_url_;
LiteralBuffer source_mapping_url_;
LiteralBuffer debug_id_;
DebugMagicCommentLocations debug_magic_comment_locations_;
bool saw_source_mapping_url_magic_comment_at_sign_ = false;
bool saw_magic_comment_compile_hints_all_ = false;
bool saw_non_comment_ = false;
Expand Down
6 changes: 6 additions & 0 deletions deps/v8/src/snapshot/code-serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ class CodeSerializer : public Serializer {

private:
void SerializeObjectImpl(Handle<HeapObject> o, SlotType slot_type) override;
// Slices usually refer to the script source (e.g. debug magic comment
// values), which is an attached object: off-thread deserialization attaches
// a placeholder instead of the source.
bool SerializeSlicedStringsAsSequentialStrings() const override {
return true;
}

DISALLOW_GARBAGE_COLLECTION(no_gc_)
uint32_t source_hash_;
Expand Down
Loading
Loading