Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TStorage.cxx
Go to the documentation of this file.
1// @(#)root/base:$Id$
2// Author: Fons Rademakers 29/07/95
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TStorage
13\ingroup Base
14
15Storage manager. The storage manager works best in conjunction with
16the custom ROOT new and delete operators defined in the file
17NewDelete.cxx (libNew.so). Only when using the custom allocation
18operators will memory usage statistics be gathered using the
19TStorage EnterStat(), RemoveStat(), etc. functions.
20Memory checking is by default enabled (when using libNew.so) and
21usage statistics is gathered. Using the resource (in .rootrc):
22Root.MemStat one can toggle statistics gathering on or off. More
23specifically on can trap the allocation of a block of memory of a
24certain size. This can be specified using the resource:
25Root.MemStat.size, using the resource Root.MemStat.cnt one can
26specify after how many allocations of this size the trap should
27occur.
28
29Set the compile option R__NOSTATS to de-activate all memory checking
30and statistics gathering in the system.
31*/
32
33#include <stdlib.h>
34
35#include "TROOT.h"
36#include "TObjectTable.h"
37#include "TError.h"
38#include "TString.h"
39#include "TVirtualMutex.h"
40#include "TInterpreter.h"
41
42#if !defined(R__NOSTATS)
43# define MEM_DEBUG
44# define MEM_STAT
45# define MEM_CHECKOBJECTPOINTERS
46#endif
47
48#if defined(MEM_STAT) && !defined(MEM_DEBUG)
49# define MEM_DEBUG
50#endif
51
52#ifdef MEM_DEBUG
53# ifdef R__B64
54# define storage_size(p) ((size_t)(((size_t*)p)[-1]))
55# else
56# define storage_size(p) ((size_t)(((int*)p)[-2]))
57# endif
58#else
59# define storage_size(p) ((size_t)0)
60#endif
61
62#define PVOID (-1)
63
69
70
72
73//------------------------------------------------------------------------------
74
75static const char *gSpaceErr = "storage exhausted";
76
77const size_t kObjMaxSize = 10024;
78
82static void **gTraceArray = nullptr;
84 gMemSize = -1, gMemIndex = -1;
85
86// Used in NewDelete.cxx; set by TMapFile.
89void *ROOT::Internal::gMmallocDesc = nullptr; //is used and set in TMapFile
90
91
92
93////////////////////////////////////////////////////////////////////////////////
94/// Register a memory allocation operation. If desired one can trap an
95/// allocation of a certain size in case one tries to find a memory
96/// leak of that particular size. This function is only called via
97/// the ROOT custom new operators.
98
99void TStorage::EnterStat(size_t size, void *p)
100{
102
103 if (!gMemStatistics) return;
104
105 if ((Int_t)size == gMemSize) {
106 if (gTraceIndex == gMemIndex)
107 Fatal("EnterStat", "trapped allocation %d", gMemIndex);
108
109 if (!gTraceArray)
110 gTraceArray = (void**) malloc(sizeof(void*)*gTraceCapacity);
111
114 gTraceArray = (void**) realloc(gTraceArray, sizeof(void*)*gTraceCapacity);
115 }
117 }
118 if (size >= kObjMaxSize)
120 else
121 gAllocated[size]++;
123}
124
125////////////////////////////////////////////////////////////////////////////////
126/// Register a memory free operation. This function is only called via
127/// the custom ROOT delete operator.
128
130{
131 if (!gMemStatistics) return;
132
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) {
137 gTraceArray[i] = nullptr;
138 break;
139 }
140 }
141 if (size >= kObjMaxSize)
142 gFreed[kObjMaxSize-1]++;
143 else
144 gFreed[size]++;
145 gFreedTotal += size;
146}
147
148////////////////////////////////////////////////////////////////////////////////
149/// Allocate a block of memory, that later can be resized using
150/// TStorage::ReAlloc().
151
153{
154 static const char *where = "TStorage::Alloc";
155
156#ifndef WIN32
157 void *vp = ::operator new[](size);
158#else
159 void *vp = ::operator new(size);
160#endif
161 if (vp == nullptr)
162 Fatal(where, "%s", gSpaceErr);
163
164 return vp;
165}
166
167////////////////////////////////////////////////////////////////////////////////
168/// De-allocate block of memory, that was allocated via TStorage::Alloc().
169
170void TStorage::Dealloc(void *ptr)
171{
172#ifndef WIN32
173 ::operator delete[](ptr);
174#else
175 ::operator delete(ptr);
176#endif
177}
178
179////////////////////////////////////////////////////////////////////////////////
180/// Reallocate (i.e. resize) block of memory. Checks if current size is
181/// equal to oldsize. If not memory was overwritten.
182
183void *TStorage::ReAlloc(void *ovp, size_t size, size_t oldsize)
184{
185 // Needs to be protected by global mutex
186 {
188
190 return (*fgReAllocCHook)(ovp, size, oldsize);
191 }
192
193 static const char *where = "TStorage::ReAlloc";
194
195 if (oldsize == size)
196 return ovp;
197
198#ifndef WIN32
199 void *vp = ::operator new[](size);
200#else
201 void *vp = ::operator new(size);
202#endif
203 if (vp == nullptr) {
204 Fatal(where, "%s", gSpaceErr);
205 return nullptr; // Unreachable unless gErrorIgnoreLevel > kFatal.
206 }
207
208 if (ovp == nullptr)
209 return vp;
210
211 if (size > oldsize) {
212 memcpy(vp, ovp, oldsize);
213 memset((char*)vp+oldsize, 0, size-oldsize);
214 } else
215 memcpy(vp, ovp, size);
216#ifndef WIN32
217 ::operator delete[](ovp);
218#else
219 ::operator delete(ovp);
220#endif
221 return vp;
222}
223
224////////////////////////////////////////////////////////////////////////////////
225/// Reallocate (i.e. resize) array of chars. Size and oldsize are
226/// in number of chars.
227
228char *TStorage::ReAllocChar(char *ovp, size_t size, size_t oldsize)
229{
230 static const char *where = "TStorage::ReAllocChar";
231
232 char *vp;
233 if (ovp == nullptr) {
234 vp = new char[size];
235 if (vp == nullptr)
236 Fatal(where, "%s", gSpaceErr);
237 return vp;
238 }
239 if (oldsize == size)
240 return ovp;
241
242 vp = new char[size];
243 if (vp == nullptr)
244 Fatal(where, "%s", gSpaceErr);
245 if (size > oldsize) {
246 memcpy(vp, ovp, oldsize);
247 memset((char*)vp+oldsize, 0, size-oldsize);
248 } else
249 memcpy(vp, ovp, size);
250 delete [] ovp;
251 return vp;
252}
253
254////////////////////////////////////////////////////////////////////////////////
255/// Reallocate (i.e. resize) array of integers. Size and oldsize are
256/// number of integers (not number of bytes).
257
258Int_t *TStorage::ReAllocInt(Int_t *ovp, size_t size, size_t oldsize)
259{
260 static const char *where = "TStorage::ReAllocInt";
261
262 Int_t *vp;
263 if (ovp == nullptr) {
264 vp = new Int_t[size];
265 if (vp == nullptr)
266 Fatal(where, "%s", gSpaceErr);
267 return vp;
268 }
269 if (oldsize == size)
270 return ovp;
271
272 vp = new Int_t[size];
273 if (vp == nullptr)
274 Fatal(where, "%s", gSpaceErr);
275 if (size > oldsize) {
276 memcpy(vp, ovp, oldsize*sizeof(Int_t));
277 memset((Int_t*)vp+oldsize, 0, (size-oldsize)*sizeof(Int_t));
278 } else
279 memcpy(vp, ovp, size*sizeof(Int_t));
280 delete [] ovp;
281 return vp;
282}
283
284////////////////////////////////////////////////////////////////////////////////
285/// Used to allocate a TObject on the heap (via TObject::operator new()).
286/// Directly after this routine one can call (in the TObject ctor)
287/// TStorage::FilledByObjectAlloc() to find out if the just created object is on
288/// the heap. This technique is necessary as there is one stack per thread
289/// and we can not rely on comparison with the current stack memory position.
290
291void *TStorage::ObjectAlloc(size_t sz)
292{
293 void* space = ::operator new(sz);
294 memset(space, kObjectAllocMemValue, sz);
295 return space;
296}
297
298////////////////////////////////////////////////////////////////////////////////
299/// Used to allocate array of TObject on the heap (via TObject::operator new[]()).
300/// Unlike the 'singular' ObjectAlloc, we do not mark those object has being
301/// allocated on the heap as they can not be individually deleted.
302
304{
305 void* space = ::operator new(sz);
306 return space;
307}
308
309////////////////////////////////////////////////////////////////////////////////
310/// Used to allocate a TObject on the heap (via TObject::operator new(size_t,void*))
311/// in position vp. vp is already allocated (maybe on heap, maybe on
312/// stack) so just return.
313
314void *TStorage::ObjectAlloc(size_t , void *vp)
315{
316 return vp;
317}
318
319////////////////////////////////////////////////////////////////////////////////
320/// Used to deallocate a TObject on the heap (via TObject::operator delete()).
321
323{
324
325 ::operator delete(vp);
326}
327
328////////////////////////////////////////////////////////////////////////////////
329/// Used to deallocate a TObject on the heap (via TObject::operator delete(void*,void*)).
330
331void TStorage::ObjectDealloc(void *vp, void *ptr)
332{
333 if (vp && ptr) { }
334}
335
336#ifdef R__SIZEDDELETE
337////////////////////////////////////////////////////////////////////////////////
338/// Used to deallocate a TObject on the heap (via TObject::operator delete()),
339/// for sized deallocation.
340
341void TStorage::ObjectDealloc(void *vp, size_t size)
342{
343 ::operator delete(vp, size);
344}
345#endif
346
347////////////////////////////////////////////////////////////////////////////////
348/// Set a free handler.
349
351{
352 fgFreeHook = fh;
354}
355
356////////////////////////////////////////////////////////////////////////////////
357/// Set a custom ReAlloc handlers. This function is typically
358/// called via a static object in the ROOT libNew.so shared library.
359
361{
362 fgReAllocCHook = rh2;
363}
364
365////////////////////////////////////////////////////////////////////////////////
366/// Print memory usage statistics.
367
369{
370 // Needs to be protected by global mutex
372
373#if defined(MEM_DEBUG) && defined(MEM_STAT)
374
376 return;
377
378 //Printf("");
379 Printf("Heap statistics");
380 Printf("%12s%12s%12s%12s", "size", "alloc", "free", "diff");
381 Printf("================================================");
382
383 int i;
384 for (i = 0; i < (int)kObjMaxSize; i++)
385 if (gAllocated[i] != gFreed[i])
386 //if (gAllocated[i])
387 Printf("%12d%12d%12d%12d", i, gAllocated[i], gFreed[i],
388 gAllocated[i]-gFreed[i]);
389
391 Printf("------------------------------------------------");
392 Printf("Total: %12d%12d%12d", gAllocatedTotal, gFreedTotal,
394 }
395
396 if (gMemSize != -1) {
397 Printf("------------------------------------------------");
398 for (i= 0; i < gTraceIndex; i++)
399 if (gTraceArray[i])
400 Printf("block %d of size %d not freed", i, gMemSize);
401 }
402 Printf("================================================");
403 Printf(" ");
404#endif
405}
406
407////////////////////////////////////////////////////////////////////////////////
408/// Enable memory usage statistics gathering. Size is the size of the memory
409/// block that should be trapped and ix is after how many such allocations
410/// the trap should happen.
411
413{
414#ifdef MEM_STAT
415 gMemSize = size;
416 gMemIndex = ix;
418#else
419 int idum = size; int iidum = ix;
420#endif
421}
422
423////////////////////////////////////////////////////////////////////////////////
424///return static free hook data
425
427{
428 return fgFreeHookData;
429}
430
431////////////////////////////////////////////////////////////////////////////////
432///return the has custom delete flag
433
435{
437}
438
439////////////////////////////////////////////////////////////////////////////////
440///set the has custom delete flag
441
443{
445}
446
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
#define ClassImp(name)
Definition Rtypes.h:382
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:244
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
static Int_t gMemIndex
Definition TStorage.cxx:84
static const char * gSpaceErr
Definition TStorage.cxx:75
static Int_t gTraceCapacity
Definition TStorage.cxx:83
static Int_t gTraceIndex
Definition TStorage.cxx:83
static Bool_t gMemStatistics
Definition TStorage.cxx:79
static Int_t gMemSize
Definition TStorage.cxx:84
const size_t kObjMaxSize
Definition TStorage.cxx:77
static Int_t gFreed[kObjMaxSize]
Definition TStorage.cxx:80
static void ** gTraceArray
Definition TStorage.cxx:82
static Int_t gAllocated[kObjMaxSize]
Definition TStorage.cxx:80
static Int_t gAllocatedTotal
Definition TStorage.cxx:81
#define storage_size(p)
Definition TStorage.cxx:56
static Int_t gFreedTotal
Definition TStorage.cxx:81
void *(* ReAllocCFun_t)(void *, size_t, size_t)
Definition TStorage.h:29
void *(* ReAllocFun_t)(void *, size_t)
Definition TStorage.h:28
void(* FreeHookFun_t)(void *, void *addr, size_t)
Definition TStorage.h:27
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2503
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define realloc
Definition civetweb.c:1538
#define malloc
Definition civetweb.c:1536
Storage manager.
Definition TStorage.h:33
static ReAllocCFun_t fgReAllocCHook
Definition TStorage.h:39
static void RemoveStat(void *p)
Register a memory free operation.
Definition TStorage.cxx:129
static void * Alloc(size_t size)
Allocate a block of memory, that later can be resized using TStorage::ReAlloc().
Definition TStorage.cxx:152
static Bool_t fgHasCustomNewDelete
Definition TStorage.h:40
static char * ReAllocChar(char *vp, size_t size, size_t oldsize)
Reallocate (i.e.
Definition TStorage.cxx:228
static FreeHookFun_t fgFreeHook
Definition TStorage.h:37
static Bool_t HasCustomNewDelete()
return the has custom delete flag
Definition TStorage.cxx:434
static void EnterStat(size_t size, void *p)
Register a memory allocation operation.
Definition TStorage.cxx:99
static void ObjectDealloc(void *vp)
Used to deallocate a TObject on the heap (via TObject::operator delete()).
Definition TStorage.cxx:322
static void SetFreeHook(FreeHookFun_t func, void *data)
Set a free handler.
Definition TStorage.cxx:350
static void SetCustomNewDelete()
set the has custom delete flag
Definition TStorage.cxx:442
static void * GetFreeHookData()
return static free hook data
Definition TStorage.cxx:426
static void SetMaxBlockSize(size_t size)
Definition TStorage.h:133
static void * fgFreeHookData
Definition TStorage.h:38
static const UInt_t kObjectAllocMemValue
Definition TStorage.h:48
static void Dealloc(void *ptr)
De-allocate block of memory, that was allocated via TStorage::Alloc().
Definition TStorage.cxx:170
static size_t fgMaxBlockSize
Definition TStorage.h:36
static Int_t * ReAllocInt(Int_t *vp, size_t size, size_t oldsize)
Reallocate (i.e.
Definition TStorage.cxx:258
static void SetReAllocHooks(ReAllocFun_t func1, ReAllocCFun_t func2)
Set a custom ReAlloc handlers.
Definition TStorage.cxx:360
static void * ObjectAllocArray(size_t size)
Used to allocate array of TObject on the heap (via TObject::operator new[]()).
Definition TStorage.cxx:303
static void EnableStatistics(int size=-1, int ix=-1)
Enable memory usage statistics gathering.
Definition TStorage.cxx:412
static size_t GetMaxBlockSize()
Definition TStorage.h:131
static void * ReAlloc(void *vp, size_t size, size_t oldsize)
Reallocate (i.e.
Definition TStorage.cxx:183
static void * ObjectAlloc(size_t size)
Used to allocate a TObject on the heap (via TObject::operator new()).
Definition TStorage.cxx:291
static void PrintStatistics()
Print memory usage statistics.
Definition TStorage.cxx:368
R__EXTERN GetMapFileMapllocDesc_t * gGetMapFileMallocDesc
Definition TStorage.h:142
void *(void *) GetMapFileMapllocDesc_t
Definition TStorage.h:140
R__EXTERN FreeIfTMapFile_t * gFreeIfTMapFile
Definition TStorage.h:141
R__EXTERN void * gMmallocDesc
Definition TStorage.h:143
bool(void *) FreeIfTMapFile_t
Definition TStorage.h:139
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250