OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/inspector/V8HeapProfilerAgentImpl.h" | 5 #include "src/inspector/V8HeapProfilerAgentImpl.h" |
6 | 6 |
7 #include "src/inspector/InjectedScript.h" | 7 #include "src/inspector/InjectedScript.h" |
8 #include "src/inspector/StringUtil.h" | 8 #include "src/inspector/StringUtil.h" |
9 #include "src/inspector/V8Debugger.h" | 9 #include "src/inspector/V8Debugger.h" |
10 #include "src/inspector/V8InspectorImpl.h" | 10 #include "src/inspector/V8InspectorImpl.h" |
11 #include "src/inspector/V8InspectorSessionImpl.h" | 11 #include "src/inspector/V8InspectorSessionImpl.h" |
12 #include "src/inspector/protocol/Protocol.h" | 12 #include "src/inspector/protocol/Protocol.h" |
13 | 13 |
14 #include "include/v8-inspector.h" | 14 #include "include/v8-inspector.h" |
15 #include "include/v8-profiler.h" | 15 #include "include/v8-profiler.h" |
16 #include "include/v8-version.h" | 16 #include "include/v8-version.h" |
17 | 17 |
18 namespace v8_inspector { | 18 namespace v8_inspector { |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 namespace HeapProfilerAgentState { | 22 namespace HeapProfilerAgentState { |
23 static const char heapProfilerEnabled[] = "heapProfilerEnabled"; | 23 static const char heapProfilerEnabled[] = "heapProfilerEnabled"; |
24 static const char heapObjectsTrackingEnabled[] = "heapObjectsTrackingEnabled"; | 24 static const char heapObjectsTrackingEnabled[] = "heapObjectsTrackingEnabled"; |
25 static const char allocationTrackingEnabled[] = "allocationTrackingEnabled"; | 25 static const char allocationTrackingEnabled[] = "allocationTrackingEnabled"; |
26 #if V8_MAJOR_VERSION >= 5 | |
27 static const char samplingHeapProfilerEnabled[] = "samplingHeapProfilerEnabled"; | 26 static const char samplingHeapProfilerEnabled[] = "samplingHeapProfilerEnabled"; |
28 static const char samplingHeapProfilerInterval[] = | 27 static const char samplingHeapProfilerInterval[] = |
29 "samplingHeapProfilerInterval"; | 28 "samplingHeapProfilerInterval"; |
30 #endif | |
31 } | 29 } |
32 | 30 |
33 class HeapSnapshotProgress final : public v8::ActivityControl { | 31 class HeapSnapshotProgress final : public v8::ActivityControl { |
34 public: | 32 public: |
35 HeapSnapshotProgress(protocol::HeapProfiler::Frontend* frontend) | 33 HeapSnapshotProgress(protocol::HeapProfiler::Frontend* frontend) |
36 : m_frontend(frontend) {} | 34 : m_frontend(frontend) {} |
37 ControlOption ReportProgressValue(int done, int total) override { | 35 ControlOption ReportProgressValue(int done, int total) override { |
38 m_frontend->reportHeapSnapshotProgress(done, total, | 36 m_frontend->reportHeapSnapshotProgress(done, total, |
39 protocol::Maybe<bool>()); | 37 protocol::Maybe<bool>()); |
40 if (done >= total) { | 38 if (done >= total) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 V8HeapProfilerAgentImpl::~V8HeapProfilerAgentImpl() {} | 155 V8HeapProfilerAgentImpl::~V8HeapProfilerAgentImpl() {} |
158 | 156 |
159 void V8HeapProfilerAgentImpl::restore() { | 157 void V8HeapProfilerAgentImpl::restore() { |
160 if (m_state->booleanProperty(HeapProfilerAgentState::heapProfilerEnabled, | 158 if (m_state->booleanProperty(HeapProfilerAgentState::heapProfilerEnabled, |
161 false)) | 159 false)) |
162 m_frontend.resetProfiles(); | 160 m_frontend.resetProfiles(); |
163 if (m_state->booleanProperty( | 161 if (m_state->booleanProperty( |
164 HeapProfilerAgentState::heapObjectsTrackingEnabled, false)) | 162 HeapProfilerAgentState::heapObjectsTrackingEnabled, false)) |
165 startTrackingHeapObjectsInternal(m_state->booleanProperty( | 163 startTrackingHeapObjectsInternal(m_state->booleanProperty( |
166 HeapProfilerAgentState::allocationTrackingEnabled, false)); | 164 HeapProfilerAgentState::allocationTrackingEnabled, false)); |
167 #if V8_MAJOR_VERSION >= 5 | |
168 if (m_state->booleanProperty( | 165 if (m_state->booleanProperty( |
169 HeapProfilerAgentState::samplingHeapProfilerEnabled, false)) { | 166 HeapProfilerAgentState::samplingHeapProfilerEnabled, false)) { |
170 ErrorString error; | 167 ErrorString error; |
171 double samplingInterval = m_state->doubleProperty( | 168 double samplingInterval = m_state->doubleProperty( |
172 HeapProfilerAgentState::samplingHeapProfilerInterval, -1); | 169 HeapProfilerAgentState::samplingHeapProfilerInterval, -1); |
173 DCHECK_GE(samplingInterval, 0); | 170 DCHECK_GE(samplingInterval, 0); |
174 startSampling(&error, Maybe<double>(samplingInterval)); | 171 startSampling(&error, Maybe<double>(samplingInterval)); |
175 } | 172 } |
176 #endif | |
177 } | 173 } |
178 | 174 |
179 void V8HeapProfilerAgentImpl::collectGarbage(ErrorString*) { | 175 void V8HeapProfilerAgentImpl::collectGarbage(ErrorString*) { |
180 m_isolate->LowMemoryNotification(); | 176 m_isolate->LowMemoryNotification(); |
181 } | 177 } |
182 | 178 |
183 void V8HeapProfilerAgentImpl::startTrackingHeapObjects( | 179 void V8HeapProfilerAgentImpl::startTrackingHeapObjects( |
184 ErrorString*, const protocol::Maybe<bool>& trackAllocations) { | 180 ErrorString*, const protocol::Maybe<bool>& trackAllocations) { |
185 m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, true); | 181 m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, true); |
186 bool allocationTrackingEnabled = trackAllocations.fromMaybe(false); | 182 bool allocationTrackingEnabled = trackAllocations.fromMaybe(false); |
187 m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, | 183 m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, |
188 allocationTrackingEnabled); | 184 allocationTrackingEnabled); |
189 startTrackingHeapObjectsInternal(allocationTrackingEnabled); | 185 startTrackingHeapObjectsInternal(allocationTrackingEnabled); |
190 } | 186 } |
191 | 187 |
192 void V8HeapProfilerAgentImpl::stopTrackingHeapObjects( | 188 void V8HeapProfilerAgentImpl::stopTrackingHeapObjects( |
193 ErrorString* error, const protocol::Maybe<bool>& reportProgress) { | 189 ErrorString* error, const protocol::Maybe<bool>& reportProgress) { |
194 requestHeapStatsUpdate(); | 190 requestHeapStatsUpdate(); |
195 takeHeapSnapshot(error, reportProgress); | 191 takeHeapSnapshot(error, reportProgress); |
196 stopTrackingHeapObjectsInternal(); | 192 stopTrackingHeapObjectsInternal(); |
197 } | 193 } |
198 | 194 |
199 void V8HeapProfilerAgentImpl::enable(ErrorString*) { | 195 void V8HeapProfilerAgentImpl::enable(ErrorString*) { |
200 m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, true); | 196 m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, true); |
201 } | 197 } |
202 | 198 |
203 void V8HeapProfilerAgentImpl::disable(ErrorString* error) { | 199 void V8HeapProfilerAgentImpl::disable(ErrorString* error) { |
204 stopTrackingHeapObjectsInternal(); | 200 stopTrackingHeapObjectsInternal(); |
205 #if V8_MAJOR_VERSION >= 5 | |
206 if (m_state->booleanProperty( | 201 if (m_state->booleanProperty( |
207 HeapProfilerAgentState::samplingHeapProfilerEnabled, false)) { | 202 HeapProfilerAgentState::samplingHeapProfilerEnabled, false)) { |
208 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); | 203 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); |
209 if (profiler) profiler->StopSamplingHeapProfiler(); | 204 if (profiler) profiler->StopSamplingHeapProfiler(); |
210 } | 205 } |
211 #endif | |
212 m_isolate->GetHeapProfiler()->ClearObjectIds(); | 206 m_isolate->GetHeapProfiler()->ClearObjectIds(); |
213 m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, false); | 207 m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, false); |
214 } | 208 } |
215 | 209 |
216 void V8HeapProfilerAgentImpl::takeHeapSnapshot( | 210 void V8HeapProfilerAgentImpl::takeHeapSnapshot( |
217 ErrorString* errorString, const protocol::Maybe<bool>& reportProgress) { | 211 ErrorString* errorString, const protocol::Maybe<bool>& reportProgress) { |
218 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); | 212 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); |
219 if (!profiler) { | 213 if (!profiler) { |
220 *errorString = "Cannot access v8 heap profiler"; | 214 *errorString = "Cannot access v8 heap profiler"; |
221 return; | 215 return; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 m_hasTimer = false; | 327 m_hasTimer = false; |
334 } | 328 } |
335 m_isolate->GetHeapProfiler()->StopTrackingHeapObjects(); | 329 m_isolate->GetHeapProfiler()->StopTrackingHeapObjects(); |
336 m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, | 330 m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, |
337 false); | 331 false); |
338 m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, false); | 332 m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, false); |
339 } | 333 } |
340 | 334 |
341 void V8HeapProfilerAgentImpl::startSampling( | 335 void V8HeapProfilerAgentImpl::startSampling( |
342 ErrorString* errorString, const Maybe<double>& samplingInterval) { | 336 ErrorString* errorString, const Maybe<double>& samplingInterval) { |
343 #if V8_MAJOR_VERSION >= 5 | |
344 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); | 337 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); |
345 if (!profiler) { | 338 if (!profiler) { |
346 *errorString = "Cannot access v8 heap profiler"; | 339 *errorString = "Cannot access v8 heap profiler"; |
347 return; | 340 return; |
348 } | 341 } |
349 const unsigned defaultSamplingInterval = 1 << 15; | 342 const unsigned defaultSamplingInterval = 1 << 15; |
350 double samplingIntervalValue = | 343 double samplingIntervalValue = |
351 samplingInterval.fromMaybe(defaultSamplingInterval); | 344 samplingInterval.fromMaybe(defaultSamplingInterval); |
352 m_state->setDouble(HeapProfilerAgentState::samplingHeapProfilerInterval, | 345 m_state->setDouble(HeapProfilerAgentState::samplingHeapProfilerInterval, |
353 samplingIntervalValue); | 346 samplingIntervalValue); |
354 m_state->setBoolean(HeapProfilerAgentState::samplingHeapProfilerEnabled, | 347 m_state->setBoolean(HeapProfilerAgentState::samplingHeapProfilerEnabled, |
355 true); | 348 true); |
356 #if V8_MAJOR_VERSION * 1000 + V8_MINOR_VERSION >= 5002 | |
357 profiler->StartSamplingHeapProfiler( | 349 profiler->StartSamplingHeapProfiler( |
358 static_cast<uint64_t>(samplingIntervalValue), 128, | 350 static_cast<uint64_t>(samplingIntervalValue), 128, |
359 v8::HeapProfiler::kSamplingForceGC); | 351 v8::HeapProfiler::kSamplingForceGC); |
360 #else | |
361 profiler->StartSamplingHeapProfiler( | |
362 static_cast<uint64_t>(samplingIntervalValue), 128); | |
363 #endif | |
364 #endif | |
365 } | 352 } |
366 | 353 |
367 #if V8_MAJOR_VERSION >= 5 | |
368 namespace { | 354 namespace { |
369 std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfileNode> | 355 std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfileNode> |
370 buildSampingHeapProfileNode(const v8::AllocationProfile::Node* node) { | 356 buildSampingHeapProfileNode(const v8::AllocationProfile::Node* node) { |
371 auto children = protocol::Array< | 357 auto children = protocol::Array< |
372 protocol::HeapProfiler::SamplingHeapProfileNode>::create(); | 358 protocol::HeapProfiler::SamplingHeapProfileNode>::create(); |
373 for (const auto* child : node->children) | 359 for (const auto* child : node->children) |
374 children->addItem(buildSampingHeapProfileNode(child)); | 360 children->addItem(buildSampingHeapProfileNode(child)); |
375 size_t selfSize = 0; | 361 size_t selfSize = 0; |
376 for (const auto& allocation : node->allocations) | 362 for (const auto& allocation : node->allocations) |
377 selfSize += allocation.size * allocation.count; | 363 selfSize += allocation.size * allocation.count; |
378 std::unique_ptr<protocol::Runtime::CallFrame> callFrame = | 364 std::unique_ptr<protocol::Runtime::CallFrame> callFrame = |
379 protocol::Runtime::CallFrame::create() | 365 protocol::Runtime::CallFrame::create() |
380 .setFunctionName(toProtocolString(node->name)) | 366 .setFunctionName(toProtocolString(node->name)) |
381 .setScriptId(String16::fromInteger(node->script_id)) | 367 .setScriptId(String16::fromInteger(node->script_id)) |
382 .setUrl(toProtocolString(node->script_name)) | 368 .setUrl(toProtocolString(node->script_name)) |
383 .setLineNumber(node->line_number - 1) | 369 .setLineNumber(node->line_number - 1) |
384 .setColumnNumber(node->column_number - 1) | 370 .setColumnNumber(node->column_number - 1) |
385 .build(); | 371 .build(); |
386 std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfileNode> result = | 372 std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfileNode> result = |
387 protocol::HeapProfiler::SamplingHeapProfileNode::create() | 373 protocol::HeapProfiler::SamplingHeapProfileNode::create() |
388 .setCallFrame(std::move(callFrame)) | 374 .setCallFrame(std::move(callFrame)) |
389 .setSelfSize(selfSize) | 375 .setSelfSize(selfSize) |
390 .setChildren(std::move(children)) | 376 .setChildren(std::move(children)) |
391 .build(); | 377 .build(); |
392 return result; | 378 return result; |
393 } | 379 } |
394 } // namespace | 380 } // namespace |
395 #endif | |
396 | 381 |
397 void V8HeapProfilerAgentImpl::stopSampling( | 382 void V8HeapProfilerAgentImpl::stopSampling( |
398 ErrorString* errorString, | 383 ErrorString* errorString, |
399 std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfile>* profile) { | 384 std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfile>* profile) { |
400 #if V8_MAJOR_VERSION >= 5 | |
401 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); | 385 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); |
402 if (!profiler) { | 386 if (!profiler) { |
403 *errorString = "Cannot access v8 heap profiler"; | 387 *errorString = "Cannot access v8 heap profiler"; |
404 return; | 388 return; |
405 } | 389 } |
406 v8::HandleScope scope( | 390 v8::HandleScope scope( |
407 m_isolate); // Allocation profile contains Local handles. | 391 m_isolate); // Allocation profile contains Local handles. |
408 std::unique_ptr<v8::AllocationProfile> v8Profile( | 392 std::unique_ptr<v8::AllocationProfile> v8Profile( |
409 profiler->GetAllocationProfile()); | 393 profiler->GetAllocationProfile()); |
410 profiler->StopSamplingHeapProfiler(); | 394 profiler->StopSamplingHeapProfiler(); |
411 m_state->setBoolean(HeapProfilerAgentState::samplingHeapProfilerEnabled, | 395 m_state->setBoolean(HeapProfilerAgentState::samplingHeapProfilerEnabled, |
412 false); | 396 false); |
413 if (!v8Profile) { | 397 if (!v8Profile) { |
414 *errorString = "Cannot access v8 sampled heap profile."; | 398 *errorString = "Cannot access v8 sampled heap profile."; |
415 return; | 399 return; |
416 } | 400 } |
417 v8::AllocationProfile::Node* root = v8Profile->GetRootNode(); | 401 v8::AllocationProfile::Node* root = v8Profile->GetRootNode(); |
418 *profile = protocol::HeapProfiler::SamplingHeapProfile::create() | 402 *profile = protocol::HeapProfiler::SamplingHeapProfile::create() |
419 .setHead(buildSampingHeapProfileNode(root)) | 403 .setHead(buildSampingHeapProfileNode(root)) |
420 .build(); | 404 .build(); |
421 #endif | |
422 } | 405 } |
423 | 406 |
424 } // namespace v8_inspector | 407 } // namespace v8_inspector |
OLD | NEW |