1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "build/build_config.h"
7 #if defined(COMPILER_MSVC)
8 // MSDN says to #include <intrin.h>, but that breaks the VS2005 build.
10 void* _ReturnAddress();
14 #include "base/tracked.h"
16 #include "base/stringprintf.h"
17 #include "base/tracked_objects.h"
19 using base::TimeTicks
;
21 namespace tracked_objects
{
23 //------------------------------------------------------------------------------
25 Location::Location(const char* function_name
,
26 const char* file_name
,
28 const void* program_counter
)
29 : function_name_(function_name
),
30 file_name_(file_name
),
31 line_number_(line_number
),
32 program_counter_(program_counter
) {
36 : function_name_("Unknown"),
37 file_name_("Unknown"),
39 program_counter_(NULL
) {
42 void Location::Write(bool display_filename
, bool display_function_name
,
43 std::string
* output
) const {
44 base::StringAppendF(output
, "%s[%d] ",
45 display_filename
? file_name_
: "line",
48 if (display_function_name
) {
49 WriteFunctionName(output
);
50 output
->push_back(' ');
54 void Location::WriteFunctionName(std::string
* output
) const {
55 // Translate "<" to "<" for HTML safety.
56 // TODO(jar): Support ASCII or html for logging in ASCII.
57 for (const char *p
= function_name_
; *p
; p
++) {
60 output
->append("<");
64 output
->append(">");
68 output
->push_back(*p
);
74 #if defined(COMPILER_MSVC)
77 BASE_API
const void* GetProgramCounter() {
78 #if defined(COMPILER_MSVC)
79 return _ReturnAddress();
80 #elif defined(COMPILER_GCC)
81 return __builtin_extract_return_addr(__builtin_return_address(0));
82 #endif // COMPILER_GCC
87 //------------------------------------------------------------------------------
89 #if !defined(TRACK_ALL_TASK_OBJECTS)
91 Tracked::Tracked() : birth_program_counter_(NULL
) {}
92 Tracked::~Tracked() {}
94 void Tracked::SetBirthPlace(const Location
& from_here
) {
95 birth_program_counter_
= from_here
.program_counter();
98 const Location
Tracked::GetBirthPlace() const {
99 static Location
kNone("NoFunctionName", "NeedToSetBirthPlace", -1, NULL
);
102 bool Tracked::MissingBirthPlace() const { return false; }
103 void Tracked::ResetBirthTime() {}
108 : tracked_births_(NULL
),
109 tracked_birth_time_(TimeTicks::Now()) {
112 Tracked::~Tracked() {
113 if (!ThreadData::IsActive() || !tracked_births_
)
115 ThreadData::current()->TallyADeath(*tracked_births_
,
116 TimeTicks::Now() - tracked_birth_time_
);
119 void Tracked::SetBirthPlace(const Location
& from_here
) {
120 if (!ThreadData::IsActive())
123 tracked_births_
->ForgetBirth();
124 ThreadData
* current_thread_data
= ThreadData::current();
125 if (!current_thread_data
)
126 return; // Shutdown started, and this thread wasn't registered.
127 tracked_births_
= current_thread_data
->TallyABirth(from_here
);
129 birth_program_counter_
= from_here
.program_counter();
132 const Location
Tracked::GetBirthPlace() const {
133 static Location
kNone("UnknownFunctionName", "UnknownFile", -1, NULL
);
134 return tracked_births_
? tracked_births_
->location() : kNone
;
137 void Tracked::ResetBirthTime() {
138 tracked_birth_time_
= TimeTicks::Now();
141 bool Tracked::MissingBirthPlace() const {
142 return !tracked_births_
|| tracked_births_
->location().line_number() == -1;
145 #endif // !defined(TRACK_ALL_TASK_OBJECTS)
147 } // namespace tracked_objects