Commit c179400b authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Compiler] Remove SharedFunctionInfo from ParseInfo.

Removes the SharedFunctionInfo field from the ParseInfo structure. Instead
require a SharedFunctionInfo to be explicitly passed to ParseFunction.
Also renames GetUnoptimizedCode to CompileUnoptimizedFunction to make it
clear it should only be called for non-top-level code.

BUG=v8:5203

Change-Id: Ibce016e6a5290c3685f7f0a2f5fb1eb2df2ffc3b
Reviewed-on: https://chromium-review.googlesource.com/574589
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46814}
parent b2d1f272
......@@ -30,7 +30,6 @@ namespace internal {
PARSE_INFO_GETTER(Handle<Script>, script)
PARSE_INFO_GETTER(FunctionLiteral*, literal)
PARSE_INFO_GETTER_WITH_DEFAULT(DeclarationScope*, scope, nullptr)
PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info)
#undef PARSE_INFO_GETTER
#undef PARSE_INFO_GETTER_WITH_DEFAULT
......@@ -49,14 +48,13 @@ void CompilationInfo::PrepareForSerializing() {
SetFlag(kSerializing);
}
bool CompilationInfo::has_shared_info() const {
return parse_info_ && !parse_info_->shared_info().is_null();
}
CompilationInfo::CompilationInfo(Zone* zone, ParseInfo* parse_info,
Isolate* isolate, Handle<JSFunction> closure)
Isolate* isolate,
Handle<SharedFunctionInfo> shared,
Handle<JSFunction> closure)
: CompilationInfo(parse_info, {}, Code::ComputeFlags(Code::FUNCTION), BASE,
isolate, zone) {
shared_info_ = shared;
closure_ = closure;
if (FLAG_function_context_specialization) MarkAsFunctionContextSpecializing();
......@@ -139,6 +137,9 @@ void CompilationInfo::set_deferred_handles(DeferredHandles* deferred_handles) {
}
void CompilationInfo::ReopenHandlesInNewHandleScope() {
if (!shared_info_.is_null()) {
shared_info_ = Handle<SharedFunctionInfo>(*shared_info_);
}
if (!closure_.is_null()) {
closure_ = Handle<JSFunction>(*closure_);
}
......@@ -153,8 +154,8 @@ std::unique_ptr<char[]> CompilationInfo::GetDebugName() const {
AllowHandleDereference allow_deref;
return parse_info()->literal()->debug_name()->ToCString();
}
if (parse_info() && !parse_info()->shared_info().is_null()) {
return parse_info()->shared_info()->DebugName()->ToCString();
if (!shared_info().is_null()) {
return shared_info()->DebugName()->ToCString();
}
Vector<const char> name_vec = debug_name_;
if (name_vec.is_empty()) name_vec = ArrayVector("unknown");
......
......@@ -55,6 +55,7 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
};
CompilationInfo(Zone* zone, ParseInfo* parse_info, Isolate* isolate,
Handle<SharedFunctionInfo> shared,
Handle<JSFunction> closure);
CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone,
Code::Flags code_flags);
......@@ -68,13 +69,16 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
Handle<Script> script() const;
FunctionLiteral* literal() const;
DeclarationScope* scope() const;
Handle<SharedFunctionInfo> shared_info() const;
bool has_shared_info() const;
// -----------------------------------------------------------
Isolate* isolate() const { return isolate_; }
Zone* zone() { return zone_; }
bool is_osr() const { return !osr_ast_id_.IsNone(); }
Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
void set_shared_info(Handle<SharedFunctionInfo> shared_info) {
shared_info_ = shared_info;
}
bool has_shared_info() const { return !shared_info().is_null(); }
Handle<JSFunction> closure() const { return closure_; }
Handle<Code> code() const { return code_; }
Code::Flags code_flags() const { return code_flags_; }
......@@ -349,6 +353,8 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
Code::Flags code_flags_;
Handle<SharedFunctionInfo> shared_info_;
Handle<JSFunction> closure_;
// The compiled code.
......
......@@ -146,7 +146,8 @@ CompilerDispatcherJob::CompilerDispatcherJob(
parse_info_(new ParseInfo(shared_)),
parse_zone_(parse_zone),
compile_info_(new CompilationInfo(parse_info_->zone(), parse_info_.get(),
isolate_, Handle<JSFunction>::null())),
isolate_, shared_,
Handle<JSFunction>::null())),
trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
parse_info_->set_literal(literal);
parse_info_->set_script(script);
......@@ -398,7 +399,6 @@ void CompilerDispatcherJob::FinalizeParsingOnMainThread() {
handle(ScopeInfo::cast(shared_->outer_scope_info())));
parse_info_->set_outer_scope_info(outer_scope_info);
}
parse_info_->set_shared_info(shared_);
// Internalize ast values on the main thread.
parse_info_->ast_value_factory()->Internalize(isolate_);
......@@ -421,9 +421,9 @@ void CompilerDispatcherJob::AnalyzeOnMainThread() {
PrintF("CompilerDispatcherJob[%p]: Analyzing\n", static_cast<void*>(this));
}
compile_info_.reset(new CompilationInfo(parse_info_->zone(),
parse_info_.get(), isolate_,
Handle<JSFunction>::null()));
compile_info_.reset(new CompilationInfo(
parse_info_->zone(), parse_info_.get(), isolate_,
Handle<SharedFunctionInfo>::null(), Handle<JSFunction>::null()));
DeferredHandleScope scope(isolate_);
{
......@@ -486,6 +486,8 @@ void CompilerDispatcherJob::FinalizeCompilingOnMainThread() {
{
HandleScope scope(isolate_);
compile_info_->set_shared_info(shared_);
if (compile_job_->state() == CompilationJob::State::kFailed ||
!Compiler::FinalizeCompilationJob(compile_job_.release())) {
if (!isolate_->has_pending_exception()) isolate_->StackOverflow();
......
......@@ -411,7 +411,7 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) {
isolate->factory()->NewSharedFunctionInfoForLiteral(info->literal(),
info->script());
shared->set_is_toplevel(true);
parse_info->set_shared_info(shared);
info->set_shared_info(shared);
}
}
SetSharedFunctionFlagsFromLiteral(info->literal(), info->shared_info());
......@@ -430,30 +430,13 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) {
return status;
}
bool Renumber(ParseInfo* parse_info,
bool Renumber(ParseInfo* info,
Compiler::EagerInnerFunctionLiterals* eager_literals) {
RuntimeCallTimerScope runtimeTimer(parse_info->runtime_call_stats(),
RuntimeCallTimerScope runtimeTimer(info->runtime_call_stats(),
&RuntimeCallStats::CompileRenumber);
// CollectTypeProfile uses its own feedback slots. If we have existing
// FeedbackMetadata, we can only collect type profile, if the feedback vector
// has the appropriate slots.
bool collect_type_profile;
if (parse_info->shared_info().is_null() ||
parse_info->shared_info()->feedback_metadata()->length() == 0) {
collect_type_profile =
FLAG_type_profile && parse_info->script()->IsUserJavaScript();
} else {
collect_type_profile =
parse_info->shared_info()->feedback_metadata()->HasTypeProfileSlot();
}
if (!AstNumbering::Renumber(parse_info->stack_limit(), parse_info->zone(),
parse_info->literal(), eager_literals,
collect_type_profile)) {
return false;
}
return true;
return AstNumbering::Renumber(info->stack_limit(), info->zone(),
info->literal(), eager_literals,
info->collect_type_profile());
}
bool GenerateUnoptimizedCode(CompilationInfo* info) {
......@@ -512,11 +495,10 @@ bool CompileUnoptimizedInnerFunctions(
} else {
// Otherwise generate unoptimized code now.
ParseInfo parse_info(script);
CompilationInfo info(parse_info.zone(), &parse_info, isolate,
CompilationInfo info(parse_info.zone(), &parse_info, isolate, shared,
Handle<JSFunction>::null());
parse_info.set_toplevel(false);
parse_info.set_literal(literal);
parse_info.set_shared_info(shared);
parse_info.set_function_literal_id(shared->function_literal_id());
parse_info.set_language_mode(literal->scope()->language_mode());
parse_info.set_ast_value_factory(
......@@ -591,17 +573,18 @@ bool CompileUnoptimizedCode(CompilationInfo* info,
return true;
}
MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(
CompilationInfo* info, ConcurrencyMode inner_function_mode) {
MUST_USE_RESULT MaybeHandle<Code> CompileUnoptimizedFunction(
CompilationInfo* info, Handle<SharedFunctionInfo> shared_info,
ConcurrencyMode inner_function_mode) {
RuntimeCallTimerScope runtimeTimer(
info->isolate(), &RuntimeCallStats::CompileGetUnoptimizedCode);
info->isolate(), &RuntimeCallStats::CompileUnoptimizedFunction);
VMState<COMPILER> state(info->isolate());
PostponeInterruptsScope postpone(info->isolate());
// Parse and update ParseInfo with the results.
{
if (!parsing::ParseAny(
info->parse_info(), info->isolate(),
if (!parsing::ParseFunction(
info->parse_info(), shared_info, info->isolate(),
inner_function_mode != ConcurrencyMode::kConcurrent)) {
return MaybeHandle<Code>();
}
......@@ -989,11 +972,11 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) {
// Function doesn't have any baseline compiled code, compile now.
DCHECK(!function->shared()->HasBytecodeArray());
ParseInfo parse_info(handle(function->shared()));
Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared);
Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo info(&compile_zone, &parse_info, isolate, function);
CompilationInfo info(&compile_zone, &parse_info, isolate, shared, function);
if (FLAG_experimental_preparser_scope_analysis) {
Handle<SharedFunctionInfo> shared(function->shared());
if (shared->HasPreParsedScopeData()) {
Handle<PreParsedScopeData> data(
PreParsedScopeData::cast(shared->preparsed_scope_data()));
......@@ -1008,7 +991,8 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) {
: ConcurrencyMode::kNotConcurrent;
Handle<Code> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result, GetUnoptimizedCode(&info, inner_function_mode), Code);
isolate, result,
CompileUnoptimizedFunction(&info, shared, inner_function_mode), Code);
if (FLAG_always_opt && !info.shared_info()->HasAsmWasmData()) {
if (FLAG_trace_opt) {
......@@ -1108,8 +1092,12 @@ bool Compiler::Analyze(CompilationInfo* info,
return Compiler::Analyze(info->parse_info(), info->isolate(), eager_literals);
}
bool Compiler::ParseAndAnalyze(ParseInfo* info, Isolate* isolate) {
if (!parsing::ParseAny(info, isolate)) return false;
bool Compiler::ParseAndAnalyze(ParseInfo* info,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate) {
if (!parsing::ParseAny(info, shared_info, isolate)) {
return false;
}
if (!Compiler::Analyze(info, isolate)) return false;
DCHECK_NOT_NULL(info->literal());
DCHECK_NOT_NULL(info->scope());
......@@ -1117,9 +1105,9 @@ bool Compiler::ParseAndAnalyze(ParseInfo* info, Isolate* isolate) {
}
bool Compiler::ParseAndAnalyze(CompilationInfo* info) {
return Compiler::ParseAndAnalyze(info->parse_info(), info->isolate());
return Compiler::ParseAndAnalyze(info->parse_info(), info->shared_info(),
info->isolate());
}
bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
if (function->is_compiled()) return true;
Isolate* isolate = function->GetIsolate();
......@@ -1196,13 +1184,22 @@ bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) {
// Start a compilation.
ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, isolate,
CompilationInfo info(parse_info.zone(), &parse_info, isolate, shared,
Handle<JSFunction>::null());
info.MarkAsDebug();
if (GetUnoptimizedCode(&info, ConcurrencyMode::kNotConcurrent).is_null()) {
if (parse_info.is_toplevel()) {
if (CompileToplevel(&info).is_null()) {
isolate->clear_pending_exception();
return false;
}
} else {
if (CompileUnoptimizedFunction(&info, shared,
ConcurrencyMode::kNotConcurrent)
.is_null()) {
isolate->clear_pending_exception();
return false;
}
}
// Check postconditions on success.
DCHECK(!isolate->has_pending_exception());
......@@ -1226,6 +1223,7 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) {
ParseInfo parse_info(script);
Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo info(&compile_zone, &parse_info, isolate,
Handle<SharedFunctionInfo>::null(),
Handle<JSFunction>::null());
info.MarkAsDebug();
......@@ -1248,18 +1246,21 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) {
}
bool Compiler::EnsureBytecode(CompilationInfo* info) {
if (!info->shared_info()->is_compiled()) {
Handle<SharedFunctionInfo> shared_info = info->shared_info();
if (!shared_info->is_compiled()) {
DCHECK(!info->parse_info()->is_toplevel());
CompilerDispatcher* dispatcher = info->isolate()->compiler_dispatcher();
if (dispatcher->IsEnqueued(info->shared_info())) {
if (dispatcher->IsEnqueued(shared_info)) {
if (!dispatcher->FinishNow(info->shared_info())) return false;
} else if (GetUnoptimizedCode(info, ConcurrencyMode::kNotConcurrent)
} else if (CompileUnoptimizedFunction(info, shared_info,
ConcurrencyMode::kNotConcurrent)
.is_null()) {
return false;
}
}
DCHECK(info->shared_info()->is_compiled());
if (info->shared_info()->HasAsmWasmData()) return false;
return info->shared_info()->HasBytecodeArray();
DCHECK(shared_info->is_compiled());
if (shared_info->HasAsmWasmData()) return false;
return shared_info->HasBytecodeArray();
}
MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
......@@ -1321,6 +1322,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
ParseInfo parse_info(script);
Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo info(&compile_zone, &parse_info, isolate,
Handle<SharedFunctionInfo>::null(),
Handle<JSFunction>::null());
parse_info.set_eval();
parse_info.set_language_mode(language_mode);
......@@ -1534,6 +1536,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
ParseInfo parse_info(script);
Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo info(&compile_zone, &parse_info, isolate,
Handle<SharedFunctionInfo>::null(),
Handle<JSFunction>::null());
if (resource_options.IsModule()) parse_info.set_module();
if (compile_options != ScriptCompiler::kNoCompileOptions) {
......@@ -1603,6 +1606,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForStreamedScript(
Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo compile_info(&compile_zone, parse_info, isolate,
Handle<SharedFunctionInfo>::null(),
Handle<JSFunction>::null());
// The source was parsed lazily, so compiling for debugging is not possible.
......
......@@ -68,8 +68,10 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
EagerInnerFunctionLiterals;
// Parser::Parse, then Compiler::Analyze.
static bool ParseAndAnalyze(ParseInfo* info, Isolate* isolate);
// Convenience function
static bool ParseAndAnalyze(ParseInfo* info,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate);
// Convenience function.
static bool ParseAndAnalyze(CompilationInfo* info);
// Rewrite, analyze scopes, and renumber. If |eager_literals| is non-null, it
// is appended with inner function literals which should be eagerly compiled.
......
......@@ -508,7 +508,8 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
ParseInfo parse_info(shared_info);
CompilationInfo info(parse_info.zone(), &parse_info,
shared_info->GetIsolate(), Handle<JSFunction>::null());
shared_info->GetIsolate(), shared_info,
Handle<JSFunction>::null());
if (info_->is_deoptimization_enabled()) info.MarkAsDeoptimizationEnabled();
info.MarkAsOptimizeFromBytecode();
......
......@@ -597,14 +597,16 @@ PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info,
class PipelineCompilationJob final : public CompilationJob {
public:
PipelineCompilationJob(ParseInfo* parse_info, Handle<JSFunction> function)
PipelineCompilationJob(ParseInfo* parse_info,
Handle<SharedFunctionInfo> shared_info,
Handle<JSFunction> function)
// Note that the CompilationInfo is not initialized at the time we pass it
// to the CompilationJob constructor, but it is not dereferenced there.
: CompilationJob(function->GetIsolate(), &info_, "TurboFan"),
parse_info_(parse_info),
zone_stats_(function->GetIsolate()->allocator()),
info_(parse_info_.get()->zone(), parse_info_.get(),
function->GetIsolate(), function),
function->GetIsolate(), shared_info, function),
pipeline_statistics_(CreatePipelineStatistics(info(), &zone_stats_)),
data_(&zone_stats_, info(), pipeline_statistics_.get()),
pipeline_(&data_),
......@@ -1961,7 +1963,7 @@ CompilationJob* Pipeline::NewCompilationJob(Handle<JSFunction> function,
} else {
parse_info = new ParseInfo(shared);
}
return new PipelineCompilationJob(parse_info, function);
return new PipelineCompilationJob(parse_info, shared, function);
}
// static
......
......@@ -765,7 +765,7 @@ class RuntimeCallTimer final {
V(CompileBackgroundIgnition) \
V(CompileFunction) \
V(CompileGetFromOptimizedCodeMap) \
V(CompileGetUnoptimizedCode) \
V(CompileUnoptimizedFunction) \
V(CompileIgnition) \
V(CompileIgnitionFinalization) \
V(CompileInnerFunction) \
......
......@@ -114,7 +114,7 @@ void ScopeIterator::TryParseAndRetrieveScopes(ScopeIterator::Option option) {
// Inner function.
info.reset(new ParseInfo(shared_info));
}
if (parsing::ParseAny(info.get(), isolate_) &&
if (parsing::ParseAny(info.get(), shared_info, isolate_) &&
Rewriter::Rewrite(info.get(), isolate_)) {
DeclarationScope* scope = info->literal()->scope();
if (!ignore_nested_scopes || collect_non_locals) {
......
......@@ -57,7 +57,6 @@ ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared)
set_end_position(shared->end_position());
function_literal_id_ = shared->function_literal_id();
set_language_mode(shared->language_mode());
set_shared_info(shared);
set_module(shared->kind() == FunctionKind::kModule);
Handle<Script> script(Script::cast(shared->script()));
......@@ -70,12 +69,14 @@ ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared)
Handle<ScopeInfo>::cast(scope_info)->length() > 0) {
set_outer_scope_info(Handle<ScopeInfo>::cast(scope_info));
}
}
ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared,
std::shared_ptr<Zone> zone)
: ParseInfo(shared) {
zone_.swap(zone);
// CollectTypeProfile uses its own feedback slots. If we have existing
// FeedbackMetadata, we can only collect type profile if the feedback vector
// has the appropriate slots.
set_collect_type_profile(
shared->feedback_metadata()->length() == 0
? FLAG_type_profile && script->IsUserJavaScript()
: shared->feedback_metadata()->HasTypeProfileSlot());
}
ParseInfo::ParseInfo(Handle<Script> script)
......@@ -88,6 +89,8 @@ ParseInfo::ParseInfo(Handle<Script> script)
set_native(script->type() == Script::TYPE_NATIVE);
set_eval(script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
set_collect_type_profile(FLAG_type_profile && script->IsUserJavaScript());
}
ParseInfo::~ParseInfo() {
......@@ -112,7 +115,6 @@ ParseInfo* ParseInfo::AllocateWithoutScript(Handle<SharedFunctionInfo> shared) {
p->set_end_position(shared->end_position());
p->function_literal_id_ = shared->function_literal_id();
p->set_language_mode(shared->language_mode());
p->set_shared_info(shared);
p->set_module(shared->kind() == FunctionKind::kModule);
// BUG(5946): This function exists as a workaround until we can
......
......@@ -30,7 +30,6 @@ class DeferredHandles;
class FunctionLiteral;
class RuntimeCallStats;
class ScriptData;
class SharedFunctionInfo;
class SourceRangeMap;
class UnicodeCache;
class Utf16CharacterStream;
......@@ -43,9 +42,6 @@ class V8_EXPORT_PRIVATE ParseInfo : public CompileJobFinishCallback {
ParseInfo(Handle<Script> script);
ParseInfo(Handle<SharedFunctionInfo> shared);
// TODO(rmcilroy): Remove once Hydrogen no longer needs this.
ParseInfo(Handle<SharedFunctionInfo> shared, std::shared_ptr<Zone> zone);
~ParseInfo();
void InitFromIsolate(Isolate* isolate);
......@@ -80,7 +76,8 @@ class V8_EXPORT_PRIVATE ParseInfo : public CompileJobFinishCallback {
set_is_named_expression)
FLAG_ACCESSOR(kDebug, is_debug, set_is_debug)
FLAG_ACCESSOR(kSerializing, will_serialize, set_will_serialize)
FLAG_ACCESSOR(kCollectTypeProfile, collect_type_profile,
set_collect_type_profile)
#undef FLAG_ACCESSOR
void set_parse_restriction(ParseRestriction restriction) {
......@@ -218,13 +215,11 @@ class V8_EXPORT_PRIVATE ParseInfo : public CompileJobFinishCallback {
//--------------------------------------------------------------------------
// TODO(titzer): these should not be part of ParseInfo.
//--------------------------------------------------------------------------
Handle<SharedFunctionInfo> shared_info() const { return shared_; }
Handle<Script> script() const { return script_; }
MaybeHandle<ScopeInfo> maybe_outer_scope_info() const {
return maybe_outer_scope_info_;
}
void clear_script() { script_ = Handle<Script>::null(); }
void set_shared_info(Handle<SharedFunctionInfo> shared) { shared_ = shared; }
void set_outer_scope_info(Handle<ScopeInfo> outer_scope_info) {
maybe_outer_scope_info_ = outer_scope_info;
}
......@@ -243,9 +238,6 @@ class V8_EXPORT_PRIVATE ParseInfo : public CompileJobFinishCallback {
if (!script_.is_null()) {
script_ = Handle<Script>(*script_);
}
if (!shared_.is_null()) {
shared_ = Handle<SharedFunctionInfo>(*shared_);
}
Handle<ScopeInfo> outer_scope_info;
if (maybe_outer_scope_info_.ToHandle(&outer_scope_info)) {
maybe_outer_scope_info_ = Handle<ScopeInfo>(*outer_scope_info);
......@@ -279,6 +271,7 @@ class V8_EXPORT_PRIVATE ParseInfo : public CompileJobFinishCallback {
kDebug = 1 << 9,
kSerializing = 1 << 10,
kAstValueFactoryOwned = 1 << 11,
kCollectTypeProfile = 1 << 12,
};
//------------- Inputs to parsing and scope analysis -----------------------
......@@ -302,7 +295,6 @@ class V8_EXPORT_PRIVATE ParseInfo : public CompileJobFinishCallback {
int max_function_literal_id_;
// TODO(titzer): Move handles out of ParseInfo.
Handle<SharedFunctionInfo> shared_;
Handle<Script> script_;
MaybeHandle<ScopeInfo> maybe_outer_scope_info_;
......
......@@ -749,7 +749,8 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
return result;
}
FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) {
FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
Handle<SharedFunctionInfo> shared_info) {
// It's OK to use the Isolate & counters here, since this function is only
// called in the main thread.
DCHECK(parsing_on_main_thread_);
......@@ -762,7 +763,6 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) {
if (FLAG_trace_parse) {
timer.Start();
}
Handle<SharedFunctionInfo> shared_info = info->shared_info();
DeserializeScopeChain(info, info->maybe_outer_scope_info());
if (info->asm_function_scope()) {
original_scope_ = info->asm_function_scope();
......
......@@ -217,7 +217,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
friend class ParserBase<Parser>;
friend class v8::internal::ExpressionClassifier<ParserTypes<Parser>>;
friend bool v8::internal::parsing::ParseProgram(ParseInfo*, Isolate*, bool);
friend bool v8::internal::parsing::ParseFunction(ParseInfo*, Isolate*, bool);
friend bool v8::internal::parsing::ParseFunction(
ParseInfo*, Handle<SharedFunctionInfo> shared_info, Isolate*, bool);
bool AllowsLazyParsingWithoutUnresolvedVariables() const {
return scope()->AllowsLazyParsingWithoutUnresolvedVariables(
......@@ -265,7 +266,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// Returns NULL if parsing failed.
FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info);
FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info);
FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info,
Handle<SharedFunctionInfo> shared_info);
FunctionLiteral* DoParseFunction(ParseInfo* info);
// Called by ParseProgram after setting up the scanner.
......
......@@ -40,8 +40,10 @@ bool ParseProgram(ParseInfo* info, Isolate* isolate, bool internalize) {
return (result != nullptr);
}
bool ParseFunction(ParseInfo* info, Isolate* isolate, bool internalize) {
bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, bool internalize) {
DCHECK(!info->is_toplevel());
DCHECK(!shared_info.is_null());
DCHECK_NULL(info->literal());
Parser parser(info);
......@@ -50,7 +52,7 @@ bool ParseFunction(ParseInfo* info, Isolate* isolate, bool internalize) {
// Ok to use Isolate here; this function is only called in the main thread.
DCHECK(parser.parsing_on_main_thread_);
result = parser.ParseFunction(isolate, info);
result = parser.ParseFunction(isolate, info, shared_info);
info->set_literal(result);
if (result == nullptr) {
parser.ReportErrors(isolate, info->script());
......@@ -62,9 +64,12 @@ bool ParseFunction(ParseInfo* info, Isolate* isolate, bool internalize) {
return (result != nullptr);
}
bool ParseAny(ParseInfo* info, Isolate* isolate, bool internalize) {
return info->is_toplevel() ? ParseProgram(info, isolate, internalize)
: ParseFunction(info, isolate, internalize);
bool ParseAny(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, bool internalize) {
DCHECK(!shared_info.is_null());
return info->is_toplevel()
? ParseProgram(info, isolate, internalize)
: ParseFunction(info, shared_info, isolate, internalize);
}
} // namespace parsing
......
......@@ -11,6 +11,7 @@ namespace v8 {
namespace internal {
class ParseInfo;
class SharedFunctionInfo;
namespace parsing {
......@@ -21,16 +22,19 @@ namespace parsing {
V8_EXPORT_PRIVATE bool ParseProgram(ParseInfo* info, Isolate* isolate,
bool internalize = true);
// Like ParseProgram but for an individual function. Internalizes AST nodes on
// Like ParseProgram but for an individual function which already has a
// allocated shared function info. Internalizes AST nodes on
// the heap if |internalize|.
V8_EXPORT_PRIVATE bool ParseFunction(ParseInfo* info, Isolate* isolate,
bool internalize = true);
V8_EXPORT_PRIVATE bool ParseFunction(ParseInfo* info,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, bool internalize = true);
// If you don't know whether info->is_toplevel() is true or not, use this method
// to dispatch to either of the above functions. Prefer to use the above methods
// whenever possible. Internalizes AST nodes on the heap if |internalize|.
V8_EXPORT_PRIVATE bool ParseAny(ParseInfo* info, Isolate* isolate,
bool internalize = true);
V8_EXPORT_PRIVATE bool ParseAny(ParseInfo* info,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, bool internalize = true);
} // namespace parsing
} // namespace internal
......
......@@ -397,7 +397,7 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
MessageLocation location;
if (ComputeLocation(isolate, &location)) {
ParseInfo info(location.shared());
if (parsing::ParseAny(&info, isolate)) {
if (parsing::ParseAny(&info, location.shared(), isolate)) {
CallPrinter printer(isolate, location.shared()->IsUserJavaScript());
Handle<String> str = printer.Print(info.literal(), location.start_pos());
*hint = printer.GetIteratorHint();
......
......@@ -139,9 +139,10 @@ Handle<JSFunction> FunctionTester::ForMachineGraph(Graph* graph,
}
Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
ParseInfo parse_info(handle(function->shared()));
Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(),
function);
shared, function);
info.SetOptimizing();
if (flags_ & CompilationInfo::kInliningEnabled) {
......@@ -168,11 +169,13 @@ Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
// Compile the given machine graph instead of the source of the function
// and replace the JSFunction's code with the result.
Handle<JSFunction> FunctionTester::CompileGraph(Graph* graph) {
ParseInfo parse_info(handle(function->shared()));
Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(),
function);
shared, function);
CHECK(parsing::ParseFunction(info.parse_info(), info.isolate()));
CHECK(parsing::ParseFunction(info.parse_info(), info.shared_info(),
info.isolate()));
info.SetOptimizing();
Handle<Code> code = Pipeline::GenerateCodeForTesting(&info, graph);
......
......@@ -45,9 +45,10 @@ static Handle<JSFunction> Compile(const char* source) {
TEST(TestLinkageCreate) {
HandleAndZoneScope handles;
Handle<JSFunction> function = Compile("a + b");
ParseInfo parse_info(handle(function->shared()));
Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(),
function);
shared, function);
CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info);
CHECK(descriptor);
}
......@@ -62,9 +63,10 @@ TEST(TestLinkageJSFunctionIncoming) {
Handle<JSFunction> function =
Handle<JSFunction>::cast(v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(CompileRun(sources[i]))));
ParseInfo parse_info(handle(function->shared()));
Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(),
function);
shared, function);
CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info);
CHECK(descriptor);
......@@ -79,9 +81,10 @@ TEST(TestLinkageJSFunctionIncoming) {
TEST(TestLinkageJSCall) {
HandleAndZoneScope handles;
Handle<JSFunction> function = Compile("a + c");
ParseInfo parse_info(handle(function->shared()));
Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(),
function);
shared, function);
for (int i = 0; i < 32; i++) {
CallDescriptor* descriptor = Linkage::GetJSCallDescriptor(
......
......@@ -33,11 +33,13 @@ struct TestHelper : public HandleAndZoneScope {
void CheckLoopAssignedCount(int expected, const char* var_name) {
// TODO(titzer): don't scope analyze every single time.
ParseInfo parse_info(handle(function->shared()));
Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(),
function);
shared, function);
CHECK(parsing::ParseFunction(&parse_info, info.isolate()));
CHECK(parsing::ParseFunction(&parse_info, info.shared_info(),
info.isolate()));
CHECK(Rewriter::Rewrite(&parse_info, function->GetIsolate()));
DeclarationScope::Analyze(&parse_info, info.isolate(),
AnalyzeMode::kRegular);
......
......@@ -120,10 +120,11 @@ class BytecodeGraphTester {
// TODO(mstarzinger): We should be able to prime CompilationInfo without
// having to instantiate a ParseInfo first. Fix this!
ParseInfo parse_info(handle(function->shared()));
Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared);
CompilationInfo compilation_info(parse_info.zone(), &parse_info,
function->GetIsolate(), function);
function->GetIsolate(), shared, function);
compilation_info.SetOptimizing();
compilation_info.MarkAsDeoptimizationEnabled();
compilation_info.MarkAsOptimizeFromBytecode();
......
......@@ -889,7 +889,7 @@ static void CheckParsesToNumber(const char* source) {
info.set_allow_lazy_parsing(false);
info.set_toplevel(true);
CHECK(i::Compiler::ParseAndAnalyze(&info, isolate));
CHECK(i::parsing::ParseProgram(&info, isolate));
CHECK_EQ(1, info.scope()->declarations()->LengthForTest());
i::Declaration* decl = info.scope()->declarations()->AtForTest(0);
......@@ -3361,7 +3361,7 @@ TEST(InnerAssignment) {
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared());
info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(shared));
CHECK(i::parsing::ParseFunction(info.get(), isolate));
CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
} else {
i::Handle<i::String> source =
factory->InternalizeUtf8String(program.start());
......@@ -3475,7 +3475,7 @@ TEST(MaybeAssignedParameters) {
i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared());
info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(shared));
info->set_allow_lazy_parsing(allow_lazy);
CHECK(i::parsing::ParseFunction(info.get(), isolate));
CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
CHECK(i::Compiler::Analyze(info.get(), isolate));
CHECK_NOT_NULL(info->literal());
......
......@@ -958,7 +958,7 @@ TEST_F(CompilerDispatcherTest, EnqueueParsed) {
Handle<Script> script(Script::cast(shared->script()), i_isolate());
ParseInfo parse_info(shared);
ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info, i_isolate()));
ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info, shared, i_isolate()));
std::shared_ptr<DeferredHandles> handles;
ASSERT_FALSE(dispatcher.IsEnqueued(shared));
......@@ -985,7 +985,7 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStepParsed) {
Handle<Script> script(Script::cast(shared->script()), i_isolate());
ParseInfo parse_info(shared);
ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info, i_isolate()));
ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info, shared, i_isolate()));
std::shared_ptr<DeferredHandles> handles;
ASSERT_FALSE(dispatcher.IsEnqueued(shared));
......@@ -1019,7 +1019,7 @@ TEST_F(CompilerDispatcherTest, CompileParsedOutOfScope) {
ASSERT_FALSE(shared->is_compiled());
ParseInfo parse_info(shared);
ASSERT_TRUE(parsing::ParseAny(&parse_info, i_isolate()));
ASSERT_TRUE(parsing::ParseAny(&parse_info, shared, i_isolate()));
DeferredHandleScope handles_scope(i_isolate());
{ ASSERT_TRUE(Compiler::Analyze(&parse_info, i_isolate())); }
std::shared_ptr<DeferredHandles> compilation_handles(
......@@ -1086,7 +1086,7 @@ TEST_F(CompilerDispatcherTestWithoutContext, CompileExtensionWithoutContext) {
ParseInfo parse_info(script);
parse_info.set_extension(&extension);
ASSERT_TRUE(parsing::ParseAny(&parse_info, i_isolate()));
ASSERT_TRUE(parsing::ParseProgram(&parse_info, i_isolate()));
Handle<FixedArray> shared_infos_array(i_isolate()->factory()->NewFixedArray(
parse_info.max_function_literal_id() + 1));
parse_info.script()->set_shared_function_infos(*shared_infos_array);
......@@ -1097,7 +1097,6 @@ TEST_F(CompilerDispatcherTestWithoutContext, CompileExtensionWithoutContext) {
shared = i_isolate()->factory()->NewSharedFunctionInfoForLiteral(
parse_info.literal(), script);
parse_info.set_shared_info(shared);
ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(dispatcher.Enqueue(
......@@ -1175,7 +1174,7 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStepTwice) {
Handle<Script> script(Script::cast(shared->script()), i_isolate());
ParseInfo parse_info(shared);
ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info, i_isolate()));
ASSERT_TRUE(Compiler::ParseAndAnalyze(&parse_info, shared, i_isolate()));
std::shared_ptr<DeferredHandles> handles;
ASSERT_FALSE(dispatcher.IsEnqueued(shared));
......
......@@ -28,8 +28,9 @@ class BlockingCompilationJob : public CompilationJob {
BlockingCompilationJob(Isolate* isolate, Handle<JSFunction> function)
: CompilationJob(isolate, &info_, "BlockingCompilationJob",
State::kReadyToExecute),
parse_info_(handle(function->shared())),
info_(parse_info_.zone(), &parse_info_, function->GetIsolate(),
shared_(function->shared()),
parse_info_(shared_),
info_(parse_info_.zone(), &parse_info_, function->GetIsolate(), shared_,
function),
blocking_(false),
semaphore_(0) {}
......@@ -53,6 +54,7 @@ class BlockingCompilationJob : public CompilationJob {
Status FinalizeJobImpl() override { return SUCCEEDED; }
private:
Handle<SharedFunctionInfo> shared_;
ParseInfo parse_info_;
CompilationInfo info_;
base::AtomicValue<bool> blocking_;
......
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