| 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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 return; | 547 return; |
| 521 } | 548 } |
| 522 | 549 |
| 523 TRACE_EVENT_WITH_FLOW0(kTraceCategory, | 550 TRACE_EVENT_WITH_FLOW0(kTraceCategory, |
| 524 "MemoryDumpManager::FinalizeDumpAndAddToTrace", | 551 "MemoryDumpManager::FinalizeDumpAndAddToTrace", |
| 525 TRACE_ID_MANGLE(dump_guid), TRACE_EVENT_FLAG_FLOW_IN); | 552 TRACE_ID_MANGLE(dump_guid), TRACE_EVENT_FLAG_FLOW_IN); |
| 526 | 553 |
| 527 for (const auto& kv : pmd_async_state->process_dumps) { | 554 for (const auto& kv : pmd_async_state->process_dumps) { |
| 528 ProcessId pid = kv.first; // kNullProcessId for the current process. | 555 ProcessId pid = kv.first; // kNullProcessId for the current process. |
| 529 ProcessMemoryDump* process_memory_dump = kv.second.get(); | 556 ProcessMemoryDump* process_memory_dump = kv.second.get(); |
| 530 TracedValue* traced_value = new TracedValue(); | 557 scoped_ptr<TracedValue> traced_value(new TracedValue); |
| 531 scoped_refptr<ConvertableToTraceFormat> event_value(traced_value); | 558 process_memory_dump->AsValueInto(traced_value.get()); |
| 532 process_memory_dump->AsValueInto(traced_value); | |
| 533 traced_value->SetString("level_of_detail", | 559 traced_value->SetString("level_of_detail", |
| 534 MemoryDumpLevelOfDetailToString( | 560 MemoryDumpLevelOfDetailToString( |
| 535 pmd_async_state->req_args.level_of_detail)); | 561 pmd_async_state->req_args.level_of_detail)); |
| 536 const char* const event_name = | 562 const char* const event_name = |
| 537 MemoryDumpTypeToString(pmd_async_state->req_args.dump_type); | 563 MemoryDumpTypeToString(pmd_async_state->req_args.dump_type); |
| 538 | 564 |
| 565 scoped_ptr<ConvertableToTraceFormat> event_value(std::move(traced_value)); |
| 539 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( | 566 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( |
| 540 TRACE_EVENT_PHASE_MEMORY_DUMP, | 567 TRACE_EVENT_PHASE_MEMORY_DUMP, |
| 541 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, | 568 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, |
| 542 trace_event_internal::kGlobalScope, dump_guid, pid, | 569 trace_event_internal::kGlobalScope, dump_guid, pid, |
| 543 kTraceEventNumArgs, kTraceEventArgNames, | 570 kTraceEventNumArgs, kTraceEventArgNames, |
| 544 kTraceEventArgTypes, nullptr /* arg_values */, &event_value, | 571 kTraceEventArgTypes, nullptr /* arg_values */, &event_value, |
| 545 TRACE_EVENT_FLAG_HAS_ID); | 572 TRACE_EVENT_FLAG_HAS_ID); |
| 546 } | 573 } |
| 547 | 574 |
| 548 bool tracing_still_enabled; | 575 bool tracing_still_enabled; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 573 // Spin-up the thread used to invoke unbound dump providers. | 600 // Spin-up the thread used to invoke unbound dump providers. |
| 574 scoped_ptr<Thread> dump_thread(new Thread("MemoryInfra")); | 601 scoped_ptr<Thread> dump_thread(new Thread("MemoryInfra")); |
| 575 if (!dump_thread->Start()) { | 602 if (!dump_thread->Start()) { |
| 576 LOG(ERROR) << "Failed to start the memory-infra thread for tracing"; | 603 LOG(ERROR) << "Failed to start the memory-infra thread for tracing"; |
| 577 return; | 604 return; |
| 578 } | 605 } |
| 579 | 606 |
| 580 AutoLock lock(lock_); | 607 AutoLock lock(lock_); |
| 581 | 608 |
| 582 DCHECK(delegate_); // At this point we must have a delegate. | 609 DCHECK(delegate_); // At this point we must have a delegate. |
| 583 | 610 session_state_ = new MemoryDumpSessionState; |
| 584 scoped_refptr<StackFrameDeduplicator> stack_frame_deduplicator = nullptr; | |
| 585 scoped_refptr<TypeNameDeduplicator> type_name_deduplicator = nullptr; | |
| 586 | 611 |
| 587 if (heap_profiling_enabled_) { | 612 if (heap_profiling_enabled_) { |
| 588 // If heap profiling is enabled, the stack frame deduplicator and type name | 613 // If heap profiling is enabled, the stack frame deduplicator and type name |
| 589 // deduplicator will be in use. Add a metadata events to write the frames | 614 // deduplicator will be in use. Add a metadata events to write the frames |
| 590 // and type IDs. | 615 // and type IDs. |
| 591 stack_frame_deduplicator = new StackFrameDeduplicator; | 616 session_state_->SetStackFrameDeduplicator( |
| 592 type_name_deduplicator = new TypeNameDeduplicator; | 617 make_scoped_ptr(new StackFrameDeduplicator)); |
| 618 |
| 619 session_state_->SetTypeNameDeduplicator( |
| 620 make_scoped_ptr(new TypeNameDeduplicator)); |
| 621 |
| 593 TRACE_EVENT_API_ADD_METADATA_EVENT( | 622 TRACE_EVENT_API_ADD_METADATA_EVENT( |
| 594 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames", | 623 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames", |
| 595 "stackFrames", | 624 "stackFrames", |
| 596 scoped_refptr<ConvertableToTraceFormat>(stack_frame_deduplicator)); | 625 make_scoped_ptr( |
| 626 new SessionStateConvertableProxy<StackFrameDeduplicator>( |
| 627 session_state_, |
| 628 &MemoryDumpSessionState::stack_frame_deduplicator))); |
| 629 |
| 597 TRACE_EVENT_API_ADD_METADATA_EVENT( | 630 TRACE_EVENT_API_ADD_METADATA_EVENT( |
| 598 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", | 631 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", |
| 599 "typeNames", | 632 "typeNames", |
| 600 scoped_refptr<ConvertableToTraceFormat>(type_name_deduplicator)); | 633 make_scoped_ptr(new SessionStateConvertableProxy<TypeNameDeduplicator>( |
| 634 session_state_, &MemoryDumpSessionState::type_name_deduplicator))); |
| 601 } | 635 } |
| 602 | 636 |
| 603 DCHECK(!dump_thread_); | 637 DCHECK(!dump_thread_); |
| 604 dump_thread_ = std::move(dump_thread); | 638 dump_thread_ = std::move(dump_thread); |
| 605 session_state_ = new MemoryDumpSessionState(stack_frame_deduplicator, | |
| 606 type_name_deduplicator); | |
| 607 | |
| 608 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); | 639 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); |
| 609 | 640 |
| 610 // TODO(primiano): This is a temporary hack to disable periodic memory dumps | 641 // TODO(primiano): This is a temporary hack to disable periodic memory dumps |
| 611 // when running memory benchmarks until telemetry uses TraceConfig to | 642 // when running memory benchmarks until telemetry uses TraceConfig to |
| 612 // enable/disable periodic dumps. See crbug.com/529184 . | 643 // enable/disable periodic dumps. See crbug.com/529184 . |
| 613 if (!is_coordinator_ || | 644 if (!is_coordinator_ || |
| 614 CommandLine::ForCurrentProcess()->HasSwitch( | 645 CommandLine::ForCurrentProcess()->HasSwitch( |
| 615 "enable-memory-benchmarking")) { | 646 "enable-memory-benchmarking")) { |
| 616 return; | 647 return; |
| 617 } | 648 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 auto iter = process_dumps.find(pid); | 750 auto iter = process_dumps.find(pid); |
| 720 if (iter == process_dumps.end()) { | 751 if (iter == process_dumps.end()) { |
| 721 scoped_ptr<ProcessMemoryDump> new_pmd(new ProcessMemoryDump(session_state)); | 752 scoped_ptr<ProcessMemoryDump> new_pmd(new ProcessMemoryDump(session_state)); |
| 722 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; | 753 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; |
| 723 } | 754 } |
| 724 return iter->second.get(); | 755 return iter->second.get(); |
| 725 } | 756 } |
| 726 | 757 |
| 727 } // namespace trace_event | 758 } // namespace trace_event |
| 728 } // namespace base | 759 } // namespace base |
| OLD | NEW |