OLD | NEW |
1 // Copyright (c) 2006, Google Inc. | 1 // Copyright (c) 2006, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 | 122 |
123 HeapProfileTable::HeapProfileTable(Allocator alloc, DeAllocator dealloc) | 123 HeapProfileTable::HeapProfileTable(Allocator alloc, DeAllocator dealloc) |
124 : alloc_(alloc), dealloc_(dealloc) { | 124 : alloc_(alloc), dealloc_(dealloc) { |
125 // Make the table | 125 // Make the table |
126 const int table_bytes = kHashTableSize * sizeof(*table_); | 126 const int table_bytes = kHashTableSize * sizeof(*table_); |
127 table_ = reinterpret_cast<Bucket**>(alloc_(table_bytes)); | 127 table_ = reinterpret_cast<Bucket**>(alloc_(table_bytes)); |
128 memset(table_, 0, table_bytes); | 128 memset(table_, 0, table_bytes); |
129 // Make allocation map | 129 // Make allocation map |
130 allocation_ = | 130 allocation_ = |
131 new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_); | 131 new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_); |
| 132 |
| 133 allocation_mmap_ = |
| 134 new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_); |
| 135 mmap_record_ = false; |
| 136 |
132 // init the rest: | 137 // init the rest: |
133 memset(&total_, 0, sizeof(total_)); | 138 memset(&total_, 0, sizeof(total_)); |
134 num_buckets_ = 0; | 139 num_buckets_ = 0; |
135 } | 140 } |
136 | 141 |
137 HeapProfileTable::~HeapProfileTable() { | 142 HeapProfileTable::~HeapProfileTable() { |
138 // free allocation map | 143 // free allocation map |
139 allocation_->~AllocationMap(); | 144 allocation_->~AllocationMap(); |
140 dealloc_(allocation_); | 145 dealloc_(allocation_); |
141 allocation_ = NULL; | 146 allocation_ = NULL; |
| 147 |
| 148 allocation_mmap_->~AllocationMap(); |
| 149 dealloc_(allocation_mmap_); |
| 150 allocation_mmap_ = NULL; |
| 151 |
142 // free hash table | 152 // free hash table |
143 for (int b = 0; b < kHashTableSize; b++) { | 153 for (int b = 0; b < kHashTableSize; b++) { |
144 for (Bucket* x = table_[b]; x != 0; /**/) { | 154 for (Bucket* x = table_[b]; x != 0; /**/) { |
145 Bucket* b = x; | 155 Bucket* b = x; |
146 x = x->next; | 156 x = x->next; |
147 dealloc_(b->stack); | 157 dealloc_(b->stack); |
148 dealloc_(b); | 158 dealloc_(b); |
149 } | 159 } |
150 } | 160 } |
151 dealloc_(table_); | 161 dealloc_(table_); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 const void* const call_stack[]) { | 212 const void* const call_stack[]) { |
203 Bucket* b = GetBucket(stack_depth, call_stack); | 213 Bucket* b = GetBucket(stack_depth, call_stack); |
204 b->allocs++; | 214 b->allocs++; |
205 b->alloc_size += bytes; | 215 b->alloc_size += bytes; |
206 total_.allocs++; | 216 total_.allocs++; |
207 total_.alloc_size += bytes; | 217 total_.alloc_size += bytes; |
208 | 218 |
209 AllocValue v; | 219 AllocValue v; |
210 v.set_bucket(b); // also did set_live(false); set_ignore(false) | 220 v.set_bucket(b); // also did set_live(false); set_ignore(false) |
211 v.bytes = bytes; | 221 v.bytes = bytes; |
212 allocation_->Insert(ptr, v); | 222 |
| 223 if(mmap_record_) |
| 224 allocation_mmap_->Insert(ptr, v); |
| 225 else |
| 226 allocation_->Insert(ptr, v); |
213 } | 227 } |
214 | 228 |
215 void HeapProfileTable::RecordFree(const void* ptr) { | 229 void HeapProfileTable::RecordFree(const void* ptr) { |
216 AllocValue v; | 230 AllocValue v; |
217 if (allocation_->FindAndRemove(ptr, &v)) { | 231 AllocationMap* a; |
| 232 if(mmap_record_) |
| 233 a = allocation_mmap_; |
| 234 else |
| 235 a = allocation_; |
| 236 |
| 237 if(a->FindAndRemove(ptr, &v)){ |
218 Bucket* b = v.bucket(); | 238 Bucket* b = v.bucket(); |
219 b->frees++; | 239 b->frees++; |
220 b->free_size += v.bytes; | 240 b->free_size += v.bytes; |
221 total_.frees++; | 241 total_.frees++; |
222 total_.free_size += v.bytes; | 242 total_.free_size += v.bytes; |
223 } | 243 } |
224 } | 244 } |
225 | 245 |
226 bool HeapProfileTable::FindAlloc(const void* ptr, size_t* object_size) const { | 246 bool HeapProfileTable::FindAlloc(const void* ptr, size_t* object_size) const { |
227 const AllocValue* alloc_value = allocation_->Find(ptr); | 247 const AllocValue* alloc_value = allocation_->Find(ptr); |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 char* unused) { | 615 char* unused) { |
596 // Perhaps also log the allocation stack trace (unsymbolized) | 616 // Perhaps also log the allocation stack trace (unsymbolized) |
597 // on this line in case somebody finds it useful. | 617 // on this line in case somebody finds it useful. |
598 RAW_LOG(ERROR, "leaked %"PRIuS" byte object %p", v->bytes, ptr); | 618 RAW_LOG(ERROR, "leaked %"PRIuS" byte object %p", v->bytes, ptr); |
599 } | 619 } |
600 | 620 |
601 void HeapProfileTable::Snapshot::ReportIndividualObjects() { | 621 void HeapProfileTable::Snapshot::ReportIndividualObjects() { |
602 char unused; | 622 char unused; |
603 map_.Iterate(ReportObject, &unused); | 623 map_.Iterate(ReportObject, &unused); |
604 } | 624 } |
OLD | NEW |