Chromium Code Reviews| Index: src/compiler.cc |
| diff --git a/src/compiler.cc b/src/compiler.cc |
| index a5d303044d8e474accfe77aafb68d4d092593d10..ac65fbbad85f8a63cefeb6fd7d2b74bfe23e17e5 100644 |
| --- a/src/compiler.cc |
| +++ b/src/compiler.cc |
| @@ -34,7 +34,6 @@ |
| namespace v8 { |
| namespace internal { |
| - |
| std::ostream& operator<<(std::ostream& os, const SourcePosition& p) { |
| if (p.IsUnknown()) { |
| return os << "<?>"; |
| @@ -46,76 +45,59 @@ std::ostream& operator<<(std::ostream& os, const SourcePosition& p) { |
| } |
| -ScriptData::ScriptData(const byte* data, int length) |
| - : owns_data_(false), rejected_(false), data_(data), length_(length) { |
| - if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { |
| - byte* copy = NewArray<byte>(length); |
| - DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); |
| - CopyBytes(copy, data, length); |
| - data_ = copy; |
| - AcquireDataOwnership(); |
| +#define PARSE_INFO_GETTER(type, name) \ |
| + type CompilationInfo::name() const { \ |
| + CHECK(parse_info()); \ |
| + return parse_info()->name(); \ |
| } |
| -} |
| -CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone) |
| - : flags_(kThisHasUses), |
| - script_(script), |
| - source_stream_(NULL), |
| - osr_ast_id_(BailoutId::None()), |
| - parameter_count_(0), |
| - optimization_id_(-1), |
| - ast_value_factory_(NULL), |
| - ast_value_factory_owned_(false), |
| - aborted_due_to_dependency_change_(false), |
| - osr_expr_stack_height_(0) { |
| - Initialize(script->GetIsolate(), BASE, zone); |
| -} |
| +#define PARSE_INFO_GETTER_WITH_DEFAULT(type, name, def) \ |
| + type CompilationInfo::name() const { \ |
| + return parse_info() ? parse_info()->name() : def; \ |
| + } |
| -CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, |
| - Zone* zone) |
| - : flags_(kLazy | kThisHasUses), |
| - shared_info_(shared_info), |
| - script_(Handle<Script>(Script::cast(shared_info->script()))), |
| - source_stream_(NULL), |
| - osr_ast_id_(BailoutId::None()), |
| - parameter_count_(0), |
| - optimization_id_(-1), |
| - ast_value_factory_(NULL), |
| - ast_value_factory_owned_(false), |
| - aborted_due_to_dependency_change_(false), |
| - osr_expr_stack_height_(0) { |
| - Initialize(script_->GetIsolate(), BASE, zone); |
| +PARSE_INFO_GETTER(Handle<Script>, script); |
| +PARSE_INFO_GETTER(bool, is_eval); |
| +PARSE_INFO_GETTER(bool, is_native); |
| +PARSE_INFO_GETTER(bool, is_module); |
| +PARSE_INFO_GETTER(bool, this_has_uses); |
| +PARSE_INFO_GETTER(LanguageMode, language_mode); |
| +PARSE_INFO_GETTER_WITH_DEFAULT(Handle<JSFunction>, closure, |
| + Handle<JSFunction>::null()); |
| +PARSE_INFO_GETTER(FunctionLiteral*, function); |
| +PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr); |
| +PARSE_INFO_GETTER(Handle<Context>, context); |
| +PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info); |
| + |
| +#undef PARSE_INFO_GETTER |
| +#undef PARSE_INFO_GETTER_WITH_DEFAULT |
| + |
| + |
| +bool CompilationInfo::has_shared_info() const { |
| + return parse_info_ && !parse_info_->shared_info().is_null(); |
| } |
| -CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone) |
| - : flags_(kLazy | kThisHasUses), |
| - closure_(closure), |
| - shared_info_(Handle<SharedFunctionInfo>(closure->shared())), |
| - script_(Handle<Script>(Script::cast(shared_info_->script()))), |
| - source_stream_(NULL), |
| - context_(closure->context()), |
| +CompilationInfo::CompilationInfo(ParseInfo* parse_info) |
| + : parse_info_(parse_info), |
| + flags_(0), |
| osr_ast_id_(BailoutId::None()), |
| parameter_count_(0), |
| optimization_id_(-1), |
| - ast_value_factory_(NULL), |
| - ast_value_factory_owned_(false), |
| aborted_due_to_dependency_change_(false), |
| osr_expr_stack_height_(0) { |
| - Initialize(script_->GetIsolate(), BASE, zone); |
| + Initialize(parse_info->isolate(), BASE, parse_info->zone()); |
| } |
| CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone) |
| - : flags_(kLazy | kThisHasUses), |
| - source_stream_(NULL), |
| + : parse_info_(nullptr), |
| + flags_(0), |
| osr_ast_id_(BailoutId::None()), |
| parameter_count_(0), |
| optimization_id_(-1), |
| - ast_value_factory_(NULL), |
| - ast_value_factory_owned_(false), |
| aborted_due_to_dependency_change_(false), |
| osr_expr_stack_height_(0) { |
| Initialize(isolate, STUB, zone); |
| @@ -123,39 +105,15 @@ CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone) |
| } |
| -CompilationInfo::CompilationInfo( |
| - ScriptCompiler::ExternalSourceStream* stream, |
| - ScriptCompiler::StreamedSource::Encoding encoding, Isolate* isolate, |
| - Zone* zone) |
| - : flags_(kThisHasUses), |
| - source_stream_(stream), |
| - source_stream_encoding_(encoding), |
| - osr_ast_id_(BailoutId::None()), |
| - parameter_count_(0), |
| - optimization_id_(-1), |
| - ast_value_factory_(NULL), |
| - ast_value_factory_owned_(false), |
| - aborted_due_to_dependency_change_(false), |
| - osr_expr_stack_height_(0) { |
| - Initialize(isolate, BASE, zone); |
| -} |
| - |
| - |
| void CompilationInfo::Initialize(Isolate* isolate, |
| Mode mode, |
| Zone* zone) { |
| isolate_ = isolate; |
| - function_ = NULL; |
| - scope_ = NULL; |
| - script_scope_ = NULL; |
| - extension_ = NULL; |
| - cached_data_ = NULL; |
| - compile_options_ = ScriptCompiler::kNoCompileOptions; |
| zone_ = zone; |
| deferred_handles_ = NULL; |
| code_stub_ = NULL; |
| prologue_offset_ = Code::kPrologueOffsetNotSet; |
| - opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count(); |
| + opt_count_ = has_shared_info() ? shared_info()->opt_count() : 0; |
| no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() |
| ? new List<OffsetRange>(2) : NULL; |
| if (FLAG_hydrogen_track_positions) { |
| @@ -174,9 +132,6 @@ void CompilationInfo::Initialize(Isolate* isolate, |
| return; |
| } |
| mode_ = mode; |
| - if (!script_.is_null() && script_->type()->value() == Script::TYPE_NATIVE) { |
| - MarkAsNative(); |
| - } |
| // Compiling for the snapshot typically results in different code than |
| // compiling later on. This means that code recompiled with deoptimization |
| // support won't be "equivalent" (as defined by SharedFunctionInfo:: |
| @@ -191,13 +146,9 @@ void CompilationInfo::Initialize(Isolate* isolate, |
| if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); |
| if (FLAG_turbo_types) MarkAsTypingEnabled(); |
| - if (!shared_info_.is_null()) { |
| - DCHECK(is_sloppy(language_mode())); |
| - SetLanguageMode(shared_info_->language_mode()); |
| - } |
| bailout_reason_ = kNoReason; |
| - if (!shared_info().is_null() && shared_info()->is_compiled()) { |
| + if (has_shared_info() && shared_info()->is_compiled()) { |
| // We should initialize the CompilationInfo feedback vector from the |
| // passed in shared info, rather than creating a new one. |
| feedback_vector_ = |
| @@ -214,7 +165,6 @@ CompilationInfo::~CompilationInfo() { |
| delete no_frame_ranges_; |
| delete inlined_function_infos_; |
| delete inlining_id_to_function_id_; |
| - if (ast_value_factory_owned_) delete ast_value_factory_; |
| #ifdef DEBUG |
| // Check that no dependent maps have been added or added dependent maps have |
| // been rolled back or committed. |
| @@ -307,17 +257,10 @@ Code::Flags CompilationInfo::flags() const { |
| // profiler, so they trigger their own optimization when they're called |
| // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. |
| bool CompilationInfo::ShouldSelfOptimize() { |
| - return FLAG_crankshaft && |
| - !function()->flags()->Contains(kDontSelfOptimize) && |
| - !function()->dont_optimize() && |
| - function()->scope()->AllowsLazyCompilation() && |
| - (shared_info().is_null() || !shared_info()->optimization_disabled()); |
| -} |
| - |
| - |
| -void CompilationInfo::PrepareForCompilation(Scope* scope) { |
| - DCHECK(scope_ == NULL); |
| - scope_ = scope; |
| + return FLAG_crankshaft && !function()->flags()->Contains(kDontSelfOptimize) && |
| + !function()->dont_optimize() && |
| + function()->scope()->AllowsLazyCompilation() && |
| + (!has_shared_info() || !shared_info()->optimization_disabled()); |
| } |
| @@ -330,7 +273,7 @@ void CompilationInfo::EnsureFeedbackVector() { |
| bool CompilationInfo::is_simple_parameter_list() { |
| - return scope_->is_simple_parameter_list(); |
| + return scope()->is_simple_parameter_list(); |
| } |
| @@ -549,7 +492,8 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { |
| : new(info()->zone()) HOptimizedGraphBuilder(info()); |
| Timer t(this, &time_taken_to_create_graph_); |
| - info()->set_this_has_uses(false); |
| + // TODO(titzer): how is that possibly ok? |
|
Michael Starzinger
2015/03/04 22:50:46
I can shed light on that. IIRC, the "this_has_uses
|
| + info()->parse_info()->set_this_has_uses(false); |
| graph_ = graph_builder_->CreateGraph(); |
| if (isolate()->has_pending_exception()) { |
| @@ -599,7 +543,8 @@ OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { |
| // TODO(turbofan): Currently everything is done in the first phase. |
| if (!info()->code().is_null()) { |
| if (FLAG_turbo_deoptimization) { |
| - info()->context()->native_context()->AddOptimizedCode(*info()->code()); |
| + info()->parse_info()->context()->native_context()->AddOptimizedCode( |
| + *info()->code()); |
| } |
| RecordOptimizationStats(); |
| return last_status(); |
| @@ -711,7 +656,7 @@ static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, |
| // enabled as finding the line number is not free. |
| if (info->isolate()->logger()->is_logging_code_events() || |
| info->isolate()->cpu_profiler()->is_profiling()) { |
| - Handle<Script> script = info->script(); |
| + Handle<Script> script = info->parse_info()->script(); |
| Handle<Code> code = info->code(); |
| if (code.is_identical_to(info->isolate()->builtins()->CompileLazy())) { |
| return; |
| @@ -732,7 +677,8 @@ static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, |
| static bool CompileUnoptimizedCode(CompilationInfo* info) { |
| DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
| - if (!Compiler::Analyze(info) || !FullCodeGenerator::MakeCode(info)) { |
| + if (!Compiler::Analyze(info->parse_info()) || |
| + !FullCodeGenerator::MakeCode(info)) { |
| Isolate* isolate = info->isolate(); |
| if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| return false; |
| @@ -747,7 +693,7 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( |
| PostponeInterruptsScope postpone(info->isolate()); |
| // Parse and update CompilationInfo with the results. |
| - if (!Parser::ParseStatic(info)) return MaybeHandle<Code>(); |
| + if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
| Handle<SharedFunctionInfo> shared = info->shared_info(); |
| FunctionLiteral* lit = info->function(); |
| shared->set_language_mode(lit->language_mode()); |
| @@ -823,22 +769,23 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { |
| } |
| -static bool Renumber(CompilationInfo* info) { |
| - if (!AstNumbering::Renumber(info->isolate(), info->zone(), |
| - info->function())) { |
| +static bool Renumber(ParseInfo* parse_info) { |
| + if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), |
| + parse_info->function())) { |
| return false; |
| } |
| - if (!info->shared_info().is_null()) { |
| - FunctionLiteral* lit = info->function(); |
| - info->shared_info()->set_ast_node_count(lit->ast_node_count()); |
| - MaybeDisableOptimization(info->shared_info(), lit->dont_optimize_reason()); |
| - info->shared_info()->set_dont_cache(lit->flags()->Contains(kDontCache)); |
| + Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
| + if (!shared_info.is_null()) { |
| + FunctionLiteral* lit = parse_info->function(); |
| + shared_info->set_ast_node_count(lit->ast_node_count()); |
| + MaybeDisableOptimization(shared_info, lit->dont_optimize_reason()); |
| + shared_info->set_dont_cache(lit->flags()->Contains(kDontCache)); |
| } |
| return true; |
| } |
| -bool Compiler::Analyze(CompilationInfo* info) { |
| +bool Compiler::Analyze(ParseInfo* info) { |
| DCHECK(info->function() != NULL); |
| if (!Rewriter::Rewrite(info)) return false; |
| if (!Scope::Analyze(info)) return false; |
| @@ -848,14 +795,14 @@ bool Compiler::Analyze(CompilationInfo* info) { |
| } |
| -bool Compiler::ParseAndAnalyze(CompilationInfo* info) { |
| +bool Compiler::ParseAndAnalyze(ParseInfo* info) { |
| if (!Parser::ParseStatic(info)) return false; |
| return Compiler::Analyze(info); |
| } |
| static bool GetOptimizedCodeNow(CompilationInfo* info) { |
| - if (!Compiler::ParseAndAnalyze(info)) return false; |
| + if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
| TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
| @@ -892,8 +839,11 @@ static bool GetOptimizedCodeLater(CompilationInfo* info) { |
| } |
| CompilationHandleScope handle_scope(info); |
| - if (!Compiler::ParseAndAnalyze(info)) return false; |
| - info->SaveHandles(); // Copy handles to the compilation handle scope. |
| + if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
| + |
| + // Reopen handles in the new CompilationHandleScope. |
| + info->ReopenHandlesInNewHandleScope(); |
| + info->parse_info()->ReopenHandlesInNewHandleScope(); |
| TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
| @@ -1013,13 +963,15 @@ bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
| DCHECK(info->function() != NULL); |
| DCHECK(info->scope() != NULL); |
| if (!info->shared_info()->has_deoptimization_support()) { |
| + // TODO(titzer): just reuse the ParseInfo for the unoptimized compile. |
| Handle<SharedFunctionInfo> shared = info->shared_info(); |
| CompilationInfoWithZone unoptimized(shared); |
| // Note that we use the same AST that we will use for generating the |
| // optimized code. |
| - unoptimized.SetFunction(info->function()); |
| - unoptimized.PrepareForCompilation(info->scope()); |
| - unoptimized.SetContext(info->context()); |
| + ParseInfo* parse_info = unoptimized.parse_info(); |
| + parse_info->set_literal(info->function()); |
| + parse_info->set_scope(info->scope()); |
| + parse_info->set_context(info->context()); |
| unoptimized.EnableDeoptimizationSupport(); |
| // If the current code has reloc info for serialization, also include |
| // reloc info for serialization for the new code, so that deopt support |
| @@ -1093,12 +1045,12 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) { |
| PostponeInterruptsScope postpone(info.isolate()); |
| VMState<COMPILER> state(info.isolate()); |
| - info.MarkAsGlobal(); |
| - if (!Parser::ParseStatic(&info)) return; |
| + info.parse_info()->set_global(); |
| + if (!Parser::ParseStatic(info.parse_info())) return; |
| LiveEditFunctionTracker tracker(info.isolate(), info.function()); |
| if (!CompileUnoptimizedCode(&info)) return; |
| - if (!info.shared_info().is_null()) { |
| + if (info.has_shared_info()) { |
| Handle<ScopeInfo> scope_info = |
| ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
| info.shared_info()->set_scope_info(*scope_info); |
| @@ -1111,7 +1063,8 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
| Isolate* isolate = info->isolate(); |
| PostponeInterruptsScope postpone(isolate); |
| DCHECK(!isolate->native_context().is_null()); |
| - Handle<Script> script = info->script(); |
| + ParseInfo* parse_info = info->parse_info(); |
| + Handle<Script> script = parse_info->script(); |
| // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? |
| FixedArray* array = isolate->native_context()->embedder_data(); |
| @@ -1119,9 +1072,10 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
| isolate->debug()->OnBeforeCompile(script); |
| - DCHECK(info->is_eval() || info->is_global() || info->is_module()); |
| + DCHECK(parse_info->is_eval() || parse_info->is_global() || |
| + parse_info->is_module()); |
| - info->MarkAsToplevel(); |
| + parse_info->set_toplevel(); |
| Handle<SharedFunctionInfo> result; |
| @@ -1129,22 +1083,25 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
| if (info->function() == NULL) { |
| // Parse the script if needed (if it's already parsed, function() is |
| // non-NULL). |
| - bool parse_allow_lazy = |
| - (info->compile_options() == ScriptCompiler::kConsumeParserCache || |
| - String::cast(script->source())->length() > |
| - FLAG_min_preparse_length) && |
| - !Compiler::DebuggerWantsEagerCompilation(info); |
| + ScriptCompiler::CompileOptions options = |
| + info->parse_info()->compile_options(); |
| + bool parse_allow_lazy = (options == ScriptCompiler::kConsumeParserCache || |
| + String::cast(script->source())->length() > |
| + FLAG_min_preparse_length) && |
| + !Compiler::DebuggerWantsEagerCompilation(isolate); |
| if (!parse_allow_lazy && |
| - (info->compile_options() == ScriptCompiler::kProduceParserCache || |
| - info->compile_options() == ScriptCompiler::kConsumeParserCache)) { |
| + (options == ScriptCompiler::kProduceParserCache || |
| + options == ScriptCompiler::kConsumeParserCache)) { |
| // We are going to parse eagerly, but we either 1) have cached data |
| // produced by lazy parsing or 2) are asked to generate cached data. |
| // Eager parsing cannot benefit from cached data, and producing cached |
| // data while parsing eagerly is not implemented. |
| - info->SetCachedData(NULL, ScriptCompiler::kNoCompileOptions); |
| + info->parse_info()->set_cached_data(nullptr); |
| + info->parse_info()->set_compile_options( |
| + ScriptCompiler::kNoCompileOptions); |
| } |
| - if (!Parser::ParseStatic(info, parse_allow_lazy)) { |
| + if (!Parser::ParseStatic(info->parse_info(), parse_allow_lazy)) { |
| return Handle<SharedFunctionInfo>::null(); |
| } |
| } |
| @@ -1224,11 +1181,12 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( |
| if (!maybe_shared_info.ToHandle(&shared_info)) { |
| Handle<Script> script = isolate->factory()->NewScript(source); |
| CompilationInfoWithZone info(script); |
| - info.MarkAsEval(); |
| - if (context->IsNativeContext()) info.MarkAsGlobal(); |
| - info.SetLanguageMode(language_mode); |
| - info.SetParseRestriction(restriction); |
| - info.SetContext(context); |
| + ParseInfo* parse_info = info.parse_info(); |
| + parse_info->set_eval(); |
| + if (context->IsNativeContext()) parse_info->set_global(); |
| + parse_info->set_language_mode(language_mode); |
| + parse_info->set_parse_restriction(restriction); |
| + parse_info->set_context(context); |
| Debug::RecordEvalCaller(script); |
| @@ -1338,20 +1296,24 @@ Handle<SharedFunctionInfo> Compiler::CompileScript( |
| // Compile the function and add it to the cache. |
| CompilationInfoWithZone info(script); |
| + ParseInfo* parse_info = info.parse_info(); |
| if (FLAG_harmony_modules && is_module) { |
| - info.MarkAsModule(); |
| + parse_info->set_module(); |
| } else { |
| - info.MarkAsGlobal(); |
| + parse_info->set_global(); |
| + } |
| + if (compile_options != ScriptCompiler::kNoCompileOptions) { |
| + parse_info->set_cached_data(cached_data); |
| } |
| - info.SetCachedData(cached_data, compile_options); |
| - info.SetExtension(extension); |
| - info.SetContext(context); |
| + parse_info->set_compile_options(compile_options); |
| + parse_info->set_extension(extension); |
| + parse_info->set_context(context); |
| if (FLAG_serialize_toplevel && |
| compile_options == ScriptCompiler::kProduceCodeCache) { |
| info.PrepareForSerializing(); |
| } |
| - info.SetLanguageMode( |
| + parse_info->set_language_mode( |
| static_cast<LanguageMode>(info.language_mode() | language_mode)); |
| result = CompileToplevel(&info); |
| if (extension == NULL && !result.is_null() && !result->dont_cache()) { |
| @@ -1377,19 +1339,21 @@ Handle<SharedFunctionInfo> Compiler::CompileScript( |
| Handle<SharedFunctionInfo> Compiler::CompileStreamedScript( |
| - CompilationInfo* info, int source_length) { |
| - Isolate* isolate = info->isolate(); |
| + Handle<Script> script, ParseInfo* parse_info, int source_length) { |
| + Isolate* isolate = script->GetIsolate(); |
| + // TODO(titzer): increment the counters in caller. |
| isolate->counters()->total_load_size()->Increment(source_length); |
| isolate->counters()->total_compile_size()->Increment(source_length); |
| LanguageMode language_mode = |
| construct_language_mode(FLAG_use_strict, FLAG_use_strong); |
| - info->SetLanguageMode( |
| - static_cast<LanguageMode>(info->language_mode() | language_mode)); |
| + parse_info->set_language_mode( |
| + static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); |
| + CompilationInfo compile_info(parse_info); |
| // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the |
| // real code caching lands, streaming needs to be adapted to use it. |
| - return CompileToplevel(info); |
| + return CompileToplevel(&compile_info); |
| } |
| @@ -1398,9 +1362,10 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( |
| CompilationInfo* outer_info) { |
| // Precondition: code has been parsed and scopes have been analyzed. |
| CompilationInfoWithZone info(script); |
| - info.SetFunction(literal); |
| - info.PrepareForCompilation(literal->scope()); |
| - info.SetLanguageMode(literal->scope()->language_mode()); |
| + ParseInfo* parse_info = info.parse_info(); |
| + parse_info->set_literal(literal); |
| + parse_info->set_scope(literal->scope()); |
| + parse_info->set_language_mode(literal->scope()->language_mode()); |
| if (outer_info->will_serialize()) info.PrepareForSerializing(); |
| Isolate* isolate = info.isolate(); |
| @@ -1416,10 +1381,11 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( |
| // of functions without an outer context when setting a breakpoint through |
| // Debug::FindSharedFunctionInfoInScript. |
| bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext(); |
| - bool allow_lazy = literal->AllowsLazyCompilation() && |
| - !DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx); |
| + bool allow_lazy = |
| + literal->AllowsLazyCompilation() && |
| + !DebuggerWantsEagerCompilation(isolate, allow_lazy_without_ctx); |
| - if (outer_info->is_toplevel() && outer_info->will_serialize()) { |
| + if (outer_info->parse_info()->is_toplevel() && outer_info->will_serialize()) { |
| // Make sure that if the toplevel code (possibly to be serialized), |
| // the inner function must be allowed to be compiled lazily. |
| // This is necessary to serialize toplevel code without inner functions. |
| @@ -1440,7 +1406,8 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( |
| // called. |
| info.EnsureFeedbackVector(); |
| scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); |
| - } else if (Renumber(&info) && FullCodeGenerator::MakeCode(&info)) { |
| + } else if (Renumber(info.parse_info()) && |
| + FullCodeGenerator::MakeCode(&info)) { |
| // MakeCode will ensure that the feedback vector is present and |
| // appropriately sized. |
| DCHECK(!info.code().is_null()); |
| @@ -1569,10 +1536,10 @@ Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) { |
| } |
| -bool Compiler::DebuggerWantsEagerCompilation(CompilationInfo* info, |
| +bool Compiler::DebuggerWantsEagerCompilation(Isolate* isolate, |
| bool allow_lazy_without_ctx) { |
| - if (LiveEditFunctionTracker::IsActive(info->isolate())) return true; |
| - Debug* debug = info->isolate()->debug(); |
| + if (LiveEditFunctionTracker::IsActive(isolate)) return true; |
| + Debug* debug = isolate->debug(); |
| bool debugging = debug->is_active() || debug->has_break_points(); |
| return debugging && !allow_lazy_without_ctx; |
| } |
| @@ -1609,6 +1576,23 @@ bool CompilationPhase::ShouldProduceTraceOutput() const { |
| } |
| +CompilationInfoWithZone::CompilationInfoWithZone(Handle<Script> script) |
| + : CompilationInfo((new ParseInfo(&zone_))->InitializeFromScript(script)) {} |
| + |
| +CompilationInfoWithZone::CompilationInfoWithZone(Handle<JSFunction> function) |
| + : CompilationInfo( |
| + (new ParseInfo(&zone_))->InitializeFromJSFunction(function)) {} |
| + |
| +CompilationInfoWithZone::CompilationInfoWithZone( |
| + Handle<SharedFunctionInfo> shared_info) |
| + : CompilationInfo((new ParseInfo(&zone_)) |
| + ->InitializeFromSharedFunctionInfo(shared_info)) {} |
| + |
| +CompilationInfoWithZone::~CompilationInfoWithZone() { |
| + RollbackDependencies(); |
| + if (parse_info()) delete parse_info(); |
| +} |
| + |
| #if DEBUG |
| void CompilationInfo::PrintAstForTesting() { |
| PrintF("--- Source from AST ---\n%s\n", |