Commit df0cb999 authored by marja's avatar marja Committed by Commit bot

Parsing: Make Parser not know about Isolate during background parsing.

Parser must be able to operate independent of Isolate and the V8 heap during
parsing. After the heap-independent phase, there is a heap dependent phase,
during which we internalize strings, handle errors, etc.

This makes Isolate (also via CompilationInfo) unaccessible during parsing, and
thus decreases the probability of accidental code changes which would add
heap-dependent operations into the heap-independent phase.

Since Isolate is also accessible via CompilationInfo, now CompilationInfo is
only passed to the entry points of parsing, and not stored in Parser.

R=rossberg@chromium.org
BUG=

Review URL: https://codereview.chromium.org/908173003

Cr-Commit-Position: refs/heads/master@{#26612}
parent 3336d2e1
......@@ -1727,8 +1727,8 @@ Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
// Do the parsing tasks which need to be done on the main thread. This will
// also handle parse errors.
source->parser->Internalize();
source->parser->HandleSourceURLComments();
source->parser->Internalize(source->info.get());
source->parser->HandleSourceURLComments(source->info.get());
i::Handle<i::SharedFunctionInfo> result =
i::Handle<i::SharedFunctionInfo>::null();
......
......@@ -54,7 +54,7 @@ void BackgroundParsingTask::Run() {
source_->hash_seed,
&source_->unicode_cache));
source_->parser->set_allow_lazy(source_->allow_lazy);
source_->parser->ParseOnBackground();
source_->parser->ParseOnBackground(source_->info.get());
if (script_data != NULL) {
source_->cached_data.Reset(new ScriptCompiler::CachedData(
......
......@@ -645,7 +645,7 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
PostponeInterruptsScope postpone(info->isolate());
// Parse and update CompilationInfo with the results.
if (!Parser::Parse(info)) return MaybeHandle<Code>();
if (!Parser::ParseStatic(info)) return MaybeHandle<Code>();
Handle<SharedFunctionInfo> shared = info->shared_info();
FunctionLiteral* lit = info->function();
shared->set_language_mode(lit->language_mode());
......@@ -817,7 +817,7 @@ bool Compiler::Analyze(CompilationInfo* info) {
bool Compiler::ParseAndAnalyze(CompilationInfo* info) {
if (!Parser::Parse(info)) return false;
if (!Parser::ParseStatic(info)) return false;
return Compiler::Analyze(info);
}
......@@ -1058,7 +1058,7 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) {
VMState<COMPILER> state(info.isolate());
info.MarkAsGlobal();
if (!Parser::Parse(&info)) return;
if (!Parser::ParseStatic(&info)) return;
LiveEditFunctionTracker tracker(info.isolate(), info.function());
if (!CompileUnoptimizedCode(&info)) return;
......@@ -1108,7 +1108,7 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
// data while parsing eagerly is not implemented.
info->SetCachedData(NULL, ScriptCompiler::kNoCompileOptions);
}
if (!Parser::Parse(info, parse_allow_lazy)) {
if (!Parser::ParseStatic(info, parse_allow_lazy)) {
return Handle<SharedFunctionInfo>::null();
}
}
......
This diff is collapsed.
......@@ -647,14 +647,14 @@ class Parser : public ParserBase<ParserTraits> {
// Parses the source code represented by the compilation info and sets its
// function literal. Returns false (and deallocates any allocated AST
// nodes) if parsing failed.
static bool Parse(CompilationInfo* info, bool allow_lazy = false);
bool Parse();
void ParseOnBackground();
static bool ParseStatic(CompilationInfo* info, bool allow_lazy = false);
bool Parse(CompilationInfo* info);
void ParseOnBackground(CompilationInfo* info);
// Handle errors detected during parsing, move statistics to Isolate,
// internalize strings (move them to the heap).
void Internalize();
void HandleSourceURLComments();
void Internalize(CompilationInfo* info);
void HandleSourceURLComments(CompilationInfo* info);
private:
friend class ParserTraits;
......@@ -681,31 +681,28 @@ class Parser : public ParserBase<ParserTraits> {
};
// Returns NULL if parsing failed.
FunctionLiteral* ParseProgram();
FunctionLiteral* ParseProgram(CompilationInfo* info);
FunctionLiteral* ParseLazy();
FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
Isolate* isolate() { return info_->isolate(); }
CompilationInfo* info() const { return info_; }
Handle<Script> script() const { return info_->script(); }
FunctionLiteral* ParseLazy(CompilationInfo* info);
FunctionLiteral* ParseLazy(CompilationInfo* info,
Utf16CharacterStream* source);
// Called by ParseProgram after setting up the scanner.
FunctionLiteral* DoParseProgram(CompilationInfo* info, Scope** scope,
Scope** ad_hoc_eval_scope);
void SetCachedData();
void SetCachedData(CompilationInfo* info);
bool inside_with() const { return scope_->inside_with(); }
ScriptCompiler::CompileOptions compile_options() const {
return info_->compile_options();
return compile_options_;
}
bool consume_cached_parse_data() const {
return compile_options() == ScriptCompiler::kConsumeParserCache &&
return compile_options_ == ScriptCompiler::kConsumeParserCache &&
cached_parse_data_ != NULL;
}
bool produce_cached_parse_data() const {
return compile_options() == ScriptCompiler::kProduceParserCache;
return compile_options_ == ScriptCompiler::kProduceParserCache;
}
Scope* DeclarationScope(VariableMode mode) {
return IsLexicalVariableMode(mode)
......@@ -841,7 +838,7 @@ class Parser : public ParserBase<ParserTraits> {
const AstRawString* function_name, int pos, Variable* fvar,
Token::Value fvar_init_op, FunctionKind kind, bool* ok);
void ThrowPendingError();
void ThrowPendingError(Isolate* isolate, Handle<Script> script);
TemplateLiteralState OpenTemplateLiteral(int pos);
void AddTemplateSpan(TemplateLiteralState* state, bool tail);
......@@ -855,9 +852,9 @@ class Parser : public ParserBase<ParserTraits> {
PreParser* reusable_preparser_;
Scope* original_scope_; // for ES5 function declarations in sloppy eval
Target* target_stack_; // for break, continue statements
ScriptCompiler::CompileOptions compile_options_;
ParseData* cached_parse_data_;
CompilationInfo* info_;
bool parsing_lazy_arrow_parameters_; // for lazily parsed arrow functions.
// Pending errors.
......@@ -873,6 +870,8 @@ class Parser : public ParserBase<ParserTraits> {
int use_counts_[v8::Isolate::kUseCounterFeatureCount];
int total_preparse_skipped_;
HistogramTimer* pre_parse_timer_;
bool parsing_on_main_thread_;
};
......
......@@ -67,10 +67,9 @@ class ParserBase : public Traits {
typedef typename Traits::Type::Literal LiteralT;
typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
ParserBase(Isolate* isolate, Zone* zone, Scanner* scanner,
uintptr_t stack_limit, v8::Extension* extension,
AstValueFactory* ast_value_factory, ParserRecorder* log,
typename Traits::Type::Parser this_object)
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory,
ParserRecorder* log, typename Traits::Type::Parser this_object)
: Traits(this_object),
parenthesized_function_(false),
scope_(NULL),
......@@ -81,7 +80,6 @@ class ParserBase : public Traits {
log_(log),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
stack_limit_(stack_limit),
isolate_(isolate),
zone_(zone),
scanner_(scanner),
stack_overflow_(false),
......@@ -318,7 +316,6 @@ class ParserBase : public Traits {
return result;
}
Isolate* isolate() const { return isolate_; }
Scanner* scanner() const { return scanner_; }
AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
int position() { return scanner_->location().beg_pos; }
......@@ -653,7 +650,6 @@ class ParserBase : public Traits {
uintptr_t stack_limit_;
private:
Isolate* isolate_;
Zone* zone_;
Scanner* scanner_;
......@@ -1507,10 +1503,9 @@ class PreParser : public ParserBase<PreParserTraits> {
kPreParseSuccess
};
PreParser(Isolate* isolate, Zone* zone, Scanner* scanner,
AstValueFactory* ast_value_factory, ParserRecorder* log,
uintptr_t stack_limit)
: ParserBase<PreParserTraits>(isolate, zone, scanner, stack_limit, NULL,
PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
ParserRecorder* log, uintptr_t stack_limit)
: ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL,
ast_value_factory, log, this) {}
// Pre-parse the program from the character stream; returns true on
......
......@@ -1208,14 +1208,14 @@ class ScopeIterator {
info.MarkAsEval();
info.SetContext(Handle<Context>(function_->context()));
}
if (Parser::Parse(&info) && Scope::Analyze(&info)) {
if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) {
scope = info.function()->scope();
}
RetrieveScopeChain(scope, shared_info);
} else {
// Function code
CompilationInfoWithZone info(shared_info);
if (Parser::Parse(&info) && Scope::Analyze(&info)) {
if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) {
scope = info.function()->scope();
}
RetrieveScopeChain(scope, shared_info);
......
......@@ -166,7 +166,7 @@ RUNTIME_FUNCTION(Runtime_RenderCallSite) {
Zone zone;
if (location.function()->shared()->is_function()) {
CompilationInfo info(location.function(), &zone);
if (!Parser::Parse(&info)) {
if (!Parser::ParseStatic(&info)) {
isolate->clear_pending_exception();
return isolate->heap()->empty_string();
}
......@@ -176,7 +176,7 @@ RUNTIME_FUNCTION(Runtime_RenderCallSite) {
}
CompilationInfo info(location.script(), &zone);
if (!Parser::Parse(&info)) {
if (!Parser::ParseStatic(&info)) {
isolate->clear_pending_exception();
return isolate->heap()->empty_string();
}
......
......@@ -154,7 +154,7 @@ class FunctionTester : public InitializedHandleScope {
#if V8_TURBOFAN_TARGET
CompilationInfoWithZone info(function);
CHECK(Parser::Parse(&info));
CHECK(Parser::ParseStatic(&info));
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
if (flags_ & CompilationInfo::kContextSpecializing) {
info.MarkAsContextSpecializing();
......@@ -210,7 +210,7 @@ class FunctionTester : public InitializedHandleScope {
CHECK(Pipeline::SupportedTarget());
CompilationInfoWithZone info(function);
CHECK(Parser::Parse(&info));
CHECK(Parser::ParseStatic(&info));
info.SetOptimizing(BailoutId::None(),
Handle<Code>(function->shared()->code()));
CHECK(Compiler::Analyze(&info));
......
......@@ -46,7 +46,7 @@ class DeoptCodegenTester {
function(NewFunction(src)),
info(function, scope->main_zone()),
bailout_id(-1) {
CHECK(Parser::Parse(&info));
CHECK(Parser::ParseStatic(&info));
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
CHECK(Compiler::Analyze(&info));
CHECK(Compiler::EnsureDeoptimizationSupport(&info));
......
......@@ -31,7 +31,7 @@ struct TestHelper : public HandleAndZoneScope {
// TODO(titzer): don't scope analyze every single time.
CompilationInfo info(function, main_zone());
CHECK(Parser::Parse(&info));
CHECK(Parser::ParseStatic(&info));
CHECK(Rewriter::Rewrite(&info));
CHECK(Scope::Analyze(&info));
......
......@@ -160,8 +160,8 @@ TEST(ScanHTMLEndComments) {
i::Zone zone;
i::AstValueFactory ast_value_factory(
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PreParser preparser(CcTest::i_isolate(), &zone, &scanner,
&ast_value_factory, &log, stack_limit);
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
stack_limit);
preparser.set_allow_lazy(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
......@@ -178,8 +178,8 @@ TEST(ScanHTMLEndComments) {
i::Zone zone;
i::AstValueFactory ast_value_factory(
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PreParser preparser(CcTest::i_isolate(), &zone, &scanner,
&ast_value_factory, &log, stack_limit);
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
stack_limit);
preparser.set_allow_lazy(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned.
......@@ -328,8 +328,8 @@ TEST(StandAlonePreParser) {
i::Zone zone;
i::AstValueFactory ast_value_factory(
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PreParser preparser(CcTest::i_isolate(), &zone, &scanner,
&ast_value_factory, &log, stack_limit);
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
stack_limit);
preparser.set_allow_lazy(true);
preparser.set_allow_natives(true);
preparser.set_allow_harmony_arrow_functions(true);
......@@ -366,8 +366,8 @@ TEST(StandAlonePreParserNoNatives) {
i::Zone zone;
i::AstValueFactory ast_value_factory(
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PreParser preparser(CcTest::i_isolate(), &zone, &scanner,
&ast_value_factory, &log, stack_limit);
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
stack_limit);
preparser.set_allow_lazy(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
......@@ -435,8 +435,7 @@ TEST(RegressChromium62639) {
i::Zone zone;
i::AstValueFactory ast_value_factory(&zone,
CcTest::i_isolate()->heap()->HashSeed());
i::PreParser preparser(CcTest::i_isolate(), &zone, &scanner,
&ast_value_factory, &log,
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
CcTest::i_isolate()->stack_guard()->real_climit());
preparser.set_allow_lazy(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
......@@ -471,8 +470,7 @@ TEST(Regress928) {
i::Zone zone;
i::AstValueFactory ast_value_factory(&zone,
CcTest::i_isolate()->heap()->HashSeed());
i::PreParser preparser(CcTest::i_isolate(), &zone, &scanner,
&ast_value_factory, &log,
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
CcTest::i_isolate()->stack_guard()->real_climit());
preparser.set_allow_lazy(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
......@@ -524,8 +522,8 @@ TEST(PreParseOverflow) {
i::Zone zone;
i::AstValueFactory ast_value_factory(&zone,
CcTest::i_isolate()->heap()->HashSeed());
i::PreParser preparser(CcTest::i_isolate(), &zone, &scanner,
&ast_value_factory, &log, stack_limit);
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
stack_limit);
preparser.set_allow_lazy(true);
preparser.set_allow_harmony_arrow_functions(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
......@@ -1062,7 +1060,7 @@ TEST(ScopeUsesArgumentsSuperThis) {
parser.set_allow_harmony_scoping(true);
parser.set_allow_harmony_sloppy(true);
info.MarkAsGlobal();
CHECK(parser.Parse());
CHECK(parser.Parse(&info));
CHECK(i::Rewriter::Rewrite(&info));
CHECK(i::Scope::Analyze(&info));
CHECK(info.function() != NULL);
......@@ -1317,7 +1315,7 @@ TEST(ScopePositions) {
parser.set_allow_harmony_arrow_functions(true);
info.MarkAsGlobal();
info.SetLanguageMode(source_data[i].language_mode);
parser.Parse();
parser.Parse(&info);
CHECK(info.function() != NULL);
// Check scope types and positions.
......@@ -1453,8 +1451,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
i::Zone zone;
i::AstValueFactory ast_value_factory(
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PreParser preparser(CcTest::i_isolate(), &zone, &scanner,
&ast_value_factory, &log, stack_limit);
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
stack_limit);
SetParserFlags(&preparser, flags);
scanner.Initialize(&stream);
i::PreParser::PreParseResult result = preparser.PreParseProgram(
......@@ -1473,7 +1471,7 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
isolate->heap()->HashSeed(), isolate->unicode_cache());
SetParserFlags(&parser, flags);
info.MarkAsGlobal();
parser.Parse();
parser.Parse(&info);
function = info.function();
if (function) {
parser_materialized_literals = function->materialized_literal_count();
......@@ -2558,7 +2556,7 @@ TEST(DontRegressPreParserDataSizes) {
i::CompilationInfoWithZone info(script);
i::ScriptData* sd = NULL;
info.SetCachedData(&sd, v8::ScriptCompiler::kProduceParserCache);
i::Parser::Parse(&info, true);
i::Parser::ParseStatic(&info, true);
i::ParseData* pd = i::ParseData::FromCachedData(sd);
if (pd->FunctionCount() != test_cases[i].functions) {
......@@ -3437,7 +3435,7 @@ TEST(InnerAssignment) {
isolate->heap()->HashSeed(),
isolate->unicode_cache());
parser.set_allow_harmony_scoping(true);
CHECK(parser.Parse());
CHECK(parser.Parse(&info));
CHECK(i::Compiler::Analyze(&info));
CHECK(info.function() != NULL);
......@@ -5051,7 +5049,7 @@ TEST(BasicImportExportParsing) {
parser.set_allow_harmony_modules(true);
parser.set_allow_harmony_scoping(true);
info.MarkAsModule();
if (!parser.Parse()) {
if (!parser.Parse(&info)) {
i::Handle<i::JSObject> exception_handle(
i::JSObject::cast(isolate->pending_exception()));
i::Handle<i::String> message_string =
......@@ -5079,7 +5077,7 @@ TEST(BasicImportExportParsing) {
parser.set_allow_harmony_modules(true);
parser.set_allow_harmony_scoping(true);
info.MarkAsGlobal();
CHECK(!parser.Parse());
CHECK(!parser.Parse(&info));
}
}
}
......@@ -5169,7 +5167,7 @@ TEST(ImportExportParsingErrors) {
parser.set_allow_harmony_modules(true);
parser.set_allow_harmony_scoping(true);
info.MarkAsModule();
CHECK(!parser.Parse());
CHECK(!parser.Parse(&info));
}
}
......@@ -5261,7 +5259,7 @@ void TestLanguageMode(const char* source,
isolate->heap()->HashSeed(), isolate->unicode_cache());
parser.set_allow_strong_mode(true);
info.MarkAsGlobal();
parser.Parse();
parser.Parse(&info);
CHECK(info.function() != NULL);
CHECK_EQ(expected_language_mode, info.function()->language_mode());
}
......
......@@ -95,7 +95,7 @@ std::pair<v8::base::TimeDelta, v8::base::TimeDelta> RunBaselineParser(
v8::base::ElapsedTimer timer;
timer.Start();
// Allow lazy parsing; otherwise we won't produce cached data.
bool success = Parser::Parse(&info, true);
bool success = Parser::ParseStatic(&info, true);
parse_time1 = timer.Elapsed();
if (!success) {
fprintf(stderr, "Parsing failed\n");
......@@ -111,7 +111,7 @@ std::pair<v8::base::TimeDelta, v8::base::TimeDelta> RunBaselineParser(
v8::base::ElapsedTimer timer;
timer.Start();
// Allow lazy parsing; otherwise cached data won't help.
bool success = Parser::Parse(&info, true);
bool success = Parser::ParseStatic(&info, true);
parse_time2 = timer.Elapsed();
if (!success) {
fprintf(stderr, "Parsing failed\n");
......
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