Skip to content

Commit 14ac02c

Browse files
a1phCommit Bot
authored andcommitted
[cpu-profiler] Clear code entries when no observers are present.
Performed manual testing as well by making 20 CPU profile recordings of loading http://meduza.io page. Without the patch the page renderer memory size grows beyond 300MB. With the patch it remains below 200MB. BUG=v8:6623 Change-Id: Ifce541b84bb2aaaa5175520f8dd49dbc0cb5dd20 Reviewed-on: https://chromium-review.googlesource.com/798020 Commit-Queue: Alexei Filippov <alph@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#49914}
1 parent 27cff23 commit 14ac02c

File tree

3 files changed

+44
-15
lines changed

3 files changed

+44
-15
lines changed

src/profiler/profiler-listener.cc

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ namespace internal {
1616
ProfilerListener::ProfilerListener(Isolate* isolate)
1717
: function_and_resource_names_(isolate->heap()) {}
1818

19-
ProfilerListener::~ProfilerListener() {
20-
for (auto code_entry : code_entries_) {
21-
delete code_entry;
22-
}
23-
}
19+
ProfilerListener::~ProfilerListener() = default;
2420

2521
void ProfilerListener::CallbackEvent(Name* name, Address entry_point) {
2622
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
@@ -274,19 +270,23 @@ CodeEntry* ProfilerListener::NewCodeEntry(
274270
CodeEventListener::LogEventsAndTags tag, const char* name,
275271
const char* name_prefix, const char* resource_name, int line_number,
276272
int column_number, JITLineInfoTable* line_info, Address instruction_start) {
277-
CodeEntry* code_entry =
278-
new CodeEntry(tag, name, name_prefix, resource_name, line_number,
279-
column_number, line_info, instruction_start);
280-
code_entries_.push_back(code_entry);
281-
return code_entry;
273+
std::unique_ptr<CodeEntry> code_entry = base::make_unique<CodeEntry>(
274+
tag, name, name_prefix, resource_name, line_number, column_number,
275+
line_info, instruction_start);
276+
CodeEntry* raw_code_entry = code_entry.get();
277+
code_entries_.push_back(std::move(code_entry));
278+
return raw_code_entry;
282279
}
283280

284281
void ProfilerListener::AddObserver(CodeEventObserver* observer) {
285282
base::LockGuard<base::Mutex> guard(&mutex_);
286-
if (std::find(observers_.begin(), observers_.end(), observer) !=
287-
observers_.end())
288-
return;
289-
observers_.push_back(observer);
283+
if (observers_.empty()) {
284+
code_entries_.clear();
285+
}
286+
if (std::find(observers_.begin(), observers_.end(), observer) ==
287+
observers_.end()) {
288+
observers_.push_back(observer);
289+
}
290290
}
291291

292292
void ProfilerListener::RemoveObserver(CodeEventObserver* observer) {

src/profiler/profiler-listener.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class ProfilerListener : public CodeEventListener {
7373
const char* GetFunctionName(const char* name) {
7474
return function_and_resource_names_.GetFunctionName(name);
7575
}
76+
size_t entries_count_for_test() const { return code_entries_.size(); }
7677

7778
private:
7879
void RecordInliningInfo(CodeEntry* entry, AbstractCode* abstract_code);
@@ -86,7 +87,7 @@ class ProfilerListener : public CodeEventListener {
8687
}
8788

8889
StringsStorage function_and_resource_names_;
89-
std::vector<CodeEntry*> code_entries_;
90+
std::vector<std::unique_ptr<CodeEntry>> code_entries_;
9091
std::vector<CodeEventObserver*> observers_;
9192
base::Mutex mutex_;
9293

test/cctest/test-cpu-profiler.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,6 +2267,34 @@ TEST(StaticCollectSampleAPI) {
22672267
profile->Delete();
22682268
}
22692269

2270+
TEST(CodeEntriesMemoryLeak) {
2271+
v8::HandleScope scope(CcTest::isolate());
2272+
v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
2273+
v8::Context::Scope context_scope(env);
2274+
2275+
std::string source = "function start() {}\n";
2276+
for (int i = 0; i < 1000; ++i) {
2277+
source += "function foo" + std::to_string(i) + "() { return " +
2278+
std::to_string(i) +
2279+
"; }\n"
2280+
"foo" +
2281+
std::to_string(i) + "();\n";
2282+
}
2283+
CompileRun(source.c_str());
2284+
v8::Local<v8::Function> function = GetFunction(env, "start");
2285+
2286+
ProfilerHelper helper(env);
2287+
2288+
for (int j = 0; j < 100; ++j) {
2289+
v8::CpuProfile* profile = helper.Run(function, nullptr, 0);
2290+
profile->Delete();
2291+
}
2292+
ProfilerListener* profiler_listener =
2293+
CcTest::i_isolate()->logger()->profiler_listener();
2294+
2295+
CHECK_GE(10000ul, profiler_listener->entries_count_for_test());
2296+
}
2297+
22702298
} // namespace test_cpu_profiler
22712299
} // namespace internal
22722300
} // namespace v8

0 commit comments

Comments
 (0)