[M120 Migration] Set IO|GPU thread type with higher priorites
[platform/framework/web/chromium-efl.git] / gin / v8_isolate_memory_dump_provider_unittest.cc
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gin/v8_isolate_memory_dump_provider.h"
6
7 #include <memory>
8
9 #include "base/containers/contains.h"
10 #include "base/task/single_thread_task_runner.h"
11 #include "base/task/thread_pool/thread_pool_instance.h"
12 #include "base/trace_event/process_memory_dump.h"
13 #include "base/trace_event/trace_event.h"
14 #include "build/build_config.h"
15 #include "gin/public/isolate_holder.h"
16 #include "gin/test/v8_test.h"
17 #include "v8/include/v8-initialization.h"
18
19 namespace gin {
20
21 class V8MemoryDumpProviderTest : public V8Test {
22   void SetUp() override {
23     // Sets the track objects flag for dumping object statistics. Set this
24     // before initializing V8, because flags should not be modified after
25     // initialization. Also, setting the flag as early as possible ensures more
26     // precise numbers.
27     v8::V8::SetFlagsFromString("--track-gc-object-stats");
28     V8Test::SetUp();
29   }
30 };
31
32 class V8MemoryDumpProviderWorkerTest : public V8MemoryDumpProviderTest {
33  protected:
34   std::unique_ptr<IsolateHolder> CreateIsolateHolder() const override {
35     return std::make_unique<gin::IsolateHolder>(
36         base::SingleThreadTaskRunner::GetCurrentDefault(),
37         gin::IsolateHolder::IsolateType::kBlinkWorkerThread);
38   }
39 };
40
41 // Checks if the dump provider runs without crashing and dumps root objects.
42 TEST_F(V8MemoryDumpProviderTest, DumpStatistics) {
43   base::trace_event::MemoryDumpArgs dump_args = {
44       base::trace_event::MemoryDumpLevelOfDetail::kDetailed};
45   std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
46       new base::trace_event::ProcessMemoryDump(dump_args));
47   instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
48       dump_args, process_memory_dump.get());
49   const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
50       allocator_dumps = process_memory_dump->allocator_dumps();
51
52   bool did_dump_isolate_stats = false;
53   bool did_dump_space_stats = false;
54   bool did_dump_objects_stats = false;
55   for (const auto& name_dump : allocator_dumps) {
56     const std::string& name = name_dump.first;
57     if (base::Contains(name, "v8/main")) {
58       did_dump_isolate_stats = true;
59     }
60     if (base::Contains(name, "v8/main/heap")) {
61       did_dump_space_stats = true;
62     }
63     if (base::Contains(name, "v8/main/heap_objects")) {
64       did_dump_objects_stats = true;
65     }
66   }
67
68   ASSERT_TRUE(did_dump_isolate_stats);
69   ASSERT_TRUE(did_dump_space_stats);
70   ASSERT_TRUE(did_dump_objects_stats);
71 }
72
73 TEST_F(V8MemoryDumpProviderTest, DumpGlobalHandlesSize) {
74   base::trace_event::MemoryDumpArgs dump_args = {
75       base::trace_event::MemoryDumpLevelOfDetail::kBackground};
76   std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
77       new base::trace_event::ProcessMemoryDump(dump_args));
78   instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
79       dump_args, process_memory_dump.get());
80   const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
81       allocator_dumps = process_memory_dump->allocator_dumps();
82
83   bool did_dump_global_handles = false;
84   for (const auto& name_dump : allocator_dumps) {
85     const std::string& name = name_dump.first;
86     if (base::Contains(name, "v8/main/global_handles")) {
87       did_dump_global_handles = true;
88     }
89   }
90
91   ASSERT_TRUE(did_dump_global_handles);
92 }
93
94 TEST_F(V8MemoryDumpProviderTest, DumpContextStatistics) {
95   base::trace_event::MemoryDumpArgs dump_args = {
96       base::trace_event::MemoryDumpLevelOfDetail::kLight};
97   std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
98       new base::trace_event::ProcessMemoryDump(dump_args));
99   instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
100       dump_args, process_memory_dump.get());
101   const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
102       allocator_dumps = process_memory_dump->allocator_dumps();
103
104   bool did_dump_detached_contexts = false;
105   bool did_dump_native_contexts = false;
106   for (const auto& name_dump : allocator_dumps) {
107     const std::string& name = name_dump.first;
108     if (base::Contains(name, "main/contexts/detached_context")) {
109       did_dump_detached_contexts = true;
110     }
111     if (base::Contains(name, "main/contexts/native_context")) {
112       did_dump_native_contexts = true;
113     }
114   }
115
116   ASSERT_TRUE(did_dump_detached_contexts);
117   ASSERT_TRUE(did_dump_native_contexts);
118 }
119
120 TEST_F(V8MemoryDumpProviderWorkerTest, DumpContextStatistics) {
121   base::trace_event::MemoryDumpArgs dump_args = {
122       base::trace_event::MemoryDumpLevelOfDetail::kLight};
123   std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
124       new base::trace_event::ProcessMemoryDump(dump_args));
125   instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
126       dump_args, process_memory_dump.get());
127   const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
128       allocator_dumps = process_memory_dump->allocator_dumps();
129
130   bool did_dump_detached_contexts = false;
131   bool did_dump_native_contexts = false;
132   for (const auto& name_dump : allocator_dumps) {
133     const std::string& name = name_dump.first;
134     if (base::Contains(name, "workers/contexts/detached_context/isolate_0x")) {
135       did_dump_detached_contexts = true;
136     }
137     if (base::Contains(name, "workers/contexts/native_context/isolate_0x")) {
138       did_dump_native_contexts = true;
139     }
140   }
141
142   ASSERT_TRUE(did_dump_detached_contexts);
143   ASSERT_TRUE(did_dump_native_contexts);
144 }
145
146 TEST_F(V8MemoryDumpProviderTest, DumpCodeStatistics) {
147   // Code stats are disabled unless this category is enabled.
148   base::trace_event::TraceLog::GetInstance()->SetEnabled(
149       base::trace_event::TraceConfig(
150           TRACE_DISABLED_BY_DEFAULT("memory-infra.v8.code_stats"), ""),
151       base::trace_event::TraceLog::RECORDING_MODE);
152
153   base::trace_event::MemoryDumpArgs dump_args = {
154       base::trace_event::MemoryDumpLevelOfDetail::kLight};
155   std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
156       new base::trace_event::ProcessMemoryDump(dump_args));
157   instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
158       dump_args, process_memory_dump.get());
159   const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
160       allocator_dumps = process_memory_dump->allocator_dumps();
161
162   bool did_dump_bytecode_size = false;
163   bool did_dump_code_size = false;
164   bool did_dump_external_scripts_size = false;
165   bool did_dump_cpu_profiler_metadata_size = false;
166
167   for (const auto& name_dump : allocator_dumps) {
168     const std::string& name = name_dump.first;
169     if (base::Contains(name, "code_stats")) {
170       for (const base::trace_event::MemoryAllocatorDump::Entry& entry :
171            name_dump.second->entries()) {
172         if (base::Contains(entry.name, "bytecode_and_metadata_size")) {
173           did_dump_bytecode_size = true;
174         } else if (base::Contains(entry.name, "code_and_metadata_size")) {
175           did_dump_code_size = true;
176         } else if (base::Contains(entry.name, "external_script_source_size")) {
177           did_dump_external_scripts_size = true;
178         } else if (base::Contains(entry.name, "cpu_profiler_metadata_size")) {
179           did_dump_cpu_profiler_metadata_size = true;
180         }
181       }
182     }
183   }
184   base::trace_event::TraceLog::GetInstance()->SetDisabled();
185
186   ASSERT_TRUE(did_dump_bytecode_size);
187   ASSERT_TRUE(did_dump_code_size);
188   ASSERT_TRUE(did_dump_external_scripts_size);
189   ASSERT_TRUE(did_dump_cpu_profiler_metadata_size);
190 }
191
192 // Tests that a deterministic memory dump request performs a GC.
193 TEST_F(V8MemoryDumpProviderTest, Deterministic) {
194   base::trace_event::MemoryDumpArgs dump_args = {
195       base::trace_event::MemoryDumpLevelOfDetail::kLight,
196       base::trace_event::MemoryDumpDeterminism::kForceGc};
197   std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
198       new base::trace_event::ProcessMemoryDump(dump_args));
199
200   // Allocate an object that has only a weak reference.
201   v8::Global<v8::Object> weak_ref;
202   {
203     v8::HandleScope scope(instance_->isolate());
204     v8::Local<v8::Object> object = v8::Object::New(instance_->isolate());
205     weak_ref.Reset(instance_->isolate(), object);
206     weak_ref.SetWeak();
207   }
208
209   // Deterministic memory dump should trigger GC.
210   instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
211       dump_args, process_memory_dump.get());
212
213   // GC reclaimed the object.
214   ASSERT_TRUE(weak_ref.IsEmpty());
215 }
216
217 }  // namespace gin