Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: base/trace_event/trace_event_impl.cc

Issue 1641513004: Update //base to chromium 9659b08ea5a34f889dc4166217f438095ddc10d2 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/trace_event/trace_event_impl.h ('k') | base/trace_event/trace_event_memory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/trace_event_impl.h" 5 #include "base/trace_event/trace_event_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/base_switches.h" 10 #include "base/base_switches.h"
(...skipping 15 matching lines...) Expand all
26 #include "base/strings/utf_string_conversions.h" 26 #include "base/strings/utf_string_conversions.h"
27 #include "base/synchronization/cancellation_flag.h" 27 #include "base/synchronization/cancellation_flag.h"
28 #include "base/synchronization/waitable_event.h" 28 #include "base/synchronization/waitable_event.h"
29 #include "base/sys_info.h" 29 #include "base/sys_info.h"
30 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 30 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
31 #include "base/thread_task_runner_handle.h" 31 #include "base/thread_task_runner_handle.h"
32 #include "base/threading/platform_thread.h" 32 #include "base/threading/platform_thread.h"
33 #include "base/threading/thread_id_name_manager.h" 33 #include "base/threading/thread_id_name_manager.h"
34 #include "base/threading/worker_pool.h" 34 #include "base/threading/worker_pool.h"
35 #include "base/time/time.h" 35 #include "base/time/time.h"
36 #include "base/trace_event/memory_dump_manager.h"
37 #include "base/trace_event/memory_dump_provider.h"
38 #include "base/trace_event/process_memory_dump.h"
36 #include "base/trace_event/trace_event.h" 39 #include "base/trace_event/trace_event.h"
37 #include "base/trace_event/trace_event_synthetic_delay.h" 40 #include "base/trace_event/trace_event_synthetic_delay.h"
38 41
39 #if defined(OS_WIN) 42 #if defined(OS_WIN)
40 #include "base/trace_event/trace_event_etw_export_win.h" 43 #include "base/trace_event/trace_event_etw_export_win.h"
41 #include "base/trace_event/trace_event_win.h" 44 #include "base/trace_event/trace_event_win.h"
42 #endif 45 #endif
43 46
44 class DeleteTraceLogForTesting { 47 class DeleteTraceLogForTesting {
45 public: 48 public:
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 queue_index = NextQueueIndex(queue_index)) { 210 queue_index = NextQueueIndex(queue_index)) {
208 size_t chunk_index = recyclable_chunks_queue_[queue_index]; 211 size_t chunk_index = recyclable_chunks_queue_[queue_index];
209 if (chunk_index >= chunks_.size()) // Skip uninitialized chunks. 212 if (chunk_index >= chunks_.size()) // Skip uninitialized chunks.
210 continue; 213 continue;
211 TraceBufferChunk* chunk = chunks_[chunk_index]; 214 TraceBufferChunk* chunk = chunks_[chunk_index];
212 cloned_buffer->chunks_.push_back(chunk ? chunk->Clone().release() : NULL); 215 cloned_buffer->chunks_.push_back(chunk ? chunk->Clone().release() : NULL);
213 } 216 }
214 return cloned_buffer.Pass(); 217 return cloned_buffer.Pass();
215 } 218 }
216 219
220 void EstimateTraceMemoryOverhead(
221 TraceEventMemoryOverhead* overhead) override {
222 overhead->Add("TraceBufferRingBuffer", sizeof(*this));
223 for (size_t queue_index = queue_head_; queue_index != queue_tail_;
224 queue_index = NextQueueIndex(queue_index)) {
225 size_t chunk_index = recyclable_chunks_queue_[queue_index];
226 if (chunk_index >= chunks_.size()) // Skip uninitialized chunks.
227 continue;
228 chunks_[chunk_index]->EstimateTraceMemoryOverhead(overhead);
229 }
230 }
231
217 private: 232 private:
218 class ClonedTraceBuffer : public TraceBuffer { 233 class ClonedTraceBuffer : public TraceBuffer {
219 public: 234 public:
220 ClonedTraceBuffer() : current_iteration_index_(0) {} 235 ClonedTraceBuffer() : current_iteration_index_(0) {}
221 236
222 // The only implemented method. 237 // The only implemented method.
223 const TraceBufferChunk* NextChunk() override { 238 const TraceBufferChunk* NextChunk() override {
224 return current_iteration_index_ < chunks_.size() ? 239 return current_iteration_index_ < chunks_.size() ?
225 chunks_[current_iteration_index_++] : NULL; 240 chunks_[current_iteration_index_++] : NULL;
226 } 241 }
227 242
228 scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) override { 243 scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) override {
229 NOTIMPLEMENTED(); 244 NOTIMPLEMENTED();
230 return scoped_ptr<TraceBufferChunk>(); 245 return scoped_ptr<TraceBufferChunk>();
231 } 246 }
232 void ReturnChunk(size_t index, scoped_ptr<TraceBufferChunk>) override { 247 void ReturnChunk(size_t index, scoped_ptr<TraceBufferChunk>) override {
233 NOTIMPLEMENTED(); 248 NOTIMPLEMENTED();
234 } 249 }
235 bool IsFull() const override { return false; } 250 bool IsFull() const override { return false; }
236 size_t Size() const override { return 0; } 251 size_t Size() const override { return 0; }
237 size_t Capacity() const override { return 0; } 252 size_t Capacity() const override { return 0; }
238 TraceEvent* GetEventByHandle(TraceEventHandle handle) override { 253 TraceEvent* GetEventByHandle(TraceEventHandle handle) override {
239 return NULL; 254 return NULL;
240 } 255 }
241 scoped_ptr<TraceBuffer> CloneForIteration() const override { 256 scoped_ptr<TraceBuffer> CloneForIteration() const override {
242 NOTIMPLEMENTED(); 257 NOTIMPLEMENTED();
243 return scoped_ptr<TraceBuffer>(); 258 return scoped_ptr<TraceBuffer>();
244 } 259 }
260 void EstimateTraceMemoryOverhead(
261 TraceEventMemoryOverhead* overhead) override {
262 NOTIMPLEMENTED();
263 }
245 264
246 size_t current_iteration_index_; 265 size_t current_iteration_index_;
247 ScopedVector<TraceBufferChunk> chunks_; 266 ScopedVector<TraceBufferChunk> chunks_;
248 }; 267 };
249 268
250 bool QueueIsEmpty() const { 269 bool QueueIsEmpty() const {
251 return queue_head_ == queue_tail_; 270 return queue_head_ == queue_tail_;
252 } 271 }
253 272
254 size_t QueueSize() const { 273 size_t QueueSize() const {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 return chunk; 362 return chunk;
344 } 363 }
345 return NULL; 364 return NULL;
346 } 365 }
347 366
348 scoped_ptr<TraceBuffer> CloneForIteration() const override { 367 scoped_ptr<TraceBuffer> CloneForIteration() const override {
349 NOTIMPLEMENTED(); 368 NOTIMPLEMENTED();
350 return scoped_ptr<TraceBuffer>(); 369 return scoped_ptr<TraceBuffer>();
351 } 370 }
352 371
372 void EstimateTraceMemoryOverhead(
373 TraceEventMemoryOverhead* overhead) override {
374 const size_t chunks_ptr_vector_allocated_size =
375 sizeof(*this) + max_chunks_ * sizeof(decltype(chunks_)::value_type);
376 const size_t chunks_ptr_vector_resident_size =
377 sizeof(*this) + chunks_.size() * sizeof(decltype(chunks_)::value_type);
378 overhead->Add("TraceBufferVector", chunks_ptr_vector_allocated_size,
379 chunks_ptr_vector_resident_size);
380 for (size_t i = 0; i < chunks_.size(); ++i) {
381 TraceBufferChunk* chunk = chunks_[i];
382 // Skip the in-flight (nullptr) chunks. They will be accounted by the
383 // per-thread-local dumpers, see ThreadLocalEventBuffer::OnMemoryDump.
384 if (chunk)
385 chunk->EstimateTraceMemoryOverhead(overhead);
386 }
387 }
388
353 private: 389 private:
354 size_t in_flight_chunk_count_; 390 size_t in_flight_chunk_count_;
355 size_t current_iteration_index_; 391 size_t current_iteration_index_;
356 size_t max_chunks_; 392 size_t max_chunks_;
357 ScopedVector<TraceBufferChunk> chunks_; 393 ScopedVector<TraceBufferChunk> chunks_;
358 394
359 DISALLOW_COPY_AND_ASSIGN(TraceBufferVector); 395 DISALLOW_COPY_AND_ASSIGN(TraceBufferVector);
360 }; 396 };
361 397
362 template <typename T> 398 template <typename T>
(...skipping 28 matching lines...) Expand all
391 thread_local_boolean_->Set(false); 427 thread_local_boolean_->Set(false);
392 } 428 }
393 429
394 private: 430 private:
395 ThreadLocalBoolean* thread_local_boolean_; 431 ThreadLocalBoolean* thread_local_boolean_;
396 DISALLOW_COPY_AND_ASSIGN(AutoThreadLocalBoolean); 432 DISALLOW_COPY_AND_ASSIGN(AutoThreadLocalBoolean);
397 }; 433 };
398 434
399 } // namespace 435 } // namespace
400 436
437 TraceBufferChunk::TraceBufferChunk(uint32 seq) : next_free_(0), seq_(seq) {}
438
439 TraceBufferChunk::~TraceBufferChunk() {}
440
401 void TraceBufferChunk::Reset(uint32 new_seq) { 441 void TraceBufferChunk::Reset(uint32 new_seq) {
402 for (size_t i = 0; i < next_free_; ++i) 442 for (size_t i = 0; i < next_free_; ++i)
403 chunk_[i].Reset(); 443 chunk_[i].Reset();
404 next_free_ = 0; 444 next_free_ = 0;
405 seq_ = new_seq; 445 seq_ = new_seq;
446 cached_overhead_estimate_when_full_.reset();
406 } 447 }
407 448
408 TraceEvent* TraceBufferChunk::AddTraceEvent(size_t* event_index) { 449 TraceEvent* TraceBufferChunk::AddTraceEvent(size_t* event_index) {
409 DCHECK(!IsFull()); 450 DCHECK(!IsFull());
410 *event_index = next_free_++; 451 *event_index = next_free_++;
411 return &chunk_[*event_index]; 452 return &chunk_[*event_index];
412 } 453 }
413 454
414 scoped_ptr<TraceBufferChunk> TraceBufferChunk::Clone() const { 455 scoped_ptr<TraceBufferChunk> TraceBufferChunk::Clone() const {
415 scoped_ptr<TraceBufferChunk> cloned_chunk(new TraceBufferChunk(seq_)); 456 scoped_ptr<TraceBufferChunk> cloned_chunk(new TraceBufferChunk(seq_));
416 cloned_chunk->next_free_ = next_free_; 457 cloned_chunk->next_free_ = next_free_;
417 for (size_t i = 0; i < next_free_; ++i) 458 for (size_t i = 0; i < next_free_; ++i)
418 cloned_chunk->chunk_[i].CopyFrom(chunk_[i]); 459 cloned_chunk->chunk_[i].CopyFrom(chunk_[i]);
419 return cloned_chunk.Pass(); 460 return cloned_chunk.Pass();
420 } 461 }
421 462
463 void TraceBufferChunk::EstimateTraceMemoryOverhead(
464 TraceEventMemoryOverhead* overhead) {
465 if (cached_overhead_estimate_when_full_) {
466 DCHECK(IsFull());
467 overhead->Update(*cached_overhead_estimate_when_full_);
468 return;
469 }
470
471 // Cache the memory overhead estimate only if the chunk is full.
472 TraceEventMemoryOverhead* estimate = overhead;
473 if (IsFull()) {
474 cached_overhead_estimate_when_full_.reset(new TraceEventMemoryOverhead);
475 estimate = cached_overhead_estimate_when_full_.get();
476 }
477
478 estimate->Add("TraceBufferChunk", sizeof(*this));
479 for (size_t i = 0; i < next_free_; ++i)
480 chunk_[i].EstimateTraceMemoryOverhead(estimate);
481
482 if (IsFull()) {
483 estimate->AddSelf();
484 overhead->Update(*estimate);
485 }
486 }
487
422 // A helper class that allows the lock to be acquired in the middle of the scope 488 // A helper class that allows the lock to be acquired in the middle of the scope
423 // and unlocks at the end of scope if locked. 489 // and unlocks at the end of scope if locked.
424 class TraceLog::OptionalAutoLock { 490 class TraceLog::OptionalAutoLock {
425 public: 491 public:
426 explicit OptionalAutoLock(Lock* lock) : lock_(lock), locked_(false) {} 492 explicit OptionalAutoLock(Lock* lock) : lock_(lock), locked_(false) {}
427 493
428 ~OptionalAutoLock() { 494 ~OptionalAutoLock() {
429 if (locked_) 495 if (locked_)
430 lock_->Release(); 496 lock_->Release();
431 } 497 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 ThreadTicks thread_timestamp, 588 ThreadTicks thread_timestamp,
523 char phase, 589 char phase,
524 const unsigned char* category_group_enabled, 590 const unsigned char* category_group_enabled,
525 const char* name, 591 const char* name,
526 unsigned long long id, 592 unsigned long long id,
527 int num_args, 593 int num_args,
528 const char** arg_names, 594 const char** arg_names,
529 const unsigned char* arg_types, 595 const unsigned char* arg_types,
530 const unsigned long long* arg_values, 596 const unsigned long long* arg_values,
531 const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 597 const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
532 unsigned char flags) { 598 unsigned int flags) {
533 timestamp_ = timestamp; 599 timestamp_ = timestamp;
534 thread_timestamp_ = thread_timestamp; 600 thread_timestamp_ = thread_timestamp;
535 duration_ = TimeDelta::FromInternalValue(-1); 601 duration_ = TimeDelta::FromInternalValue(-1);
536 id_ = id; 602 id_ = id;
537 category_group_enabled_ = category_group_enabled; 603 category_group_enabled_ = category_group_enabled;
538 name_ = name; 604 name_ = name;
539 thread_id_ = thread_id; 605 thread_id_ = thread_id;
540 phase_ = phase; 606 phase_ = phase;
541 flags_ = flags; 607 flags_ = flags;
542 608
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 } 669 }
604 } 670 }
605 671
606 void TraceEvent::Reset() { 672 void TraceEvent::Reset() {
607 // Only reset fields that won't be initialized in Initialize(), or that may 673 // Only reset fields that won't be initialized in Initialize(), or that may
608 // hold references to other objects. 674 // hold references to other objects.
609 duration_ = TimeDelta::FromInternalValue(-1); 675 duration_ = TimeDelta::FromInternalValue(-1);
610 parameter_copy_storage_ = NULL; 676 parameter_copy_storage_ = NULL;
611 for (int i = 0; i < kTraceMaxNumArgs; ++i) 677 for (int i = 0; i < kTraceMaxNumArgs; ++i)
612 convertable_values_[i] = NULL; 678 convertable_values_[i] = NULL;
679 cached_memory_overhead_estimate_.reset();
613 } 680 }
614 681
615 void TraceEvent::UpdateDuration(const TraceTicks& now, 682 void TraceEvent::UpdateDuration(const TraceTicks& now,
616 const ThreadTicks& thread_now) { 683 const ThreadTicks& thread_now) {
617 DCHECK_EQ(duration_.ToInternalValue(), -1); 684 DCHECK_EQ(duration_.ToInternalValue(), -1);
618 duration_ = now - timestamp_; 685 duration_ = now - timestamp_;
619 thread_duration_ = thread_now - thread_timestamp_; 686 thread_duration_ = thread_now - thread_timestamp_;
620 } 687 }
621 688
689 void TraceEvent::EstimateTraceMemoryOverhead(
690 TraceEventMemoryOverhead* overhead) {
691 if (!cached_memory_overhead_estimate_) {
692 cached_memory_overhead_estimate_.reset(new TraceEventMemoryOverhead);
693 cached_memory_overhead_estimate_->Add("TraceEvent", sizeof(*this));
694 // TODO(primiano): parameter_copy_storage_ is refcounted and, in theory,
695 // could be shared by several events and we might overcount. In practice
696 // this is unlikely but it's worth checking.
697 if (parameter_copy_storage_) {
698 cached_memory_overhead_estimate_->AddRefCountedString(
699 *parameter_copy_storage_.get());
700 }
701 for (size_t i = 0; i < kTraceMaxNumArgs; ++i) {
702 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
703 convertable_values_[i]->EstimateTraceMemoryOverhead(
704 cached_memory_overhead_estimate_.get());
705 }
706 }
707 cached_memory_overhead_estimate_->AddSelf();
708 }
709 overhead->Update(*cached_memory_overhead_estimate_);
710 }
711
622 // static 712 // static
623 void TraceEvent::AppendValueAsJSON(unsigned char type, 713 void TraceEvent::AppendValueAsJSON(unsigned char type,
624 TraceEvent::TraceValue value, 714 TraceEvent::TraceValue value,
625 std::string* out) { 715 std::string* out) {
626 switch (type) { 716 switch (type) {
627 case TRACE_VALUE_TYPE_BOOL: 717 case TRACE_VALUE_TYPE_BOOL:
628 *out += value.as_bool ? "true" : "false"; 718 *out += value.as_bool ? "true" : "false";
629 break; 719 break;
630 case TRACE_VALUE_TYPE_UINT: 720 case TRACE_VALUE_TYPE_UINT:
631 StringAppendF(out, "%" PRIu64, static_cast<uint64>(value.as_uint)); 721 StringAppendF(out, "%" PRIu64, static_cast<uint64>(value.as_uint));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 const ArgumentFilterPredicate& argument_filter_predicate) const { 780 const ArgumentFilterPredicate& argument_filter_predicate) const {
691 int64 time_int64 = timestamp_.ToInternalValue(); 781 int64 time_int64 = timestamp_.ToInternalValue();
692 int process_id = TraceLog::GetInstance()->process_id(); 782 int process_id = TraceLog::GetInstance()->process_id();
693 const char* category_group_name = 783 const char* category_group_name =
694 TraceLog::GetCategoryGroupName(category_group_enabled_); 784 TraceLog::GetCategoryGroupName(category_group_enabled_);
695 785
696 // Category group checked at category creation time. 786 // Category group checked at category creation time.
697 DCHECK(!strchr(name_, '"')); 787 DCHECK(!strchr(name_, '"'));
698 StringAppendF(out, "{\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 788 StringAppendF(out, "{\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64
699 "," 789 ","
700 "\"ph\":\"%c\",\"cat\":\"%s\",\"name\":\"%s\",\"args\":{", 790 "\"ph\":\"%c\",\"cat\":\"%s\",\"name\":\"%s\",\"args\":",
701 process_id, thread_id_, time_int64, phase_, category_group_name, 791 process_id, thread_id_, time_int64, phase_, category_group_name,
702 name_); 792 name_);
703 793
704 // Output argument names and values, stop at first NULL argument name. 794 // Output argument names and values, stop at first NULL argument name.
705 if (arg_names_[0]) { 795 bool strip_args = arg_names_[0] && !argument_filter_predicate.is_null() &&
706 bool allow_args = argument_filter_predicate.is_null() || 796 !argument_filter_predicate.Run(category_group_name, name_);
707 argument_filter_predicate.Run(category_group_name, name_);
708 797
709 if (allow_args) { 798 if (strip_args) {
710 for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { 799 *out += "\"__stripped__\"";
711 if (i > 0) 800 } else {
712 *out += ","; 801 *out += "{";
713 *out += "\"";
714 *out += arg_names_[i];
715 *out += "\":";
716 802
717 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) 803 for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) {
718 convertable_values_[i]->AppendAsTraceFormat(out); 804 if (i > 0)
719 else 805 *out += ",";
720 AppendValueAsJSON(arg_types_[i], arg_values_[i], out); 806 *out += "\"";
721 } 807 *out += arg_names_[i];
722 } else { 808 *out += "\":";
723 *out += "\"stripped\":1"; 809
810 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
811 convertable_values_[i]->AppendAsTraceFormat(out);
812 else
813 AppendValueAsJSON(arg_types_[i], arg_values_[i], out);
724 } 814 }
815
816 *out += "}";
725 } 817 }
726 818
727 *out += "}";
728
729 if (phase_ == TRACE_EVENT_PHASE_COMPLETE) { 819 if (phase_ == TRACE_EVENT_PHASE_COMPLETE) {
730 int64 duration = duration_.ToInternalValue(); 820 int64 duration = duration_.ToInternalValue();
731 if (duration != -1) 821 if (duration != -1)
732 StringAppendF(out, ",\"dur\":%" PRId64, duration); 822 StringAppendF(out, ",\"dur\":%" PRId64, duration);
733 if (!thread_timestamp_.is_null()) { 823 if (!thread_timestamp_.is_null()) {
734 int64 thread_duration = thread_duration_.ToInternalValue(); 824 int64 thread_duration = thread_duration_.ToInternalValue();
735 if (thread_duration != -1) 825 if (thread_duration != -1)
736 StringAppendF(out, ",\"tdur\":%" PRId64, thread_duration); 826 StringAppendF(out, ",\"tdur\":%" PRId64, thread_duration);
737 } 827 }
738 } 828 }
739 829
740 // Output tts if thread_timestamp is valid. 830 // Output tts if thread_timestamp is valid.
741 if (!thread_timestamp_.is_null()) { 831 if (!thread_timestamp_.is_null()) {
742 int64 thread_time_int64 = thread_timestamp_.ToInternalValue(); 832 int64 thread_time_int64 = thread_timestamp_.ToInternalValue();
743 StringAppendF(out, ",\"tts\":%" PRId64, thread_time_int64); 833 StringAppendF(out, ",\"tts\":%" PRId64, thread_time_int64);
744 } 834 }
745 835
746 // Output async tts marker field if flag is set. 836 // Output async tts marker field if flag is set.
747 if (flags_ & TRACE_EVENT_FLAG_ASYNC_TTS) { 837 if (flags_ & TRACE_EVENT_FLAG_ASYNC_TTS) {
748 StringAppendF(out, ", \"use_async_tts\":1"); 838 StringAppendF(out, ", \"use_async_tts\":1");
749 } 839 }
750 840
751 // If id_ is set, print it out as a hex string so we don't loose any 841 // If id_ is set, print it out as a hex string so we don't loose any
752 // bits (it might be a 64-bit pointer). 842 // bits (it might be a 64-bit pointer).
753 if (flags_ & TRACE_EVENT_FLAG_HAS_ID) 843 if (flags_ & TRACE_EVENT_FLAG_HAS_ID)
754 StringAppendF(out, ",\"id\":\"0x%" PRIx64 "\"", static_cast<uint64>(id_)); 844 StringAppendF(out, ",\"id\":\"0x%" PRIx64 "\"", static_cast<uint64>(id_));
755 845
846 if (flags_ & TRACE_EVENT_FLAG_BIND_TO_ENCLOSING)
847 StringAppendF(out, ",\"bp\":\"e\"");
848
756 // Instant events also output their scope. 849 // Instant events also output their scope.
757 if (phase_ == TRACE_EVENT_PHASE_INSTANT) { 850 if (phase_ == TRACE_EVENT_PHASE_INSTANT) {
758 char scope = '?'; 851 char scope = '?';
759 switch (flags_ & TRACE_EVENT_FLAG_SCOPE_MASK) { 852 switch (flags_ & TRACE_EVENT_FLAG_SCOPE_MASK) {
760 case TRACE_EVENT_SCOPE_GLOBAL: 853 case TRACE_EVENT_SCOPE_GLOBAL:
761 scope = TRACE_EVENT_SCOPE_NAME_GLOBAL; 854 scope = TRACE_EVENT_SCOPE_NAME_GLOBAL;
762 break; 855 break;
763 856
764 case TRACE_EVENT_SCOPE_PROCESS: 857 case TRACE_EVENT_SCOPE_PROCESS:
765 scope = TRACE_EVENT_SCOPE_NAME_PROCESS; 858 scope = TRACE_EVENT_SCOPE_NAME_PROCESS;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 TraceBucketData::~TraceBucketData() { 1070 TraceBucketData::~TraceBucketData() {
978 } 1071 }
979 1072
980 //////////////////////////////////////////////////////////////////////////////// 1073 ////////////////////////////////////////////////////////////////////////////////
981 // 1074 //
982 // TraceLog 1075 // TraceLog
983 // 1076 //
984 //////////////////////////////////////////////////////////////////////////////// 1077 ////////////////////////////////////////////////////////////////////////////////
985 1078
986 class TraceLog::ThreadLocalEventBuffer 1079 class TraceLog::ThreadLocalEventBuffer
987 : public MessageLoop::DestructionObserver { 1080 : public MessageLoop::DestructionObserver,
1081 public MemoryDumpProvider {
988 public: 1082 public:
989 ThreadLocalEventBuffer(TraceLog* trace_log); 1083 ThreadLocalEventBuffer(TraceLog* trace_log);
990 ~ThreadLocalEventBuffer() override; 1084 ~ThreadLocalEventBuffer() override;
991 1085
992 TraceEvent* AddTraceEvent(TraceEventHandle* handle); 1086 TraceEvent* AddTraceEvent(TraceEventHandle* handle);
993 1087
994 void ReportOverhead(const TraceTicks& event_timestamp, 1088 void ReportOverhead(const TraceTicks& event_timestamp,
995 const ThreadTicks& event_thread_timestamp); 1089 const ThreadTicks& event_thread_timestamp);
996 1090
997 TraceEvent* GetEventByHandle(TraceEventHandle handle) { 1091 TraceEvent* GetEventByHandle(TraceEventHandle handle) {
998 if (!chunk_ || handle.chunk_seq != chunk_->seq() || 1092 if (!chunk_ || handle.chunk_seq != chunk_->seq() ||
999 handle.chunk_index != chunk_index_) 1093 handle.chunk_index != chunk_index_)
1000 return NULL; 1094 return NULL;
1001 1095
1002 return chunk_->GetEventAt(handle.event_index); 1096 return chunk_->GetEventAt(handle.event_index);
1003 } 1097 }
1004 1098
1005 int generation() const { return generation_; } 1099 int generation() const { return generation_; }
1006 1100
1007 private: 1101 private:
1008 // MessageLoop::DestructionObserver 1102 // MessageLoop::DestructionObserver
1009 void WillDestroyCurrentMessageLoop() override; 1103 void WillDestroyCurrentMessageLoop() override;
1010 1104
1105 // MemoryDumpProvider implementation.
1106 bool OnMemoryDump(ProcessMemoryDump* pmd) override;
1107
1011 void FlushWhileLocked(); 1108 void FlushWhileLocked();
1012 1109
1013 void CheckThisIsCurrentBuffer() const { 1110 void CheckThisIsCurrentBuffer() const {
1014 DCHECK(trace_log_->thread_local_event_buffer_.Get() == this); 1111 DCHECK(trace_log_->thread_local_event_buffer_.Get() == this);
1015 } 1112 }
1016 1113
1017 // Since TraceLog is a leaky singleton, trace_log_ will always be valid 1114 // Since TraceLog is a leaky singleton, trace_log_ will always be valid
1018 // as long as the thread exists. 1115 // as long as the thread exists.
1019 TraceLog* trace_log_; 1116 TraceLog* trace_log_;
1020 scoped_ptr<TraceBufferChunk> chunk_; 1117 scoped_ptr<TraceBufferChunk> chunk_;
1021 size_t chunk_index_; 1118 size_t chunk_index_;
1022 int event_count_; 1119 int event_count_;
1023 TimeDelta overhead_; 1120 TimeDelta overhead_;
1024 int generation_; 1121 int generation_;
1025 1122
1026 DISALLOW_COPY_AND_ASSIGN(ThreadLocalEventBuffer); 1123 DISALLOW_COPY_AND_ASSIGN(ThreadLocalEventBuffer);
1027 }; 1124 };
1028 1125
1029 TraceLog::ThreadLocalEventBuffer::ThreadLocalEventBuffer(TraceLog* trace_log) 1126 TraceLog::ThreadLocalEventBuffer::ThreadLocalEventBuffer(TraceLog* trace_log)
1030 : trace_log_(trace_log), 1127 : trace_log_(trace_log),
1031 chunk_index_(0), 1128 chunk_index_(0),
1032 event_count_(0), 1129 event_count_(0),
1033 generation_(trace_log->generation()) { 1130 generation_(trace_log->generation()) {
1034 // ThreadLocalEventBuffer is created only if the thread has a message loop, so 1131 // ThreadLocalEventBuffer is created only if the thread has a message loop, so
1035 // the following message_loop won't be NULL. 1132 // the following message_loop won't be NULL.
1036 MessageLoop* message_loop = MessageLoop::current(); 1133 MessageLoop* message_loop = MessageLoop::current();
1037 message_loop->AddDestructionObserver(this); 1134 message_loop->AddDestructionObserver(this);
1038 1135
1136 // This is to report the local memory usage when memory-infra is enabled.
1137 MemoryDumpManager::GetInstance()->RegisterDumpProvider(
1138 this, ThreadTaskRunnerHandle::Get());
1139
1039 AutoLock lock(trace_log->lock_); 1140 AutoLock lock(trace_log->lock_);
1040 trace_log->thread_message_loops_.insert(message_loop); 1141 trace_log->thread_message_loops_.insert(message_loop);
1041 } 1142 }
1042 1143
1043 TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() { 1144 TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() {
1044 CheckThisIsCurrentBuffer(); 1145 CheckThisIsCurrentBuffer();
1045 MessageLoop::current()->RemoveDestructionObserver(this); 1146 MessageLoop::current()->RemoveDestructionObserver(this);
1147 MemoryDumpManager::GetInstance()->UnregisterDumpProvider(this);
1046 1148
1047 // Zero event_count_ happens in either of the following cases: 1149 // Zero event_count_ happens in either of the following cases:
1048 // - no event generated for the thread; 1150 // - no event generated for the thread;
1049 // - the thread has no message loop; 1151 // - the thread has no message loop;
1050 // - trace_event_overhead is disabled. 1152 // - trace_event_overhead is disabled.
1051 if (event_count_) { 1153 if (event_count_) {
1052 InitializeMetadataEvent(AddTraceEvent(NULL), 1154 InitializeMetadataEvent(AddTraceEvent(NULL),
1053 static_cast<int>(base::PlatformThread::CurrentId()), 1155 static_cast<int>(base::PlatformThread::CurrentId()),
1054 "overhead", "average_overhead", 1156 "overhead", "average_overhead",
1055 overhead_.InMillisecondsF() / event_count_); 1157 overhead_.InMillisecondsF() / event_count_);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 trace_event->UpdateDuration(now, thread_now); 1214 trace_event->UpdateDuration(now, thread_now);
1113 } 1215 }
1114 } 1216 }
1115 overhead_ += overhead; 1217 overhead_ += overhead;
1116 } 1218 }
1117 1219
1118 void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() { 1220 void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() {
1119 delete this; 1221 delete this;
1120 } 1222 }
1121 1223
1224 bool TraceLog::ThreadLocalEventBuffer::OnMemoryDump(ProcessMemoryDump* pmd) {
1225 if (!chunk_)
1226 return true;
1227 std::string dump_base_name = StringPrintf(
1228 "tracing/thread_%d", static_cast<int>(PlatformThread::CurrentId()));
1229 TraceEventMemoryOverhead overhead;
1230 chunk_->EstimateTraceMemoryOverhead(&overhead);
1231 overhead.DumpInto(dump_base_name.c_str(), pmd);
1232 return true;
1233 }
1234
1122 void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() { 1235 void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() {
1123 if (!chunk_) 1236 if (!chunk_)
1124 return; 1237 return;
1125 1238
1126 trace_log_->lock_.AssertAcquired(); 1239 trace_log_->lock_.AssertAcquired();
1127 if (trace_log_->CheckGeneration(generation_)) { 1240 if (trace_log_->CheckGeneration(generation_)) {
1128 // Return the chunk to the buffer only if the generation matches. 1241 // Return the chunk to the buffer only if the generation matches.
1129 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass()); 1242 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass());
1130 } 1243 }
1131 // Otherwise this method may be called from the destructor, or TraceLog will 1244 // Otherwise this method may be called from the destructor, or TraceLog will
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 filter.append(kEchoToConsoleCategoryFilter); 1301 filter.append(kEchoToConsoleCategoryFilter);
1189 } 1302 }
1190 1303
1191 LOG(ERROR) << "Start " << switches::kTraceToConsole 1304 LOG(ERROR) << "Start " << switches::kTraceToConsole
1192 << " with CategoryFilter '" << filter << "'."; 1305 << " with CategoryFilter '" << filter << "'.";
1193 SetEnabled(TraceConfig(filter, ECHO_TO_CONSOLE), RECORDING_MODE); 1306 SetEnabled(TraceConfig(filter, ECHO_TO_CONSOLE), RECORDING_MODE);
1194 } 1307 }
1195 #endif 1308 #endif
1196 1309
1197 logged_events_.reset(CreateTraceBuffer()); 1310 logged_events_.reset(CreateTraceBuffer());
1311
1312 MemoryDumpManager::GetInstance()->RegisterDumpProvider(this);
1198 } 1313 }
1199 1314
1200 TraceLog::~TraceLog() { 1315 TraceLog::~TraceLog() {
1201 } 1316 }
1202 1317
1318 void TraceLog::InitializeThreadLocalEventBufferIfSupported() {
1319 // A ThreadLocalEventBuffer needs the message loop
1320 // - to know when the thread exits;
1321 // - to handle the final flush.
1322 // For a thread without a message loop or the message loop may be blocked, the
1323 // trace events will be added into the main buffer directly.
1324 if (thread_blocks_message_loop_.Get() || !MessageLoop::current())
1325 return;
1326 auto thread_local_event_buffer = thread_local_event_buffer_.Get();
1327 if (thread_local_event_buffer &&
1328 !CheckGeneration(thread_local_event_buffer->generation())) {
1329 delete thread_local_event_buffer;
1330 thread_local_event_buffer = NULL;
1331 }
1332 if (!thread_local_event_buffer) {
1333 thread_local_event_buffer = new ThreadLocalEventBuffer(this);
1334 thread_local_event_buffer_.Set(thread_local_event_buffer);
1335 }
1336 }
1337
1338 bool TraceLog::OnMemoryDump(ProcessMemoryDump* pmd) {
1339 TraceEventMemoryOverhead overhead;
1340 overhead.Add("TraceLog", sizeof(*this));
1341 {
1342 AutoLock lock(lock_);
1343 if (logged_events_)
1344 logged_events_->EstimateTraceMemoryOverhead(&overhead);
1345 }
1346 overhead.AddSelf();
1347 overhead.DumpInto("tracing/main_trace_log", pmd);
1348 return true;
1349 }
1350
1203 const unsigned char* TraceLog::GetCategoryGroupEnabled( 1351 const unsigned char* TraceLog::GetCategoryGroupEnabled(
1204 const char* category_group) { 1352 const char* category_group) {
1205 TraceLog* tracelog = GetInstance(); 1353 TraceLog* tracelog = GetInstance();
1206 if (!tracelog) { 1354 if (!tracelog) {
1207 DCHECK(!g_category_group_enabled[g_category_already_shutdown]); 1355 DCHECK(!g_category_group_enabled[g_category_already_shutdown]);
1208 return &g_category_group_enabled[g_category_already_shutdown]; 1356 return &g_category_group_enabled[g_category_already_shutdown];
1209 } 1357 }
1210 return tracelog->GetCategoryGroupEnabledInternal(category_group); 1358 return tracelog->GetCategoryGroupEnabledInternal(category_group);
1211 } 1359 }
1212 1360
(...skipping 19 matching lines...) Expand all
1232 if (mode_ == RECORDING_MODE && 1380 if (mode_ == RECORDING_MODE &&
1233 trace_config_.IsCategoryGroupEnabled(category_group)) 1381 trace_config_.IsCategoryGroupEnabled(category_group))
1234 enabled_flag |= ENABLED_FOR_RECORDING; 1382 enabled_flag |= ENABLED_FOR_RECORDING;
1235 else if (mode_ == MONITORING_MODE && 1383 else if (mode_ == MONITORING_MODE &&
1236 trace_config_.IsCategoryGroupEnabled(category_group)) 1384 trace_config_.IsCategoryGroupEnabled(category_group))
1237 enabled_flag |= ENABLED_FOR_MONITORING; 1385 enabled_flag |= ENABLED_FOR_MONITORING;
1238 if (event_callback_ && 1386 if (event_callback_ &&
1239 event_callback_trace_config_.IsCategoryGroupEnabled(category_group)) 1387 event_callback_trace_config_.IsCategoryGroupEnabled(category_group))
1240 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; 1388 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK;
1241 #if defined(OS_WIN) 1389 #if defined(OS_WIN)
1242 if (base::trace_event::TraceEventETWExport::isETWExportEnabled()) 1390 if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
1391 category_group)) {
1243 enabled_flag |= ENABLED_FOR_ETW_EXPORT; 1392 enabled_flag |= ENABLED_FOR_ETW_EXPORT;
1393 }
1244 #endif 1394 #endif
1245 1395
1246 g_category_group_enabled[category_index] = enabled_flag; 1396 g_category_group_enabled[category_index] = enabled_flag;
1247 } 1397 }
1248 1398
1249 void TraceLog::UpdateCategoryGroupEnabledFlags() { 1399 void TraceLog::UpdateCategoryGroupEnabledFlags() {
1250 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); 1400 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index);
1251 for (size_t i = 0; i < category_index; i++) 1401 for (size_t i = 0; i < category_index; i++)
1252 UpdateCategoryGroupEnabledFlag(i); 1402 UpdateCategoryGroupEnabledFlag(i);
1253 } 1403 }
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 // flush_task_runner_; 1770 // flush_task_runner_;
1621 // 2. If thread_message_loops_ is not empty, thread A posts task to each message 1771 // 2. If thread_message_loops_ is not empty, thread A posts task to each message
1622 // loop to flush the thread local buffers; otherwise finish the flush; 1772 // loop to flush the thread local buffers; otherwise finish the flush;
1623 // 3. FlushCurrentThread() deletes the thread local event buffer: 1773 // 3. FlushCurrentThread() deletes the thread local event buffer:
1624 // - The last batch of events of the thread are flushed into the main buffer; 1774 // - The last batch of events of the thread are flushed into the main buffer;
1625 // - The message loop will be removed from thread_message_loops_; 1775 // - The message loop will be removed from thread_message_loops_;
1626 // If this is the last message loop, finish the flush; 1776 // If this is the last message loop, finish the flush;
1627 // 4. If any thread hasn't finish its flush in time, finish the flush. 1777 // 4. If any thread hasn't finish its flush in time, finish the flush.
1628 void TraceLog::Flush(const TraceLog::OutputCallback& cb, 1778 void TraceLog::Flush(const TraceLog::OutputCallback& cb,
1629 bool use_worker_thread) { 1779 bool use_worker_thread) {
1780 FlushInternal(cb, use_worker_thread, false);
1781 }
1782
1783 void TraceLog::CancelTracing(const OutputCallback& cb) {
1784 SetDisabled();
1785 FlushInternal(cb, false, true);
1786 }
1787
1788 void TraceLog::FlushInternal(const TraceLog::OutputCallback& cb,
1789 bool use_worker_thread,
1790 bool discard_events) {
1630 use_worker_thread_ = use_worker_thread; 1791 use_worker_thread_ = use_worker_thread;
1631 if (IsEnabled()) { 1792 if (IsEnabled()) {
1632 // Can't flush when tracing is enabled because otherwise PostTask would 1793 // Can't flush when tracing is enabled because otherwise PostTask would
1633 // - generate more trace events; 1794 // - generate more trace events;
1634 // - deschedule the calling thread on some platforms causing inaccurate 1795 // - deschedule the calling thread on some platforms causing inaccurate
1635 // timing of the trace events. 1796 // timing of the trace events.
1636 scoped_refptr<RefCountedString> empty_result = new RefCountedString; 1797 scoped_refptr<RefCountedString> empty_result = new RefCountedString;
1637 if (!cb.is_null()) 1798 if (!cb.is_null())
1638 cb.Run(empty_result, false); 1799 cb.Run(empty_result, false);
1639 LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled"; 1800 LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled";
(...skipping 23 matching lines...) Expand all
1663 thread_message_loops_.begin(); 1824 thread_message_loops_.begin();
1664 it != thread_message_loops_.end(); ++it) { 1825 it != thread_message_loops_.end(); ++it) {
1665 thread_message_loop_task_runners.push_back((*it)->task_runner()); 1826 thread_message_loop_task_runners.push_back((*it)->task_runner());
1666 } 1827 }
1667 } 1828 }
1668 } 1829 }
1669 1830
1670 if (thread_message_loop_task_runners.size()) { 1831 if (thread_message_loop_task_runners.size()) {
1671 for (size_t i = 0; i < thread_message_loop_task_runners.size(); ++i) { 1832 for (size_t i = 0; i < thread_message_loop_task_runners.size(); ++i) {
1672 thread_message_loop_task_runners[i]->PostTask( 1833 thread_message_loop_task_runners[i]->PostTask(
1673 FROM_HERE, 1834 FROM_HERE, Bind(&TraceLog::FlushCurrentThread, Unretained(this),
1674 Bind(&TraceLog::FlushCurrentThread, Unretained(this), generation)); 1835 generation, discard_events));
1675 } 1836 }
1676 flush_task_runner_->PostDelayedTask( 1837 flush_task_runner_->PostDelayedTask(
1677 FROM_HERE, 1838 FROM_HERE, Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation,
1678 Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation), 1839 discard_events),
1679 TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs)); 1840 TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs));
1680 return; 1841 return;
1681 } 1842 }
1682 1843
1683 FinishFlush(generation); 1844 FinishFlush(generation, discard_events);
1684 } 1845 }
1685 1846
1686 // Usually it runs on a different thread. 1847 // Usually it runs on a different thread.
1687 void TraceLog::ConvertTraceEventsToTraceFormat( 1848 void TraceLog::ConvertTraceEventsToTraceFormat(
1688 scoped_ptr<TraceBuffer> logged_events, 1849 scoped_ptr<TraceBuffer> logged_events,
1689 const OutputCallback& flush_output_callback, 1850 const OutputCallback& flush_output_callback,
1690 const TraceEvent::ArgumentFilterPredicate& argument_filter_predicate) { 1851 const TraceEvent::ArgumentFilterPredicate& argument_filter_predicate) {
1691 if (flush_output_callback.is_null()) 1852 if (flush_output_callback.is_null())
1692 return; 1853 return;
1693 1854
1694 // The callback need to be called at least once even if there is no events 1855 // The callback need to be called at least once even if there is no events
1695 // to let the caller know the completion of flush. 1856 // to let the caller know the completion of flush.
1696 bool has_more_events = true; 1857 scoped_refptr<RefCountedString> json_events_str_ptr = new RefCountedString();
1697 do { 1858 while (const TraceBufferChunk* chunk = logged_events->NextChunk()) {
1698 scoped_refptr<RefCountedString> json_events_str_ptr = 1859 for (size_t j = 0; j < chunk->size(); ++j) {
1699 new RefCountedString(); 1860 size_t size = json_events_str_ptr->size();
1700 1861 if (size > kTraceEventBufferSizeInBytes) {
1701 while (json_events_str_ptr->size() < kTraceEventBufferSizeInBytes) { 1862 flush_output_callback.Run(json_events_str_ptr, true);
1702 const TraceBufferChunk* chunk = logged_events->NextChunk(); 1863 json_events_str_ptr = new RefCountedString();
1703 has_more_events = chunk != NULL; 1864 } else if (size) {
1704 if (!chunk) 1865 json_events_str_ptr->data().append(",\n");
1705 break;
1706 for (size_t j = 0; j < chunk->size(); ++j) {
1707 if (json_events_str_ptr->size())
1708 json_events_str_ptr->data().append(",\n");
1709 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data()),
1710 argument_filter_predicate);
1711 } 1866 }
1867 chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data()),
1868 argument_filter_predicate);
1712 } 1869 }
1713 flush_output_callback.Run(json_events_str_ptr, has_more_events); 1870 }
1714 } while (has_more_events); 1871 flush_output_callback.Run(json_events_str_ptr, false);
1715 } 1872 }
1716 1873
1717 void TraceLog::FinishFlush(int generation) { 1874 void TraceLog::FinishFlush(int generation, bool discard_events) {
1718 scoped_ptr<TraceBuffer> previous_logged_events; 1875 scoped_ptr<TraceBuffer> previous_logged_events;
1719 OutputCallback flush_output_callback; 1876 OutputCallback flush_output_callback;
1720 TraceEvent::ArgumentFilterPredicate argument_filter_predicate; 1877 TraceEvent::ArgumentFilterPredicate argument_filter_predicate;
1721 1878
1722 if (!CheckGeneration(generation)) 1879 if (!CheckGeneration(generation))
1723 return; 1880 return;
1724 1881
1725 { 1882 {
1726 AutoLock lock(lock_); 1883 AutoLock lock(lock_);
1727 1884
1728 previous_logged_events.swap(logged_events_); 1885 previous_logged_events.swap(logged_events_);
1729 UseNextTraceBuffer(); 1886 UseNextTraceBuffer();
1730 thread_message_loops_.clear(); 1887 thread_message_loops_.clear();
1731 1888
1732 flush_task_runner_ = NULL; 1889 flush_task_runner_ = NULL;
1733 flush_output_callback = flush_output_callback_; 1890 flush_output_callback = flush_output_callback_;
1734 flush_output_callback_.Reset(); 1891 flush_output_callback_.Reset();
1735 1892
1736 if (trace_options() & kInternalEnableArgumentFilter) { 1893 if (trace_options() & kInternalEnableArgumentFilter) {
1737 CHECK(!argument_filter_predicate_.is_null()); 1894 CHECK(!argument_filter_predicate_.is_null());
1738 argument_filter_predicate = argument_filter_predicate_; 1895 argument_filter_predicate = argument_filter_predicate_;
1739 } 1896 }
1740 } 1897 }
1741 1898
1899 if (discard_events) {
1900 if (!flush_output_callback.is_null()) {
1901 scoped_refptr<RefCountedString> empty_result = new RefCountedString;
1902 flush_output_callback.Run(empty_result, false);
1903 }
1904 return;
1905 }
1906
1742 if (use_worker_thread_ && 1907 if (use_worker_thread_ &&
1743 WorkerPool::PostTask( 1908 WorkerPool::PostTask(
1744 FROM_HERE, Bind(&TraceLog::ConvertTraceEventsToTraceFormat, 1909 FROM_HERE, Bind(&TraceLog::ConvertTraceEventsToTraceFormat,
1745 Passed(&previous_logged_events), 1910 Passed(&previous_logged_events),
1746 flush_output_callback, argument_filter_predicate), 1911 flush_output_callback, argument_filter_predicate),
1747 true)) { 1912 true)) {
1748 return; 1913 return;
1749 } 1914 }
1750 1915
1751 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), 1916 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(),
1752 flush_output_callback, 1917 flush_output_callback,
1753 argument_filter_predicate); 1918 argument_filter_predicate);
1754 } 1919 }
1755 1920
1756 // Run in each thread holding a local event buffer. 1921 // Run in each thread holding a local event buffer.
1757 void TraceLog::FlushCurrentThread(int generation) { 1922 void TraceLog::FlushCurrentThread(int generation, bool discard_events) {
1758 { 1923 {
1759 AutoLock lock(lock_); 1924 AutoLock lock(lock_);
1760 if (!CheckGeneration(generation) || !flush_task_runner_) { 1925 if (!CheckGeneration(generation) || !flush_task_runner_) {
1761 // This is late. The corresponding flush has finished. 1926 // This is late. The corresponding flush has finished.
1762 return; 1927 return;
1763 } 1928 }
1764 } 1929 }
1765 1930
1766 // This will flush the thread local buffer. 1931 // This will flush the thread local buffer.
1767 delete thread_local_event_buffer_.Get(); 1932 delete thread_local_event_buffer_.Get();
1768 1933
1769 AutoLock lock(lock_); 1934 AutoLock lock(lock_);
1770 if (!CheckGeneration(generation) || !flush_task_runner_ || 1935 if (!CheckGeneration(generation) || !flush_task_runner_ ||
1771 thread_message_loops_.size()) 1936 thread_message_loops_.size())
1772 return; 1937 return;
1773 1938
1774 flush_task_runner_->PostTask( 1939 flush_task_runner_->PostTask(
1775 FROM_HERE, Bind(&TraceLog::FinishFlush, Unretained(this), generation)); 1940 FROM_HERE, Bind(&TraceLog::FinishFlush, Unretained(this), generation,
1941 discard_events));
1776 } 1942 }
1777 1943
1778 void TraceLog::OnFlushTimeout(int generation) { 1944 void TraceLog::OnFlushTimeout(int generation, bool discard_events) {
1779 { 1945 {
1780 AutoLock lock(lock_); 1946 AutoLock lock(lock_);
1781 if (!CheckGeneration(generation) || !flush_task_runner_) { 1947 if (!CheckGeneration(generation) || !flush_task_runner_) {
1782 // Flush has finished before timeout. 1948 // Flush has finished before timeout.
1783 return; 1949 return;
1784 } 1950 }
1785 1951
1786 LOG(WARNING) << 1952 LOG(WARNING) <<
1787 "The following threads haven't finished flush in time. " 1953 "The following threads haven't finished flush in time. "
1788 "If this happens stably for some thread, please call " 1954 "If this happens stably for some thread, please call "
1789 "TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop() from " 1955 "TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop() from "
1790 "the thread to avoid its trace events from being lost."; 1956 "the thread to avoid its trace events from being lost.";
1791 for (hash_set<MessageLoop*>::const_iterator it = 1957 for (hash_set<MessageLoop*>::const_iterator it =
1792 thread_message_loops_.begin(); 1958 thread_message_loops_.begin();
1793 it != thread_message_loops_.end(); ++it) { 1959 it != thread_message_loops_.end(); ++it) {
1794 LOG(WARNING) << "Thread: " << (*it)->thread_name(); 1960 LOG(WARNING) << "Thread: " << (*it)->thread_name();
1795 } 1961 }
1796 } 1962 }
1797 FinishFlush(generation); 1963 FinishFlush(generation, discard_events);
1798 } 1964 }
1799 1965
1800 void TraceLog::FlushButLeaveBufferIntact( 1966 void TraceLog::FlushButLeaveBufferIntact(
1801 const TraceLog::OutputCallback& flush_output_callback) { 1967 const TraceLog::OutputCallback& flush_output_callback) {
1802 scoped_ptr<TraceBuffer> previous_logged_events; 1968 scoped_ptr<TraceBuffer> previous_logged_events;
1803 TraceEvent::ArgumentFilterPredicate argument_filter_predicate; 1969 TraceEvent::ArgumentFilterPredicate argument_filter_predicate;
1804 { 1970 {
1805 AutoLock lock(lock_); 1971 AutoLock lock(lock_);
1806 AddMetadataEventsWhileLocked(); 1972 AddMetadataEventsWhileLocked();
1807 if (thread_shared_chunk_) { 1973 if (thread_shared_chunk_) {
(...skipping 24 matching lines...) Expand all
1832 TraceEventHandle TraceLog::AddTraceEvent( 1998 TraceEventHandle TraceLog::AddTraceEvent(
1833 char phase, 1999 char phase,
1834 const unsigned char* category_group_enabled, 2000 const unsigned char* category_group_enabled,
1835 const char* name, 2001 const char* name,
1836 unsigned long long id, 2002 unsigned long long id,
1837 int num_args, 2003 int num_args,
1838 const char** arg_names, 2004 const char** arg_names,
1839 const unsigned char* arg_types, 2005 const unsigned char* arg_types,
1840 const unsigned long long* arg_values, 2006 const unsigned long long* arg_values,
1841 const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 2007 const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
1842 unsigned char flags) { 2008 unsigned int flags) {
1843 int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 2009 int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1844 base::TraceTicks now = base::TraceTicks::Now(); 2010 base::TraceTicks now = base::TraceTicks::Now();
1845 return AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, 2011 return AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled,
1846 name, id, thread_id, now, 2012 name, id, thread_id, now,
1847 num_args, arg_names, 2013 num_args, arg_names,
1848 arg_types, arg_values, 2014 arg_types, arg_values,
1849 convertable_values, flags); 2015 convertable_values, flags);
1850 } 2016 }
1851 2017
1852 TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp( 2018 TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
1853 char phase, 2019 char phase,
1854 const unsigned char* category_group_enabled, 2020 const unsigned char* category_group_enabled,
1855 const char* name, 2021 const char* name,
1856 unsigned long long id, 2022 unsigned long long id,
1857 int thread_id, 2023 int thread_id,
1858 const TraceTicks& timestamp, 2024 const TraceTicks& timestamp,
1859 int num_args, 2025 int num_args,
1860 const char** arg_names, 2026 const char** arg_names,
1861 const unsigned char* arg_types, 2027 const unsigned char* arg_types,
1862 const unsigned long long* arg_values, 2028 const unsigned long long* arg_values,
1863 const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 2029 const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
1864 unsigned char flags) { 2030 unsigned int flags) {
1865 TraceEventHandle handle = { 0, 0, 0 }; 2031 TraceEventHandle handle = { 0, 0, 0 };
1866 if (!*category_group_enabled) 2032 if (!*category_group_enabled)
1867 return handle; 2033 return handle;
1868 2034
1869 // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when 2035 // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when
1870 // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) -> 2036 // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) ->
1871 // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ... 2037 // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ...
1872 if (thread_is_in_trace_event_.Get()) 2038 if (thread_is_in_trace_event_.Get())
1873 return handle; 2039 return handle;
1874 2040
1875 AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_); 2041 AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_);
1876 2042
1877 DCHECK(name); 2043 DCHECK(name);
1878 DCHECK(!timestamp.is_null()); 2044 DCHECK(!timestamp.is_null());
1879 2045
1880 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) 2046 if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
1881 id = MangleEventId(id); 2047 id = MangleEventId(id);
1882 2048
1883 TraceTicks offset_event_timestamp = OffsetTimestamp(timestamp); 2049 TraceTicks offset_event_timestamp = OffsetTimestamp(timestamp);
1884 TraceTicks now = flags & TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP ? 2050 TraceTicks now = flags & TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP ?
1885 OffsetNow() : offset_event_timestamp; 2051 OffsetNow() : offset_event_timestamp;
1886 ThreadTicks thread_now = ThreadNow(); 2052 ThreadTicks thread_now = ThreadNow();
1887 2053
1888 ThreadLocalEventBuffer* thread_local_event_buffer = NULL; 2054 // |thread_local_event_buffer_| can be null if the current thread doesn't have
1889 // A ThreadLocalEventBuffer needs the message loop 2055 // a message loop or the message loop is blocked.
1890 // - to know when the thread exits; 2056 InitializeThreadLocalEventBufferIfSupported();
1891 // - to handle the final flush. 2057 auto thread_local_event_buffer = thread_local_event_buffer_.Get();
1892 // For a thread without a message loop or the message loop may be blocked, the
1893 // trace events will be added into the main buffer directly.
1894 if (!thread_blocks_message_loop_.Get() && MessageLoop::current()) {
1895 thread_local_event_buffer = thread_local_event_buffer_.Get();
1896 if (thread_local_event_buffer &&
1897 !CheckGeneration(thread_local_event_buffer->generation())) {
1898 delete thread_local_event_buffer;
1899 thread_local_event_buffer = NULL;
1900 }
1901 if (!thread_local_event_buffer) {
1902 thread_local_event_buffer = new ThreadLocalEventBuffer(this);
1903 thread_local_event_buffer_.Set(thread_local_event_buffer);
1904 }
1905 }
1906 2058
1907 // Check and update the current thread name only if the event is for the 2059 // Check and update the current thread name only if the event is for the
1908 // current thread to avoid locks in most cases. 2060 // current thread to avoid locks in most cases.
1909 if (thread_id == static_cast<int>(PlatformThread::CurrentId())) { 2061 if (thread_id == static_cast<int>(PlatformThread::CurrentId())) {
1910 const char* new_name = ThreadIdNameManager::GetInstance()-> 2062 const char* new_name = ThreadIdNameManager::GetInstance()->
1911 GetName(thread_id); 2063 GetName(thread_id);
1912 // Check if the thread name has been set or changed since the previous 2064 // Check if the thread name has been set or changed since the previous
1913 // call (if any), but don't bother if the new name is empty. Note this will 2065 // call (if any), but don't bother if the new name is empty. Note this will
1914 // not detect a thread name change within the same char* buffer address: we 2066 // not detect a thread name change within the same char* buffer address: we
1915 // favor common case performance over corner case correctness. 2067 // favor common case performance over corner case correctness.
1916 if (new_name != g_current_thread_name.Get().Get() && 2068 if (new_name != g_current_thread_name.Get().Get() &&
1917 new_name && *new_name) { 2069 new_name && *new_name) {
1918 g_current_thread_name.Get().Set(new_name); 2070 g_current_thread_name.Get().Set(new_name);
1919 2071
1920 AutoLock thread_info_lock(thread_info_lock_); 2072 AutoLock thread_info_lock(thread_info_lock_);
1921 2073
1922 hash_map<int, std::string>::iterator existing_name = 2074 hash_map<int, std::string>::iterator existing_name =
1923 thread_names_.find(thread_id); 2075 thread_names_.find(thread_id);
1924 if (existing_name == thread_names_.end()) { 2076 if (existing_name == thread_names_.end()) {
1925 // This is a new thread id, and a new name. 2077 // This is a new thread id, and a new name.
1926 thread_names_[thread_id] = new_name; 2078 thread_names_[thread_id] = new_name;
1927 } else { 2079 } else {
1928 // This is a thread id that we've seen before, but potentially with a 2080 // This is a thread id that we've seen before, but potentially with a
1929 // new name. 2081 // new name.
1930 std::vector<StringPiece> existing_names; 2082 std::vector<StringPiece> existing_names = base::SplitStringPiece(
1931 Tokenize(existing_name->second, ",", &existing_names); 2083 existing_name->second, ",", base::KEEP_WHITESPACE,
2084 base::SPLIT_WANT_NONEMPTY);
1932 bool found = std::find(existing_names.begin(), 2085 bool found = std::find(existing_names.begin(),
1933 existing_names.end(), 2086 existing_names.end(),
1934 new_name) != existing_names.end(); 2087 new_name) != existing_names.end();
1935 if (!found) { 2088 if (!found) {
1936 if (existing_names.size()) 2089 if (existing_names.size())
1937 existing_name->second.push_back(','); 2090 existing_name->second.push_back(',');
1938 existing_name->second.append(new_name); 2091 existing_name->second.append(new_name);
1939 } 2092 }
1940 } 2093 }
1941 } 2094 }
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
2187 } 2340 }
2188 2341
2189 if (process_labels_.size() > 0) { 2342 if (process_labels_.size() > 0) {
2190 std::vector<std::string> labels; 2343 std::vector<std::string> labels;
2191 for(base::hash_map<int, std::string>::iterator it = process_labels_.begin(); 2344 for(base::hash_map<int, std::string>::iterator it = process_labels_.begin();
2192 it != process_labels_.end(); 2345 it != process_labels_.end();
2193 it++) { 2346 it++) {
2194 labels.push_back(it->second); 2347 labels.push_back(it->second);
2195 } 2348 }
2196 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 2349 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false),
2197 current_thread_id, 2350 current_thread_id, "process_labels", "labels",
2198 "process_labels", "labels", 2351 base::JoinString(labels, ","));
2199 JoinString(labels, ','));
2200 } 2352 }
2201 2353
2202 // Thread sort indices. 2354 // Thread sort indices.
2203 for(hash_map<int, int>::iterator it = thread_sort_indices_.begin(); 2355 for(hash_map<int, int>::iterator it = thread_sort_indices_.begin();
2204 it != thread_sort_indices_.end(); 2356 it != thread_sort_indices_.end();
2205 it++) { 2357 it++) {
2206 if (it->second == 0) 2358 if (it->second == 0)
2207 continue; 2359 continue;
2208 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 2360 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false),
2209 it->first, 2361 it->first,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2327 } 2479 }
2328 2480
2329 void TraceLog::SetCurrentThreadBlocksMessageLoop() { 2481 void TraceLog::SetCurrentThreadBlocksMessageLoop() {
2330 thread_blocks_message_loop_.Set(true); 2482 thread_blocks_message_loop_.Set(true);
2331 if (thread_local_event_buffer_.Get()) { 2483 if (thread_local_event_buffer_.Get()) {
2332 // This will flush the thread local buffer. 2484 // This will flush the thread local buffer.
2333 delete thread_local_event_buffer_.Get(); 2485 delete thread_local_event_buffer_.Get();
2334 } 2486 }
2335 } 2487 }
2336 2488
2489 void ConvertableToTraceFormat::EstimateTraceMemoryOverhead(
2490 TraceEventMemoryOverhead* overhead) {
2491 overhead->Add("ConvertableToTraceFormat(Unknown)", sizeof(*this));
2492 }
2493
2337 } // namespace trace_event 2494 } // namespace trace_event
2338 } // namespace base 2495 } // namespace base
2339 2496
2340 namespace trace_event_internal { 2497 namespace trace_event_internal {
2341 2498
2342 ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient( 2499 ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient(
2343 const char* category_group, const char* name) { 2500 const char* category_group, const char* name) {
2344 // The single atom works because for now the category_group can only be "gpu". 2501 // The single atom works because for now the category_group can only be "gpu".
2345 DCHECK_EQ(strcmp(category_group, "gpu"), 0); 2502 DCHECK_EQ(strcmp(category_group, "gpu"), 0);
2346 static TRACE_EVENT_API_ATOMIC_WORD atomic = 0; 2503 static TRACE_EVENT_API_ATOMIC_WORD atomic = 0;
(...skipping 12 matching lines...) Expand all
2359 } 2516 }
2360 2517
2361 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2518 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2362 if (*category_group_enabled_) { 2519 if (*category_group_enabled_) {
2363 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, 2520 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_,
2364 name_, event_handle_); 2521 name_, event_handle_);
2365 } 2522 }
2366 } 2523 }
2367 2524
2368 } // namespace trace_event_internal 2525 } // namespace trace_event_internal
OLDNEW
« no previous file with comments | « base/trace_event/trace_event_impl.h ('k') | base/trace_event/trace_event_memory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698