| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium 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 "platform/v8_inspector/V8HeapProfilerAgentImpl.h" | 5 #include "platform/v8_inspector/V8HeapProfilerAgentImpl.h" |
| 6 | 6 |
| 7 #include "platform/v8_inspector/InjectedScript.h" | 7 #include "platform/v8_inspector/InjectedScript.h" |
| 8 #include "platform/v8_inspector/V8DebuggerImpl.h" | 8 #include "platform/v8_inspector/V8InspectorImpl.h" |
| 9 #include "platform/v8_inspector/V8InspectorSessionImpl.h" | 9 #include "platform/v8_inspector/V8InspectorSessionImpl.h" |
| 10 #include "platform/v8_inspector/V8StringUtil.h" | 10 #include "platform/v8_inspector/V8StringUtil.h" |
| 11 #include "platform/v8_inspector/public/V8DebuggerClient.h" | 11 #include "platform/v8_inspector/public/V8InspectorClient.h" |
| 12 #include <v8-profiler.h> | 12 #include <v8-profiler.h> |
| 13 #include <v8-version.h> | 13 #include <v8-version.h> |
| 14 | 14 |
| 15 namespace blink { | 15 namespace blink { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 namespace HeapProfilerAgentState { | 19 namespace HeapProfilerAgentState { |
| 20 static const char heapProfilerEnabled[] = "heapProfilerEnabled"; | 20 static const char heapProfilerEnabled[] = "heapProfilerEnabled"; |
| 21 static const char heapObjectsTrackingEnabled[] = "heapObjectsTrackingEnabled"; | 21 static const char heapObjectsTrackingEnabled[] = "heapObjectsTrackingEnabled"; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 43 protocol::HeapProfiler::Frontend* m_frontend; | 43 protocol::HeapProfiler::Frontend* m_frontend; |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 class GlobalObjectNameResolver final : public v8::HeapProfiler::ObjectNameResolv
er { | 46 class GlobalObjectNameResolver final : public v8::HeapProfiler::ObjectNameResolv
er { |
| 47 public: | 47 public: |
| 48 explicit GlobalObjectNameResolver(V8InspectorSessionImpl* session) | 48 explicit GlobalObjectNameResolver(V8InspectorSessionImpl* session) |
| 49 : m_offset(0), m_strings(10000), m_session(session) {} | 49 : m_offset(0), m_strings(10000), m_session(session) {} |
| 50 | 50 |
| 51 const char* GetName(v8::Local<v8::Object> object) override | 51 const char* GetName(v8::Local<v8::Object> object) override |
| 52 { | 52 { |
| 53 int contextId = V8DebuggerImpl::contextId(object->CreationContext()); | 53 int contextId = V8InspectorImpl::contextId(object->CreationContext()); |
| 54 if (!contextId) | 54 if (!contextId) |
| 55 return ""; | 55 return ""; |
| 56 ErrorString errorString; | 56 ErrorString errorString; |
| 57 InjectedScript* injectedScript = m_session->findInjectedScript(&errorStr
ing, contextId); | 57 InjectedScript* injectedScript = m_session->findInjectedScript(&errorStr
ing, contextId); |
| 58 if (!injectedScript) | 58 if (!injectedScript) |
| 59 return ""; | 59 return ""; |
| 60 String16 name = injectedScript->context()->origin(); | 60 String16 name = injectedScript->context()->origin(); |
| 61 size_t length = name.length(); | 61 size_t length = name.length(); |
| 62 if (m_offset + length + 1 >= m_strings.size()) | 62 if (m_offset + length + 1 >= m_strings.size()) |
| 63 return ""; | 63 return ""; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 142 } |
| 143 | 143 |
| 144 private: | 144 private: |
| 145 protocol::HeapProfiler::Frontend* m_frontend; | 145 protocol::HeapProfiler::Frontend* m_frontend; |
| 146 }; | 146 }; |
| 147 | 147 |
| 148 } // namespace | 148 } // namespace |
| 149 | 149 |
| 150 V8HeapProfilerAgentImpl::V8HeapProfilerAgentImpl(V8InspectorSessionImpl* session
, protocol::FrontendChannel* frontendChannel, protocol::DictionaryValue* state) | 150 V8HeapProfilerAgentImpl::V8HeapProfilerAgentImpl(V8InspectorSessionImpl* session
, protocol::FrontendChannel* frontendChannel, protocol::DictionaryValue* state) |
| 151 : m_session(session) | 151 : m_session(session) |
| 152 , m_isolate(session->debugger()->isolate()) | 152 , m_isolate(session->inspector()->isolate()) |
| 153 , m_frontend(frontendChannel) | 153 , m_frontend(frontendChannel) |
| 154 , m_state(state) | 154 , m_state(state) |
| 155 , m_hasTimer(false) | 155 , m_hasTimer(false) |
| 156 { | 156 { |
| 157 } | 157 } |
| 158 | 158 |
| 159 V8HeapProfilerAgentImpl::~V8HeapProfilerAgentImpl() | 159 V8HeapProfilerAgentImpl::~V8HeapProfilerAgentImpl() |
| 160 { | 160 { |
| 161 } | 161 } |
| 162 | 162 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 return; | 246 return; |
| 247 } | 247 } |
| 248 | 248 |
| 249 v8::HandleScope handles(m_isolate); | 249 v8::HandleScope handles(m_isolate); |
| 250 v8::Local<v8::Object> heapObject = objectByHeapObjectId(m_isolate, id); | 250 v8::Local<v8::Object> heapObject = objectByHeapObjectId(m_isolate, id); |
| 251 if (heapObject.IsEmpty()) { | 251 if (heapObject.IsEmpty()) { |
| 252 *error = "Object is not available"; | 252 *error = "Object is not available"; |
| 253 return; | 253 return; |
| 254 } | 254 } |
| 255 | 255 |
| 256 if (!m_session->debugger()->client()->isInspectableHeapObject(heapObject)) { | 256 if (!m_session->inspector()->client()->isInspectableHeapObject(heapObject))
{ |
| 257 *error = "Object is not available"; | 257 *error = "Object is not available"; |
| 258 return; | 258 return; |
| 259 } | 259 } |
| 260 | 260 |
| 261 *result = m_session->wrapObject(heapObject->CreationContext(), heapObject, o
bjectGroup.fromMaybe(""), false); | 261 *result = m_session->wrapObject(heapObject->CreationContext(), heapObject, o
bjectGroup.fromMaybe(""), false); |
| 262 if (!result) | 262 if (!result) |
| 263 *error = "Object is not available"; | 263 *error = "Object is not available"; |
| 264 } | 264 } |
| 265 | 265 |
| 266 void V8HeapProfilerAgentImpl::addInspectedHeapObject(ErrorString* errorString, c
onst String16& inspectedHeapObjectId) | 266 void V8HeapProfilerAgentImpl::addInspectedHeapObject(ErrorString* errorString, c
onst String16& inspectedHeapObjectId) |
| 267 { | 267 { |
| 268 bool ok; | 268 bool ok; |
| 269 int id = inspectedHeapObjectId.toInt(&ok); | 269 int id = inspectedHeapObjectId.toInt(&ok); |
| 270 if (!ok) { | 270 if (!ok) { |
| 271 *errorString = "Invalid heap snapshot object id"; | 271 *errorString = "Invalid heap snapshot object id"; |
| 272 return; | 272 return; |
| 273 } | 273 } |
| 274 | 274 |
| 275 v8::HandleScope handles(m_isolate); | 275 v8::HandleScope handles(m_isolate); |
| 276 v8::Local<v8::Object> heapObject = objectByHeapObjectId(m_isolate, id); | 276 v8::Local<v8::Object> heapObject = objectByHeapObjectId(m_isolate, id); |
| 277 if (heapObject.IsEmpty()) { | 277 if (heapObject.IsEmpty()) { |
| 278 *errorString = "Object is not available"; | 278 *errorString = "Object is not available"; |
| 279 return; | 279 return; |
| 280 } | 280 } |
| 281 | 281 |
| 282 if (!m_session->debugger()->client()->isInspectableHeapObject(heapObject)) { | 282 if (!m_session->inspector()->client()->isInspectableHeapObject(heapObject))
{ |
| 283 *errorString = "Object is not available"; | 283 *errorString = "Object is not available"; |
| 284 return; | 284 return; |
| 285 } | 285 } |
| 286 | 286 |
| 287 m_session->addInspectedObject(wrapUnique(new InspectableHeapObject(id))); | 287 m_session->addInspectedObject(wrapUnique(new InspectableHeapObject(id))); |
| 288 } | 288 } |
| 289 | 289 |
| 290 void V8HeapProfilerAgentImpl::getHeapObjectId(ErrorString* errorString, const St
ring16& objectId, String16* heapSnapshotObjectId) | 290 void V8HeapProfilerAgentImpl::getHeapObjectId(ErrorString* errorString, const St
ring16& objectId, String16* heapSnapshotObjectId) |
| 291 { | 291 { |
| 292 v8::HandleScope handles(m_isolate); | 292 v8::HandleScope handles(m_isolate); |
| 293 v8::Local<v8::Value> value; | 293 v8::Local<v8::Value> value; |
| 294 v8::Local<v8::Context> context; | 294 v8::Local<v8::Context> context; |
| 295 String16 objectGroup; | 295 String16 objectGroup; |
| 296 if (!m_session->unwrapObject(errorString, objectId, &value, &context, &objec
tGroup) || value->IsUndefined()) | 296 if (!m_session->unwrapObject(errorString, objectId, &value, &context, &objec
tGroup) || value->IsUndefined()) |
| 297 return; | 297 return; |
| 298 | 298 |
| 299 v8::SnapshotObjectId id = m_isolate->GetHeapProfiler()->GetObjectId(value); | 299 v8::SnapshotObjectId id = m_isolate->GetHeapProfiler()->GetObjectId(value); |
| 300 *heapSnapshotObjectId = String16::fromInteger(id); | 300 *heapSnapshotObjectId = String16::fromInteger(id); |
| 301 } | 301 } |
| 302 | 302 |
| 303 void V8HeapProfilerAgentImpl::requestHeapStatsUpdate() | 303 void V8HeapProfilerAgentImpl::requestHeapStatsUpdate() |
| 304 { | 304 { |
| 305 HeapStatsStream stream(&m_frontend); | 305 HeapStatsStream stream(&m_frontend); |
| 306 v8::SnapshotObjectId lastSeenObjectId = m_isolate->GetHeapProfiler()->GetHea
pStats(&stream); | 306 v8::SnapshotObjectId lastSeenObjectId = m_isolate->GetHeapProfiler()->GetHea
pStats(&stream); |
| 307 m_frontend.lastSeenObjectId(lastSeenObjectId, m_session->debugger()->client(
)->currentTimeMS()); | 307 m_frontend.lastSeenObjectId(lastSeenObjectId, m_session->inspector()->client
()->currentTimeMS()); |
| 308 } | 308 } |
| 309 | 309 |
| 310 // static | 310 // static |
| 311 void V8HeapProfilerAgentImpl::onTimer(void* data) | 311 void V8HeapProfilerAgentImpl::onTimer(void* data) |
| 312 { | 312 { |
| 313 reinterpret_cast<V8HeapProfilerAgentImpl*>(data)->requestHeapStatsUpdate(); | 313 reinterpret_cast<V8HeapProfilerAgentImpl*>(data)->requestHeapStatsUpdate(); |
| 314 } | 314 } |
| 315 | 315 |
| 316 void V8HeapProfilerAgentImpl::startTrackingHeapObjectsInternal(bool trackAllocat
ions) | 316 void V8HeapProfilerAgentImpl::startTrackingHeapObjectsInternal(bool trackAllocat
ions) |
| 317 { | 317 { |
| 318 m_isolate->GetHeapProfiler()->StartTrackingHeapObjects(trackAllocations); | 318 m_isolate->GetHeapProfiler()->StartTrackingHeapObjects(trackAllocations); |
| 319 if (!m_hasTimer) { | 319 if (!m_hasTimer) { |
| 320 m_hasTimer = true; | 320 m_hasTimer = true; |
| 321 m_session->debugger()->client()->startRepeatingTimer(0.05, &V8HeapProfil
erAgentImpl::onTimer, reinterpret_cast<void*>(this)); | 321 m_session->inspector()->client()->startRepeatingTimer(0.05, &V8HeapProfi
lerAgentImpl::onTimer, reinterpret_cast<void*>(this)); |
| 322 } | 322 } |
| 323 } | 323 } |
| 324 | 324 |
| 325 void V8HeapProfilerAgentImpl::stopTrackingHeapObjectsInternal() | 325 void V8HeapProfilerAgentImpl::stopTrackingHeapObjectsInternal() |
| 326 { | 326 { |
| 327 if (m_hasTimer) { | 327 if (m_hasTimer) { |
| 328 m_session->debugger()->client()->cancelTimer(reinterpret_cast<void*>(thi
s)); | 328 m_session->inspector()->client()->cancelTimer(reinterpret_cast<void*>(th
is)); |
| 329 m_hasTimer = false; | 329 m_hasTimer = false; |
| 330 } | 330 } |
| 331 m_isolate->GetHeapProfiler()->StopTrackingHeapObjects(); | 331 m_isolate->GetHeapProfiler()->StopTrackingHeapObjects(); |
| 332 m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, fals
e); | 332 m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, fals
e); |
| 333 m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, false
); | 333 m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, false
); |
| 334 } | 334 } |
| 335 | 335 |
| 336 void V8HeapProfilerAgentImpl::startSampling(ErrorString* errorString, const Mayb
e<double>& samplingInterval) | 336 void V8HeapProfilerAgentImpl::startSampling(ErrorString* errorString, const Mayb
e<double>& samplingInterval) |
| 337 { | 337 { |
| 338 #if V8_MAJOR_VERSION >= 5 | 338 #if V8_MAJOR_VERSION >= 5 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 *errorString = "Cannot access v8 sampled heap profile."; | 395 *errorString = "Cannot access v8 sampled heap profile."; |
| 396 return; | 396 return; |
| 397 } | 397 } |
| 398 v8::AllocationProfile::Node* root = v8Profile->GetRootNode(); | 398 v8::AllocationProfile::Node* root = v8Profile->GetRootNode(); |
| 399 *profile = protocol::HeapProfiler::SamplingHeapProfile::create() | 399 *profile = protocol::HeapProfiler::SamplingHeapProfile::create() |
| 400 .setHead(buildSampingHeapProfileNode(root)).build(); | 400 .setHead(buildSampingHeapProfileNode(root)).build(); |
| 401 #endif | 401 #endif |
| 402 } | 402 } |
| 403 | 403 |
| 404 } // namespace blink | 404 } // namespace blink |
| OLD | NEW |