Commit 14097e62 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[compiler-dispatcher] Move to full SFI keying

Remove the concept of JobId from LazyCompileDispatcher, and make SFIs
the canonical id for these jobs.

This has several consequences:

  * We no longer split enqueing a job and registering a SFI with that
    job. We did this previously because we could not allocate SFIs in
    the Parser -- now with LocalHeap we can, so we do.
  * We remove the separate Job vector, and make the SFI IdentityMap
    hold pointers to Jobs directly. This requires a small amount of
    extra care to deallocate Jobs when removing them from the map,
    but it means not having to allocate new global handles for jobs.
  * The SFI is passed into the BackgroundCompileTask instead of the
    script, so our task finalization doesn't need the SFI anymore.
  * We no longer need to iterate ParallelTasks after compiling (to
    register SFIs), so we can get rid of ParallelTasks entirely and
    access the dispatcher directly from the parser.

There are a few drive-bys since we're touching this code:

  * Jobs are move to have a "state" variable rather than a collection
    of bools, for stricter DCHECKing.
  * There's no longer a set of "currently running" jobs, since this
    was only used to check if a job is running, we can instead inspect
    the job's state directly.
  * s/LazyCompilerDispatcher/LazyCompileDispatcher/g

Change-Id: I85e4bd6db108f5e8e7fe2e919c548ce45796dd50
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3259647
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarVictor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77712}
parent e7e46b12
......@@ -338,10 +338,11 @@ const AstRawString* AstValueFactory::GetTwoByteStringInternal(
base::Vector<const byte>::cast(literal));
}
const AstRawString* AstValueFactory::GetString(Handle<String> literal) {
const AstRawString* AstValueFactory::GetString(
String literal, const SharedStringAccessGuardIfNeeded& access_guard) {
const AstRawString* result = nullptr;
DisallowGarbageCollection no_gc;
String::FlatContent content = literal->GetFlatContent(no_gc);
String::FlatContent content = literal.GetFlatContent(no_gc, access_guard);
if (content.IsOneByte()) {
result = GetOneByteStringInternal(content.ToOneByteVector());
} else {
......@@ -351,15 +352,6 @@ const AstRawString* AstValueFactory::GetString(Handle<String> literal) {
return result;
}
const AstRawString* AstValueFactory::CloneFromOtherFactory(
const AstRawString* raw_string) {
const AstRawString* result =
GetString(raw_string->raw_hash_field(), raw_string->is_one_byte(),
base::Vector<const byte>(raw_string->raw_data(),
raw_string->byte_length()));
return result;
}
AstConsString* AstValueFactory::NewConsString() {
return zone()->New<AstConsString>();
}
......
......@@ -340,11 +340,8 @@ class AstValueFactory {
const AstRawString* GetTwoByteString(base::Vector<const uint16_t> literal) {
return GetTwoByteStringInternal(literal);
}
const AstRawString* GetString(Handle<String> literal);
// Clones an AstRawString from another ast value factory, adding it to this
// factory and returning the clone.
const AstRawString* CloneFromOtherFactory(const AstRawString* raw_string);
const AstRawString* GetString(String literal,
const SharedStringAccessGuardIfNeeded&);
V8_EXPORT_PRIVATE AstConsString* NewConsString();
V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str);
......
......@@ -212,7 +212,9 @@ ClassScope::ClassScope(Isolate* isolate, Zone* zone,
DCHECK_EQ(scope_info->ContextLocalMaybeAssignedFlag(index),
MaybeAssignedFlag::kMaybeAssigned);
Variable* var = DeclareClassVariable(
ast_value_factory, ast_value_factory->GetString(handle(name, isolate)),
ast_value_factory,
ast_value_factory->GetString(name,
SharedStringAccessGuardIfNeeded(isolate)),
kNoSourcePosition);
var->AllocateTo(VariableLocation::CONTEXT,
Context::MIN_CONTEXT_SLOTS + index);
......@@ -460,9 +462,11 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
String name = scope_info.ContextLocalName(0);
MaybeAssignedFlag maybe_assigned =
scope_info.ContextLocalMaybeAssignedFlag(0);
outer_scope = zone->New<Scope>(
zone, ast_value_factory->GetString(handle(name, isolate)),
maybe_assigned, handle(scope_info, isolate));
outer_scope =
zone->New<Scope>(zone,
ast_value_factory->GetString(
name, SharedStringAccessGuardIfNeeded(isolate)),
maybe_assigned, handle(scope_info, isolate));
}
if (deserialization_mode == DeserializationMode::kScopesOnly) {
outer_scope->scope_info_ = Handle<ScopeInfo>::null();
......
This diff is collapsed.
......@@ -105,9 +105,9 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
Isolate* isolate);
// Finalize and install code from previously run background compile task.
static bool FinalizeBackgroundCompileTask(
BackgroundCompileTask* task, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, ClearExceptionFlag flag);
static bool FinalizeBackgroundCompileTask(BackgroundCompileTask* task,
Isolate* isolate,
ClearExceptionFlag flag);
// Finalize and install optimized code from previously run job.
static bool FinalizeOptimizedCompilationJob(OptimizedCompilationJob* job,
......@@ -504,12 +504,12 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
BackgroundCompileTask& operator=(const BackgroundCompileTask&) = delete;
~BackgroundCompileTask();
// Creates a new task that when run will parse and compile the
// Creates a new task that when run will parse and compile the top-level
// |function_literal| and can be finalized with FinalizeFunction
// Compiler::FinalizeBackgroundCompileTask.
BackgroundCompileTask(
Isolate* isolate, const ParseInfo* outer_parse_info,
Handle<Script> script, const AstRawString* function_name,
Handle<SharedFunctionInfo> shared_info,
const FunctionLiteral* function_literal,
WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
TimedHistogram* timer, int max_stack_size);
......@@ -520,9 +520,7 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
Isolate* isolate, Handle<String> source,
const ScriptDetails& script_details);
bool FinalizeFunction(Isolate* isolate,
Handle<SharedFunctionInfo> shared_info,
Compiler::ClearExceptionFlag flag);
bool FinalizeFunction(Isolate* isolate, Compiler::ClearExceptionFlag flag);
UnoptimizedCompileFlags flags() const { return flags_; }
LanguageMode language_mode() const { return language_mode_; }
......@@ -540,7 +538,7 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_;
TimedHistogram* timer_;
// Data needed for merging onto the main thread.
// Data needed for merging onto the main thread after background finalization.
std::unique_ptr<PersistentHandles> persistent_handles_;
MaybeHandle<SharedFunctionInfo> outer_function_sfi_;
Handle<Script> script_;
......@@ -551,6 +549,7 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
int total_preparse_skipped_ = 0;
// Single function data for top-level function compilation.
MaybeHandle<SharedFunctionInfo> input_shared_info_;
int start_position_;
int end_position_;
int function_literal_id_;
......
......@@ -81,16 +81,9 @@ class V8_EXPORT_PRIVATE LazyCompileDispatcher {
LazyCompileDispatcher& operator=(const LazyCompileDispatcher&) = delete;
~LazyCompileDispatcher();
base::Optional<JobId> Enqueue(const ParseInfo* outer_parse_info,
Handle<Script> script,
const AstRawString* function_name,
const FunctionLiteral* function_literal);
// Registers the given |function| with the compilation job |job_id|.
void RegisterSharedFunctionInfo(JobId job_id, SharedFunctionInfo function);
// Returns true if there is a pending job with the given id.
bool IsEnqueued(JobId job_id) const;
void Enqueue(const ParseInfo* outer_parse_info,
Handle<SharedFunctionInfo> shared_info,
const FunctionLiteral* function_literal);
// Returns true if there is a pending job registered for the given function.
bool IsEnqueued(Handle<SharedFunctionInfo> function) const;
......@@ -99,56 +92,54 @@ class V8_EXPORT_PRIVATE LazyCompileDispatcher {
// possible). Returns true if the compile job was successful.
bool FinishNow(Handle<SharedFunctionInfo> function);
// Aborts compilation job |job_id|.
void AbortJob(JobId job_id);
// Aborts compilation job for the given function.
void AbortJob(Handle<SharedFunctionInfo> function);
// Aborts all jobs, blocking until all jobs are aborted.
void AbortAll();
private:
FRIEND_TEST(LazyCompilerDispatcherTest, IdleTaskNoIdleTime);
FRIEND_TEST(LazyCompilerDispatcherTest, IdleTaskSmallIdleTime);
FRIEND_TEST(LazyCompilerDispatcherTest, FinishNowWithWorkerTask);
FRIEND_TEST(LazyCompilerDispatcherTest, AbortJobNotStarted);
FRIEND_TEST(LazyCompilerDispatcherTest, AbortJobAlreadyStarted);
FRIEND_TEST(LazyCompilerDispatcherTest, AsyncAbortAllPendingWorkerTask);
FRIEND_TEST(LazyCompilerDispatcherTest, AsyncAbortAllRunningWorkerTask);
FRIEND_TEST(LazyCompilerDispatcherTest, CompileMultipleOnBackgroundThread);
FRIEND_TEST(LazyCompileDispatcherTest, IdleTaskNoIdleTime);
FRIEND_TEST(LazyCompileDispatcherTest, IdleTaskSmallIdleTime);
FRIEND_TEST(LazyCompileDispatcherTest, FinishNowWithWorkerTask);
FRIEND_TEST(LazyCompileDispatcherTest, AbortJobNotStarted);
FRIEND_TEST(LazyCompileDispatcherTest, AbortJobAlreadyStarted);
FRIEND_TEST(LazyCompileDispatcherTest, AsyncAbortAllPendingWorkerTask);
FRIEND_TEST(LazyCompileDispatcherTest, AsyncAbortAllRunningWorkerTask);
FRIEND_TEST(LazyCompileDispatcherTest, CompileMultipleOnBackgroundThread);
// JobTask for PostJob API.
class JobTask;
struct Job {
explicit Job(BackgroundCompileTask* task_arg);
enum class State {
kPending,
kRunning,
kReadyToFinalize,
kFinalized,
kAbortRequested,
kAborted,
kPendingToRunOnForeground
};
explicit Job(std::unique_ptr<BackgroundCompileTask> task);
~Job();
bool IsReadyToFinalize(const base::MutexGuard&) {
return has_run && (!function.is_null() || aborted);
}
bool IsReadyToFinalize(base::Mutex* mutex) {
base::MutexGuard lock(mutex);
return IsReadyToFinalize(lock);
bool is_running_on_background() const {
return state == State::kRunning || state == State::kAbortRequested;
}
std::unique_ptr<BackgroundCompileTask> task;
MaybeHandle<SharedFunctionInfo> function;
bool has_run;
bool aborted;
State state = State::kPending;
};
using JobMap = std::map<JobId, std::unique_ptr<Job>>;
using SharedToJobIdMap = IdentityMap<JobId, FreeStoreAllocationPolicy>;
using SharedToJobMap = IdentityMap<Job*, FreeStoreAllocationPolicy>;
void WaitForJobIfRunningOnBackground(Job* job);
JobMap::const_iterator GetJobFor(Handle<SharedFunctionInfo> shared) const;
Job* GetJobFor(Handle<SharedFunctionInfo> shared) const;
void ScheduleIdleTaskFromAnyThread(const base::MutexGuard&);
void DoBackgroundWork(JobDelegate* delegate);
void DoIdleWork(double deadline_in_seconds);
// Returns iterator to the inserted job.
JobMap::const_iterator InsertJob(std::unique_ptr<Job> job);
// Returns iterator following the removed job.
JobMap::const_iterator RemoveJob(JobMap::const_iterator job);
#ifdef DEBUG
void VerifyBackgroundTaskCount(const base::MutexGuard&);
......@@ -170,15 +161,9 @@ class V8_EXPORT_PRIVATE LazyCompileDispatcher {
std::unique_ptr<CancelableTaskManager> idle_task_manager_;
// Id for next job to be added
JobId next_job_id_;
// Mapping from job_id to job.
JobMap jobs_;
// Mapping from SharedFunctionInfo to the corresponding unoptimized
// compilation's JobId;
SharedToJobIdMap shared_to_unoptimized_job_id_;
// compilation job.
SharedToJobMap shared_to_unoptimized_job_;
// The following members can be accessed from any thread. Methods need to hold
// the mutex |mutex_| while accessing them.
......@@ -190,9 +175,6 @@ class V8_EXPORT_PRIVATE LazyCompileDispatcher {
// The set of jobs that can be run on a background thread.
std::unordered_set<Job*> pending_background_jobs_;
// The set of jobs currently being run on background threads.
std::unordered_set<Job*> running_background_jobs_;
// The total number of jobs, pending and running.
std::atomic<size_t> num_jobs_for_background_;
......
......@@ -125,6 +125,7 @@ class V8_EXPORT_PRIVATE LocalIsolate final : private HiddenLocalFactory {
private:
friend class v8::internal::LocalFactory;
friend class LocalIsolateFactory;
void InitializeBigIntProcessor();
......
......@@ -643,19 +643,20 @@ Handle<String> String::Flatten(LocalIsolate* isolate, Handle<String> string,
// static
base::Optional<String::FlatContent> String::TryGetFlatContentFromDirectString(
PtrComprCageBase cage_base, const DisallowGarbageCollection& no_gc,
String string, int offset, int length) {
String string, int offset, int length,
const SharedStringAccessGuardIfNeeded& access_guard) {
DCHECK_GE(offset, 0);
DCHECK_GE(length, 0);
DCHECK_LE(offset + length, string.length());
switch (StringShape{string, cage_base}.full_representation_tag()) {
case kSeqOneByteStringTag:
return FlatContent(
SeqOneByteString::cast(string).GetChars(no_gc) + offset, length,
no_gc);
SeqOneByteString::cast(string).GetChars(no_gc, access_guard) + offset,
length, no_gc);
case kSeqTwoByteStringTag:
return FlatContent(
SeqTwoByteString::cast(string).GetChars(no_gc) + offset, length,
no_gc);
SeqTwoByteString::cast(string).GetChars(no_gc, access_guard) + offset,
length, no_gc);
case kExternalOneByteStringTag:
return FlatContent(
ExternalOneByteString::cast(string).GetChars(cage_base) + offset,
......@@ -672,11 +673,27 @@ base::Optional<String::FlatContent> String::TryGetFlatContentFromDirectString(
String::FlatContent String::GetFlatContent(
const DisallowGarbageCollection& no_gc) {
#if DEBUG
// Check that this method is called only from the main thread.
{
Isolate* isolate;
// We don't have to check read only strings as those won't move.
DCHECK_IMPLIES(GetIsolateFromHeapObject(*this, &isolate),
ThreadId::Current() == isolate->thread_id());
}
#endif
return GetFlatContent(no_gc, SharedStringAccessGuardIfNeeded::NotNeeded());
}
String::FlatContent String::GetFlatContent(
const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard) {
PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
base::Optional<FlatContent> flat_content =
TryGetFlatContentFromDirectString(cage_base, no_gc, *this, 0, length());
base::Optional<FlatContent> flat_content = TryGetFlatContentFromDirectString(
cage_base, no_gc, *this, 0, length(), access_guard);
if (flat_content.has_value()) return flat_content.value();
return SlowGetFlatContent(no_gc);
return SlowGetFlatContent(no_gc, access_guard);
}
uint16_t String::Get(int index) const {
......
......@@ -569,17 +569,9 @@ Handle<Object> String::ToNumber(Isolate* isolate, Handle<String> subject) {
}
String::FlatContent String::SlowGetFlatContent(
const DisallowGarbageCollection& no_gc) {
#if DEBUG
// Check that this method is called only from the main thread.
{
Isolate* isolate;
// We don't have to check read only strings as those won't move.
DCHECK_IMPLIES(GetIsolateFromHeapObject(*this, &isolate),
ThreadId::Current() == isolate->thread_id());
}
#endif
const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard) {
USE(no_gc);
PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
String string = *this;
StringShape shape(string, cage_base);
......@@ -610,7 +602,7 @@ String::FlatContent String::SlowGetFlatContent(
DCHECK(shape.IsDirect());
return TryGetFlatContentFromDirectString(cage_base, no_gc, string, offset,
length())
length(), access_guard)
.value();
}
......
......@@ -263,8 +263,13 @@ class String : public TorqueGeneratedString<String, Name> {
// If the string isn't flat, and therefore doesn't have flat content, the
// returned structure will report so, and can't provide a vector of either
// kind.
// When using a SharedStringAccessGuard, the guard's must outlive the
// returned FlatContent.
V8_EXPORT_PRIVATE V8_INLINE FlatContent
GetFlatContent(const DisallowGarbageCollection& no_gc);
V8_EXPORT_PRIVATE V8_INLINE FlatContent
GetFlatContent(const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded&);
// Returns the parent of a sliced string or first part of a flat cons string.
// Requires: StringShape(this).IsIndirect() && this->IsFlat()
......@@ -589,9 +594,11 @@ class String : public TorqueGeneratedString<String, Name> {
V8_EXPORT_PRIVATE V8_INLINE static base::Optional<FlatContent>
TryGetFlatContentFromDirectString(PtrComprCageBase cage_base,
const DisallowGarbageCollection& no_gc,
String string, int offset, int length);
String string, int offset, int length,
const SharedStringAccessGuardIfNeeded&);
V8_EXPORT_PRIVATE FlatContent
SlowGetFlatContent(const DisallowGarbageCollection& no_gc);
SlowGetFlatContent(const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded&);
static Handle<String> SlowCopy(Isolate* isolate, Handle<SeqString> source,
AllocationType allocation);
......
......@@ -169,10 +169,7 @@ UnoptimizedCompileState::UnoptimizedCompileState(Isolate* isolate)
allocator_(isolate->allocator()),
ast_string_constants_(isolate->ast_string_constants()),
logger_(isolate->logger()),
parallel_tasks_(
isolate->lazy_compile_dispatcher()
? new ParallelTasks(isolate->lazy_compile_dispatcher())
: nullptr) {}
dispatcher_(isolate->lazy_compile_dispatcher()) {}
UnoptimizedCompileState::UnoptimizedCompileState(
const UnoptimizedCompileState& other) V8_NOEXCEPT
......@@ -180,8 +177,7 @@ UnoptimizedCompileState::UnoptimizedCompileState(
allocator_(other.allocator()),
ast_string_constants_(other.ast_string_constants()),
logger_(other.logger()),
// TODO(leszeks): Should this create a new ParallelTasks instance?
parallel_tasks_(nullptr) {}
dispatcher_(other.dispatcher()) {}
ParseInfo::ParseInfo(const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state)
......@@ -216,23 +212,10 @@ ParseInfo::ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags,
isolate->counters()->runtime_call_stats());
}
// static
std::unique_ptr<ParseInfo> ParseInfo::ForToplevelFunction(
const UnoptimizedCompileFlags flags, UnoptimizedCompileState* compile_state,
const FunctionLiteral* literal, const AstRawString* function_name) {
std::unique_ptr<ParseInfo> result(new ParseInfo(flags, compile_state));
// Clone the function_name AstRawString into the ParseInfo's own
// AstValueFactory.
const AstRawString* cloned_function_name =
result->GetOrCreateAstValueFactory()->CloneFromOtherFactory(
function_name);
// Setup function specific details.
DCHECK(!literal->is_toplevel());
result->set_function_name(cloned_function_name);
return result;
ParseInfo::ParseInfo(LocalIsolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state)
: ParseInfo(flags, state) {
SetPerThreadState(0, nullptr);
}
ParseInfo::~ParseInfo() = default;
......@@ -331,15 +314,5 @@ void ParseInfo::CheckFlagsForFunctionFromScript(Script script) {
source_range_map() != nullptr);
}
void UnoptimizedCompileState::ParallelTasks::Enqueue(
ParseInfo* outer_parse_info, Handle<Script> script,
const AstRawString* function_name, FunctionLiteral* literal) {
base::Optional<LazyCompileDispatcher::JobId> job_id =
dispatcher_->Enqueue(outer_parse_info, script, function_name, literal);
if (job_id) {
enqueued_jobs_.emplace_front(std::make_pair(literal, *job_id));
}
}
} // namespace internal
} // namespace v8
......@@ -162,29 +162,6 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileState {
explicit UnoptimizedCompileState(Isolate*);
UnoptimizedCompileState(const UnoptimizedCompileState& other) V8_NOEXCEPT;
class ParallelTasks {
public:
explicit ParallelTasks(LazyCompileDispatcher* lazy_compile_dispatcher)
: dispatcher_(lazy_compile_dispatcher) {
DCHECK_NOT_NULL(dispatcher_);
}
void Enqueue(ParseInfo* outer_parse_info, Handle<Script> script,
const AstRawString* function_name, FunctionLiteral* literal);
using EnqueuedJobsIterator =
std::forward_list<std::pair<FunctionLiteral*, uintptr_t>>::iterator;
EnqueuedJobsIterator begin() { return enqueued_jobs_.begin(); }
EnqueuedJobsIterator end() { return enqueued_jobs_.end(); }
LazyCompileDispatcher* dispatcher() { return dispatcher_; }
private:
LazyCompileDispatcher* dispatcher_;
std::forward_list<std::pair<FunctionLiteral*, uintptr_t>> enqueued_jobs_;
};
uint64_t hash_seed() const { return hash_seed_; }
AccountingAllocator* allocator() const { return allocator_; }
const AstStringConstants* ast_string_constants() const {
......@@ -197,7 +174,7 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileState {
const PendingCompilationErrorHandler* pending_error_handler() const {
return &pending_error_handler_;
}
ParallelTasks* parallel_tasks() const { return parallel_tasks_.get(); }
LazyCompileDispatcher* dispatcher() const { return dispatcher_; }
private:
uint64_t hash_seed_;
......@@ -205,7 +182,7 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileState {
const AstStringConstants* ast_string_constants_;
PendingCompilationErrorHandler pending_error_handler_;
Logger* logger_;
std::unique_ptr<ParallelTasks> parallel_tasks_;
LazyCompileDispatcher* dispatcher_;
};
// A container for the inputs, configuration options, and outputs of parsing.
......@@ -213,13 +190,8 @@ class V8_EXPORT_PRIVATE ParseInfo {
public:
ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state);
// Creates a new parse info based on parent top-level |outer_parse_info| for
// function |literal|.
static std::unique_ptr<ParseInfo> ForToplevelFunction(
const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* compile_state, const FunctionLiteral* literal,
const AstRawString* function_name);
ParseInfo(LocalIsolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state);
~ParseInfo();
......@@ -248,9 +220,7 @@ class V8_EXPORT_PRIVATE ParseInfo {
PendingCompilationErrorHandler* pending_error_handler() {
return state_->pending_error_handler();
}
UnoptimizedCompileState::ParallelTasks* parallel_tasks() const {
return state_->parallel_tasks();
}
LazyCompileDispatcher* dispatcher() const { return state_->dispatcher(); }
const UnoptimizedCompileState* state() const { return state_; }
// Accessors for per-thread state.
......
......@@ -419,11 +419,13 @@ Expression* Parser::NewV8RuntimeFunctionForFuzzing(
return factory()->NewCallRuntime(function, permissive_args, pos);
}
Parser::Parser(ParseInfo* info, Handle<Script> script)
Parser::Parser(LocalIsolate* local_isolate, ParseInfo* info,
Handle<Script> script)
: ParserBase<Parser>(
info->zone(), &scanner_, info->stack_limit(),
info->GetOrCreateAstValueFactory(), info->pending_error_handler(),
info->runtime_call_stats(), info->logger(), info->flags(), true),
local_isolate_(local_isolate),
info_(info),
script_(script),
scanner_(info->character_stream(), flags()),
......@@ -723,7 +725,8 @@ ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
zone->New<ZonePtrList<const AstRawString>>(arguments_length, zone);
for (int i = 0; i < arguments_length; i++) {
const AstRawString* argument_string = ast_value_factory()->GetString(
Handle<String>(String::cast(arguments->get(i)), isolate));
String::cast(arguments->get(i)),
SharedStringAccessGuardIfNeeded(isolate));
arguments_for_wrapped_function->Add(argument_string, zone);
}
return arguments_for_wrapped_function;
......@@ -849,8 +852,8 @@ void Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
}
// Initialize parser state.
Handle<String> name(shared_info->Name(), isolate);
info->set_function_name(ast_value_factory()->GetString(name));
info->set_function_name(ast_value_factory()->GetString(
shared_info->Name(), SharedStringAccessGuardIfNeeded(isolate)));
scanner_.Initialize();
FunctionLiteral* result;
......@@ -2596,7 +2599,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// in a parallel task on a worker thread.
bool should_post_parallel_task =
parse_lazily() && is_eager_top_level_function &&
FLAG_parallel_compile_tasks && info()->parallel_tasks() &&
FLAG_parallel_compile_tasks && info()->dispatcher() &&
scanner()->stream()->can_be_cloned_for_parallel_access();
// This may be modified later to reflect preparsing decision taken
......@@ -2695,8 +2698,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (should_post_parallel_task) {
// Start a parallel parse / compile task on the compiler dispatcher.
info()->parallel_tasks()->Enqueue(info(), script_, function_name,
function_literal);
Handle<SharedFunctionInfo> shared_info =
local_isolate_->factory()->NewSharedFunctionInfoForLiteral(
function_literal, script_, false);
info()->dispatcher()->Enqueue(info(), shared_info, function_literal);
}
if (should_infer_name) {
......
......@@ -130,7 +130,7 @@ struct ParserTypes<Parser> {
class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
public:
explicit Parser(ParseInfo* info, Handle<Script> script);
Parser(LocalIsolate* local_isolate, ParseInfo* info, Handle<Script> script);
~Parser() {
delete reusable_preparser_;
reusable_preparser_ = nullptr;
......@@ -1056,6 +1056,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
friend class PreParserZoneScope; // Uses reusable_preparser().
friend class PreparseDataBuilder; // Uses preparse_data_buffer()
LocalIsolate* local_isolate_;
ParseInfo* info_;
Handle<Script> script_;
Scanner scanner_;
......
......@@ -52,7 +52,7 @@ bool ParseProgram(ParseInfo* info, Handle<Script> script,
ScannerStream::For(isolate, source));
info->set_character_stream(std::move(stream));
Parser parser(info, script);
Parser parser(isolate->main_thread_local_isolate(), info, script);
// Ok to use Isolate here; this function is only called in the main thread.
DCHECK(parser.parsing_on_main_thread_);
......@@ -83,7 +83,7 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
shared_info->EndPosition()));
info->set_character_stream(std::move(stream));
Parser parser(info, script);
Parser parser(isolate->main_thread_local_isolate(), info, script);
// Ok to use Isolate here; this function is only called in the main thread.
DCHECK(parser.parsing_on_main_thread_);
......
......@@ -174,6 +174,7 @@ class IdentityMap : public IdentityMapBase {
V* operator*() { return entry(); }
V* operator->() { return entry(); }
bool operator!=(const Iterator& other) { return index_ != other.index_; }
bool operator==(const Iterator& other) { return index_ == other.index_; }
private:
Iterator(IdentityMap* map, int index) : map_(map), index_(index) {}
......
......@@ -84,7 +84,8 @@ class LocalFactoryTest : public TestWithIsolateAndZone {
DisallowGarbageCollection no_gc;
DisallowHeapAccess no_heap_access;
Parser parser(parse_info(), script_);
Parser parser(isolate()->main_thread_local_isolate(), parse_info(),
script_);
parser.InitializeEmptyScopeChain(parse_info());
parser.ParseOnBackground(parse_info(), 0, 0, kFunctionLiteralIdTopLevel);
}
......
......@@ -80,9 +80,7 @@ class BackgroundCompileTaskTest : public TestWithNativeContext {
shared->function_literal_id(), nullptr);
return new BackgroundCompileTask(
isolate, outer_parse_info.get(),
handle(Script::cast(shared->script()), isolate), function_name,
function_literal,
isolate, outer_parse_info.get(), shared, function_literal,
isolate->counters()->worker_thread_runtime_call_stats(),
isolate->counters()->compile_function_on_background(), FLAG_stack_size);
}
......@@ -111,7 +109,7 @@ TEST_F(BackgroundCompileTaskTest, SyntaxError) {
task->Run();
ASSERT_FALSE(Compiler::FinalizeBackgroundCompileTask(
task.get(), shared, isolate(), Compiler::KEEP_EXCEPTION));
task.get(), isolate(), Compiler::KEEP_EXCEPTION));
ASSERT_TRUE(isolate()->has_pending_exception());
isolate()->clear_pending_exception();
......@@ -137,7 +135,7 @@ TEST_F(BackgroundCompileTaskTest, CompileAndRun) {
task->Run();
ASSERT_TRUE(Compiler::FinalizeBackgroundCompileTask(
task.get(), shared, isolate(), Compiler::KEEP_EXCEPTION));
task.get(), isolate(), Compiler::KEEP_EXCEPTION));
ASSERT_TRUE(shared->is_compiled());
Smi value = Smi::cast(*RunJS("f(100);"));
......@@ -163,7 +161,7 @@ TEST_F(BackgroundCompileTaskTest, CompileFailure) {
task->Run();
ASSERT_FALSE(Compiler::FinalizeBackgroundCompileTask(
task.get(), shared, isolate(), Compiler::KEEP_EXCEPTION));
task.get(), isolate(), Compiler::KEEP_EXCEPTION));
ASSERT_TRUE(isolate()->has_pending_exception());
isolate()->clear_pending_exception();
......@@ -208,7 +206,7 @@ TEST_F(BackgroundCompileTaskTest, CompileOnBackgroundThread) {
V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(background_task));
semaphore.Wait();
ASSERT_TRUE(Compiler::FinalizeBackgroundCompileTask(
task.get(), shared, isolate(), Compiler::KEEP_EXCEPTION));
task.get(), isolate(), Compiler::KEEP_EXCEPTION));
ASSERT_TRUE(shared->is_compiled());
}
......@@ -233,7 +231,7 @@ TEST_F(BackgroundCompileTaskTest, EagerInnerFunctions) {
task->Run();
ASSERT_TRUE(Compiler::FinalizeBackgroundCompileTask(
task.get(), shared, isolate(), Compiler::KEEP_EXCEPTION));
task.get(), isolate(), Compiler::KEEP_EXCEPTION));
ASSERT_TRUE(shared->is_compiled());
Handle<JSFunction> e = RunJS<JSFunction>("f();");
......@@ -261,7 +259,7 @@ TEST_F(BackgroundCompileTaskTest, LazyInnerFunctions) {
task->Run();
ASSERT_TRUE(Compiler::FinalizeBackgroundCompileTask(
task.get(), shared, isolate(), Compiler::KEEP_EXCEPTION));
task.get(), isolate(), Compiler::KEEP_EXCEPTION));
ASSERT_TRUE(shared->is_compiled());
Handle<JSFunction> e = RunJS<JSFunction>("f();");
......
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