[offthread] Add off-thread support to Script

Adds support for off-thread allocation to Script allocation and
line-end calculation.

This includes adding support for keeping/merging a script list on
the OffThreadIsolate, and adding syntactical support for logging
(in the future this could do actual logging).

Bug: chromium:1011762
Change-Id: Id90f2ad7458e90e06f6926f1fce7ef7a1ef50b3d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2046884
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66213}
This commit is contained in:
Leszek Swirski 2020-02-10 15:21:24 +01:00 committed by Commit Bot
parent 3645656b05
commit 5a5976fc51
28 changed files with 267 additions and 90 deletions

View File

@ -2235,6 +2235,7 @@ v8_source_set("v8_base_without_compiler") {
"src/execution/messages.h",
"src/execution/microtask-queue.cc",
"src/execution/microtask-queue.h",
"src/execution/off-thread-isolate.cc",
"src/execution/off-thread-isolate.h",
"src/execution/protectors-inl.h",
"src/execution/protectors.cc",
@ -2449,6 +2450,7 @@ v8_source_set("v8_base_without_compiler") {
"src/logging/log-utils.h",
"src/logging/log.cc",
"src/logging/log.h",
"src/logging/off-thread-logger.h",
"src/numbers/bignum-dtoa.cc",
"src/numbers/bignum-dtoa.h",
"src/numbers/bignum.cc",

View File

@ -9439,7 +9439,7 @@ std::vector<int> debug::Script::LineEnds() const {
i::Isolate* isolate = script->GetIsolate();
i::HandleScope scope(isolate);
i::Script::InitLineEnds(script);
i::Script::InitLineEnds(isolate, script);
CHECK(script->line_ends().IsFixedArray());
i::Handle<i::FixedArray> line_ends(i::FixedArray::cast(script->line_ends()),
isolate);
@ -9531,9 +9531,9 @@ bool debug::Script::GetPossibleBreakpoints(
locations);
}
i::Script::InitLineEnds(script);
CHECK(script->line_ends().IsFixedArray());
i::Isolate* isolate = script->GetIsolate();
i::Script::InitLineEnds(isolate, script);
CHECK(script->line_ends().IsFixedArray());
i::Handle<i::FixedArray> line_ends =
i::Handle<i::FixedArray>::cast(i::handle(script->line_ends(), isolate));
CHECK(line_ends->length());
@ -9586,7 +9586,7 @@ int debug::Script::GetSourceOffset(const debug::Location& location) const {
column = std::max(0, column - script->column_offset());
}
i::Script::InitLineEnds(script);
i::Script::InitLineEnds(script->GetIsolate(), script);
CHECK(script->line_ends().IsFixedArray());
i::Handle<i::FixedArray> line_ends = i::Handle<i::FixedArray>::cast(
i::handle(script->line_ends(), script->GetIsolate()));

View File

@ -2068,7 +2068,7 @@ void Debug::PrintBreakLocation() {
if (script_obj->IsScript()) {
Handle<Script> script = Handle<Script>::cast(script_obj);
Handle<String> source(String::cast(script->source()), isolate_);
Script::InitLineEnds(script);
Script::InitLineEnds(isolate_, script);
int line =
Script::GetLineNumber(script, source_position) - script->line_offset();
int column = Script::GetColumnNumber(script, source_position) -

View File

@ -2856,6 +2856,9 @@ Isolate::Isolate(std::unique_ptr<i::IsolateAllocator> isolate_allocator)
builtins_(this),
rail_mode_(PERFORMANCE_ANIMATION),
code_event_dispatcher_(new CodeEventDispatcher()),
#if V8_SFI_HAS_UNIQUE_ID
next_unique_sfi_id_(0),
#endif
cancelable_task_manager_(new CancelableTaskManager()) {
TRACE_ISOLATE(constructor);
CheckIsolateLayout();
@ -4247,6 +4250,8 @@ void Isolate::CountUsage(v8::Isolate::UseCounterFeature feature) {
}
}
int Isolate::GetNextScriptId() { return heap()->NextScriptId(); }
// static
std::string Isolate::GetTurboCfgFileName(Isolate* isolate) {
if (FLAG_trace_turbo_cfg_file == nullptr) {

View File

@ -1287,6 +1287,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
static std::string GetTurboCfgFileName(Isolate* isolate);
int GetNextScriptId();
#if V8_SFI_HAS_UNIQUE_ID
int GetNextUniqueSharedFunctionInfoId() { return next_unique_sfi_id_++; }
#endif

View File

@ -0,0 +1,32 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/execution/off-thread-isolate.h"
#include "src/execution/isolate.h"
#include "src/logging/off-thread-logger.h"
namespace v8 {
namespace internal {
OffThreadIsolate::OffThreadIsolate(Isolate* isolate)
: HiddenOffThreadFactory(isolate),
isolate_(isolate),
logger_(new OffThreadLogger()) {}
OffThreadIsolate::~OffThreadIsolate() { delete logger_; }
int OffThreadIsolate::GetNextScriptId() { return isolate_->GetNextScriptId(); }
bool OffThreadIsolate::NeedsSourcePositionsForProfiling() {
// TODO(leszeks): Figure out if it makes sense to check this asynchronously.
return isolate_->NeedsSourcePositionsForProfiling();
}
bool OffThreadIsolate::is_collecting_type_profile() {
// TODO(leszeks): Figure out if it makes sense to check this asynchronously.
return isolate_->is_collecting_type_profile();
}
} // namespace internal
} // namespace v8

View File

@ -13,8 +13,8 @@ namespace v8 {
namespace internal {
class Isolate;
class OffThreadIsolate;
class OffThreadLogger;
template <>
struct HandleTraits<OffThreadIsolate> {
@ -38,10 +38,11 @@ class V8_EXPORT_PRIVATE HiddenOffThreadFactory : private OffThreadFactory {
// This class holds an OffThreadFactory, but is otherwise effectively a stub
// implementation of an Isolate. In particular, it doesn't allow throwing
// exceptions, and hard crashes if you try.
class V8_EXPORT_PRIVATE OffThreadIsolate : private HiddenOffThreadFactory {
class V8_EXPORT_PRIVATE OffThreadIsolate final
: private HiddenOffThreadFactory {
public:
explicit OffThreadIsolate(Isolate* isolate)
: HiddenOffThreadFactory(isolate) {}
explicit OffThreadIsolate(Isolate* isolate);
~OffThreadIsolate();
v8::internal::OffThreadFactory* factory() {
// Upcast to the privately inherited base-class using c-style casts to avoid
@ -58,8 +59,20 @@ class V8_EXPORT_PRIVATE OffThreadIsolate : private HiddenOffThreadFactory {
[[noreturn]] void FatalProcessOutOfHeapMemory(const char* location) {
UNREACHABLE();
}
inline bool CanAllocateInReadOnlySpace() { return false; }
inline bool EmptyStringRootIsInitialized() { return true; }
int GetNextScriptId();
bool NeedsSourcePositionsForProfiling();
bool is_collecting_type_profile();
OffThreadLogger* logger() { return logger_; }
private:
// TODO(leszeks): Extract out the fields of the Isolate we want and store
// those instead of the whole thing.
Isolate* isolate_;
OffThreadLogger* logger_;
};
} // namespace internal

View File

@ -10,6 +10,8 @@
#include "src/heap/factory.h"
#include "src/heap/off-thread-factory-inl.h"
#include "src/heap/read-only-heap.h"
#include "src/logging/log.h"
#include "src/logging/off-thread-logger.h"
#include "src/objects/literal-objects-inl.h"
#include "src/objects/module-inl.h"
#include "src/objects/oddball.h"
@ -112,6 +114,40 @@ HandleFor<Impl, FixedArrayBase> FactoryBase<Impl>::NewFixedDoubleArray(
return array;
}
template <typename Impl>
HandleFor<Impl, Script> FactoryBase<Impl>::NewScript(
HandleFor<Impl, String> source) {
return NewScriptWithId(source, isolate()->GetNextScriptId());
}
template <typename Impl>
HandleFor<Impl, Script> FactoryBase<Impl>::NewScriptWithId(
HandleFor<Impl, String> source, int script_id) {
// Create and initialize script object.
ReadOnlyRoots roots = read_only_roots();
HandleFor<Impl, Script> script = HandleFor<Impl, Script>::cast(
NewStruct(SCRIPT_TYPE, AllocationType::kOld));
script->set_source(*source);
script->set_name(roots.undefined_value());
script->set_id(script_id);
script->set_line_offset(0);
script->set_column_offset(0);
script->set_context_data(roots.undefined_value());
script->set_type(Script::TYPE_NORMAL);
script->set_line_ends(roots.undefined_value());
script->set_eval_from_shared_or_wrapped_arguments(roots.undefined_value());
script->set_eval_from_position(0);
script->set_shared_function_infos(roots.empty_weak_fixed_array(),
SKIP_WRITE_BARRIER);
script->set_flags(0);
script->set_host_defined_options(roots.empty_fixed_array());
impl()->AddToScriptList(script);
LOG(isolate(), ScriptEvent(Logger::ScriptEventType::kCreate, script_id));
return script;
}
template <typename Impl>
HandleFor<Impl, ObjectBoilerplateDescription>
FactoryBase<Impl>::NewObjectBoilerplateDescription(int boilerplate,

View File

@ -88,6 +88,10 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase {
HandleFor<Impl, FixedArray> raw_strings,
HandleFor<Impl, FixedArray> cooked_strings);
HandleFor<Impl, Script> NewScript(HandleFor<Impl, String> source);
HandleFor<Impl, Script> NewScriptWithId(HandleFor<Impl, String> source,
int script_id);
HandleFor<Impl, SeqOneByteString> NewOneByteInternalizedString(
const Vector<const uint8_t>& str, uint32_t hash_field);
HandleFor<Impl, SeqTwoByteString> NewTwoByteInternalizedString(

View File

@ -1284,41 +1284,16 @@ Handle<AccessorInfo> Factory::NewAccessorInfo() {
return info;
}
Handle<Script> Factory::NewScript(Handle<String> source) {
return NewScriptWithId(source, isolate()->heap()->NextScriptId());
}
Handle<Script> Factory::NewScriptWithId(Handle<String> source, int script_id) {
// Create and initialize script object.
Heap* heap = isolate()->heap();
ReadOnlyRoots roots(heap);
Handle<Script> script =
Handle<Script>::cast(NewStruct(SCRIPT_TYPE, AllocationType::kOld));
script->set_source(*source);
script->set_name(roots.undefined_value());
script->set_id(script_id);
script->set_line_offset(0);
script->set_column_offset(0);
script->set_context_data(roots.undefined_value());
script->set_type(Script::TYPE_NORMAL);
script->set_line_ends(roots.undefined_value());
script->set_eval_from_shared_or_wrapped_arguments(roots.undefined_value());
script->set_eval_from_position(0);
script->set_shared_function_infos(*empty_weak_fixed_array(),
SKIP_WRITE_BARRIER);
script->set_flags(0);
script->set_host_defined_options(*empty_fixed_array());
void Factory::AddToScriptList(Handle<Script> script) {
Handle<WeakArrayList> scripts = script_list();
scripts = WeakArrayList::Append(isolate(), scripts,
MaybeObjectHandle::Weak(script));
heap->set_script_list(*scripts);
LOG(isolate(), ScriptEvent(Logger::ScriptEventType::kCreate, script_id));
return script;
isolate()->heap()->set_script_list(*scripts);
}
Handle<Script> Factory::CloneScript(Handle<Script> script) {
Heap* heap = isolate()->heap();
int script_id = isolate()->heap()->NextScriptId();
int script_id = isolate()->GetNextScriptId();
Handle<Script> new_script =
Handle<Script>::cast(NewStruct(SCRIPT_TYPE, AllocationType::kOld));
new_script->set_source(script->source());

View File

@ -391,8 +391,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<AccessorInfo> NewAccessorInfo();
Handle<Script> NewScript(Handle<String> source);
Handle<Script> NewScriptWithId(Handle<String> source, int script_id);
Handle<Script> CloneScript(Handle<Script> script);
Handle<BreakPointInfo> NewBreakPointInfo(int source_position);
@ -947,6 +945,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<String> MakeOrFindTwoCharacterString(uint16_t c1, uint16_t c2);
void AddToScriptList(Handle<Script> shared);
// ------
HeapObject AllocateRawWithAllocationSite(

View File

@ -122,6 +122,11 @@ void OffThreadFactory::Publish(Isolate* isolate) {
string.set_map_no_write_barrier(map);
}
std::vector<Handle<Script>> script_handles;
for (Script script : script_list_) {
script_handles.push_back(handle(script, isolate));
}
// Then merge the spaces. At this point, we are allowed to point between (no
// longer) off-thread pages and main-thread heap pages, and objects in the
// previously off-thread page can move.
@ -160,6 +165,16 @@ void OffThreadFactory::Publish(Isolate* isolate) {
}
}
}
// Merge the recorded scripts into the isolate's script list.
// This for loop may seem expensive, but practically there's unlikely to be
// more than one script in the OffThreadFactory.
Handle<WeakArrayList> scripts = isolate->factory()->script_list();
for (Handle<Script> script_handle : script_handles) {
scripts = WeakArrayList::Append(isolate, scripts,
MaybeObjectHandle::Weak(script_handle));
}
isolate->heap()->SetRootScriptList(*scripts);
}
// Hacky method for creating a simple object with a slot pointing to a string.
@ -193,6 +208,10 @@ OffThreadHandle<String> OffThreadFactory::MakeOrFindTwoCharacterString(
return ret;
}
void OffThreadFactory::AddToScriptList(OffThreadHandle<Script> shared) {
script_list_.push_back(*shared);
}
HeapObject OffThreadFactory::AllocateRaw(int size, AllocationType allocation,
AllocationAlignment alignment) {
DCHECK(!is_finished);

View File

@ -93,12 +93,15 @@ class V8_EXPORT_PRIVATE OffThreadFactory
OffThreadHandle<String> MakeOrFindTwoCharacterString(uint16_t c1,
uint16_t c2);
void AddToScriptList(OffThreadHandle<Script> shared);
// ------
ReadOnlyRoots roots_;
OffThreadSpace space_;
OffThreadLargeObjectSpace lo_space_;
std::vector<RelativeSlot> string_slots_;
std::vector<Script> script_list_;
bool is_finished = false;
};

View File

@ -267,7 +267,7 @@ void JsonParser<Char>::ReportUnexpectedToken(JsonToken token) {
Handle<Script> script(factory->NewScript(original_source_));
if (isolate()->NeedsSourcePositionsForProfiling()) {
Script::InitLineEnds(script);
Script::InitLineEnds(isolate(), script);
}
// We should sent compile error event because we compile JSON object in
// separated source file.

View File

@ -70,15 +70,15 @@ class Profiler;
class Ticker;
#undef LOG
#define LOG(isolate, Call) \
do { \
v8::internal::Logger* logger = (isolate)->logger(); \
if (logger->is_logging()) logger->Call; \
#define LOG(isolate, Call) \
do { \
auto* logger = (isolate)->logger(); \
if (logger->is_logging()) logger->Call; \
} while (false)
#define LOG_CODE_EVENT(isolate, Call) \
do { \
v8::internal::Logger* logger = (isolate)->logger(); \
auto* logger = (isolate)->logger(); \
if (logger->is_listening_to_code_events()) logger->Call; \
} while (false)

View File

@ -0,0 +1,27 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_LOGGING_OFF_THREAD_LOGGER_H_
#define V8_LOGGING_OFF_THREAD_LOGGER_H_
#include "src/base/logging.h"
#include "src/logging/log.h"
namespace v8 {
namespace internal {
// TODO(leszeks): Possibly add support for logging from off-thread.
class OffThreadLogger {
public:
bool is_logging() const { return false; }
bool is_listening_to_code_events() const { return false; }
void ScriptEvent(Logger::ScriptEventType type, int script_id) {
UNREACHABLE();
}
};
} // namespace internal
} // namespace v8
#endif // V8_LOGGING_OFF_THREAD_LOGGER_H_

View File

@ -4701,8 +4701,9 @@ int Script::GetEvalPosition(Isolate* isolate, Handle<Script> script) {
return position;
}
void Script::InitLineEnds(Handle<Script> script) {
Isolate* isolate = script->GetIsolate();
template <typename Isolate>
// static
void Script::InitLineEnds(Isolate* isolate, HandleFor<Isolate, Script> script) {
if (!script->line_ends().IsUndefined(isolate)) return;
DCHECK(script->type() != Script::TYPE_WASM ||
script->source_mapping_url().IsString());
@ -4713,19 +4714,26 @@ void Script::InitLineEnds(Handle<Script> script) {
script->set_line_ends(ReadOnlyRoots(isolate).empty_fixed_array());
} else {
DCHECK(src_obj.IsString());
Handle<String> src(String::cast(src_obj), isolate);
Handle<FixedArray> array = String::CalculateLineEnds(isolate, src, true);
HandleFor<Isolate, String> src(String::cast(src_obj), isolate);
HandleFor<Isolate, FixedArray> array =
String::CalculateLineEnds(isolate, src, true);
script->set_line_ends(*array);
}
DCHECK(script->line_ends().IsFixedArray());
}
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void Script::InitLineEnds(
Isolate* isolate, Handle<Script> script);
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void Script::InitLineEnds(
OffThreadIsolate* isolate, OffThreadHandle<Script> script);
bool Script::GetPositionInfo(Handle<Script> script, int position,
PositionInfo* info, OffsetFlag offset_flag) {
// For wasm, we do not create an artificial line_ends array, but do the
// translation directly.
if (script->type() != Script::TYPE_WASM) InitLineEnds(script);
if (script->type() != Script::TYPE_WASM)
InitLineEnds(script->GetIsolate(), script);
return script->GetPositionInfo(position, info, offset_flag);
}

View File

@ -7,6 +7,7 @@
#include <memory>
#include "src/base/export-template.h"
#include "src/objects/fixed-array.h"
#include "src/objects/objects.h"
#include "src/objects/struct.h"
@ -154,7 +155,9 @@ class Script : public Struct {
bool ContainsAsmModule();
// Init line_ends array with source code positions of line ends.
V8_EXPORT_PRIVATE static void InitLineEnds(Handle<Script> script);
template <typename Isolate>
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
static void InitLineEnds(Isolate* isolate, HandleFor<Isolate, Script> script);
// Carries information about a source position.
struct PositionInfo {

View File

@ -397,6 +397,14 @@ Handle<String> String::Flatten(Isolate* isolate, Handle<String> string,
return string;
}
OffThreadHandle<String> String::Flatten(OffThreadIsolate* isolate,
OffThreadHandle<String> string,
AllocationType allocation) {
// We should never pass non-flat strings to String::Flatten when off-thread.
DCHECK(string->IsFlat());
return string;
}
uint16_t String::Get(int index) {
DCHECK(index >= 0 && index < length());

View File

@ -4,6 +4,7 @@
#include "src/objects/string.h"
#include "src/common/globals.h"
#include "src/handles/handles-inl.h"
#include "src/heap/heap-inl.h" // For LooksValid implementation.
#include "src/heap/read-only-heap.h"
@ -688,7 +689,7 @@ void String::WriteToFlat(String src, sinkchar* sink, int f, int t) {
}
template <typename SourceChar>
static void CalculateLineEndsImpl(Isolate* isolate, std::vector<int>* line_ends,
static void CalculateLineEndsImpl(std::vector<int>* line_ends,
Vector<const SourceChar> src,
bool include_ending_line) {
const int src_len = src.length();
@ -708,9 +709,10 @@ static void CalculateLineEndsImpl(Isolate* isolate, std::vector<int>* line_ends,
}
}
Handle<FixedArray> String::CalculateLineEnds(Isolate* isolate,
Handle<String> src,
bool include_ending_line) {
template <typename Isolate>
HandleFor<Isolate, FixedArray> String::CalculateLineEnds(
Isolate* isolate, HandleFor<Isolate, String> src,
bool include_ending_line) {
src = Flatten(isolate, src);
// Rough estimate of line count based on a roughly estimated average
// length of (unpacked) code.
@ -723,21 +725,29 @@ Handle<FixedArray> String::CalculateLineEnds(Isolate* isolate,
String::FlatContent content = src->GetFlatContent(no_allocation);
DCHECK(content.IsFlat());
if (content.IsOneByte()) {
CalculateLineEndsImpl(isolate, &line_ends, content.ToOneByteVector(),
CalculateLineEndsImpl(&line_ends, content.ToOneByteVector(),
include_ending_line);
} else {
CalculateLineEndsImpl(isolate, &line_ends, content.ToUC16Vector(),
CalculateLineEndsImpl(&line_ends, content.ToUC16Vector(),
include_ending_line);
}
}
int line_count = static_cast<int>(line_ends.size());
Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
HandleFor<Isolate, FixedArray> array =
isolate->factory()->NewFixedArray(line_count, AllocationType::kOld);
for (int i = 0; i < line_count; i++) {
array->set(i, Smi::FromInt(line_ends[i]));
}
return array;
}
template Handle<FixedArray> String::CalculateLineEnds(Isolate* isolate,
Handle<String> src,
bool include_ending_line);
template OffThreadHandle<FixedArray> String::CalculateLineEnds(
OffThreadIsolate* isolate, OffThreadHandle<String> src,
bool include_ending_line);
bool String::SlowEquals(String other) {
DisallowHeapAllocation no_gc;
// Fast check: negative check with lengths.

View File

@ -9,6 +9,7 @@
#include "src/base/bits.h"
#include "src/base/export-template.h"
#include "src/handles/handle-for.h"
#include "src/objects/instance-type.h"
#include "src/objects/name.h"
#include "src/objects/smi.h"
@ -203,6 +204,9 @@ class String : public TorqueGeneratedString<String, Name> {
static inline Handle<String> Flatten(
Isolate* isolate, Handle<String> string,
AllocationType allocation = AllocationType::kYoung);
static inline OffThreadHandle<String> Flatten(
OffThreadIsolate* isolate, OffThreadHandle<String> string,
AllocationType allocation = AllocationType::kYoung);
// Tries to return the content of a flat string as a structure holding either
// a flat vector of char or of uc16.
@ -454,9 +458,10 @@ class String : public TorqueGeneratedString<String, Name> {
static inline ConsString VisitFlat(Visitor* visitor, String string,
int offset = 0);
static Handle<FixedArray> CalculateLineEnds(Isolate* isolate,
Handle<String> string,
bool include_ending_line);
template <typename Isolate>
static HandleFor<Isolate, FixedArray> CalculateLineEnds(
Isolate* isolate, HandleFor<Isolate, String> string,
bool include_ending_line);
private:
friend class Name;

View File

@ -70,7 +70,7 @@ ParseInfo::ParseInfo(Isolate* isolate, AccountingAllocator* zone_allocator)
ParseInfo::ParseInfo(Isolate* isolate)
: ParseInfo(isolate, isolate->allocator()) {
script_id_ = isolate->heap()->NextScriptId();
script_id_ = isolate->GetNextScriptId();
LOG(isolate, ScriptEvent(Logger::ScriptEventType::kReserveId, script_id_));
}
@ -121,9 +121,8 @@ ParseInfo::ParseInfo(Isolate* isolate, SharedFunctionInfo shared)
ParseInfo::ParseInfo(Isolate* isolate, Script script)
: ParseInfo(isolate, isolate->allocator()) {
SetFlagsForToplevelCompileFromScript(isolate, script);
set_collect_type_profile(isolate->is_collecting_type_profile() &&
script.IsUserJavaScript());
SetFlagsForToplevelCompileFromScript(isolate, script,
isolate->is_collecting_type_profile());
}
// static
@ -165,19 +164,20 @@ ParseInfo::~ParseInfo() = default;
DeclarationScope* ParseInfo::scope() const { return literal()->scope(); }
Handle<Script> ParseInfo::CreateScript(Isolate* isolate, Handle<String> source,
ScriptOriginOptions origin_options,
REPLMode repl_mode,
NativesFlag natives) {
template <typename Isolate>
HandleFor<Isolate, Script> ParseInfo::CreateScript(
Isolate* isolate, HandleFor<Isolate, String> source,
ScriptOriginOptions origin_options, REPLMode repl_mode,
NativesFlag natives) {
// Create a script object describing the script to be compiled.
Handle<Script> script;
HandleFor<Isolate, Script> script;
if (script_id_ == -1) {
script = isolate->factory()->NewScript(source);
} else {
script = isolate->factory()->NewScriptWithId(source, script_id_);
}
if (isolate->NeedsSourcePositionsForProfiling()) {
Script::InitLineEnds(script);
Script::InitLineEnds(isolate, script);
}
switch (natives) {
case EXTENSION_CODE:
@ -192,10 +192,23 @@ Handle<Script> ParseInfo::CreateScript(Isolate* isolate, Handle<String> source,
script->set_origin_options(origin_options);
script->set_is_repl_mode(repl_mode == REPLMode::kYes);
SetFlagsForToplevelCompileFromScript(isolate, *script);
SetFlagsForToplevelCompileFromScript(isolate, *script,
isolate->is_collecting_type_profile());
return script;
}
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
Handle<Script> ParseInfo::CreateScript(Isolate* isolate,
Handle<String> source,
ScriptOriginOptions origin_options,
REPLMode repl_mode,
NativesFlag natives);
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
OffThreadHandle<Script> ParseInfo::CreateScript(
OffThreadIsolate* isolate, OffThreadHandle<String> source,
ScriptOriginOptions origin_options, REPLMode repl_mode,
NativesFlag natives);
AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
if (!ast_value_factory_.get()) {
ast_value_factory_.reset(
@ -217,20 +230,21 @@ void ParseInfo::set_character_stream(
character_stream_.swap(character_stream);
}
void ParseInfo::SetFlagsForToplevelCompileFromScript(Isolate* isolate,
Script script) {
template <typename Isolate>
void ParseInfo::SetFlagsForToplevelCompileFromScript(
Isolate* isolate, Script script, bool is_collecting_type_profile) {
SetFlagsFromScript(isolate, script);
set_allow_lazy_parsing();
set_toplevel();
set_collect_type_profile(isolate->is_collecting_type_profile() &&
set_collect_type_profile(is_collecting_type_profile &&
script.IsUserJavaScript());
set_repl_mode(script.is_repl_mode());
if (script.is_wrapped()) {
set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
}
}
template <typename Isolate>
void ParseInfo::SetFlagsFromScript(Isolate* isolate, Script script) {
DCHECK(script_id_ == -1 || script_id_ == script.id());
script_id_ = script.id();
@ -244,7 +258,13 @@ void ParseInfo::SetFlagsFromScript(Isolate* isolate, Script script) {
}
if (script.is_wrapped()) {
set_wrapped_arguments(handle(script.wrapped_arguments(), isolate));
// This should only ever happen on the main thread. Convert this templated
// handle into a real Handle via HandleOrOffThreadHandle to avoid having to
// use template specialization for this.
DCHECK((std::is_same<Isolate, v8::internal::Isolate>::value));
HandleOrOffThreadHandle<FixedArray> wrapped_arguments_handle =
handle(script.wrapped_arguments(), isolate);
set_wrapped_arguments(wrapped_arguments_handle);
}
}

View File

@ -10,6 +10,7 @@
#include <vector>
#include "include/v8.h"
#include "src/base/export-template.h"
#include "src/common/globals.h"
#include "src/handles/handles.h"
#include "src/objects/function-kind.h"
@ -54,10 +55,12 @@ class V8_EXPORT_PRIVATE ParseInfo {
~ParseInfo();
Handle<Script> CreateScript(Isolate* isolate, Handle<String> source,
ScriptOriginOptions origin_options,
REPLMode repl_mode = REPLMode::kNo,
NativesFlag natives = NOT_NATIVES_CODE);
template <typename Isolate>
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
HandleFor<Isolate, Script> CreateScript(
Isolate* isolate, HandleFor<Isolate, String> source,
ScriptOriginOptions origin_options, REPLMode repl_mode = REPLMode::kNo,
NativesFlag natives = NOT_NATIVES_CODE);
// Either returns the ast-value-factory associcated with this ParseInfo, or
// creates and returns a new factory if none exists.
@ -256,6 +259,7 @@ class V8_EXPORT_PRIVATE ParseInfo {
ParallelTasks* parallel_tasks() { return parallel_tasks_.get(); }
template <typename Isolate>
void SetFlagsFromScript(Isolate* isolate, Script script);
//--------------------------------------------------------------------------
@ -285,7 +289,9 @@ class V8_EXPORT_PRIVATE ParseInfo {
}
private:
void SetFlagsForToplevelCompileFromScript(Isolate* isolate, Script script);
template <typename Isolate>
void SetFlagsForToplevelCompileFromScript(Isolate* isolate, Script script,
bool is_collecting_type_profile);
// Set function info flags based on those in either FunctionLiteral or
// SharedFunctionInfo |function|

View File

@ -497,7 +497,7 @@ int ScriptLinePosition(Handle<Script> script, int line) {
return GetWasmFunctionOffset(script->wasm_native_module()->module(), line);
}
Script::InitLineEnds(script);
Script::InitLineEnds(script->GetIsolate(), script);
FixedArray line_ends_array = FixedArray::cast(script->line_ends());
const int line_count = line_ends_array.length();

View File

@ -323,7 +323,7 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
result->StartPosition(), result->EndPosition(), *name));
}
if (log_code_creation) {
Script::InitLineEnds(script);
Script::InitLineEnds(isolate, script);
SharedFunctionInfo::ScriptIterator iter(isolate, *script);
for (SharedFunctionInfo info = iter.Next(); !info.is_null();
@ -350,7 +350,7 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
if (needs_source_positions) {
Handle<Script> script(Script::cast(result->script()), isolate);
Script::InitLineEnds(script);
Script::InitLineEnds(isolate, script);
}
return scope.CloseAndEscape(result);
}

View File

@ -81,7 +81,7 @@ void ObjectDeserializer::CommitPostProcessedObjects() {
Factory* factory = isolate()->factory();
for (Handle<Script> script : new_scripts()) {
// Assign a new script id to avoid collision.
script->set_id(isolate()->heap()->NextScriptId());
script->set_id(isolate()->GetNextScriptId());
LogScriptEvents(*script);
// Add script to list.
Handle<WeakArrayList> list = factory->script_list();

View File

@ -22988,7 +22988,7 @@ TEST(ScriptPositionInfo) {
// Fail when position is larger than script size.
CHECK(!script1->GetPositionInfo(220384, &info, script1->NO_OFFSET));
i::Script::InitLineEnds(script1);
i::Script::InitLineEnds(i_isolate, script1);
}
}

View File

@ -3242,7 +3242,7 @@ TEST(DebugScriptLineEndsAreAscending) {
Handle<v8::internal::Script> script = Handle<v8::internal::Script>(
v8::internal::Script::cast(instances->get(i)), CcTest::i_isolate());
v8::internal::Script::InitLineEnds(script);
v8::internal::Script::InitLineEnds(CcTest::i_isolate(), script);
v8::internal::FixedArray ends =
v8::internal::FixedArray::cast(script->line_ends());
CHECK_GT(ends.length(), 0);