diff options
Diffstat (limited to 'deps/v8/src/compiler.cc')
-rw-r--r-- | deps/v8/src/compiler.cc | 135 |
1 files changed, 88 insertions, 47 deletions
diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc index 20aa558c3d..d55bf33bab 100644 --- a/deps/v8/src/compiler.cc +++ b/deps/v8/src/compiler.cc @@ -11,15 +11,16 @@ #include "src/codegen.h" #include "src/compilation-cache.h" #include "src/compiler/pipeline.h" +#include "src/crankshaft/hydrogen.h" +#include "src/crankshaft/lithium.h" +#include "src/crankshaft/typing.h" #include "src/debug/debug.h" #include "src/debug/liveedit.h" #include "src/deoptimizer.h" #include "src/full-codegen/full-codegen.h" #include "src/gdb-jit.h" -#include "src/hydrogen.h" #include "src/interpreter/interpreter.h" #include "src/isolate-inl.h" -#include "src/lithium.h" #include "src/log-inl.h" #include "src/messages.h" #include "src/parser.h" @@ -31,7 +32,6 @@ #include "src/scopeinfo.h" #include "src/scopes.h" #include "src/snapshot/serialize.h" -#include "src/typing.h" #include "src/vm-state-inl.h" namespace v8 { @@ -172,9 +172,6 @@ CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub, dependencies_(isolate, zone), bailout_reason_(kNoReason), prologue_offset_(Code::kPrologueOffsetNotSet), - no_frame_ranges_(isolate->cpu_profiler()->is_profiling() - ? new List<OffsetRange>(2) - : nullptr), track_positions_(FLAG_hydrogen_track_positions || isolate->cpu_profiler()->is_profiling()), opt_count_(has_shared_info() ? shared_info()->opt_count() : 0), @@ -200,7 +197,6 @@ CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub, CompilationInfo::~CompilationInfo() { DisableFutureOptimization(); delete deferred_handles_; - delete no_frame_ranges_; #ifdef DEBUG // Check that no dependent maps have been added or added dependent maps have // been rolled back or committed. @@ -249,13 +245,15 @@ bool CompilationInfo::ShouldSelfOptimize() { void CompilationInfo::EnsureFeedbackVector() { if (feedback_vector_.is_null()) { - feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector( - literal()->feedback_vector_spec()); + Handle<TypeFeedbackMetadata> feedback_metadata = + TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec()); + feedback_vector_ = TypeFeedbackVector::New(isolate(), feedback_metadata); } // It's very important that recompiles do not alter the structure of the // type feedback vector. - CHECK(!feedback_vector_->SpecDiffersFrom(literal()->feedback_vector_spec())); + CHECK(!feedback_vector_->metadata()->SpecDiffersFrom( + literal()->feedback_vector_spec())); } @@ -330,9 +328,8 @@ base::SmartArrayPointer<char> CompilationInfo::GetDebugName() const { } -bool CompilationInfo::MustReplaceUndefinedReceiverWithGlobalProxy() { - return is_sloppy(language_mode()) && !is_native() && - scope()->has_this_declaration() && scope()->receiver()->is_used(); +bool CompilationInfo::ExpectsJSReceiverAsReceiver() { + return is_sloppy(language_mode()) && !is_native(); } @@ -441,9 +438,10 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { if (info()->shared_info()->asm_function()) { if (info()->osr_frame()) info()->MarkAsFrameSpecializing(); info()->MarkAsFunctionContextSpecializing(); - } else if (FLAG_turbo_type_feedback) { - info()->MarkAsTypeFeedbackEnabled(); - info()->EnsureFeedbackVector(); + } else if (info()->has_global_object() && + FLAG_native_context_specialization) { + info()->MarkAsNativeContextSpecializing(); + info()->MarkAsTypingEnabled(); } if (!info()->shared_info()->asm_function() || FLAG_turbo_asm_deoptimization) { @@ -705,15 +703,37 @@ static bool CompileUnoptimizedCode(CompilationInfo* info) { } +// TODO(rmcilroy): Remove this temporary work-around when ignition supports +// catch and eval. +static bool IgnitionShouldFallbackToFullCodeGen(Scope* scope) { + if (!FLAG_ignition_fallback_on_eval_and_catch) return false; + + if (scope->is_eval_scope() || scope->is_catch_scope() || + scope->calls_eval()) { + return true; + } + for (auto inner_scope : *scope->inner_scopes()) { + if (IgnitionShouldFallbackToFullCodeGen(inner_scope)) return true; + } + return false; +} + + static bool GenerateBytecode(CompilationInfo* info) { DCHECK(AllowCompilation::IsAllowed(info->isolate())); - if (!Compiler::Analyze(info->parse_info()) || - !interpreter::Interpreter::MakeBytecode(info)) { + bool success = false; + if (Compiler::Analyze(info->parse_info())) { + if (IgnitionShouldFallbackToFullCodeGen(info->scope())) { + success = FullCodeGenerator::MakeCode(info); + } else { + success = interpreter::Interpreter::MakeBytecode(info); + } + } + if (!success) { Isolate* isolate = info->isolate(); if (!isolate->has_pending_exception()) isolate->StackOverflow(); - return false; } - return true; + return success; } @@ -730,7 +750,8 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); MaybeDisableOptimization(shared, lit->dont_optimize_reason()); - if (FLAG_ignition && info->closure()->PassesFilter(FLAG_ignition_filter)) { + if (FLAG_ignition && !shared->HasBuiltinFunctionId() && + info->closure()->PassesFilter(FLAG_ignition_filter)) { // Compile bytecode for the interpreter. if (!GenerateBytecode(info)) return MaybeHandle<Code>(); } else { @@ -750,6 +771,10 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( // Update the code and feedback vector for the shared function info. shared->ReplaceCode(*info->code()); shared->set_feedback_vector(*info->feedback_vector()); + if (info->has_bytecode_array()) { + DCHECK(shared->function_data()->IsUndefined()); + shared->set_function_data(*info->bytecode_array()); + } return info->code(); } @@ -776,7 +801,8 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { Handle<Code> code = info->code(); if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. - // Context specialization folds-in the context, so no sharing can occur. + // Function context specialization folds-in the function context, + // so no sharing can occur. if (info->is_function_context_specializing()) return; // Frame specialization implies function context specialization. DCHECK(!info->is_frame_specializing()); @@ -786,19 +812,18 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { if (function->shared()->bound()) return; // Cache optimized context-specific code. - if (FLAG_cache_optimized_code) { - Handle<SharedFunctionInfo> shared(function->shared()); - Handle<LiteralsArray> literals(function->literals()); - Handle<Context> native_context(function->context()->native_context()); - SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, - literals, info->osr_ast_id()); - } + Handle<SharedFunctionInfo> shared(function->shared()); + Handle<LiteralsArray> literals(function->literals()); + Handle<Context> native_context(function->context()->native_context()); + SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, + literals, info->osr_ast_id()); - // Do not cache context-independent code compiled for OSR. + // Do not cache (native) context-independent code compiled for OSR. if (code->is_turbofanned() && info->is_osr()) return; - // Cache optimized context-independent code. - if (FLAG_turbo_cache_shared_code && code->is_turbofanned()) { + // Cache optimized (native) context-independent code. + if (FLAG_turbo_cache_shared_code && code->is_turbofanned() && + !info->is_native_context_specializing()) { DCHECK(!info->is_function_context_specializing()); DCHECK(info->osr_ast_id().IsNone()); Handle<SharedFunctionInfo> shared(function->shared()); @@ -841,9 +866,12 @@ bool Compiler::ParseAndAnalyze(ParseInfo* info) { static bool GetOptimizedCodeNow(CompilationInfo* info) { + Isolate* isolate = info->isolate(); + CanonicalHandleScope canonical(isolate); + if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; - TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); + TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); OptimizedCompileJob job(info); if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED || @@ -858,7 +886,7 @@ static bool GetOptimizedCodeNow(CompilationInfo* info) { } // Success! - DCHECK(!info->isolate()->has_pending_exception()); + DCHECK(!isolate->has_pending_exception()); InsertCodeIntoOptimizedCodeMap(info); RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, info->shared_info()); @@ -868,6 +896,8 @@ static bool GetOptimizedCodeNow(CompilationInfo* info) { static bool GetOptimizedCodeLater(CompilationInfo* info) { Isolate* isolate = info->isolate(); + CanonicalHandleScope canonical(isolate); + if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) { if (FLAG_trace_concurrent_recompilation) { PrintF(" ** Compilation queue full, will retry optimizing "); @@ -1146,6 +1176,13 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) { } +// Checks whether top level functions should be passed by {raw_filter}. +static bool TopLevelFunctionPassesFilter(const char* raw_filter) { + Vector<const char> filter = CStrVector(raw_filter); + return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); +} + + static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { Isolate* isolate = info->isolate(); PostponeInterruptsScope postpone(isolate); @@ -1209,8 +1246,14 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { HistogramTimerScope timer(rate); // Compile the code. - if (!CompileUnoptimizedCode(info)) { - return Handle<SharedFunctionInfo>::null(); + if (FLAG_ignition && TopLevelFunctionPassesFilter(FLAG_ignition_filter)) { + if (!GenerateBytecode(info)) { + return Handle<SharedFunctionInfo>::null(); + } + } else { + if (!CompileUnoptimizedCode(info)) { + return Handle<SharedFunctionInfo>::null(); + } } // Allocate function. @@ -1220,6 +1263,10 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { info->code(), ScopeInfo::Create(info->isolate(), info->zone(), info->scope()), info->feedback_vector()); + if (info->has_bytecode_array()) { + DCHECK(result->function_data()->IsUndefined()); + result->set_function_data(*info->bytecode_array()); + } DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); SharedFunctionInfo::InitFromFunctionLiteral(result, lit); @@ -1230,9 +1277,10 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { result->set_allows_lazy_compilation_without_context(false); } - Handle<String> script_name = script->name()->IsString() - ? Handle<String>(String::cast(script->name())) - : isolate->factory()->empty_string(); + Handle<String> script_name = + script->name()->IsString() + ? Handle<String>(String::cast(script->name())) + : isolate->factory()->empty_string(); Logger::LogEventsAndTags log_tag = info->is_eval() ? Logger::EVAL_TAG : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); @@ -1534,13 +1582,6 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( !LiveEditFunctionTracker::IsActive(isolate) && (!info.is_debug() || allow_lazy_without_ctx); - 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. - DCHECK(allow_lazy); - } - bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile(); // Generate code @@ -1763,7 +1804,7 @@ bool CompilationPhase::ShouldProduceTraceOutput() const { #if DEBUG void CompilationInfo::PrintAstForTesting() { PrintF("--- Source from AST ---\n%s\n", - PrettyPrinter(isolate(), zone()).PrintProgram(literal())); + PrettyPrinter(isolate()).PrintProgram(literal())); } #endif } // namespace internal |