Commit 611a0d19 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Don't allocate JSHeapBroker in the zone

This fixes a memory leak.

Bug: v8:9191, v8:7790
Change-Id: I0df49cd3a6791600638a67b4b7ad9687562e500b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1588426
Commit-Queue: Georg Neis <neis@chromium.org>
Auto-Submit: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61166}
parent b6fb2707
...@@ -776,7 +776,7 @@ struct FeedbackSource { ...@@ -776,7 +776,7 @@ struct FeedbackSource {
}; };
}; };
class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) { class V8_EXPORT_PRIVATE JSHeapBroker {
public: public:
JSHeapBroker(Isolate* isolate, Zone* broker_zone); JSHeapBroker(Isolate* isolate, Zone* broker_zone);
......
...@@ -113,6 +113,7 @@ class PipelineData { ...@@ -113,6 +113,7 @@ class PipelineData {
instruction_zone_(instruction_zone_scope_.zone()), instruction_zone_(instruction_zone_scope_.zone()),
codegen_zone_scope_(zone_stats_, ZONE_NAME), codegen_zone_scope_(zone_stats_, ZONE_NAME),
codegen_zone_(codegen_zone_scope_.zone()), codegen_zone_(codegen_zone_scope_.zone()),
broker_(new JSHeapBroker(isolate_, info_->zone())),
register_allocation_zone_scope_(zone_stats_, ZONE_NAME), register_allocation_zone_scope_(zone_stats_, ZONE_NAME),
register_allocation_zone_(register_allocation_zone_scope_.zone()), register_allocation_zone_(register_allocation_zone_scope_.zone()),
assembler_options_(AssemblerOptions::Default(isolate)) { assembler_options_(AssemblerOptions::Default(isolate)) {
...@@ -131,7 +132,6 @@ class PipelineData { ...@@ -131,7 +132,6 @@ class PipelineData {
javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_); javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_);
jsgraph_ = new (graph_zone_) jsgraph_ = new (graph_zone_)
JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_); JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_);
broker_ = new (info_->zone()) JSHeapBroker(isolate_, info_->zone());
dependencies_ = dependencies_ =
new (info_->zone()) CompilationDependencies(broker_, info_->zone()); new (info_->zone()) CompilationDependencies(broker_, info_->zone());
} }
...@@ -226,7 +226,6 @@ class PipelineData { ...@@ -226,7 +226,6 @@ class PipelineData {
delete code_generator_; delete code_generator_;
code_generator_ = nullptr; code_generator_ = nullptr;
DeleteTyper(); DeleteTyper();
DeleteRegisterAllocationZone(); DeleteRegisterAllocationZone();
DeleteInstructionZone(); DeleteInstructionZone();
DeleteCodegenZone(); DeleteCodegenZone();
...@@ -274,6 +273,11 @@ class PipelineData { ...@@ -274,6 +273,11 @@ class PipelineData {
} }
JSHeapBroker* broker() const { return broker_; } JSHeapBroker* broker() const { return broker_; }
std::unique_ptr<JSHeapBroker> ReleaseBroker() {
std::unique_ptr<JSHeapBroker> broker(broker_);
broker_ = nullptr;
return broker;
}
Schedule* schedule() const { return schedule_; } Schedule* schedule() const { return schedule_; }
void set_schedule(Schedule* schedule) { void set_schedule(Schedule* schedule) {
...@@ -362,6 +366,7 @@ class PipelineData { ...@@ -362,6 +366,7 @@ class PipelineData {
codegen_zone_scope_.Destroy(); codegen_zone_scope_.Destroy();
codegen_zone_ = nullptr; codegen_zone_ = nullptr;
dependencies_ = nullptr; dependencies_ = nullptr;
delete broker_;
broker_ = nullptr; broker_ = nullptr;
frame_ = nullptr; frame_ = nullptr;
} }
...@@ -419,7 +424,6 @@ class PipelineData { ...@@ -419,7 +424,6 @@ class PipelineData {
void InitializeCodeGenerator(Linkage* linkage, void InitializeCodeGenerator(Linkage* linkage,
std::unique_ptr<AssemblerBuffer> buffer) { std::unique_ptr<AssemblerBuffer> buffer) {
DCHECK_NULL(code_generator_); DCHECK_NULL(code_generator_);
code_generator_ = new CodeGenerator( code_generator_ = new CodeGenerator(
codegen_zone(), frame(), linkage, sequence(), info(), isolate(), codegen_zone(), frame(), linkage, sequence(), info(), isolate(),
osr_helper_, start_source_position_, jump_optimization_info_, osr_helper_, start_source_position_, jump_optimization_info_,
...@@ -2370,16 +2374,12 @@ MaybeHandle<Code> Pipeline::GenerateCodeForWasmHeapStub( ...@@ -2370,16 +2374,12 @@ MaybeHandle<Code> Pipeline::GenerateCodeForWasmHeapStub(
// static // static
MaybeHandle<Code> Pipeline::GenerateCodeForTesting( MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
OptimizedCompilationInfo* info, Isolate* isolate, OptimizedCompilationInfo* info, Isolate* isolate,
JSHeapBroker** out_broker) { std::unique_ptr<JSHeapBroker>* out_broker) {
ZoneStats zone_stats(isolate->allocator()); ZoneStats zone_stats(isolate->allocator());
std::unique_ptr<PipelineStatistics> pipeline_statistics( std::unique_ptr<PipelineStatistics> pipeline_statistics(
CreatePipelineStatistics(Handle<Script>::null(), info, isolate, CreatePipelineStatistics(Handle<Script>::null(), info, isolate,
&zone_stats)); &zone_stats));
PipelineData data(&zone_stats, isolate, info, pipeline_statistics.get()); PipelineData data(&zone_stats, isolate, info, pipeline_statistics.get());
if (out_broker != nullptr) {
*out_broker = data.broker();
}
PipelineImpl pipeline(&data); PipelineImpl pipeline(&data);
Linkage linkage(Linkage::ComputeIncoming(data.instruction_zone(), info)); Linkage linkage(Linkage::ComputeIncoming(data.instruction_zone(), info));
...@@ -2391,6 +2391,7 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting( ...@@ -2391,6 +2391,7 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
Handle<Code> code; Handle<Code> code;
if (pipeline.FinalizeCode(out_broker == nullptr).ToHandle(&code) && if (pipeline.FinalizeCode(out_broker == nullptr).ToHandle(&code) &&
pipeline.CommitDependencies(code)) { pipeline.CommitDependencies(code)) {
if (out_broker != nullptr) *out_broker = data.ReleaseBroker();
return code; return code;
} }
return MaybeHandle<Code>(); return MaybeHandle<Code>();
......
...@@ -79,12 +79,12 @@ class Pipeline : public AllStatic { ...@@ -79,12 +79,12 @@ class Pipeline : public AllStatic {
// The following methods are for testing purposes only. Avoid production use. // The following methods are for testing purposes only. Avoid production use.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Run the pipeline on JavaScript bytecode and generate code. // Run the pipeline on JavaScript bytecode and generate code. If requested,
// If requested, hands out the heap broker, which is allocated // hands out the heap broker on success, transferring its ownership to the
// in {info}'s zone. // caller.
V8_EXPORT_PRIVATE static MaybeHandle<Code> GenerateCodeForTesting( V8_EXPORT_PRIVATE static MaybeHandle<Code> GenerateCodeForTesting(
OptimizedCompilationInfo* info, Isolate* isolate, OptimizedCompilationInfo* info, Isolate* isolate,
JSHeapBroker** out_broker = nullptr); std::unique_ptr<JSHeapBroker>* out_broker = nullptr);
// Run the pipeline on a machine graph and generate code. If {schedule} is // Run the pipeline on a machine graph and generate code. If {schedule} is
// {nullptr}, then compute a new schedule for code generation. // {nullptr}, then compute a new schedule for code generation.
......
...@@ -225,10 +225,9 @@ HandleAndZoneScope::HandleAndZoneScope() ...@@ -225,10 +225,9 @@ HandleAndZoneScope::HandleAndZoneScope()
HandleAndZoneScope::~HandleAndZoneScope() = default; HandleAndZoneScope::~HandleAndZoneScope() = default;
i::Handle<i::JSFunction> Optimize(i::Handle<i::JSFunction> function, i::Handle<i::JSFunction> Optimize(
i::Zone* zone, i::Isolate* isolate, i::Handle<i::JSFunction> function, i::Zone* zone, i::Isolate* isolate,
uint32_t flags, uint32_t flags, std::unique_ptr<i::compiler::JSHeapBroker>* out_broker) {
i::compiler::JSHeapBroker** out_broker) {
i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate); i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate);
i::IsCompiledScope is_compiled_scope(shared->is_compiled_scope()); i::IsCompiledScope is_compiled_scope(shared->is_compiled_scope());
CHECK(is_compiled_scope.is_compiled() || CHECK(is_compiled_scope.is_compiled() ||
......
...@@ -500,11 +500,13 @@ static inline v8::Local<v8::Value> CompileRunWithOrigin( ...@@ -500,11 +500,13 @@ static inline v8::Local<v8::Value> CompileRunWithOrigin(
// Takes a JSFunction and runs it through the test version of the optimizing // Takes a JSFunction and runs it through the test version of the optimizing
// pipeline, allocating the temporary compilation artifacts in a given Zone. // pipeline, allocating the temporary compilation artifacts in a given Zone.
// For possible {flags} values, look at OptimizedCompilationInfo::Flag. // For possible {flags} values, look at OptimizedCompilationInfo::Flag. If
// If passed a non-null pointer for {broker}, outputs the JSHeapBroker to it. // {out_broker} is not nullptr, returns the JSHeapBroker via that (transferring
// ownership to the caller).
i::Handle<i::JSFunction> Optimize( i::Handle<i::JSFunction> Optimize(
i::Handle<i::JSFunction> function, i::Zone* zone, i::Isolate* isolate, i::Handle<i::JSFunction> function, i::Zone* zone, i::Isolate* isolate,
uint32_t flags, i::compiler::JSHeapBroker** out_broker = nullptr); uint32_t flags,
std::unique_ptr<i::compiler::JSHeapBroker>* out_broker = nullptr);
static inline void ExpectString(const char* code, const char* expected) { static inline void ExpectString(const char* code, const char* expected) {
v8::Local<v8::Value> result = CompileRun(code); v8::Local<v8::Value> result = CompileRun(code);
......
...@@ -45,7 +45,7 @@ SerializerTester::SerializerTester(const char* source) ...@@ -45,7 +45,7 @@ SerializerTester::SerializerTester(const char* source)
i::OptimizedCompilationInfo::kSplittingEnabled | i::OptimizedCompilationInfo::kSplittingEnabled |
i::OptimizedCompilationInfo::kAnalyzeEnvironmentLiveness; i::OptimizedCompilationInfo::kAnalyzeEnvironmentLiveness;
Optimize(function, main_zone(), main_isolate(), flags, &broker_); Optimize(function, main_zone(), main_isolate(), flags, &broker_);
function_ = JSFunctionRef(broker_, function); function_ = JSFunctionRef(broker(), function);
} }
TEST(SerializeEmptyFunction) { TEST(SerializeEmptyFunction) {
......
...@@ -27,13 +27,13 @@ class SerializerTester : public HandleAndZoneScope { ...@@ -27,13 +27,13 @@ class SerializerTester : public HandleAndZoneScope {
explicit SerializerTester(const char* source); explicit SerializerTester(const char* source);
JSFunctionRef function() const { return function_.value(); } JSFunctionRef function() const { return function_.value(); }
JSHeapBroker* broker() const { return broker_; } JSHeapBroker* broker() const { return broker_.get(); }
Isolate* isolate() { return main_isolate(); } Isolate* isolate() { return main_isolate(); }
private: private:
CanonicalHandleScope canonical_; CanonicalHandleScope canonical_;
base::Optional<JSFunctionRef> function_; base::Optional<JSFunctionRef> function_;
JSHeapBroker* broker_ = nullptr; std::unique_ptr<JSHeapBroker> broker_;
}; };
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
......
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