42 #if !defined(R__NOSTATS)
45 # define MEM_CHECKOBJECTPOINTERS
48 #if defined(MEM_STAT) && !defined(MEM_DEBUG)
54 # define storage_size(p) ((size_t)(((size_t*)p)[-1]))
56 # define storage_size(p) ((size_t)(((int*)p)[-2]))
59 # define storage_size(p) ((size_t)0)
64 size_t TStorage::fgMaxBlockSize;
65 FreeHookFun_t TStorage::fgFreeHook;
66 void *TStorage::fgFreeHookData;
67 ReAllocFun_t TStorage::fgReAllocHook;
68 ReAllocCFun_t TStorage::fgReAllocCHook;
69 Bool_t TStorage::fgHasCustomNewDelete;
76 static const char *gSpaceErr =
"storage exhausted";
78 const size_t kObjMaxSize = 10024;
80 static Bool_t gMemStatistics;
81 static Int_t gAllocated[kObjMaxSize], gFreed[kObjMaxSize];
82 static Int_t gAllocatedTotal, gFreedTotal;
83 static void **gTraceArray = 0;
84 static Int_t gTraceCapacity = 10, gTraceIndex = 0,
85 gMemSize = -1, gMemIndex = -1;
88 ROOT::Internal::FreeIfTMapFile_t *ROOT::Internal::gFreeIfTMapFile =
nullptr;
89 void *ROOT::Internal::gMmallocDesc = 0;
99 void TStorage::EnterStat(
size_t size,
void *p)
101 TStorage::SetMaxBlockSize(TMath::Max(TStorage::GetMaxBlockSize(), size));
103 if (!gMemStatistics)
return;
105 if ((Int_t)size == gMemSize) {
106 if (gTraceIndex == gMemIndex)
107 Fatal(
"EnterStat",
"trapped allocation %d", gMemIndex);
110 gTraceArray = (
void**) malloc(
sizeof(
void*)*gTraceCapacity);
112 if (gTraceIndex >= gTraceCapacity) {
113 gTraceCapacity = gTraceCapacity*2;
114 gTraceArray = (
void**) realloc(gTraceArray,
sizeof(
void*)*gTraceCapacity);
116 gTraceArray[gTraceIndex++] = p;
118 if (size >= kObjMaxSize)
119 gAllocated[kObjMaxSize-1]++;
122 gAllocatedTotal += size;
129 void TStorage::RemoveStat(
void *vp)
131 if (!gMemStatistics)
return;
133 size_t size = storage_size(vp);
134 if ((Int_t)size == gMemSize) {
135 for (
int i = 0; i < gTraceIndex; i++)
136 if (gTraceArray[i] == vp) {
141 if (size >= kObjMaxSize)
142 gFreed[kObjMaxSize-1]++;
152 void *TStorage::Alloc(
size_t size)
154 static const char *where =
"TStorage::Alloc";
157 void *vp = ::operator
new[](size);
159 void *vp = ::operator
new(size);
162 Fatal(where,
"%s", gSpaceErr);
170 void TStorage::Dealloc(
void *ptr)
173 ::operator
delete[](ptr);
175 ::operator
delete(ptr);
183 void *TStorage::ReAlloc(
void *ovp,
size_t size)
185 ::Obsolete(
"ReAlloc(void*,size_t)",
"v5-34-00",
"v6-02-00");
186 ::Info(
"ReAlloc(void*,size_t)",
"please use ReAlloc(void*,size_t,size_t)");
190 R__LOCKGUARD(gGlobalMutex);
192 if (fgReAllocHook && fgHasCustomNewDelete && !TROOT::MemCheck())
193 return (*fgReAllocHook)(ovp, size);
196 static const char *where =
"TStorage::ReAlloc";
199 void *vp = ::operator
new[](size);
201 void *vp = ::operator
new(size);
204 Fatal(where,
"%s", gSpaceErr);
209 memmove(vp, ovp, size);
211 ::operator
delete[](ovp);
213 ::operator
delete(ovp);
222 void *TStorage::ReAlloc(
void *ovp,
size_t size,
size_t oldsize)
226 R__LOCKGUARD(gGlobalMutex);
228 if (fgReAllocCHook && fgHasCustomNewDelete && !TROOT::MemCheck())
229 return (*fgReAllocCHook)(ovp, size, oldsize);
232 static const char *where =
"TStorage::ReAlloc";
238 void *vp = ::operator
new[](size);
240 void *vp = ::operator
new(size);
243 Fatal(where,
"%s", gSpaceErr);
248 if (size > oldsize) {
249 memcpy(vp, ovp, oldsize);
250 memset((
char*)vp+oldsize, 0, size-oldsize);
252 memcpy(vp, ovp, size);
254 ::operator
delete[](ovp);
256 ::operator
delete(ovp);
265 char *TStorage::ReAllocChar(
char *ovp,
size_t size,
size_t oldsize)
267 static const char *where =
"TStorage::ReAllocChar";
273 Fatal(where,
"%s", gSpaceErr);
281 Fatal(where,
"%s", gSpaceErr);
282 if (size > oldsize) {
283 memcpy(vp, ovp, oldsize);
284 memset((
char*)vp+oldsize, 0, size-oldsize);
286 memcpy(vp, ovp, size);
295 Int_t *TStorage::ReAllocInt(Int_t *ovp,
size_t size,
size_t oldsize)
297 static const char *where =
"TStorage::ReAllocInt";
301 vp =
new Int_t[size];
303 Fatal(where,
"%s", gSpaceErr);
309 vp =
new Int_t[size];
311 Fatal(where,
"%s", gSpaceErr);
312 if (size > oldsize) {
313 memcpy(vp, ovp, oldsize*
sizeof(Int_t));
314 memset((Int_t*)vp+oldsize, 0, (size-oldsize)*
sizeof(Int_t));
316 memcpy(vp, ovp, size*
sizeof(Int_t));
328 void *TStorage::ObjectAlloc(
size_t sz)
330 void* space = ::operator
new(sz);
331 memset(space, kObjectAllocMemValue, sz);
340 void *TStorage::ObjectAllocArray(
size_t sz)
342 void* space = ::operator
new(sz);
351 void *TStorage::ObjectAlloc(
size_t ,
void *vp)
359 void TStorage::ObjectDealloc(
void *vp)
362 ::operator
delete(vp);
368 void TStorage::ObjectDealloc(
void *vp,
void *ptr)
373 #ifdef R__SIZEDDELETE
378 void TStorage::ObjectDealloc(
void *vp,
size_t size)
380 ::operator
delete(vp, size);
387 void TStorage::SetFreeHook(FreeHookFun_t fh,
void *data)
390 fgFreeHookData = data;
397 void TStorage::SetReAllocHooks(ReAllocFun_t rh1, ReAllocCFun_t rh2)
400 fgReAllocCHook = rh2;
406 void TStorage::PrintStatistics()
409 R__LOCKGUARD(gGlobalMutex);
411 #if defined(MEM_DEBUG) && defined(MEM_STAT)
413 if (!gMemStatistics || !HasCustomNewDelete())
417 Printf(
"Heap statistics");
418 Printf(
"%12s%12s%12s%12s",
"size",
"alloc",
"free",
"diff");
419 Printf(
"================================================");
422 for (i = 0; i < (int)kObjMaxSize; i++)
423 if (gAllocated[i] != gFreed[i])
425 Printf(
"%12d%12d%12d%12d", i, gAllocated[i], gFreed[i],
426 gAllocated[i]-gFreed[i]);
428 if (gAllocatedTotal != gFreedTotal) {
429 Printf(
"------------------------------------------------");
430 Printf(
"Total: %12d%12d%12d", gAllocatedTotal, gFreedTotal,
431 gAllocatedTotal-gFreedTotal);
434 if (gMemSize != -1) {
435 Printf(
"------------------------------------------------");
436 for (i= 0; i < gTraceIndex; i++)
438 Printf(
"block %d of size %d not freed", i, gMemSize);
440 Printf(
"================================================");
450 void TStorage::EnableStatistics(
int size,
int ix)
455 gMemStatistics = kTRUE;
457 int idum = size;
int iidum = ix;
463 ULong_t TStorage::GetHeapBegin()
465 ::Obsolete(
"GetHeapBegin()",
"v5-34-00",
"v6-02-00");
472 ULong_t TStorage::GetHeapEnd()
474 ::Obsolete(
"GetHeapBegin()",
"v5-34-00",
"v6-02-00");
482 void *TStorage::GetFreeHookData()
484 return fgFreeHookData;
490 Bool_t TStorage::HasCustomNewDelete()
492 return fgHasCustomNewDelete;
498 void TStorage::SetCustomNewDelete()
500 fgHasCustomNewDelete = kTRUE;
507 void TStorage::AddToHeap(ULong_t, ULong_t)
509 ::Obsolete(
"AddToHeap(ULong_t,ULong_t)",
"v5-34-00",
"v6-02-00");
515 Bool_t TStorage::IsOnHeap(
void *)
517 ::Obsolete(
"IsOnHeap(void*)",
"v5-34-00",
"v6-02-00");