aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/pipeline.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/pipeline.cc')
-rw-r--r--deps/v8/src/compiler/pipeline.cc122
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,