| 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 |