Commit 601ee4eb authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[compiler] Untangle CompilationInfo allocated with new.

This removes the CompilationInfoWithZone class, which was used to
allocate a CompilationInfo on the C-heap. By now the CompilationJob is
the single object being allocated on the C-heap and passed between the
main thread and the compilation thread. Structs requiring destruction
can be embedded within that CompilationJob. This simplifies involved
lifetimes by coupling all lifetimes to one single object.

R=bmeurer@chromium.org

Review-Url: https://codereview.chromium.org/1930773003
Cr-Commit-Position: refs/heads/master@{#35936}
parent 81db29dd
...@@ -77,28 +77,6 @@ class CompilationHandleScope BASE_EMBEDDED { ...@@ -77,28 +77,6 @@ class CompilationHandleScope BASE_EMBEDDED {
CompilationInfo* info_; CompilationInfo* info_;
}; };
// Exactly like a CompilationInfo, except being allocated via {new} and it also
// creates and enters a Zone on construction and deallocates it on destruction.
class CompilationInfoWithZone : public CompilationInfo {
public:
explicit CompilationInfoWithZone(Handle<JSFunction> function)
: CompilationInfo(new ParseInfo(&zone_, function), function),
zone_(function->GetIsolate()->allocator()) {}
// Virtual destructor because a CompilationInfoWithZone has to exit the
// zone scope and get rid of dependent maps even when the destructor is
// called when cast as a CompilationInfo.
virtual ~CompilationInfoWithZone() {
DisableFutureOptimization();
dependencies()->Rollback();
delete parse_info_;
parse_info_ = nullptr;
}
private:
Zone zone_;
};
// Helper that times a scoped region and records the elapsed time. // Helper that times a scoped region and records the elapsed time.
struct ScopedTimer { struct ScopedTimer {
explicit ScopedTimer(base::TimeDelta* location) : location_(location) { explicit ScopedTimer(base::TimeDelta* location) : location_(location) {
...@@ -168,12 +146,8 @@ CompilationInfo::CompilationInfo(ParseInfo* parse_info, ...@@ -168,12 +146,8 @@ CompilationInfo::CompilationInfo(ParseInfo* parse_info,
CompilationInfo::~CompilationInfo() { CompilationInfo::~CompilationInfo() {
DisableFutureOptimization(); DisableFutureOptimization();
dependencies()->Rollback();
delete deferred_handles_; delete deferred_handles_;
#ifdef DEBUG
// Check that no dependent maps have been added or added dependent maps have
// been rolled back or committed.
DCHECK(dependencies()->IsEmpty());
#endif // DEBUG
} }
...@@ -669,15 +643,14 @@ bool Renumber(ParseInfo* parse_info) { ...@@ -669,15 +643,14 @@ bool Renumber(ParseInfo* parse_info) {
return true; return true;
} }
bool UseTurboFan(CompilationInfo* info) { bool UseTurboFan(Handle<SharedFunctionInfo> shared, BailoutId osr_ast_id) {
bool optimization_disabled = info->shared_info()->optimization_disabled(); bool optimization_disabled = shared->optimization_disabled();
bool dont_crankshaft = info->shared_info()->dont_crankshaft(); bool dont_crankshaft = shared->dont_crankshaft();
// Check the enabling conditions for Turbofan. // Check the enabling conditions for Turbofan.
// 1. "use asm" code. // 1. "use asm" code.
bool is_turbofanable_asm = FLAG_turbo_asm && bool is_turbofanable_asm =
info->shared_info()->asm_function() && FLAG_turbo_asm && shared->asm_function() && !optimization_disabled;
!optimization_disabled;
// 2. Fallback for features unsupported by Crankshaft. // 2. Fallback for features unsupported by Crankshaft.
bool is_unsupported_by_crankshaft_but_turbofanable = bool is_unsupported_by_crankshaft_but_turbofanable =
...@@ -685,11 +658,10 @@ bool UseTurboFan(CompilationInfo* info) { ...@@ -685,11 +658,10 @@ bool UseTurboFan(CompilationInfo* info) {
!optimization_disabled; !optimization_disabled;
// 3. Explicitly enabled by the command-line filter. // 3. Explicitly enabled by the command-line filter.
bool passes_turbo_filter = bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter);
info->shared_info()->PassesFilter(FLAG_turbo_filter);
// If this is OSR request, OSR must be enabled by Turbofan. // If this is OSR request, OSR must be enabled by Turbofan.
bool passes_osr_test = FLAG_turbo_osr || !info->is_osr(); bool passes_osr_test = FLAG_turbo_osr || osr_ast_id.IsNone();
return (is_turbofanable_asm || return (is_turbofanable_asm ||
is_unsupported_by_crankshaft_but_turbofanable || is_unsupported_by_crankshaft_but_turbofanable ||
...@@ -800,11 +772,14 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, ...@@ -800,11 +772,14 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
base::SmartPointer<CompilationInfo> info(
new CompilationInfoWithZone(function));
VMState<COMPILER> state(isolate); VMState<COMPILER> state(isolate);
DCHECK(!isolate->has_pending_exception()); DCHECK(!isolate->has_pending_exception());
PostponeInterruptsScope postpone(isolate); PostponeInterruptsScope postpone(isolate);
bool use_turbofan = UseTurboFan(shared, osr_ast_id);
base::SmartPointer<CompilationJob> job(
use_turbofan ? compiler::Pipeline::NewCompilationJob(function)
: new HCompilationJob(function));
CompilationInfo* info = job->info();
info->SetOptimizingForOsr(osr_ast_id); info->SetOptimizingForOsr(osr_ast_id);
...@@ -833,12 +808,7 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, ...@@ -833,12 +808,7 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate);
TRACE_EVENT0("v8", "V8.OptimizeCode"); TRACE_EVENT0("v8", "V8.OptimizeCode");
bool use_turbofan = UseTurboFan(info.get()); // TurboFan can optimize directly from existing bytecode.
base::SmartPointer<CompilationJob> job(
use_turbofan ? compiler::Pipeline::NewCompilationJob(info.get())
: new HCompilationJob(info.get()));
// TruboFan can optimize directly from existing bytecode.
if (FLAG_turbo_from_bytecode && use_turbofan && if (FLAG_turbo_from_bytecode && use_turbofan &&
info->shared_info()->HasBytecodeArray()) { info->shared_info()->HasBytecodeArray()) {
info->MarkAsOptimizeFromBytecode(); info->MarkAsOptimizeFromBytecode();
...@@ -846,7 +816,6 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, ...@@ -846,7 +816,6 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
if (mode == Compiler::CONCURRENT) { if (mode == Compiler::CONCURRENT) {
if (GetOptimizedCodeLater(job.get())) { if (GetOptimizedCodeLater(job.get())) {
info.Detach(); // The background recompile job owns this now.
job.Detach(); // The background recompile job owns this now. job.Detach(); // The background recompile job owns this now.
return isolate->builtins()->InOptimizationQueue(); return isolate->builtins()->InOptimizationQueue();
} }
...@@ -1755,10 +1724,10 @@ MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, ...@@ -1755,10 +1724,10 @@ MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame); return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame);
} }
void Compiler::FinalizeCompilationJob(CompilationJob* job) { void Compiler::FinalizeCompilationJob(CompilationJob* raw_job) {
// Take ownership of compilation info. Deleting compilation info // Take ownership of compilation job. Deleting job also tears down the zone.
// also tears down the zone. base::SmartPointer<CompilationJob> job(raw_job);
base::SmartPointer<CompilationInfo> info(job->info()); CompilationInfo* info = job->info();
Isolate* isolate = info->isolate(); Isolate* isolate = info->isolate();
VMState<COMPILER> state(isolate); VMState<COMPILER> state(isolate);
...@@ -1782,10 +1751,10 @@ void Compiler::FinalizeCompilationJob(CompilationJob* job) { ...@@ -1782,10 +1751,10 @@ void Compiler::FinalizeCompilationJob(CompilationJob* job) {
job->RetryOptimization(kBailedOutDueToDependencyChange); job->RetryOptimization(kBailedOutDueToDependencyChange);
} else if (job->GenerateCode() == CompilationJob::SUCCEEDED) { } else if (job->GenerateCode() == CompilationJob::SUCCEEDED) {
job->RecordOptimizationStats(); job->RecordOptimizationStats();
RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info.get()); RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info);
if (shared->SearchOptimizedCodeMap(info->context()->native_context(), if (shared->SearchOptimizedCodeMap(info->context()->native_context(),
info->osr_ast_id()).code == nullptr) { info->osr_ast_id()).code == nullptr) {
InsertCodeIntoOptimizedCodeMap(info.get()); InsertCodeIntoOptimizedCodeMap(info);
} }
if (FLAG_trace_opt) { if (FLAG_trace_opt) {
PrintF("[completed optimizing "); PrintF("[completed optimizing ");
...@@ -1793,7 +1762,6 @@ void Compiler::FinalizeCompilationJob(CompilationJob* job) { ...@@ -1793,7 +1762,6 @@ void Compiler::FinalizeCompilationJob(CompilationJob* job) {
PrintF("]\n"); PrintF("]\n");
} }
info->closure()->ReplaceCode(*info->code()); info->closure()->ReplaceCode(*info->code());
delete job;
return; return;
} }
} }
...@@ -1805,7 +1773,6 @@ void Compiler::FinalizeCompilationJob(CompilationJob* job) { ...@@ -1805,7 +1773,6 @@ void Compiler::FinalizeCompilationJob(CompilationJob* job) {
PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason()));
} }
info->closure()->ReplaceCode(shared->code()); info->closure()->ReplaceCode(shared->code());
delete job;
} }
void Compiler::PostInstantiation(Handle<JSFunction> function, void Compiler::PostInstantiation(Handle<JSFunction> function,
......
...@@ -139,7 +139,7 @@ struct InlinedFunctionInfo { ...@@ -139,7 +139,7 @@ struct InlinedFunctionInfo {
// CompilationInfo encapsulates some information known at compile time. It // CompilationInfo encapsulates some information known at compile time. It
// is constructed based on the resources available at compile-time. // is constructed based on the resources available at compile-time.
class CompilationInfo { class CompilationInfo final {
public: public:
// Various configuration flags for a compilation, as well as some properties // Various configuration flags for a compilation, as well as some properties
// of the compiled code produced by a compilation. // of the compiled code produced by a compilation.
...@@ -167,7 +167,7 @@ class CompilationInfo { ...@@ -167,7 +167,7 @@ class CompilationInfo {
CompilationInfo(ParseInfo* parse_info, Handle<JSFunction> closure); CompilationInfo(ParseInfo* parse_info, Handle<JSFunction> closure);
CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone, CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone,
Code::Flags code_flags = Code::ComputeFlags(Code::STUB)); Code::Flags code_flags = Code::ComputeFlags(Code::STUB));
virtual ~CompilationInfo(); ~CompilationInfo();
ParseInfo* parse_info() const { return parse_info_; } ParseInfo* parse_info() const { return parse_info_; }
...@@ -573,7 +573,6 @@ class CompilationInfo { ...@@ -573,7 +573,6 @@ class CompilationInfo {
// as well. When failing we distinguish between the following levels: // as well. When failing we distinguish between the following levels:
// a) AbortOptimization: Persistent failure, disable future optimization. // a) AbortOptimization: Persistent failure, disable future optimization.
// b) RetryOptimzation: Transient failure, try again next time. // b) RetryOptimzation: Transient failure, try again next time.
// TODO(mstarzinger): Make CompilationInfo base embedded.
class CompilationJob { class CompilationJob {
public: public:
explicit CompilationJob(CompilationInfo* info, const char* compiler_name) explicit CompilationJob(CompilationInfo* info, const char* compiler_name)
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include "src/compiler/zone-pool.h" #include "src/compiler/zone-pool.h"
#include "src/isolate-inl.h" #include "src/isolate-inl.h"
#include "src/ostreams.h" #include "src/ostreams.h"
#include "src/parsing/parser.h"
#include "src/register-configuration.h" #include "src/register-configuration.h"
#include "src/type-info.h" #include "src/type-info.h"
#include "src/utils.h" #include "src/utils.h"
...@@ -502,13 +503,18 @@ PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info, ...@@ -502,13 +503,18 @@ PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info,
class PipelineCompilationJob final : public CompilationJob { class PipelineCompilationJob final : public CompilationJob {
public: public:
explicit PipelineCompilationJob(CompilationInfo* info) PipelineCompilationJob(Isolate* isolate, Handle<JSFunction> function)
: CompilationJob(info, "TurboFan"), // Note that the CompilationInfo is not initialized at the time we pass it
zone_pool_(info->isolate()->allocator()), // to the CompilationJob constructor, but it is not dereferenced there.
pipeline_statistics_(CreatePipelineStatistics(info, &zone_pool_)), : CompilationJob(&info_, "TurboFan"),
data_(&zone_pool_, info, pipeline_statistics_.get()), zone_(isolate->allocator()),
zone_pool_(isolate->allocator()),
parse_info_(&zone_, function),
info_(&parse_info_, function),
pipeline_statistics_(CreatePipelineStatistics(info(), &zone_pool_)),
data_(&zone_pool_, info(), pipeline_statistics_.get()),
pipeline_(&data_), pipeline_(&data_),
linkage_(Linkage::ComputeIncoming(info->zone(), info)) {} linkage_(nullptr) {}
protected: protected:
Status CreateGraphImpl() final; Status CreateGraphImpl() final;
...@@ -516,11 +522,14 @@ class PipelineCompilationJob final : public CompilationJob { ...@@ -516,11 +522,14 @@ class PipelineCompilationJob final : public CompilationJob {
Status GenerateCodeImpl() final; Status GenerateCodeImpl() final;
private: private:
Zone zone_;
ZonePool zone_pool_; ZonePool zone_pool_;
ParseInfo parse_info_;
CompilationInfo info_;
base::SmartPointer<PipelineStatistics> pipeline_statistics_; base::SmartPointer<PipelineStatistics> pipeline_statistics_;
PipelineData data_; PipelineData data_;
Pipeline pipeline_; Pipeline pipeline_;
Linkage linkage_; Linkage* linkage_;
}; };
PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() { PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() {
...@@ -542,6 +551,8 @@ PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() { ...@@ -542,6 +551,8 @@ PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() {
if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED; if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED;
} }
linkage_ = new (&zone_) Linkage(Linkage::ComputeIncoming(&zone_, info()));
if (!pipeline_.CreateGraph()) { if (!pipeline_.CreateGraph()) {
if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed.
return AbortOptimization(kGraphBuildingFailed); return AbortOptimization(kGraphBuildingFailed);
...@@ -551,12 +562,12 @@ PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() { ...@@ -551,12 +562,12 @@ PipelineCompilationJob::Status PipelineCompilationJob::CreateGraphImpl() {
} }
PipelineCompilationJob::Status PipelineCompilationJob::OptimizeGraphImpl() { PipelineCompilationJob::Status PipelineCompilationJob::OptimizeGraphImpl() {
if (!pipeline_.OptimizeGraph(&linkage_)) return FAILED; if (!pipeline_.OptimizeGraph(linkage_)) return FAILED;
return SUCCEEDED; return SUCCEEDED;
} }
PipelineCompilationJob::Status PipelineCompilationJob::GenerateCodeImpl() { PipelineCompilationJob::Status PipelineCompilationJob::GenerateCodeImpl() {
Handle<Code> code = pipeline_.GenerateCode(&linkage_); Handle<Code> code = pipeline_.GenerateCode(linkage_);
if (code.is_null()) { if (code.is_null()) {
if (info()->bailout_reason() == kNoReason) { if (info()->bailout_reason() == kNoReason) {
return AbortOptimization(kCodeGenerationFailed); return AbortOptimization(kCodeGenerationFailed);
...@@ -1523,8 +1534,8 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, ...@@ -1523,8 +1534,8 @@ Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info,
} }
// static // static
CompilationJob* Pipeline::NewCompilationJob(CompilationInfo* info) { CompilationJob* Pipeline::NewCompilationJob(Handle<JSFunction> function) {
return new PipelineCompilationJob(info); return new PipelineCompilationJob(function->GetIsolate(), function);
} }
// static // static
......
...@@ -72,8 +72,8 @@ class Pipeline { ...@@ -72,8 +72,8 @@ class Pipeline {
Graph* graph, Graph* graph,
Schedule* schedule = nullptr); Schedule* schedule = nullptr);
// Returns a new compilation job for the given compilation info. // Returns a new compilation job for the given function.
static CompilationJob* NewCompilationJob(CompilationInfo* info); static CompilationJob* NewCompilationJob(Handle<JSFunction> function);
// Returns a new compilation job for the WebAssembly compilation info. // Returns a new compilation job for the WebAssembly compilation info.
static CompilationJob* NewWasmCompilationJob( static CompilationJob* NewWasmCompilationJob(
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "src/compiler.h" #include "src/compiler.h"
#include "src/crankshaft/compilation-phase.h" #include "src/crankshaft/compilation-phase.h"
#include "src/crankshaft/hydrogen-instructions.h" #include "src/crankshaft/hydrogen-instructions.h"
#include "src/parsing/parser.h"
#include "src/zone.h" #include "src/zone.h"
namespace v8 { namespace v8 {
...@@ -32,8 +33,13 @@ class LiveRange; ...@@ -32,8 +33,13 @@ class LiveRange;
class HCompilationJob final : public CompilationJob { class HCompilationJob final : public CompilationJob {
public: public:
explicit HCompilationJob(CompilationInfo* info) explicit HCompilationJob(Handle<JSFunction> function)
: CompilationJob(info, "Crankshaft"), graph_(nullptr), chunk_(nullptr) {} : CompilationJob(&info_, "Crankshaft"),
zone_(function->GetIsolate()->allocator()),
parse_info_(&zone_, function),
info_(&parse_info_, function),
graph_(nullptr),
chunk_(nullptr) {}
protected: protected:
virtual Status CreateGraphImpl(); virtual Status CreateGraphImpl();
...@@ -41,6 +47,9 @@ class HCompilationJob final : public CompilationJob { ...@@ -41,6 +47,9 @@ class HCompilationJob final : public CompilationJob {
virtual Status GenerateCodeImpl(); virtual Status GenerateCodeImpl();
private: private:
Zone zone_;
ParseInfo parse_info_;
CompilationInfo info_;
HGraph* graph_; HGraph* graph_;
LChunk* chunk_; LChunk* chunk_;
}; };
......
...@@ -16,14 +16,11 @@ namespace internal { ...@@ -16,14 +16,11 @@ namespace internal {
namespace { namespace {
void DisposeCompilationJob(CompilationJob* job, bool restore_function_code) { void DisposeCompilationJob(CompilationJob* job, bool restore_function_code) {
// The recompile job is allocated in the CompilationInfo's zone.
CompilationInfo* info = job->info();
if (restore_function_code) { if (restore_function_code) {
Handle<JSFunction> function = info->closure(); Handle<JSFunction> function = job->info()->closure();
function->ReplaceCode(function->shared()->code()); function->ReplaceCode(function->shared()->code());
} }
delete job; delete job;
delete info;
} }
} // namespace } // namespace
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment