diff options
Diffstat (limited to 'deps/v8/src/compiler/pipeline.cc')
-rw-r--r-- | deps/v8/src/compiler/pipeline.cc | 122 |
1 files changed, 87 insertions, 35 deletions
diff --git a/deps/v8/src/compiler/pipeline.cc b/deps/v8/src/compiler/pipeline.cc index 585923fa69..bc8fd0cbe9 100644 --- a/deps/v8/src/compiler/pipeline.cc +++ b/deps/v8/src/compiler/pipeline.cc @@ -174,6 +174,8 @@ class PipelineData { } ~PipelineData() { + delete code_generator_; // Must happen before zones are destroyed. + code_generator_ = nullptr; DeleteRegisterAllocationZone(); DeleteInstructionZone(); DeleteGraphZone(); @@ -196,6 +198,8 @@ class PipelineData { code_ = code; } + CodeGenerator* code_generator() const { return code_generator_; } + // RawMachineAssembler generally produces graphs which cannot be verified. bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } @@ -314,6 +318,11 @@ class PipelineData { sequence(), debug_name()); } + void InitializeCodeGenerator(Linkage* linkage) { + DCHECK_NULL(code_generator_); + code_generator_ = new CodeGenerator(frame(), linkage, sequence(), info()); + } + void BeginPhaseKind(const char* phase_kind_name) { if (pipeline_statistics() != nullptr) { pipeline_statistics()->BeginPhaseKind(phase_kind_name); @@ -339,6 +348,7 @@ class PipelineData { bool verify_graph_ = false; bool is_asm_ = false; Handle<Code> code_ = Handle<Code>::null(); + CodeGenerator* code_generator_ = nullptr; // All objects in the following group of fields are allocated in graph_zone_. // They are all set to nullptr when the graph_zone_ is destroyed. @@ -356,8 +366,7 @@ class PipelineData { // All objects in the following group of fields are allocated in // instruction_zone_. They are all set to nullptr when the instruction_zone_ - // is - // destroyed. + // is destroyed. ZoneStats::Scope instruction_zone_scope_; Zone* instruction_zone_; InstructionSequence* sequence_ = nullptr; @@ -400,8 +409,11 @@ class PipelineImpl final { // Run the concurrent optimization passes. bool OptimizeGraph(Linkage* linkage); - // Perform the actual code generation and return handle to a code object. - Handle<Code> GenerateCode(Linkage* linkage); + // Run the code assembly pass. + void AssembleCode(Linkage* linkage); + + // Run the code finalization pass. + Handle<Code> FinalizeCode(); bool ScheduleAndSelectInstructions(Linkage* linkage, bool trim_graph); void RunPrintAndVerify(const char* phase, bool untyped = false); @@ -615,6 +627,11 @@ PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl() { return AbortOptimization(kGraphBuildingFailed); } + // Make sure that we have generated the maximal number of deopt entries. + // This is in order to avoid triggering the generation of deopt entries later + // during code assembly. + Deoptimizer::EnsureCodeForMaxDeoptimizationEntries(isolate()); + return SUCCEEDED; } @@ -624,7 +641,8 @@ PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl() { } PipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl() { - Handle<Code> code = pipeline_.GenerateCode(linkage_); + pipeline_.AssembleCode(linkage_); + Handle<Code> code = pipeline_.FinalizeCode(); if (code.is_null()) { if (info()->bailout_reason() == kNoReason) { return AbortOptimization(kCodeGenerationFailed); @@ -663,6 +681,8 @@ class PipelineWasmCompilationJob final : public CompilationJob { Status FinalizeJobImpl() final; private: + size_t AllocatedMemory() const override; + ZoneStats zone_stats_; std::unique_ptr<PipelineStatistics> pipeline_statistics_; PipelineData data_; @@ -709,9 +729,14 @@ PipelineWasmCompilationJob::ExecuteJobImpl() { return SUCCEEDED; } +size_t PipelineWasmCompilationJob::AllocatedMemory() const { + return pipeline_.data_->zone_stats()->GetCurrentAllocatedBytes(); +} + PipelineWasmCompilationJob::Status PipelineWasmCompilationJob::FinalizeJobImpl() { - pipeline_.GenerateCode(&linkage_); + pipeline_.AssembleCode(&linkage_); + pipeline_.FinalizeCode(); return SUCCEEDED; } @@ -765,12 +790,12 @@ struct GraphBuilderPhase { BytecodeGraphBuilder graph_builder( temp_zone, data->info()->shared_info(), handle(data->info()->closure()->feedback_vector()), - data->info()->osr_ast_id(), data->jsgraph(), 1.0f, + data->info()->osr_ast_id(), data->jsgraph(), CallFrequency(1.0f), data->source_positions(), SourcePosition::kNotInlined, flags); succeeded = graph_builder.CreateGraph(); } else { AstGraphBuilderWithPositions graph_builder( - temp_zone, data->info(), data->jsgraph(), 1.0f, + temp_zone, data->info(), data->jsgraph(), CallFrequency(1.0f), data->loop_assignment(), data->source_positions()); succeeded = graph_builder.CreateGraph(); } @@ -781,6 +806,30 @@ struct GraphBuilderPhase { } }; +namespace { + +Maybe<OuterContext> GetModuleContext(Handle<JSFunction> closure) { + Context* current = closure->context(); + size_t distance = 0; + while (!current->IsNativeContext()) { + if (current->IsModuleContext()) { + return Just(OuterContext(handle(current), distance)); + } + current = current->previous(); + distance++; + } + return Nothing<OuterContext>(); +} + +Maybe<OuterContext> ChooseSpecializationContext(CompilationInfo* info) { + if (info->is_function_context_specializing()) { + DCHECK(info->has_context()); + return Just(OuterContext(handle(info->context()), 0)); + } + return GetModuleContext(info->closure()); +} + +} // anonymous namespace struct InliningPhase { static const char* phase_name() { return "inlining"; } @@ -797,9 +846,7 @@ struct InliningPhase { data->info()->dependencies()); JSContextSpecialization context_specialization( &graph_reducer, data->jsgraph(), - data->info()->is_function_context_specializing() - ? handle(data->info()->context()) - : MaybeHandle<Context>(), + ChooseSpecializationContext(data->info()), data->info()->is_function_context_specializing() ? data->info()->closure() : MaybeHandle<JSFunction>()); @@ -1426,14 +1473,19 @@ struct JumpThreadingPhase { } }; +struct AssembleCodePhase { + static const char* phase_name() { return "assemble code"; } + + void Run(PipelineData* data, Zone* temp_zone) { + data->code_generator()->AssembleCode(); + } +}; -struct GenerateCodePhase { - static const char* phase_name() { return "generate code"; } +struct FinalizeCodePhase { + static const char* phase_name() { return "finalize code"; } - void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) { - CodeGenerator generator(data->frame(), linkage, data->sequence(), - data->info()); - data->set_code(generator.GenerateCode()); + void Run(PipelineData* data, Zone* temp_zone) { + data->set_code(data->code_generator()->FinalizeCode()); } }; @@ -1595,19 +1647,14 @@ bool PipelineImpl::OptimizeGraph(Linkage* linkage) { Run<SimplifiedLoweringPhase>(); RunPrintAndVerify("Simplified lowering", true); + // From now on it is invalid to look at types on the nodes, because the types + // on the nodes might not make sense after representation selection due to the + // way we handle truncations; if we'd want to look at types afterwards we'd + // essentially need to re-type (large portions of) the graph. + + // In order to catch bugs related to type access after this point, we now + // remove the types from the nodes (currently only in Debug builds). #ifdef DEBUG - // From now on it is invalid to look at types on the nodes, because: - // - // (a) The remaining passes (might) run concurrent to the main thread and - // therefore must not access the Heap or the Isolate in an uncontrolled - // way (as done by the type system), and - // (b) the types on the nodes might not make sense after representation - // selection due to the way we handle truncations; if we'd want to look - // at types afterwards we'd essentially need to re-type (large portions - // of) the graph. - // - // In order to catch bugs related to type access after this point we remove - // the types from the nodes at this point (currently only in Debug builds). Run<UntyperPhase>(); RunPrintAndVerify("Untyped", true); #endif @@ -1707,7 +1754,8 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info) { if (!pipeline.CreateGraph()) return Handle<Code>::null(); if (!pipeline.OptimizeGraph(&linkage)) return Handle<Code>::null(); - return pipeline.GenerateCode(&linkage); + pipeline.AssembleCode(&linkage); + return pipeline.FinalizeCode(); } // static @@ -1883,13 +1931,16 @@ bool PipelineImpl::ScheduleAndSelectInstructions(Linkage* linkage, return true; } -Handle<Code> PipelineImpl::GenerateCode(Linkage* linkage) { +void PipelineImpl::AssembleCode(Linkage* linkage) { PipelineData* data = this->data_; - data->BeginPhaseKind("code generation"); + data->InitializeCodeGenerator(linkage); + Run<AssembleCodePhase>(); +} - // Generate final machine code. - Run<GenerateCodePhase>(linkage); +Handle<Code> PipelineImpl::FinalizeCode() { + PipelineData* data = this->data_; + Run<FinalizeCodePhase>(); Handle<Code> code = data->code(); if (data->profiler_data()) { @@ -1937,7 +1988,8 @@ Handle<Code> PipelineImpl::ScheduleAndGenerateCode( if (!ScheduleAndSelectInstructions(&linkage, false)) return Handle<Code>(); // Generate the final machine code. - return GenerateCode(&linkage); + AssembleCode(&linkage); + return FinalizeCode(); } void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config, |