| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "base/trace_event/memory_dump_manager.h" | 5 #include "base/trace_event/memory_dump_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/atomic_sequence_num.h" | 10 #include "base/atomic_sequence_num.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 TRACE_EVENT_NESTABLE_ASYNC_END1( | 71 TRACE_EVENT_NESTABLE_ASYNC_END1( |
| 72 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", | 72 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", |
| 73 TRACE_ID_MANGLE(dump_guid), "success", success); | 73 TRACE_ID_MANGLE(dump_guid), "success", success); |
| 74 | 74 |
| 75 if (!wrapped_callback.is_null()) { | 75 if (!wrapped_callback.is_null()) { |
| 76 wrapped_callback.Run(dump_guid, success); | 76 wrapped_callback.Run(dump_guid, success); |
| 77 wrapped_callback.Reset(); | 77 wrapped_callback.Reset(); |
| 78 } | 78 } |
| 79 } | 79 } |
| 80 | 80 |
| 81 // Proxy class which wraps a ConvertableToTraceFormat owned by the |
| 82 // |session_state| into a proxy object that can be added to the trace event log. |
| 83 // This is to solve the problem that the MemoryDumpSessionState is refcounted |
| 84 // but the tracing subsystem wants a scoped_ptr<ConvertableToTraceFormat>. |
| 85 template <typename T> |
| 86 struct SessionStateConvertableProxy : public ConvertableToTraceFormat { |
| 87 using GetterFunctPtr = T* (MemoryDumpSessionState::*)() const; |
| 88 |
| 89 SessionStateConvertableProxy( |
| 90 scoped_refptr<MemoryDumpSessionState> session_state, |
| 91 GetterFunctPtr getter_function) |
| 92 : session_state(session_state), getter_function(getter_function) {} |
| 93 |
| 94 void AppendAsTraceFormat(std::string* out) const override { |
| 95 return (session_state.get()->*getter_function)()->AppendAsTraceFormat(out); |
| 96 } |
| 97 |
| 98 void EstimateTraceMemoryOverhead( |
| 99 TraceEventMemoryOverhead* overhead) override { |
| 100 return (session_state.get()->*getter_function)() |
| 101 ->EstimateTraceMemoryOverhead(overhead); |
| 102 } |
| 103 |
| 104 scoped_refptr<MemoryDumpSessionState> session_state; |
| 105 GetterFunctPtr const getter_function; |
| 106 }; |
| 107 |
| 81 } // namespace | 108 } // namespace |
| 82 | 109 |
| 83 // static | 110 // static |
| 84 const char* const MemoryDumpManager::kTraceCategory = | 111 const char* const MemoryDumpManager::kTraceCategory = |
| 85 TRACE_DISABLED_BY_DEFAULT("memory-infra"); | 112 TRACE_DISABLED_BY_DEFAULT("memory-infra"); |
| 86 | 113 |
| 87 // static | 114 // static |
| 88 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; | 115 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; |
| 89 | 116 |
| 90 // static | 117 // static |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 return; | 502 return; |
| 476 } | 503 } |
| 477 | 504 |
| 478 TRACE_EVENT_WITH_FLOW0(kTraceCategory, | 505 TRACE_EVENT_WITH_FLOW0(kTraceCategory, |
| 479 "MemoryDumpManager::FinalizeDumpAndAddToTrace", | 506 "MemoryDumpManager::FinalizeDumpAndAddToTrace", |
| 480 TRACE_ID_MANGLE(dump_guid), TRACE_EVENT_FLAG_FLOW_IN); | 507 TRACE_ID_MANGLE(dump_guid), TRACE_EVENT_FLAG_FLOW_IN); |
| 481 | 508 |
| 482 for (const auto& kv : pmd_async_state->process_dumps) { | 509 for (const auto& kv : pmd_async_state->process_dumps) { |
| 483 ProcessId pid = kv.first; // kNullProcessId for the current process. | 510 ProcessId pid = kv.first; // kNullProcessId for the current process. |
| 484 ProcessMemoryDump* process_memory_dump = kv.second.get(); | 511 ProcessMemoryDump* process_memory_dump = kv.second.get(); |
| 485 TracedValue* traced_value = new TracedValue(); | 512 TracedValue* traced_value = new TracedValue; |
| 486 scoped_refptr<ConvertableToTraceFormat> event_value(traced_value); | 513 scoped_ptr<ConvertableToTraceFormat> event_value(traced_value); |
| 487 process_memory_dump->AsValueInto(traced_value); | 514 process_memory_dump->AsValueInto(traced_value); |
| 488 traced_value->SetString("level_of_detail", | 515 traced_value->SetString("level_of_detail", |
| 489 MemoryDumpLevelOfDetailToString( | 516 MemoryDumpLevelOfDetailToString( |
| 490 pmd_async_state->req_args.level_of_detail)); | 517 pmd_async_state->req_args.level_of_detail)); |
| 491 const char* const event_name = | 518 const char* const event_name = |
| 492 MemoryDumpTypeToString(pmd_async_state->req_args.dump_type); | 519 MemoryDumpTypeToString(pmd_async_state->req_args.dump_type); |
| 493 | 520 |
| 494 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( | 521 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( |
| 495 TRACE_EVENT_PHASE_MEMORY_DUMP, | 522 TRACE_EVENT_PHASE_MEMORY_DUMP, |
| 496 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, | 523 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 // Spin-up the thread used to invoke unbound dump providers. | 555 // Spin-up the thread used to invoke unbound dump providers. |
| 529 scoped_ptr<Thread> dump_thread(new Thread("MemoryInfra")); | 556 scoped_ptr<Thread> dump_thread(new Thread("MemoryInfra")); |
| 530 if (!dump_thread->Start()) { | 557 if (!dump_thread->Start()) { |
| 531 LOG(ERROR) << "Failed to start the memory-infra thread for tracing"; | 558 LOG(ERROR) << "Failed to start the memory-infra thread for tracing"; |
| 532 return; | 559 return; |
| 533 } | 560 } |
| 534 | 561 |
| 535 AutoLock lock(lock_); | 562 AutoLock lock(lock_); |
| 536 | 563 |
| 537 DCHECK(delegate_); // At this point we must have a delegate. | 564 DCHECK(delegate_); // At this point we must have a delegate. |
| 538 | 565 session_state_ = new MemoryDumpSessionState; |
| 539 scoped_refptr<StackFrameDeduplicator> stack_frame_deduplicator = nullptr; | |
| 540 scoped_refptr<TypeNameDeduplicator> type_name_deduplicator = nullptr; | |
| 541 | 566 |
| 542 if (heap_profiling_enabled_) { | 567 if (heap_profiling_enabled_) { |
| 543 // If heap profiling is enabled, the stack frame deduplicator and type name | 568 // If heap profiling is enabled, the stack frame deduplicator and type name |
| 544 // deduplicator will be in use. Add a metadata events to write the frames | 569 // deduplicator will be in use. Add a metadata events to write the frames |
| 545 // and type IDs. | 570 // and type IDs. |
| 546 stack_frame_deduplicator = new StackFrameDeduplicator; | 571 session_state_->SetStackFrameDeduplicator( |
| 547 type_name_deduplicator = new TypeNameDeduplicator; | 572 make_scoped_ptr(new StackFrameDeduplicator)); |
| 573 |
| 574 session_state_->SetTypeNameDeduplicator( |
| 575 make_scoped_ptr(new TypeNameDeduplicator)); |
| 576 |
| 548 TRACE_EVENT_API_ADD_METADATA_EVENT( | 577 TRACE_EVENT_API_ADD_METADATA_EVENT( |
| 549 "stackFrames", "stackFrames", | 578 "stackFrames", "stackFrames", |
| 550 scoped_refptr<ConvertableToTraceFormat>(stack_frame_deduplicator)); | 579 make_scoped_ptr( |
| 580 new SessionStateConvertableProxy<StackFrameDeduplicator>( |
| 581 session_state_, |
| 582 &MemoryDumpSessionState::stack_frame_deduplicator))); |
| 583 |
| 551 TRACE_EVENT_API_ADD_METADATA_EVENT( | 584 TRACE_EVENT_API_ADD_METADATA_EVENT( |
| 552 "typeNames", "typeNames", | 585 "typeNames", "typeNames", |
| 553 scoped_refptr<ConvertableToTraceFormat>(type_name_deduplicator)); | 586 make_scoped_ptr(new SessionStateConvertableProxy<TypeNameDeduplicator>( |
| 587 session_state_, &MemoryDumpSessionState::type_name_deduplicator))); |
| 554 } | 588 } |
| 555 | 589 |
| 556 DCHECK(!dump_thread_); | 590 DCHECK(!dump_thread_); |
| 557 dump_thread_ = std::move(dump_thread); | 591 dump_thread_ = std::move(dump_thread); |
| 558 session_state_ = new MemoryDumpSessionState(stack_frame_deduplicator, | |
| 559 type_name_deduplicator); | |
| 560 | |
| 561 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); | 592 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); |
| 562 | 593 |
| 563 // TODO(primiano): This is a temporary hack to disable periodic memory dumps | 594 // TODO(primiano): This is a temporary hack to disable periodic memory dumps |
| 564 // when running memory benchmarks until telemetry uses TraceConfig to | 595 // when running memory benchmarks until telemetry uses TraceConfig to |
| 565 // enable/disable periodic dumps. See crbug.com/529184 . | 596 // enable/disable periodic dumps. See crbug.com/529184 . |
| 566 if (!is_coordinator_ || | 597 if (!is_coordinator_ || |
| 567 CommandLine::ForCurrentProcess()->HasSwitch( | 598 CommandLine::ForCurrentProcess()->HasSwitch( |
| 568 "enable-memory-benchmarking")) { | 599 "enable-memory-benchmarking")) { |
| 569 return; | 600 return; |
| 570 } | 601 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 auto iter = process_dumps.find(pid); | 703 auto iter = process_dumps.find(pid); |
| 673 if (iter == process_dumps.end()) { | 704 if (iter == process_dumps.end()) { |
| 674 scoped_ptr<ProcessMemoryDump> new_pmd(new ProcessMemoryDump(session_state)); | 705 scoped_ptr<ProcessMemoryDump> new_pmd(new ProcessMemoryDump(session_state)); |
| 675 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; | 706 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; |
| 676 } | 707 } |
| 677 return iter->second.get(); | 708 return iter->second.get(); |
| 678 } | 709 } |
| 679 | 710 |
| 680 } // namespace trace_event | 711 } // namespace trace_event |
| 681 } // namespace base | 712 } // namespace base |
| OLD | NEW |