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

[Compiler] Move Ast value internalization until compile finalization.

Moves parser internalization of ast values out of 
ParseAny/Program/Function and instead internalizes during compile 
finalization. Currently also internalizes during scope analysis if
there is a ScopeInfo to enable variable name lookups. We also 
internalize early for FCG / AstGraphBuilder.

BUG=v8:5203

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: Ia766795947d847517b87cd5ea39797347083174b
Reviewed-on: https://chromium-review.googlesource.com/582407Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46904}
parent 7a0898c7
......@@ -2533,15 +2533,7 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
}
source->parser->UpdateStatistics(isolate, script);
source->info->UpdateStatisticsAfterBackgroundParse(isolate);
i::DeferredHandleScope deferred_handle_scope(isolate);
{
// Internalize AST values on the main thread.
source->info->ReopenHandlesInNewHandleScope();
source->info->ast_value_factory()->Internalize(isolate);
source->parser->HandleSourceURLComments(isolate, script);
}
source->info->set_deferred_handles(deferred_handle_scope.Detach());
source->parser->HandleSourceURLComments(isolate, script);
i::Handle<i::SharedFunctionInfo> result;
if (source->info->literal() != nullptr) {
......
......@@ -631,6 +631,10 @@ void DeclarationScope::Analyze(ParseInfo* info, Isolate* isolate) {
Handle<ScopeInfo> outer_scope_info;
if (info->maybe_outer_scope_info().ToHandle(&outer_scope_info)) {
// If we have a scope info we will potentially need to lookup variable names
// on the scope info as internalized strings, so make sure ast_value_factory
// is internalized.
info->ast_value_factory()->Internalize(isolate);
if (scope->outer_scope()) {
DeclarationScope* script_scope = new (info->zone())
DeclarationScope(info->zone(), info->ast_value_factory());
......
......@@ -134,8 +134,7 @@ CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate,
CompilerDispatcherJob::CompilerDispatcherJob(
Isolate* isolate, CompilerDispatcherTracer* tracer, Handle<Script> script,
Handle<SharedFunctionInfo> shared, FunctionLiteral* literal,
std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
ParseInfo* outer_parse_info,
std::shared_ptr<DeferredHandles> compile_handles, size_t max_stack_size)
: status_(CompileJobStatus::kAnalyzed),
isolate_(isolate),
......@@ -144,14 +143,15 @@ CompilerDispatcherJob::CompilerDispatcherJob(
shared_(isolate_->global_handles()->Create(*shared)),
max_stack_size_(max_stack_size),
parse_info_(new ParseInfo(shared_)),
parse_zone_(parse_zone),
compile_info_(new CompilationInfo(parse_info_->zone(), parse_info_.get(),
compile_zone_(new Zone(isolate->allocator(), ZONE_NAME)),
compile_info_(new CompilationInfo(compile_zone_.get(), parse_info_.get(),
isolate_, shared_,
Handle<JSFunction>::null())),
trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
parse_info_->set_literal(literal);
parse_info_->set_script(script);
parse_info_->set_deferred_handles(parse_handles);
parse_info_->ShareAstValueFactory(outer_parse_info);
parse_info_->ShareZone(outer_parse_info);
compile_info_->set_deferred_handles(compile_handles);
if (trace_compiler_dispatcher_jobs_) {
......@@ -389,28 +389,20 @@ void CompilerDispatcherJob::FinalizeParsingOnMainThread() {
parser_->UpdateStatistics(isolate_, script);
parse_info_->UpdateStatisticsAfterBackgroundParse(isolate_);
DeferredHandleScope scope(isolate_);
{
parse_info_->ReopenHandlesInNewHandleScope();
if (!shared_->outer_scope_info()->IsTheHole(isolate_) &&
ScopeInfo::cast(shared_->outer_scope_info())->length() > 0) {
Handle<ScopeInfo> outer_scope_info(
handle(ScopeInfo::cast(shared_->outer_scope_info())));
parse_info_->set_outer_scope_info(outer_scope_info);
}
if (!shared_->outer_scope_info()->IsTheHole(isolate_) &&
ScopeInfo::cast(shared_->outer_scope_info())->length() > 0) {
Handle<ScopeInfo> outer_scope_info(
handle(ScopeInfo::cast(shared_->outer_scope_info())));
parse_info_->set_outer_scope_info(outer_scope_info);
}
// Internalize ast values on the main thread.
parse_info_->ast_value_factory()->Internalize(isolate_);
parser_->HandleSourceURLComments(isolate_, script);
parser_->HandleSourceURLComments(isolate_, script);
parse_info_->set_character_stream(nullptr);
parse_info_->set_unicode_cache(nullptr);
parser_.reset();
unicode_cache_.reset();
character_stream_.reset();
}
parse_info_->set_deferred_handles(scope.Detach());
parse_info_->set_character_stream(nullptr);
parse_info_->set_unicode_cache(nullptr);
parser_.reset();
unicode_cache_.reset();
character_stream_.reset();
}
void CompilerDispatcherJob::AnalyzeOnMainThread() {
......@@ -421,8 +413,9 @@ void CompilerDispatcherJob::AnalyzeOnMainThread() {
PrintF("CompilerDispatcherJob[%p]: Analyzing\n", static_cast<void*>(this));
}
compile_zone_.reset(new Zone(isolate_->allocator(), ZONE_NAME));
compile_info_.reset(new CompilationInfo(
parse_info_->zone(), parse_info_.get(), isolate_,
compile_zone_.get(), parse_info_.get(), isolate_,
Handle<SharedFunctionInfo>::null(), Handle<JSFunction>::null()));
DeferredHandleScope scope(isolate_);
......@@ -498,7 +491,7 @@ void CompilerDispatcherJob::FinalizeCompilingOnMainThread() {
compile_job_.reset();
compile_info_.reset();
parse_zone_.reset();
compile_zone_.reset();
parse_info_.reset();
status_ = CompileJobStatus::kDone;
......@@ -511,7 +504,7 @@ void CompilerDispatcherJob::ResetOnMainThread() {
compile_job_.reset();
compile_info_.reset();
parse_zone_.reset();
compile_zone_.reset();
parser_.reset();
unicode_cache_.reset();
character_stream_.reset();
......
......@@ -69,9 +69,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
CompilerDispatcherJob(Isolate* isolate, CompilerDispatcherTracer* tracer,
Handle<Script> script,
Handle<SharedFunctionInfo> shared,
FunctionLiteral* literal,
std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
FunctionLiteral* literal, ParseInfo* outer_parse_info,
std::shared_ptr<DeferredHandles> compile_handles,
size_t max_stack_size);
~CompilerDispatcherJob();
......@@ -139,10 +137,8 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
std::unique_ptr<ParseInfo> parse_info_;
std::unique_ptr<Parser> parser_;
// Members required for compiling a parsed function.
std::shared_ptr<Zone> parse_zone_;
// Members required for compiling.
std::unique_ptr<Zone> compile_zone_;
std::unique_ptr<CompilationInfo> compile_info_;
std::unique_ptr<CompilationJob> compile_job_;
......
......@@ -326,8 +326,7 @@ bool CompilerDispatcher::EnqueueAndStep(Handle<SharedFunctionInfo> function) {
bool CompilerDispatcher::Enqueue(
Handle<Script> script, Handle<SharedFunctionInfo> function,
FunctionLiteral* literal, std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
FunctionLiteral* literal, ParseInfo* outer_parse_info,
std::shared_ptr<DeferredHandles> compile_handles) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompilerDispatcherEnqueue");
......@@ -341,16 +340,15 @@ bool CompilerDispatcher::Enqueue(
}
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
isolate_, tracer_.get(), script, function, literal, parse_zone,
parse_handles, compile_handles, max_stack_size_));
isolate_, tracer_.get(), script, function, literal, outer_parse_info,
compile_handles, max_stack_size_));
Enqueue(std::move(job));
return true;
}
bool CompilerDispatcher::EnqueueAndStep(
Handle<Script> script, Handle<SharedFunctionInfo> function,
FunctionLiteral* literal, std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
FunctionLiteral* literal, ParseInfo* outer_parse_info,
std::shared_ptr<DeferredHandles> compile_handles) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompilerDispatcherEnqueueAndStep");
......@@ -364,8 +362,8 @@ bool CompilerDispatcher::EnqueueAndStep(
}
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
isolate_, tracer_.get(), script, function, literal, parse_zone,
parse_handles, compile_handles, max_stack_size_));
isolate_, tracer_.get(), script, function, literal, outer_parse_info,
compile_handles, max_stack_size_));
EnqueueAndStep(std::move(job));
return true;
}
......
......@@ -27,6 +27,7 @@ enum class MemoryPressureLevel;
namespace internal {
class AstValueFactory;
class CancelableTaskManager;
class CompileJobFinishCallback;
class CompilerDispatcherJob;
......@@ -34,6 +35,7 @@ class CompilerDispatcherTracer;
class DeferredHandles;
class FunctionLiteral;
class Isolate;
class ParseInfo;
class SharedFunctionInfo;
class Zone;
......@@ -96,8 +98,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
// Enqueue a job for compilation. Function must have already been parsed and
// analyzed and be ready for compilation. Returns true if a job was enqueued.
bool Enqueue(Handle<Script> script, Handle<SharedFunctionInfo> function,
FunctionLiteral* literal, std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
FunctionLiteral* literal, ParseInfo* outer_parse_info,
std::shared_ptr<DeferredHandles> compile_handles);
// Like Enqueue, but also advances the job so that it can potentially
......@@ -105,9 +106,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
// true if the job was enqueued.
bool EnqueueAndStep(Handle<Script> script,
Handle<SharedFunctionInfo> function,
FunctionLiteral* literal,
std::shared_ptr<Zone> parse_zone,
std::shared_ptr<DeferredHandles> parse_handles,
FunctionLiteral* literal, ParseInfo* outer_parse_info,
std::shared_ptr<DeferredHandles> compile_handles);
// Returns true if there is a pending job for the given function.
......
......@@ -42,19 +42,6 @@
namespace v8 {
namespace internal {
// A wrapper around a ParseInfo that detaches the parser handles from the
// underlying DeferredHandleScope and stores them in info_ on destruction.
class ParseHandleScope final {
public:
explicit ParseHandleScope(ParseInfo* info, Isolate* isolate)
: deferred_(isolate), info_(info) {}
~ParseHandleScope() { info_->set_deferred_handles(deferred_.Detach()); }
private:
DeferredHandleScope deferred_;
ParseInfo* info_;
};
// A wrapper around a CompilationInfo that detaches the Handles from
// the underlying DeferredHandleScope and stores them in info_ on
// destruction.
......@@ -404,6 +391,9 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) {
ParseInfo* parse_info = info->parse_info();
Isolate* isolate = info->isolate();
// Internalize ast values onto the heap.
parse_info->ast_value_factory()->Internalize(isolate);
// Allocate scope infos for the literal.
DeclarationScope::AllocateScopeInfos(parse_info, isolate,
AnalyzeMode::kRegular);
......@@ -464,8 +454,7 @@ bool GenerateUnoptimizedCode(CompilationInfo* info) {
bool CompileUnoptimizedInnerFunctions(
Compiler::EagerInnerFunctionLiterals* literals,
ConcurrencyMode inner_function_mode, std::shared_ptr<Zone> parse_zone,
CompilationInfo* outer_info) {
ConcurrencyMode inner_function_mode, CompilationInfo* outer_info) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompileUnoptimizedInnerFunctions");
Isolate* isolate = outer_info->isolate();
......@@ -486,8 +475,7 @@ bool CompileUnoptimizedInnerFunctions(
if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(),
shared, is_debug, will_serialize) &&
dispatcher->EnqueueAndStep(outer_info->script(), shared, literal,
parse_zone,
outer_info->parse_info()->deferred_handles(),
outer_info->parse_info(),
outer_info->deferred_handles())) {
// If we have successfully queued up the function for compilation on the
// compiler dispatcher then we are done.
......@@ -547,9 +535,14 @@ bool CompileUnoptimizedCode(CompilationInfo* info,
InnerFunctionShouldUseFullCodegen(&inner_literals)) {
inner_function_mode = ConcurrencyMode::kNotConcurrent;
// If we might compile with full-codegen internalize now, otherwise
// we internalize when finalizing compilation.
info->parse_info()->ast_value_factory()->Internalize(info->isolate());
// Full-codegen needs to access ScopeInfos when compiling, so allocate now.
DeclarationScope::AllocateScopeInfos(info->parse_info(), isolate,
AnalyzeMode::kRegular);
if (info->parse_info()->is_toplevel()) {
// Full-codegen needs to access SFI when compiling, so allocate the array
// now.
......@@ -557,18 +550,16 @@ bool CompileUnoptimizedCode(CompilationInfo* info,
}
}
std::shared_ptr<Zone> parse_zone;
if (inner_function_mode == ConcurrencyMode::kConcurrent) {
// Seal the parse zone so that it can be shared by parallel inner function
// compilation jobs.
DCHECK_NE(info->parse_info()->zone(), info->zone());
parse_zone = info->parse_info()->zone_shared();
parse_zone->Seal();
info->parse_info()->zone()->Seal();
}
if (!GenerateUnoptimizedCode(info) ||
!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode,
parse_zone, info)) {
info)) {
if (!isolate->has_pending_exception()) isolate->StackOverflow();
return false;
}
......@@ -585,18 +576,9 @@ MUST_USE_RESULT MaybeHandle<Code> CompileUnoptimizedFunction(
PostponeInterruptsScope postpone(info->isolate());
// Parse and update ParseInfo with the results.
{
if (!parsing::ParseFunction(
info->parse_info(), shared_info, info->isolate(),
inner_function_mode != ConcurrencyMode::kConcurrent)) {
return MaybeHandle<Code>();
}
if (inner_function_mode == ConcurrencyMode::kConcurrent) {
ParseHandleScope parse_handles(info->parse_info(), info->isolate());
info->parse_info()->ReopenHandlesInNewHandleScope();
info->parse_info()->ast_value_factory()->Internalize(info->isolate());
}
if (!parsing::ParseFunction(info->parse_info(), shared_info,
info->isolate())) {
return MaybeHandle<Code>();
}
// Compile either unoptimized code or bytecode for the interpreter.
......@@ -677,6 +659,7 @@ bool GetOptimizedCodeNow(CompilationJob* job) {
// Parsing is not required when optimizing from existing bytecode.
if (!info->is_optimizing_from_bytecode()) {
if (!Compiler::ParseAndAnalyze(info)) return false;
info->parse_info()->ast_value_factory()->Internalize(isolate);
DeclarationScope::AllocateScopeInfos(info->parse_info(), isolate,
AnalyzeMode::kRegular);
EnsureFeedbackMetadata(info);
......@@ -732,6 +715,7 @@ bool GetOptimizedCodeLater(CompilationJob* job) {
// Parsing is not required when optimizing from existing bytecode.
if (!info->is_optimizing_from_bytecode()) {
if (!Compiler::ParseAndAnalyze(info)) return false;
info->parse_info()->ast_value_factory()->Internalize(isolate);
DeclarationScope::AllocateScopeInfos(info->parse_info(), isolate,
AnalyzeMode::kRegular);
EnsureFeedbackMetadata(info);
......@@ -1036,18 +1020,9 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
Handle<SharedFunctionInfo> result;
{ VMState<COMPILER> state(info->isolate());
if (parse_info->literal() == nullptr) {
if (!parsing::ParseProgram(
parse_info, info->isolate(),
inner_function_mode != ConcurrencyMode::kConcurrent)) {
return Handle<SharedFunctionInfo>::null();
}
if (inner_function_mode == ConcurrencyMode::kConcurrent) {
ParseHandleScope parse_handles(parse_info, info->isolate());
parse_info->ReopenHandlesInNewHandleScope();
parse_info->ast_value_factory()->Internalize(info->isolate());
}
if (parse_info->literal() == nullptr &&
!parsing::ParseProgram(parse_info, info->isolate())) {
return Handle<SharedFunctionInfo>::null();
}
// Measure how long it takes to do the compilation; only take the
......@@ -1083,7 +1058,7 @@ bool Compiler::Analyze(ParseInfo* info, Isolate* isolate,
DCHECK_NOT_NULL(info->literal());
RuntimeCallTimerScope runtimeTimer(isolate,
&RuntimeCallStats::CompileAnalyse);
if (!Rewriter::Rewrite(info, isolate)) return false;
if (!Rewriter::Rewrite(info)) return false;
DeclarationScope::Analyze(info, isolate);
if (!Renumber(info, eager_literals)) {
return false;
......
......@@ -115,7 +115,8 @@ void ScopeIterator::TryParseAndRetrieveScopes(ScopeIterator::Option option) {
info.reset(new ParseInfo(shared_info));
}
if (parsing::ParseAny(info.get(), shared_info, isolate_) &&
Rewriter::Rewrite(info.get(), isolate_)) {
Rewriter::Rewrite(info.get())) {
info->ast_value_factory()->Internalize(isolate_);
DeclarationScope* scope = info->literal()->scope();
if (!ignore_nested_scopes || collect_non_locals) {
CollectNonLocals(info.get(), scope);
......
......@@ -41,8 +41,7 @@ ParseInfo::ParseInfo(AccountingAllocator* zone_allocator)
function_name_(nullptr),
runtime_call_stats_(nullptr),
source_range_map_(nullptr),
literal_(nullptr),
deferred_handles_(nullptr) {}
literal_(nullptr) {}
ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared)
: ParseInfo(shared->GetIsolate()->allocator()) {
......@@ -138,17 +137,6 @@ FunctionKind ParseInfo::function_kind() const {
return SharedFunctionInfo::FunctionKindBits::decode(compiler_hints_);
}
void ParseInfo::set_deferred_handles(
std::shared_ptr<DeferredHandles> deferred_handles) {
DCHECK(deferred_handles_.get() == nullptr);
deferred_handles_.swap(deferred_handles);
}
void ParseInfo::set_deferred_handles(DeferredHandles* deferred_handles) {
DCHECK(deferred_handles_.get() == nullptr);
deferred_handles_.reset(deferred_handles);
}
void ParseInfo::InitFromIsolate(Isolate* isolate) {
DCHECK_NOT_NULL(isolate);
set_hash_seed(isolate->heap()->HashSeed());
......@@ -193,6 +181,11 @@ std::map<int, ParseInfo*> ParseInfo::child_infos() const {
return rv;
}
void ParseInfo::ShareZone(ParseInfo* other) {
DCHECK_EQ(0, zone_->allocation_size());
zone_ = other->zone_;
}
AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
if (!ast_value_factory_.get()) {
ast_value_factory_.reset(
......
......@@ -26,7 +26,6 @@ class AstRawString;
class AstStringConstants;
class AstValueFactory;
class DeclarationScope;
class DeferredHandles;
class FunctionLiteral;
class RuntimeCallStats;
class ScriptData;
......@@ -52,18 +51,13 @@ class V8_EXPORT_PRIVATE ParseInfo : public CompileJobFinishCallback {
// creates and returns a new factory if none exists.
AstValueFactory* GetOrCreateAstValueFactory();
// Sets this parse info to share the same ast value factory as |other|.
void ShareAstValueFactory(ParseInfo* other);
Zone* zone() const { return zone_.get(); }
std::shared_ptr<Zone> zone_shared() const { return zone_; }
// Sets this parse info to share the same zone as |other|
void ShareZone(ParseInfo* other);
void set_deferred_handles(std::shared_ptr<DeferredHandles> deferred_handles);
void set_deferred_handles(DeferredHandles* deferred_handles);
std::shared_ptr<DeferredHandles> deferred_handles() const {
return deferred_handles_;
}
// Sets this parse info to share the same ast value factory as |other|
void ShareAstValueFactory(ParseInfo* other);
// Convenience accessor methods for flags.
#define FLAG_ACCESSOR(flag, getter, setter) \
......
......@@ -216,9 +216,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
private:
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::ParseProgram(ParseInfo*, Isolate*);
friend bool v8::internal::parsing::ParseFunction(
ParseInfo*, Handle<SharedFunctionInfo> shared_info, Isolate*, bool);
ParseInfo*, Handle<SharedFunctionInfo> shared_info, Isolate*);
bool AllowsLazyParsingWithoutUnresolvedVariables() const {
return scope()->AllowsLazyParsingWithoutUnresolvedVariables(
......
......@@ -15,7 +15,7 @@ namespace v8 {
namespace internal {
namespace parsing {
bool ParseProgram(ParseInfo* info, Isolate* isolate, bool internalize) {
bool ParseProgram(ParseInfo* info, Isolate* isolate) {
DCHECK(info->is_toplevel());
DCHECK_NULL(info->literal());
......@@ -34,14 +34,11 @@ bool ParseProgram(ParseInfo* info, Isolate* isolate, bool internalize) {
info->set_language_mode(info->literal()->language_mode());
}
parser.UpdateStatistics(isolate, info->script());
if (internalize) {
info->ast_value_factory()->Internalize(isolate);
}
return (result != nullptr);
}
bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, bool internalize) {
Isolate* isolate) {
DCHECK(!info->is_toplevel());
DCHECK(!shared_info.is_null());
DCHECK_NULL(info->literal());
......@@ -58,18 +55,14 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
parser.ReportErrors(isolate, info->script());
}
parser.UpdateStatistics(isolate, info->script());
if (internalize) {
info->ast_value_factory()->Internalize(isolate);
}
return (result != nullptr);
}
bool ParseAny(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, bool internalize) {
Isolate* isolate) {
DCHECK(!shared_info.is_null());
return info->is_toplevel()
? ParseProgram(info, isolate, internalize)
: ParseFunction(info, shared_info, isolate, internalize);
return info->is_toplevel() ? ParseProgram(info, isolate)
: ParseFunction(info, shared_info, isolate);
}
} // namespace parsing
......
......@@ -17,24 +17,21 @@ namespace parsing {
// Parses the top-level source code represented by the parse info and sets its
// function literal. Returns false (and deallocates any allocated AST
// nodes) if parsing failed. Internalizes AST nodes on the heap if
// |internalize|.
V8_EXPORT_PRIVATE bool ParseProgram(ParseInfo* info, Isolate* isolate,
bool internalize = true);
// nodes) if parsing failed.
V8_EXPORT_PRIVATE bool ParseProgram(ParseInfo* info, Isolate* isolate);
// Like ParseProgram but for an individual function which already has a
// allocated shared function info. Internalizes AST nodes on
// the heap if |internalize|.
// allocated shared function info.
V8_EXPORT_PRIVATE bool ParseFunction(ParseInfo* info,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, bool internalize = true);
Isolate* isolate);
// 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|.
// whenever possible.
V8_EXPORT_PRIVATE bool ParseAny(ParseInfo* info,
Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, bool internalize = true);
Isolate* isolate);
} // namespace parsing
} // namespace internal
......
......@@ -352,7 +352,7 @@ DECLARATION_NODE_LIST(DEF_VISIT)
// Assumes code has been parsed. Mutates the AST, so the AST should not
// continue to be used in the case of failure.
bool Rewriter::Rewrite(ParseInfo* info, Isolate* isolate) {
bool Rewriter::Rewrite(ParseInfo* info) {
DisallowHeapAllocation no_allocation;
DisallowHandleAllocation no_handles;
DisallowHandleDereference no_deref;
......@@ -391,15 +391,6 @@ bool Rewriter::Rewrite(ParseInfo* info, Isolate* isolate) {
body->Add(result_statement, info->zone());
}
// TODO(leszeks): Remove this check and releases once internalization is
// moved out of parsing/analysis. Also remove the parameter once done.
DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
no_deref.Release();
no_handles.Release();
no_allocation.Release();
// Internalize any values created during rewriting.
info->ast_value_factory()->Internalize(isolate);
if (processor.HasStackOverflow()) return false;
}
......
......@@ -24,7 +24,7 @@ class Rewriter {
//
// Assumes code has been parsed and scopes have been analyzed. Mutates the
// AST, so the AST should not continue to be used in the case of failure.
static bool Rewrite(ParseInfo* info, Isolate* isolate);
static bool Rewrite(ParseInfo* info);
// Rewrite a list of statements, using the same rules as a top-level program,
// to ensure identical behaviour of completion result. The temporary is added
......
......@@ -398,6 +398,7 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
if (ComputeLocation(isolate, &location)) {
ParseInfo info(location.shared());
if (parsing::ParseAny(&info, location.shared(), isolate)) {
info.ast_value_factory()->Internalize(isolate);
CallPrinter printer(isolate, location.shared()->IsUserJavaScript());
Handle<String> str = printer.Print(info.literal(), location.start_pos());
*hint = printer.GetIteratorHint();
......
......@@ -155,6 +155,7 @@ Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
info.MarkAsOptimizeFromBytecode();
} else {
CHECK(Compiler::ParseAndAnalyze(&info));
parse_info.ast_value_factory()->Internalize(info.isolate());
}
JSFunction::EnsureLiterals(function);
......
......@@ -40,7 +40,7 @@ struct TestHelper : public HandleAndZoneScope {
CHECK(parsing::ParseFunction(&parse_info, info.shared_info(),
info.isolate()));
CHECK(Rewriter::Rewrite(&parse_info, function->GetIsolate()));
CHECK(Rewriter::Rewrite(&parse_info));
DeclarationScope::Analyze(&parse_info, info.isolate());
DeclarationScope* scope = info.literal()->scope();
......
......@@ -833,7 +833,8 @@ TEST(ScopeUsesArgumentsSuperThis) {
// The information we're checking is only produced when eager parsing.
info.set_allow_lazy_parsing(false);
CHECK(i::parsing::ParseProgram(&info, isolate));
CHECK(i::Rewriter::Rewrite(&info, isolate));
CHECK(i::Rewriter::Rewrite(&info));
info.ast_value_factory()->Internalize(isolate);
i::DeclarationScope::Analyze(&info, isolate);
i::DeclarationScope::AllocateScopeInfos(&info, isolate,
i::AnalyzeMode::kRegular);
......@@ -10268,7 +10269,7 @@ TEST(LexicalLoopVariable) {
info.set_allow_lazy_parsing(false);
CHECK(i::parsing::ParseProgram(&info, isolate));
CHECK(i::Rewriter::Rewrite(&info, isolate));
CHECK(i::Rewriter::Rewrite(&info));
i::DeclarationScope::Analyze(&info, isolate);
i::DeclarationScope::AllocateScopeInfos(&info, isolate,
i::AnalyzeMode::kRegular);
......
......@@ -8,6 +8,7 @@
#include "include/v8-platform.h"
#include "src/api.h"
#include "src/ast/ast-value-factory.h"
#include "src/base/platform/semaphore.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h"
#include "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
......@@ -963,7 +964,7 @@ TEST_F(CompilerDispatcherTest, EnqueueParsed) {
ASSERT_FALSE(dispatcher.IsEnqueued(shared));
ASSERT_TRUE(dispatcher.Enqueue(script, shared, parse_info.literal(),
parse_info.zone_shared(), handles, handles));
&parse_info, handles));
ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_EQ(CompileJobStatus::kAnalyzed,
......@@ -990,8 +991,7 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStepParsed) {
ASSERT_FALSE(dispatcher.IsEnqueued(shared));
ASSERT_TRUE(dispatcher.EnqueueAndStep(script, shared, parse_info.literal(),
parse_info.zone_shared(), handles,
handles));
&parse_info, handles));
ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_EQ(CompileJobStatus::kReadyToCompile,
......@@ -1017,8 +1017,8 @@ TEST_F(CompilerDispatcherTest, CompileParsedOutOfScope) {
HandleScope scope(i_isolate()); // Create handles scope for parsing.
ASSERT_FALSE(shared->is_compiled());
ParseInfo parse_info(shared);
ParseInfo parse_info(shared);
DeferredHandleScope handles_scope(i_isolate());
ASSERT_TRUE(parsing::ParseAny(&parse_info, shared, i_isolate()));
{ ASSERT_TRUE(Compiler::Analyze(&parse_info, i_isolate())); }
......@@ -1026,9 +1026,8 @@ TEST_F(CompilerDispatcherTest, CompileParsedOutOfScope) {
handles_scope.Detach());
ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(dispatcher.Enqueue(
script, shared, parse_info.literal(), parse_info.zone_shared(),
parse_info.deferred_handles(), compilation_handles));
ASSERT_TRUE(dispatcher.Enqueue(script, shared, parse_info.literal(),
&parse_info, compilation_handles));
ASSERT_TRUE(platform.IdleTaskPending());
}
// Exit the handles scope and destroy ParseInfo before running the idle task.
......@@ -1078,7 +1077,6 @@ TEST_F(CompilerDispatcherTestWithoutContext, CompileExtensionWithoutContext) {
.ToHandleChecked();
Handle<Script> script = i_isolate()->factory()->NewScript(script_str);
script->set_type(Script::TYPE_EXTENSION);
Handle<SharedFunctionInfo> shared;
{
v8::Context::Scope scope(context);
......@@ -1094,14 +1092,14 @@ TEST_F(CompilerDispatcherTestWithoutContext, CompileExtensionWithoutContext) {
{ ASSERT_TRUE(Compiler::Analyze(&parse_info, i_isolate())); }
std::shared_ptr<DeferredHandles> compilation_handles(
handles_scope.Detach());
parse_info.ast_value_factory()->Internalize(i_isolate());
shared = i_isolate()->factory()->NewSharedFunctionInfoForLiteral(
parse_info.literal(), script);
ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(dispatcher.Enqueue(
script, shared, parse_info.literal(), parse_info.zone_shared(),
parse_info.deferred_handles(), compilation_handles));
ASSERT_TRUE(dispatcher.Enqueue(script, shared, parse_info.literal(),
&parse_info, compilation_handles));
ASSERT_TRUE(platform.IdleTaskPending());
}
// Exit the context scope before running the idle task.
......@@ -1179,8 +1177,7 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStepTwice) {
ASSERT_FALSE(dispatcher.IsEnqueued(shared));
ASSERT_TRUE(dispatcher.EnqueueAndStep(script, shared, parse_info.literal(),
parse_info.zone_shared(), handles,
handles));
&parse_info, handles));
ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_EQ(CompileJobStatus::kReadyToCompile,
......@@ -1189,8 +1186,7 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStepTwice) {
// EnqueueAndStep of the same function again (either already parsed or for
// compile and parse) shouldn't step the job.
ASSERT_TRUE(dispatcher.EnqueueAndStep(script, shared, parse_info.literal(),
parse_info.zone_shared(), handles,
handles));
&parse_info, handles));
ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_EQ(CompileJobStatus::kReadyToCompile,
GetJobStatus(dispatcher.jobs_.begin()->second));
......
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