| 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 |