allocation_record.h revision 1ed11b9ad5512cf464cb1686640df53201fa5297
18c2ff641294715864013737fdec57cdfd410270cMan Cao/* 28c2ff641294715864013737fdec57cdfd410270cMan Cao * Copyright (C) 2015 The Android Open Source Project 38c2ff641294715864013737fdec57cdfd410270cMan Cao * 48c2ff641294715864013737fdec57cdfd410270cMan Cao * Licensed under the Apache License, Version 2.0 (the "License"); 58c2ff641294715864013737fdec57cdfd410270cMan Cao * you may not use this file except in compliance with the License. 68c2ff641294715864013737fdec57cdfd410270cMan Cao * You may obtain a copy of the License at 78c2ff641294715864013737fdec57cdfd410270cMan Cao * 88c2ff641294715864013737fdec57cdfd410270cMan Cao * http://www.apache.org/licenses/LICENSE-2.0 98c2ff641294715864013737fdec57cdfd410270cMan Cao * 108c2ff641294715864013737fdec57cdfd410270cMan Cao * Unless required by applicable law or agreed to in writing, software 118c2ff641294715864013737fdec57cdfd410270cMan Cao * distributed under the License is distributed on an "AS IS" BASIS, 128c2ff641294715864013737fdec57cdfd410270cMan Cao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138c2ff641294715864013737fdec57cdfd410270cMan Cao * See the License for the specific language governing permissions and 148c2ff641294715864013737fdec57cdfd410270cMan Cao * limitations under the License. 158c2ff641294715864013737fdec57cdfd410270cMan Cao */ 168c2ff641294715864013737fdec57cdfd410270cMan Cao 178c2ff641294715864013737fdec57cdfd410270cMan Cao#ifndef ART_RUNTIME_GC_ALLOCATION_RECORD_H_ 188c2ff641294715864013737fdec57cdfd410270cMan Cao#define ART_RUNTIME_GC_ALLOCATION_RECORD_H_ 198c2ff641294715864013737fdec57cdfd410270cMan Cao 208c2ff641294715864013737fdec57cdfd410270cMan Cao#include <list> 218c2ff641294715864013737fdec57cdfd410270cMan Cao 228c2ff641294715864013737fdec57cdfd410270cMan Cao#include "base/mutex.h" 238c2ff641294715864013737fdec57cdfd410270cMan Cao#include "object_callbacks.h" 248c2ff641294715864013737fdec57cdfd410270cMan Cao#include "gc_root.h" 258c2ff641294715864013737fdec57cdfd410270cMan Cao 268c2ff641294715864013737fdec57cdfd410270cMan Caonamespace art { 278c2ff641294715864013737fdec57cdfd410270cMan Cao 288c2ff641294715864013737fdec57cdfd410270cMan Caoclass ArtMethod; 298c2ff641294715864013737fdec57cdfd410270cMan Caoclass Thread; 308c2ff641294715864013737fdec57cdfd410270cMan Cao 318c2ff641294715864013737fdec57cdfd410270cMan Caonamespace mirror { 328c2ff641294715864013737fdec57cdfd410270cMan Cao class Class; 338c2ff641294715864013737fdec57cdfd410270cMan Cao class Object; 348c2ff641294715864013737fdec57cdfd410270cMan Cao} 358c2ff641294715864013737fdec57cdfd410270cMan Cao 368c2ff641294715864013737fdec57cdfd410270cMan Caonamespace gc { 378c2ff641294715864013737fdec57cdfd410270cMan Cao 388c2ff641294715864013737fdec57cdfd410270cMan Caoclass AllocRecordStackTraceElement { 398c2ff641294715864013737fdec57cdfd410270cMan Cao public: 408c2ff641294715864013737fdec57cdfd410270cMan Cao AllocRecordStackTraceElement() : method_(nullptr), dex_pc_(0) {} 418c2ff641294715864013737fdec57cdfd410270cMan Cao 428c2ff641294715864013737fdec57cdfd410270cMan Cao int32_t ComputeLineNumber() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 438c2ff641294715864013737fdec57cdfd410270cMan Cao 448c2ff641294715864013737fdec57cdfd410270cMan Cao ArtMethod* GetMethod() const { 458c2ff641294715864013737fdec57cdfd410270cMan Cao return method_; 468c2ff641294715864013737fdec57cdfd410270cMan Cao } 478c2ff641294715864013737fdec57cdfd410270cMan Cao 488c2ff641294715864013737fdec57cdfd410270cMan Cao void SetMethod(ArtMethod* m) { 498c2ff641294715864013737fdec57cdfd410270cMan Cao method_ = m; 508c2ff641294715864013737fdec57cdfd410270cMan Cao } 518c2ff641294715864013737fdec57cdfd410270cMan Cao 528c2ff641294715864013737fdec57cdfd410270cMan Cao uint32_t GetDexPc() const { 538c2ff641294715864013737fdec57cdfd410270cMan Cao return dex_pc_; 548c2ff641294715864013737fdec57cdfd410270cMan Cao } 558c2ff641294715864013737fdec57cdfd410270cMan Cao 568c2ff641294715864013737fdec57cdfd410270cMan Cao void SetDexPc(uint32_t pc) { 578c2ff641294715864013737fdec57cdfd410270cMan Cao dex_pc_ = pc; 588c2ff641294715864013737fdec57cdfd410270cMan Cao } 598c2ff641294715864013737fdec57cdfd410270cMan Cao 608c2ff641294715864013737fdec57cdfd410270cMan Cao bool operator==(const AllocRecordStackTraceElement& other) const { 618c2ff641294715864013737fdec57cdfd410270cMan Cao if (this == &other) return true; 628c2ff641294715864013737fdec57cdfd410270cMan Cao return method_ == other.method_ && dex_pc_ == other.dex_pc_; 638c2ff641294715864013737fdec57cdfd410270cMan Cao } 648c2ff641294715864013737fdec57cdfd410270cMan Cao 658c2ff641294715864013737fdec57cdfd410270cMan Cao private: 668c2ff641294715864013737fdec57cdfd410270cMan Cao ArtMethod* method_; 678c2ff641294715864013737fdec57cdfd410270cMan Cao uint32_t dex_pc_; 688c2ff641294715864013737fdec57cdfd410270cMan Cao}; 698c2ff641294715864013737fdec57cdfd410270cMan Cao 708c2ff641294715864013737fdec57cdfd410270cMan Caoclass AllocRecordStackTrace { 718c2ff641294715864013737fdec57cdfd410270cMan Cao public: 728c2ff641294715864013737fdec57cdfd410270cMan Cao static constexpr size_t kHashMultiplier = 17; 738c2ff641294715864013737fdec57cdfd410270cMan Cao 741ed11b9ad5512cf464cb1686640df53201fa5297Man Cao explicit AllocRecordStackTrace(size_t max_depth) 751ed11b9ad5512cf464cb1686640df53201fa5297Man Cao : tid_(0), depth_(0), stack_(new AllocRecordStackTraceElement[max_depth]) {} 761ed11b9ad5512cf464cb1686640df53201fa5297Man Cao 771ed11b9ad5512cf464cb1686640df53201fa5297Man Cao AllocRecordStackTrace(const AllocRecordStackTrace& r) 781ed11b9ad5512cf464cb1686640df53201fa5297Man Cao : tid_(r.tid_), depth_(r.depth_), stack_(new AllocRecordStackTraceElement[r.depth_]) { 791ed11b9ad5512cf464cb1686640df53201fa5297Man Cao for (size_t i = 0; i < depth_; ++i) { 801ed11b9ad5512cf464cb1686640df53201fa5297Man Cao stack_[i] = r.stack_[i]; 811ed11b9ad5512cf464cb1686640df53201fa5297Man Cao } 821ed11b9ad5512cf464cb1686640df53201fa5297Man Cao } 838c2ff641294715864013737fdec57cdfd410270cMan Cao 848c2ff641294715864013737fdec57cdfd410270cMan Cao ~AllocRecordStackTrace() { 858c2ff641294715864013737fdec57cdfd410270cMan Cao delete[] stack_; 868c2ff641294715864013737fdec57cdfd410270cMan Cao } 878c2ff641294715864013737fdec57cdfd410270cMan Cao 888c2ff641294715864013737fdec57cdfd410270cMan Cao pid_t GetTid() const { 898c2ff641294715864013737fdec57cdfd410270cMan Cao return tid_; 908c2ff641294715864013737fdec57cdfd410270cMan Cao } 918c2ff641294715864013737fdec57cdfd410270cMan Cao 921ed11b9ad5512cf464cb1686640df53201fa5297Man Cao void SetTid(pid_t t) { 931ed11b9ad5512cf464cb1686640df53201fa5297Man Cao tid_ = t; 941ed11b9ad5512cf464cb1686640df53201fa5297Man Cao } 951ed11b9ad5512cf464cb1686640df53201fa5297Man Cao 968c2ff641294715864013737fdec57cdfd410270cMan Cao size_t GetDepth() const { 978c2ff641294715864013737fdec57cdfd410270cMan Cao return depth_; 988c2ff641294715864013737fdec57cdfd410270cMan Cao } 998c2ff641294715864013737fdec57cdfd410270cMan Cao 1008c2ff641294715864013737fdec57cdfd410270cMan Cao void SetDepth(size_t depth) { 1018c2ff641294715864013737fdec57cdfd410270cMan Cao depth_ = depth; 1028c2ff641294715864013737fdec57cdfd410270cMan Cao } 1038c2ff641294715864013737fdec57cdfd410270cMan Cao 1048c2ff641294715864013737fdec57cdfd410270cMan Cao const AllocRecordStackTraceElement& GetStackElement(size_t index) const { 1058c2ff641294715864013737fdec57cdfd410270cMan Cao DCHECK_LT(index, depth_); 1068c2ff641294715864013737fdec57cdfd410270cMan Cao return stack_[index]; 1078c2ff641294715864013737fdec57cdfd410270cMan Cao } 1088c2ff641294715864013737fdec57cdfd410270cMan Cao 1098c2ff641294715864013737fdec57cdfd410270cMan Cao void SetStackElementAt(size_t index, ArtMethod* m, uint32_t dex_pc) { 1108c2ff641294715864013737fdec57cdfd410270cMan Cao stack_[index].SetMethod(m); 1118c2ff641294715864013737fdec57cdfd410270cMan Cao stack_[index].SetDexPc(dex_pc); 1128c2ff641294715864013737fdec57cdfd410270cMan Cao } 1138c2ff641294715864013737fdec57cdfd410270cMan Cao 1148c2ff641294715864013737fdec57cdfd410270cMan Cao bool operator==(const AllocRecordStackTrace& other) const { 1158c2ff641294715864013737fdec57cdfd410270cMan Cao if (this == &other) return true; 1161ed11b9ad5512cf464cb1686640df53201fa5297Man Cao if (tid_ != other.tid_) return false; 1178c2ff641294715864013737fdec57cdfd410270cMan Cao if (depth_ != other.depth_) return false; 1188c2ff641294715864013737fdec57cdfd410270cMan Cao for (size_t i = 0; i < depth_; ++i) { 1198c2ff641294715864013737fdec57cdfd410270cMan Cao if (!(stack_[i] == other.stack_[i])) return false; 1208c2ff641294715864013737fdec57cdfd410270cMan Cao } 1218c2ff641294715864013737fdec57cdfd410270cMan Cao return true; 1228c2ff641294715864013737fdec57cdfd410270cMan Cao } 1238c2ff641294715864013737fdec57cdfd410270cMan Cao 1248c2ff641294715864013737fdec57cdfd410270cMan Cao private: 1251ed11b9ad5512cf464cb1686640df53201fa5297Man Cao pid_t tid_; 1268c2ff641294715864013737fdec57cdfd410270cMan Cao size_t depth_; 1278c2ff641294715864013737fdec57cdfd410270cMan Cao AllocRecordStackTraceElement* const stack_; 1288c2ff641294715864013737fdec57cdfd410270cMan Cao}; 1298c2ff641294715864013737fdec57cdfd410270cMan Cao 1308c2ff641294715864013737fdec57cdfd410270cMan Caostruct HashAllocRecordTypes { 1318c2ff641294715864013737fdec57cdfd410270cMan Cao size_t operator()(const AllocRecordStackTraceElement& r) const { 1328c2ff641294715864013737fdec57cdfd410270cMan Cao return std::hash<void*>()(reinterpret_cast<void*>(r.GetMethod())) * 1338c2ff641294715864013737fdec57cdfd410270cMan Cao AllocRecordStackTrace::kHashMultiplier + std::hash<uint32_t>()(r.GetDexPc()); 1348c2ff641294715864013737fdec57cdfd410270cMan Cao } 1358c2ff641294715864013737fdec57cdfd410270cMan Cao 1368c2ff641294715864013737fdec57cdfd410270cMan Cao size_t operator()(const AllocRecordStackTrace& r) const { 1378c2ff641294715864013737fdec57cdfd410270cMan Cao size_t depth = r.GetDepth(); 1388c2ff641294715864013737fdec57cdfd410270cMan Cao size_t result = r.GetTid() * AllocRecordStackTrace::kHashMultiplier + depth; 1398c2ff641294715864013737fdec57cdfd410270cMan Cao for (size_t i = 0; i < depth; ++i) { 1408c2ff641294715864013737fdec57cdfd410270cMan Cao result = result * AllocRecordStackTrace::kHashMultiplier + (*this)(r.GetStackElement(i)); 1418c2ff641294715864013737fdec57cdfd410270cMan Cao } 1428c2ff641294715864013737fdec57cdfd410270cMan Cao return result; 1438c2ff641294715864013737fdec57cdfd410270cMan Cao } 1448c2ff641294715864013737fdec57cdfd410270cMan Cao}; 1458c2ff641294715864013737fdec57cdfd410270cMan Cao 1468c2ff641294715864013737fdec57cdfd410270cMan Caotemplate <typename T> struct HashAllocRecordTypesPtr { 1478c2ff641294715864013737fdec57cdfd410270cMan Cao size_t operator()(const T* r) const { 1488c2ff641294715864013737fdec57cdfd410270cMan Cao if (r == nullptr) return 0; 1498c2ff641294715864013737fdec57cdfd410270cMan Cao return HashAllocRecordTypes()(*r); 1508c2ff641294715864013737fdec57cdfd410270cMan Cao } 1518c2ff641294715864013737fdec57cdfd410270cMan Cao}; 1528c2ff641294715864013737fdec57cdfd410270cMan Cao 1538c2ff641294715864013737fdec57cdfd410270cMan Caotemplate <typename T> struct EqAllocRecordTypesPtr { 1548c2ff641294715864013737fdec57cdfd410270cMan Cao bool operator()(const T* r1, const T* r2) const { 1558c2ff641294715864013737fdec57cdfd410270cMan Cao if (r1 == r2) return true; 1568c2ff641294715864013737fdec57cdfd410270cMan Cao if (r1 == nullptr || r2 == nullptr) return false; 1578c2ff641294715864013737fdec57cdfd410270cMan Cao return *r1 == *r2; 1588c2ff641294715864013737fdec57cdfd410270cMan Cao } 1598c2ff641294715864013737fdec57cdfd410270cMan Cao}; 1608c2ff641294715864013737fdec57cdfd410270cMan Cao 1618c2ff641294715864013737fdec57cdfd410270cMan Caoclass AllocRecord { 1628c2ff641294715864013737fdec57cdfd410270cMan Cao public: 1638c2ff641294715864013737fdec57cdfd410270cMan Cao // All instances of AllocRecord should be managed by an instance of AllocRecordObjectMap. 1648c2ff641294715864013737fdec57cdfd410270cMan Cao AllocRecord(size_t count, AllocRecordStackTrace* trace) 1658c2ff641294715864013737fdec57cdfd410270cMan Cao : byte_count_(count), trace_(trace) {} 1668c2ff641294715864013737fdec57cdfd410270cMan Cao 1678c2ff641294715864013737fdec57cdfd410270cMan Cao ~AllocRecord() { 1688c2ff641294715864013737fdec57cdfd410270cMan Cao delete trace_; 1698c2ff641294715864013737fdec57cdfd410270cMan Cao } 1708c2ff641294715864013737fdec57cdfd410270cMan Cao 1718c2ff641294715864013737fdec57cdfd410270cMan Cao size_t GetDepth() const { 1728c2ff641294715864013737fdec57cdfd410270cMan Cao return trace_->GetDepth(); 1738c2ff641294715864013737fdec57cdfd410270cMan Cao } 1748c2ff641294715864013737fdec57cdfd410270cMan Cao 1758c2ff641294715864013737fdec57cdfd410270cMan Cao const AllocRecordStackTrace* GetStackTrace() const { 1768c2ff641294715864013737fdec57cdfd410270cMan Cao return trace_; 1778c2ff641294715864013737fdec57cdfd410270cMan Cao } 1788c2ff641294715864013737fdec57cdfd410270cMan Cao 1798c2ff641294715864013737fdec57cdfd410270cMan Cao size_t ByteCount() const { 1808c2ff641294715864013737fdec57cdfd410270cMan Cao return byte_count_; 1818c2ff641294715864013737fdec57cdfd410270cMan Cao } 1828c2ff641294715864013737fdec57cdfd410270cMan Cao 1838c2ff641294715864013737fdec57cdfd410270cMan Cao pid_t GetTid() const { 1848c2ff641294715864013737fdec57cdfd410270cMan Cao return trace_->GetTid(); 1858c2ff641294715864013737fdec57cdfd410270cMan Cao } 1868c2ff641294715864013737fdec57cdfd410270cMan Cao 1878c2ff641294715864013737fdec57cdfd410270cMan Cao const AllocRecordStackTraceElement& StackElement(size_t index) const { 1888c2ff641294715864013737fdec57cdfd410270cMan Cao return trace_->GetStackElement(index); 1898c2ff641294715864013737fdec57cdfd410270cMan Cao } 1908c2ff641294715864013737fdec57cdfd410270cMan Cao 1918c2ff641294715864013737fdec57cdfd410270cMan Cao private: 1928c2ff641294715864013737fdec57cdfd410270cMan Cao const size_t byte_count_; 1938c2ff641294715864013737fdec57cdfd410270cMan Cao // TODO: Currently trace_ is like a std::unique_ptr, 1948c2ff641294715864013737fdec57cdfd410270cMan Cao // but in future with deduplication it could be a std::shared_ptr. 1958c2ff641294715864013737fdec57cdfd410270cMan Cao const AllocRecordStackTrace* const trace_; 1968c2ff641294715864013737fdec57cdfd410270cMan Cao}; 1978c2ff641294715864013737fdec57cdfd410270cMan Cao 1988c2ff641294715864013737fdec57cdfd410270cMan Caoclass AllocRecordObjectMap { 1998c2ff641294715864013737fdec57cdfd410270cMan Cao public: 2008c2ff641294715864013737fdec57cdfd410270cMan Cao // Since the entries contain weak roots, they need a read barrier. Do not directly access 2018c2ff641294715864013737fdec57cdfd410270cMan Cao // the mirror::Object pointers in it. Use functions that contain read barriers. 2028c2ff641294715864013737fdec57cdfd410270cMan Cao // No need for "const AllocRecord*" in the list, because all fields of AllocRecord are const. 2038c2ff641294715864013737fdec57cdfd410270cMan Cao typedef std::list<std::pair<GcRoot<mirror::Object>, AllocRecord*>> EntryList; 2048c2ff641294715864013737fdec57cdfd410270cMan Cao 2058c2ff641294715864013737fdec57cdfd410270cMan Cao // "static" because it is part of double-checked locking. It needs to check a bool first, 2068c2ff641294715864013737fdec57cdfd410270cMan Cao // in order to make sure the AllocRecordObjectMap object is not null. 2078c2ff641294715864013737fdec57cdfd410270cMan Cao static void RecordAllocation(Thread* self, mirror::Object* obj, size_t byte_count) 2088c2ff641294715864013737fdec57cdfd410270cMan Cao LOCKS_EXCLUDED(Locks::alloc_tracker_lock_) 2098c2ff641294715864013737fdec57cdfd410270cMan Cao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2108c2ff641294715864013737fdec57cdfd410270cMan Cao 2118c2ff641294715864013737fdec57cdfd410270cMan Cao static void SetAllocTrackingEnabled(bool enabled) LOCKS_EXCLUDED(Locks::alloc_tracker_lock_); 2128c2ff641294715864013737fdec57cdfd410270cMan Cao 2138c2ff641294715864013737fdec57cdfd410270cMan Cao AllocRecordObjectMap() EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_) 2148c2ff641294715864013737fdec57cdfd410270cMan Cao : alloc_record_max_(kDefaultNumAllocRecords), 2151ed11b9ad5512cf464cb1686640df53201fa5297Man Cao recent_record_max_(kDefaultNumRecentRecords), 2168c2ff641294715864013737fdec57cdfd410270cMan Cao max_stack_depth_(kDefaultAllocStackDepth), 2171ed11b9ad5512cf464cb1686640df53201fa5297Man Cao scratch_trace_(kMaxSupportedStackDepth), 2188c2ff641294715864013737fdec57cdfd410270cMan Cao alloc_ddm_thread_id_(0) {} 2198c2ff641294715864013737fdec57cdfd410270cMan Cao 2208c2ff641294715864013737fdec57cdfd410270cMan Cao ~AllocRecordObjectMap(); 2218c2ff641294715864013737fdec57cdfd410270cMan Cao 2228c2ff641294715864013737fdec57cdfd410270cMan Cao void Put(mirror::Object* obj, AllocRecord* record) 2238c2ff641294715864013737fdec57cdfd410270cMan Cao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 2248c2ff641294715864013737fdec57cdfd410270cMan Cao EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_) { 2251ed11b9ad5512cf464cb1686640df53201fa5297Man Cao if (entries_.size() == alloc_record_max_) { 2261ed11b9ad5512cf464cb1686640df53201fa5297Man Cao delete entries_.front().second; 2271ed11b9ad5512cf464cb1686640df53201fa5297Man Cao entries_.pop_front(); 2281ed11b9ad5512cf464cb1686640df53201fa5297Man Cao } 2298c2ff641294715864013737fdec57cdfd410270cMan Cao entries_.emplace_back(GcRoot<mirror::Object>(obj), record); 2308c2ff641294715864013737fdec57cdfd410270cMan Cao } 2318c2ff641294715864013737fdec57cdfd410270cMan Cao 2328c2ff641294715864013737fdec57cdfd410270cMan Cao size_t Size() const SHARED_LOCKS_REQUIRED(Locks::alloc_tracker_lock_) { 2338c2ff641294715864013737fdec57cdfd410270cMan Cao return entries_.size(); 2348c2ff641294715864013737fdec57cdfd410270cMan Cao } 2358c2ff641294715864013737fdec57cdfd410270cMan Cao 2361ed11b9ad5512cf464cb1686640df53201fa5297Man Cao size_t GetRecentAllocationSize() const SHARED_LOCKS_REQUIRED(Locks::alloc_tracker_lock_) { 2371ed11b9ad5512cf464cb1686640df53201fa5297Man Cao CHECK_LE(recent_record_max_, alloc_record_max_); 2381ed11b9ad5512cf464cb1686640df53201fa5297Man Cao size_t sz = entries_.size(); 2391ed11b9ad5512cf464cb1686640df53201fa5297Man Cao return std::min(recent_record_max_, sz); 2401ed11b9ad5512cf464cb1686640df53201fa5297Man Cao } 2411ed11b9ad5512cf464cb1686640df53201fa5297Man Cao 2421ed11b9ad5512cf464cb1686640df53201fa5297Man Cao void VisitRoots(RootVisitor* visitor) 2438c2ff641294715864013737fdec57cdfd410270cMan Cao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 2448c2ff641294715864013737fdec57cdfd410270cMan Cao EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_); 2458c2ff641294715864013737fdec57cdfd410270cMan Cao 2461ed11b9ad5512cf464cb1686640df53201fa5297Man Cao void SweepAllocationRecords(IsMarkedCallback* callback, void* arg) 2478c2ff641294715864013737fdec57cdfd410270cMan Cao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 2481ed11b9ad5512cf464cb1686640df53201fa5297Man Cao EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_); 2498c2ff641294715864013737fdec57cdfd410270cMan Cao 2508c2ff641294715864013737fdec57cdfd410270cMan Cao // TODO: Is there a better way to hide the entries_'s type? 2518c2ff641294715864013737fdec57cdfd410270cMan Cao EntryList::iterator Begin() 2528c2ff641294715864013737fdec57cdfd410270cMan Cao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 2538c2ff641294715864013737fdec57cdfd410270cMan Cao EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_) { 2548c2ff641294715864013737fdec57cdfd410270cMan Cao return entries_.begin(); 2558c2ff641294715864013737fdec57cdfd410270cMan Cao } 2568c2ff641294715864013737fdec57cdfd410270cMan Cao 2578c2ff641294715864013737fdec57cdfd410270cMan Cao EntryList::iterator End() 2588c2ff641294715864013737fdec57cdfd410270cMan Cao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 2598c2ff641294715864013737fdec57cdfd410270cMan Cao EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_) { 2608c2ff641294715864013737fdec57cdfd410270cMan Cao return entries_.end(); 2618c2ff641294715864013737fdec57cdfd410270cMan Cao } 2628c2ff641294715864013737fdec57cdfd410270cMan Cao 2638c2ff641294715864013737fdec57cdfd410270cMan Cao EntryList::reverse_iterator RBegin() 2648c2ff641294715864013737fdec57cdfd410270cMan Cao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 2658c2ff641294715864013737fdec57cdfd410270cMan Cao EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_) { 2668c2ff641294715864013737fdec57cdfd410270cMan Cao return entries_.rbegin(); 2678c2ff641294715864013737fdec57cdfd410270cMan Cao } 2688c2ff641294715864013737fdec57cdfd410270cMan Cao 2698c2ff641294715864013737fdec57cdfd410270cMan Cao EntryList::reverse_iterator REnd() 2708c2ff641294715864013737fdec57cdfd410270cMan Cao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 2718c2ff641294715864013737fdec57cdfd410270cMan Cao EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_) { 2728c2ff641294715864013737fdec57cdfd410270cMan Cao return entries_.rend(); 2738c2ff641294715864013737fdec57cdfd410270cMan Cao } 2748c2ff641294715864013737fdec57cdfd410270cMan Cao 2758c2ff641294715864013737fdec57cdfd410270cMan Cao private: 2768c2ff641294715864013737fdec57cdfd410270cMan Cao static constexpr size_t kDefaultNumAllocRecords = 512 * 1024; 2771ed11b9ad5512cf464cb1686640df53201fa5297Man Cao static constexpr size_t kDefaultNumRecentRecords = 64 * 1024 - 1; 2781ed11b9ad5512cf464cb1686640df53201fa5297Man Cao static constexpr size_t kDefaultAllocStackDepth = 16; 2791ed11b9ad5512cf464cb1686640df53201fa5297Man Cao static constexpr size_t kMaxSupportedStackDepth = 128; 2808c2ff641294715864013737fdec57cdfd410270cMan Cao size_t alloc_record_max_ GUARDED_BY(Locks::alloc_tracker_lock_); 2811ed11b9ad5512cf464cb1686640df53201fa5297Man Cao size_t recent_record_max_ GUARDED_BY(Locks::alloc_tracker_lock_); 2828c2ff641294715864013737fdec57cdfd410270cMan Cao size_t max_stack_depth_ GUARDED_BY(Locks::alloc_tracker_lock_); 2831ed11b9ad5512cf464cb1686640df53201fa5297Man Cao AllocRecordStackTrace scratch_trace_ GUARDED_BY(Locks::alloc_tracker_lock_); 2848c2ff641294715864013737fdec57cdfd410270cMan Cao pid_t alloc_ddm_thread_id_ GUARDED_BY(Locks::alloc_tracker_lock_); 2858c2ff641294715864013737fdec57cdfd410270cMan Cao EntryList entries_ GUARDED_BY(Locks::alloc_tracker_lock_); 2868c2ff641294715864013737fdec57cdfd410270cMan Cao 2878c2ff641294715864013737fdec57cdfd410270cMan Cao void SetProperties() EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_); 2888c2ff641294715864013737fdec57cdfd410270cMan Cao}; 2898c2ff641294715864013737fdec57cdfd410270cMan Cao 2908c2ff641294715864013737fdec57cdfd410270cMan Cao} // namespace gc 2918c2ff641294715864013737fdec57cdfd410270cMan Cao} // namespace art 2928c2ff641294715864013737fdec57cdfd410270cMan Cao#endif // ART_RUNTIME_GC_ALLOCATION_RECORD_H_ 293