Chromium Code Reviews| 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 "base/debug/thread_heap_usage_tracker.h" | 5 #include "base/debug/thread_heap_usage_tracker.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <type_traits> | 9 #include <type_traits> |
| 10 | 10 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 ThreadHeapUsage* GetOrCreateThreadUsage() { | 137 ThreadHeapUsage* GetOrCreateThreadUsage() { |
| 138 ThreadHeapUsage* allocator_usage = | 138 ThreadHeapUsage* allocator_usage = |
| 139 static_cast<ThreadHeapUsage*>(g_thread_allocator_usage.Get()); | 139 static_cast<ThreadHeapUsage*>(g_thread_allocator_usage.Get()); |
| 140 if (allocator_usage == kInitializingSentinel) | 140 if (allocator_usage == kInitializingSentinel) |
| 141 return nullptr; // Re-entrancy case. | 141 return nullptr; // Re-entrancy case. |
| 142 | 142 |
| 143 if (allocator_usage == nullptr) { | 143 if (allocator_usage == nullptr) { |
| 144 // Prevent reentrancy due to the allocation below. | 144 // Prevent reentrancy due to the allocation below. |
| 145 g_thread_allocator_usage.Set(kInitializingSentinel); | 145 g_thread_allocator_usage.Set(kInitializingSentinel); |
| 146 | 146 |
| 147 allocator_usage = new ThreadHeapUsage; | 147 // Delegate the allocation of the per-thread structure to the underlying |
| 148 // heap shim, for symmetry with the deallocation. Otherwise interposing | |
| 149 // shims may mis-attribute or mis-direct this allocation. | |
| 150 const AllocatorDispatch* next = allocator_dispatch.next; | |
|
Primiano Tucci (use gerrit)
2016/11/28 18:38:31
add a compile_assert(std::is_pod(ThreadHeapUsage))
Sigurður Ásgeirsson
2016/11/30 14:41:14
Got one of those down a couple of lines, added ano
| |
| 151 allocator_usage = static_cast<ThreadHeapUsage*>( | |
| 152 next->alloc_function(next, sizeof(ThreadHeapUsage))); | |
|
Primiano Tucci (use gerrit)
2016/11/28 18:38:31
maybe a placement new is slighlty cleaner here.
I
Sigurður Ásgeirsson
2016/11/30 14:41:14
Ah, placement new - cool - haven't used it for thi
| |
| 148 memset(allocator_usage, 0, sizeof(*allocator_usage)); | 153 memset(allocator_usage, 0, sizeof(*allocator_usage)); |
| 149 g_thread_allocator_usage.Set(allocator_usage); | 154 g_thread_allocator_usage.Set(allocator_usage); |
| 150 } | 155 } |
| 151 | 156 |
| 152 return allocator_usage; | 157 return allocator_usage; |
| 153 } | 158 } |
| 154 | 159 |
| 155 } // namespace | 160 } // namespace |
| 156 | 161 |
| 157 ThreadHeapUsageTracker::ThreadHeapUsageTracker() : thread_usage_(nullptr) { | 162 ThreadHeapUsageTracker::ThreadHeapUsageTracker() : thread_usage_(nullptr) { |
| 158 static_assert(std::is_pod<ThreadHeapUsage>::value, "Must be POD."); | 163 static_assert(std::is_pod<ThreadHeapUsage>::value, "Must be POD."); |
| 159 } | 164 } |
| 160 | 165 |
| 161 ThreadHeapUsageTracker::~ThreadHeapUsageTracker() { | 166 ThreadHeapUsageTracker::~ThreadHeapUsageTracker() { |
| 162 DCHECK(thread_checker_.CalledOnValidThread()); | 167 // TODO(fdoray): This DCHECK causes inexplicable fallout in Chrome. This |
| 168 // was isolated to a line in CalledOnValidThread reading. | |
| 169 // if (task_token_ == TaskToken::GetForCurrentThread()) | |
| 170 // DCHECK(thread_checker_.CalledOnValidThread()); | |
| 163 | 171 |
| 164 if (thread_usage_ != nullptr) { | 172 if (thread_usage_ != nullptr) { |
| 165 // If this tracker wasn't stopped, make it inclusive so that the | 173 // If this tracker wasn't stopped, make it inclusive so that the |
| 166 // usage isn't lost. | 174 // usage isn't lost. |
| 167 Stop(false); | 175 Stop(false); |
| 168 } | 176 } |
| 169 } | 177 } |
| 170 | 178 |
| 171 void ThreadHeapUsageTracker::Start() { | 179 void ThreadHeapUsageTracker::Start() { |
| 172 DCHECK(thread_checker_.CalledOnValidThread()); | 180 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 } | 255 } |
| 248 | 256 |
| 249 base::allocator::AllocatorDispatch* | 257 base::allocator::AllocatorDispatch* |
| 250 ThreadHeapUsageTracker::GetDispatchForTesting() { | 258 ThreadHeapUsageTracker::GetDispatchForTesting() { |
| 251 return &allocator_dispatch; | 259 return &allocator_dispatch; |
| 252 } | 260 } |
| 253 | 261 |
| 254 void ThreadHeapUsageTracker::EnsureTLSInitialized() { | 262 void ThreadHeapUsageTracker::EnsureTLSInitialized() { |
| 255 if (!g_thread_allocator_usage.initialized()) { | 263 if (!g_thread_allocator_usage.initialized()) { |
| 256 g_thread_allocator_usage.Initialize([](void* allocator_usage) { | 264 g_thread_allocator_usage.Initialize([](void* allocator_usage) { |
| 257 delete static_cast<ThreadHeapUsage*>(allocator_usage); | 265 // Delegate the freeing of the per-thread structure to the next-lower |
| 266 // heap shim. Otherwise this free will re-initialize the TLS on thread | |
| 267 // exit. | |
| 268 allocator_dispatch.next->free_function(allocator_dispatch.next, | |
| 269 allocator_usage); | |
| 258 }); | 270 }); |
| 259 } | 271 } |
| 260 } | 272 } |
| 261 | 273 |
| 262 } // namespace debug | 274 } // namespace debug |
| 263 } // namespace base | 275 } // namespace base |
| OLD | NEW |