diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2014-11-14 00:52:27 +0100 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2014-11-14 16:34:58 +0100 |
commit | 5d1b6d3e0fa4b97a490ef964be48aed9872e3ec1 (patch) | |
tree | ab5f510c4d83b175681de629395525bf7ec7cedb /deps/v8/src/compiler.cc | |
parent | 3b3d89bad26f5dfebe73fef6ae284ee78acbd5c9 (diff) | |
download | android-node-v8-5d1b6d3e0fa4b97a490ef964be48aed9872e3ec1.tar.gz android-node-v8-5d1b6d3e0fa4b97a490ef964be48aed9872e3ec1.tar.bz2 android-node-v8-5d1b6d3e0fa4b97a490ef964be48aed9872e3ec1.zip |
deps: upgrade v8 to 3.30.37
Diffstat (limited to 'deps/v8/src/compiler.cc')
-rw-r--r-- | deps/v8/src/compiler.cc | 141 |
1 files changed, 91 insertions, 50 deletions
diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc index d8467e54ee..ba5f3fd56e 100644 --- a/deps/v8/src/compiler.cc +++ b/deps/v8/src/compiler.cc @@ -6,6 +6,7 @@ #include "src/compiler.h" +#include "src/ast-numbering.h" #include "src/bootstrapper.h" #include "src/codegen.h" #include "src/compilation-cache.h" @@ -52,7 +53,8 @@ CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone) parameter_count_(0), optimization_id_(-1), ast_value_factory_(NULL), - ast_value_factory_owned_(false) { + ast_value_factory_owned_(false), + aborted_due_to_dependency_change_(false) { Initialize(script->GetIsolate(), BASE, zone); } @@ -65,7 +67,8 @@ CompilationInfo::CompilationInfo(Isolate* isolate, Zone* zone) parameter_count_(0), optimization_id_(-1), ast_value_factory_(NULL), - ast_value_factory_owned_(false) { + ast_value_factory_owned_(false), + aborted_due_to_dependency_change_(false) { Initialize(isolate, STUB, zone); } @@ -80,7 +83,8 @@ CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, parameter_count_(0), optimization_id_(-1), ast_value_factory_(NULL), - ast_value_factory_owned_(false) { + ast_value_factory_owned_(false), + aborted_due_to_dependency_change_(false) { Initialize(script_->GetIsolate(), BASE, zone); } @@ -96,7 +100,8 @@ CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone) parameter_count_(0), optimization_id_(-1), ast_value_factory_(NULL), - ast_value_factory_owned_(false) { + ast_value_factory_owned_(false), + aborted_due_to_dependency_change_(false) { Initialize(script_->GetIsolate(), BASE, zone); } @@ -109,7 +114,8 @@ CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, Isolate* isolate, parameter_count_(0), optimization_id_(-1), ast_value_factory_(NULL), - ast_value_factory_owned_(false) { + ast_value_factory_owned_(false), + aborted_due_to_dependency_change_(false) { Initialize(isolate, STUB, zone); code_stub_ = stub; } @@ -126,7 +132,8 @@ CompilationInfo::CompilationInfo( parameter_count_(0), optimization_id_(-1), ast_value_factory_(NULL), - ast_value_factory_owned_(false) { + ast_value_factory_owned_(false), + aborted_due_to_dependency_change_(false) { Initialize(isolate, BASE, zone); } @@ -159,6 +166,14 @@ void CompilationInfo::Initialize(Isolate* isolate, 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:: + // EnableDeoptimizationSupport), so it will replace the old code and all + // its type feedback. To avoid this, always compile functions in the snapshot + // with deoptimization support. + if (isolate_->serializer_enabled()) EnableDeoptimizationSupport(); + if (isolate_->debug()->is_active()) MarkAsDebug(); if (FLAG_context_specialization) MarkAsContextSpecializing(); if (FLAG_turbo_inlining) MarkAsInliningEnabled(); @@ -277,12 +292,13 @@ void CompilationInfo::PrepareForCompilation(Scope* scope) { DCHECK(scope_ == NULL); scope_ = scope; - int length = function()->slot_count(); if (feedback_vector_.is_null()) { // Allocate the feedback vector too. - feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(length); + feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector( + function()->slot_count(), function()->ic_slot_count()); } - DCHECK(feedback_vector_->length() == length); + DCHECK(feedback_vector_->Slots() == function()->slot_count() && + feedback_vector_->ICSlots() == function()->ic_slot_count()); } @@ -398,9 +414,6 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { compiler::Pipeline pipeline(info()); pipeline.GenerateCode(); if (!info()->code().is_null()) { - if (FLAG_turbo_deoptimization) { - info()->context()->native_context()->AddOptimizedCode(*info()->code()); - } return SetLastStatus(SUCCEEDED); } } @@ -469,6 +482,9 @@ OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { DCHECK(last_status() == SUCCEEDED); // 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()); + } RecordOptimizationStats(); return last_status(); } @@ -631,12 +647,7 @@ static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, static bool CompileUnoptimizedCode(CompilationInfo* info) { DCHECK(AllowCompilation::IsAllowed(info->isolate())); - DCHECK(info->function() != NULL); - if (!Rewriter::Rewrite(info)) return false; - if (!Scope::Analyze(info)) return false; - DCHECK(info->scope() != NULL); - - if (!FullCodeGenerator::MakeCode(info)) { + if (!Compiler::Analyze(info) || !FullCodeGenerator::MakeCode(info)) { Isolate* isolate = info->isolate(); if (!isolate->has_pending_exception()) isolate->StackOverflow(); return false; @@ -657,7 +668,6 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( shared->set_strict_mode(lit->strict_mode()); SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); shared->set_bailout_reason(lit->dont_optimize_reason()); - shared->set_ast_node_count(lit->ast_node_count()); // Compile unoptimized code. if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); @@ -727,17 +737,33 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { } -static bool CompileOptimizedPrologue(CompilationInfo* info) { - if (!Parser::Parse(info)) return false; +static bool Renumber(CompilationInfo* info) { + if (!AstNumbering::Renumber(info->function(), info->zone())) return false; + if (!info->shared_info().is_null()) { + info->shared_info()->set_ast_node_count(info->function()->ast_node_count()); + } + return true; +} + + +bool Compiler::Analyze(CompilationInfo* info) { + DCHECK(info->function() != NULL); if (!Rewriter::Rewrite(info)) return false; if (!Scope::Analyze(info)) return false; + if (!Renumber(info)) return false; DCHECK(info->scope() != NULL); return true; } +bool Compiler::ParseAndAnalyze(CompilationInfo* info) { + if (!Parser::Parse(info)) return false; + return Compiler::Analyze(info); +} + + static bool GetOptimizedCodeNow(CompilationInfo* info) { - if (!CompileOptimizedPrologue(info)) return false; + if (!Compiler::ParseAndAnalyze(info)) return false; TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); @@ -779,7 +805,7 @@ static bool GetOptimizedCodeLater(CompilationInfo* info) { } CompilationHandleScope handle_scope(info); - if (!CompileOptimizedPrologue(info)) return false; + if (!Compiler::ParseAndAnalyze(info)) return false; info->SaveHandles(); // Copy handles to the compilation handle scope. TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); @@ -819,14 +845,17 @@ MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) { MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) { - DCHECK(!function->GetIsolate()->has_pending_exception()); + Isolate* isolate = function->GetIsolate(); + DCHECK(!isolate->has_pending_exception()); DCHECK(!function->is_compiled()); - - if (FLAG_turbo_asm && function->shared()->asm_function()) { + // If the debugger is active, do not compile with turbofan unless we can + // deopt from turbofan code. + if (FLAG_turbo_asm && function->shared()->asm_function() && + (FLAG_turbo_deoptimization || !isolate->debug()->is_active())) { CompilationInfoWithZone info(function); - VMState<COMPILER> state(info.isolate()); - PostponeInterruptsScope postpone(info.isolate()); + VMState<COMPILER> state(isolate); + PostponeInterruptsScope postpone(isolate); info.SetOptimizing(BailoutId::None(), Handle<Code>(function->shared()->code())); @@ -835,7 +864,10 @@ MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) { info.MarkAsTypingEnabled(); info.MarkAsInliningDisabled(); - if (GetOptimizedCodeNow(&info)) return info.code(); + if (GetOptimizedCodeNow(&info)) { + DCHECK(function->shared()->is_compiled()); + return info.code(); + } } if (function->shared()->is_compiled()) { @@ -844,13 +876,12 @@ MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) { CompilationInfoWithZone info(function); Handle<Code> result; - ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result, - GetUnoptimizedCodeCommon(&info), Code); + ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info), + Code); - if (FLAG_always_opt && - info.isolate()->use_crankshaft() && + if (FLAG_always_opt && isolate->use_crankshaft() && !info.shared_info()->optimization_disabled() && - !info.isolate()->DebuggerHasBreakPoints()) { + !isolate->DebuggerHasBreakPoints()) { Handle<Code> opt_code; if (Compiler::GetOptimizedCode( function, result, @@ -893,6 +924,8 @@ bool Compiler::EnsureCompiled(Handle<JSFunction> function, // TODO(turbofan): In the future, unoptimized code with deopt support could // be generated lazily once deopt is triggered. bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { + DCHECK(info->function() != NULL); + DCHECK(info->scope() != NULL); if (!info->shared_info()->has_deoptimization_support()) { CompilationInfoWithZone unoptimized(info->shared_info()); // Note that we use the same AST that we will use for generating the @@ -1079,11 +1112,9 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( - Handle<String> source, - Handle<Context> context, - StrictMode strict_mode, - ParseRestriction restriction, - int scope_position) { + Handle<String> source, Handle<SharedFunctionInfo> outer_info, + Handle<Context> context, StrictMode strict_mode, + ParseRestriction restriction, int scope_position) { Isolate* isolate = source->GetIsolate(); int source_length = source->length(); isolate->counters()->total_eval_size()->Increment(source_length); @@ -1091,7 +1122,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( CompilationCache* compilation_cache = isolate->compilation_cache(); MaybeHandle<SharedFunctionInfo> maybe_shared_info = - compilation_cache->LookupEval(source, context, strict_mode, + compilation_cache->LookupEval(source, outer_info, context, strict_mode, scope_position); Handle<SharedFunctionInfo> shared_info; @@ -1118,8 +1149,8 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( // If caller is strict mode, the result must be in strict mode as well. DCHECK(strict_mode == SLOPPY || shared_info->strict_mode() == STRICT); if (!shared_info->dont_cache()) { - compilation_cache->PutEval( - source, context, shared_info, scope_position); + compilation_cache->PutEval(source, outer_info, context, shared_info, + scope_position); } } } else if (shared_info->ic_age() != isolate->heap()->global_ic_age()) { @@ -1163,7 +1194,12 @@ Handle<SharedFunctionInfo> Compiler::CompileScript( compile_options == ScriptCompiler::kConsumeCodeCache && !isolate->debug()->is_loaded()) { HistogramTimerScope timer(isolate->counters()->compile_deserialize()); - return CodeSerializer::Deserialize(isolate, *cached_data, source); + Handle<SharedFunctionInfo> result; + if (CodeSerializer::Deserialize(isolate, *cached_data, source) + .ToHandle(&result)) { + return result; + } + // Deserializer failed. Fall through to compile. } else { maybe_result = compilation_cache->LookupScript( source, script_name, line_offset, column_offset, @@ -1207,14 +1243,17 @@ Handle<SharedFunctionInfo> Compiler::CompileScript( result = CompileToplevel(&info); if (extension == NULL && !result.is_null() && !result->dont_cache()) { compilation_cache->PutScript(source, context, result); - if (FLAG_serialize_toplevel && + // TODO(yangguo): Issue 3628 + // With block scoping, top-level variables may resolve to a global, + // context, which makes the code context-dependent. + if (FLAG_serialize_toplevel && !FLAG_harmony_scoping && compile_options == ScriptCompiler::kProduceCodeCache) { HistogramTimerScope histogram_timer( isolate->counters()->compile_serialize()); *cached_data = CodeSerializer::Serialize(isolate, result, source); if (FLAG_profile_deserialization) { - PrintF("[Compiling and serializing %d bytes took %0.3f ms]\n", - (*cached_data)->length(), timer.Elapsed().InMillisecondsF()); + PrintF("[Compiling and serializing took %0.3f ms]\n", + timer.Elapsed().InMillisecondsF()); } } } @@ -1269,7 +1308,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( if (outer_info->is_toplevel() && outer_info->will_serialize()) { // Make sure that if the toplevel code (possibly to be serialized), - // the inner unction must be allowed to be compiled lazily. + // the inner function must be allowed to be compiled lazily. DCHECK(allow_lazy); } @@ -1279,7 +1318,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( Handle<Code> code = isolate->builtins()->CompileLazy(); info.SetCode(code); scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); - } else if (FullCodeGenerator::MakeCode(&info)) { + } else if (Renumber(&info) && FullCodeGenerator::MakeCode(&info)) { DCHECK(!info.code().is_null()); scope_info = ScopeInfo::Create(info.scope(), info.zone()); } else { @@ -1403,8 +1442,10 @@ Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) { bool Compiler::DebuggerWantsEagerCompilation(CompilationInfo* info, bool allow_lazy_without_ctx) { - return LiveEditFunctionTracker::IsActive(info->isolate()) || - (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx); + if (LiveEditFunctionTracker::IsActive(info->isolate())) return true; + Debug* debug = info->isolate()->debug(); + bool debugging = debug->is_active() || debug->has_break_points(); + return debugging && !allow_lazy_without_ctx; } |