Logo ROOT   6.19/01
Reference Guide
TObjectTable.cxx
Go to the documentation of this file.
1 // @(#)root/cont:$Id$
2 // Author: Fons Rademakers 11/08/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 TObjectTable
13 \ingroup Containers
14 This class registers all instances of TObject and its derived
15 classes in a hash table. The Add() and Remove() members are called
16 from the TObject ctor and dtor, respectively. Using the Print()
17 member one can see all currently active objects in the system.
18 Using the resource (in .rootrc): Root.ObjectStat one can toggle this
19 feature on or off.
20 
21 Using the compile option R__NOSTATS one can de-active this feature
22 for the entire system (for maximum performance in highly time
23 critical applications).
24 
25 The following output has been produced in a ROOT interactive session
26 via the command gObjectTable->Print()
27 ~~~ {.cpp}
28  class cnt on heap size total size heap size
29  ============================================================================
30  TKey 4 4 72 288 288
31  TClass 84 84 80 6720 6720
32  TDataMember 276 276 24 6624 6624
33  TObject 11 11 12 132 132
34  TMethod 1974 1974 64 126336 126336
35  TDataType 34 34 56 1904 1904
36  TList 2328 2328 36 83808 83808
37  TH1F 1 1 448 448 448
38  TText 2688 2688 56 150528 150528
39  TGaxis 1 0 120 120 0
40  TAxis 6 3 88 528 264
41  TBox 57 57 52 2964 2964
42  TLine 118 118 40 4720 4720
43  TWbox 1 1 56 56 56
44  TArrow 1 1 64 64 64
45  TPaveText 59 59 124 7316 7316
46  TPave 1 1 92 92 92
47  TFile 1 1 136 136 136
48  TCanvas 3 3 444 1332 1332
49  TPad 1 1 312 312 312
50  TContextMenu 3 3 48 144 144
51  TMethodArg 2166 2166 44 95304 95304
52  TPaveLabel 1 1 120 120 120
53  THtml 1 1 32 32 32
54  TROOT 1 0 208 208 0
55  TApplication 1 1 28 28 28
56  TFileHandler 1 1 20 20 20
57  TColor 163 163 40 6520 6520
58  TStyle 1 1 364 364 364
59  TRealData 117 117 28 3276 3276
60  TBaseClass 88 88 36 3168 3168
61  THashList 5 5 40 200 200
62  THashTable 5 5 36 180 180
63  TGeometry 1 1 64 64 64
64  TLink 7 7 60 420 420
65  TPostScript 1 1 764 764 764
66  TMinuit 1 1 792 792 792
67  TStopwatch 1 0 56 56 0
68  TRootGuiFactory 1 1 28 28 28
69  TGX11 1 1 172 172 172
70  TUnixSystem 1 1 252 252 252
71  TSignalHandler 1 1 20 20 20
72  TOrdCollection 3 3 40 120 120
73  TEnv 1 1 24 24 24
74  TCling 1 1 208 208 208
75  TBenchmark 1 1 52 52 52
76  TClassTable 1 1 12 12 12
77  TObjectTable 1 1 12 12 12
78  ----------------------------------------------------------------------------
79  Total: 10225 10219 5976 506988 506340
80  ============================================================================
81 ~~~
82 */
83 
84 #include "TObjectTable.h"
85 #include "TROOT.h"
86 #include "TClass.h"
87 #include "TError.h"
88 
89 
91 
92 
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Create an object table.
97 
99 {
100  fSize = (Int_t)TMath::NextPrime(tableSize);
101  fTable = new TObject* [fSize];
102  memset(fTable, 0, fSize*sizeof(TObject*));
103  fTally = 0;
104 }
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 /// Delete TObjectTable.
108 
110 {
111  delete [] fTable; fTable = 0;
112 }
113 
114 ////////////////////////////////////////////////////////////////////////////////
115 /// Print the object table.
116 /// If option ="all" prints the list of all objects with the format
117 /// object number, pointer, class name, object name
118 
119 void TObjectTable::Print(Option_t *option) const
120 {
121  TString opt = option;
122  opt.ToLower();
123  if (opt.Contains("all")) {
124  TObject *obj;
125  int i, num = 0;
126  Printf("\nList of all objects");
127  Printf("object address class name");
128  Printf("================================================================================");
129  for (i = 0; i < fSize; i++) {
130  if (!fTable[i]) continue;
131  num++;
132  obj = fTable[i];
133  printf("%-8d 0x%-16lx %-24s %s\n", num, (Long_t)obj, obj->ClassName(),
134  obj->GetName());
135  }
136  Printf("================================================================================\n");
137  }
138 
139  //print the number of instances per class
141 }
142 
143 ////////////////////////////////////////////////////////////////////////////////
144 /// Add an object to the object table.
145 
147 {
148  if (!op) {
149  Error("Add", "op is 0");
150  return;
151  }
152  if (!fTable)
153  return;
154 
155  Int_t slot = FindElement(op);
156  if (fTable[slot] == 0) {
157  fTable[slot] = op;
158  fTally++;
159  if (HighWaterMark())
160  Expand(2 * fSize);
161  }
162 }
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 /// Add an object to the global object table gObjectTable. If the global
166 /// table does not exist create it first. This member function may only
167 /// be used by TObject::TObject. Use Add() to add objects to any other
168 /// TObjectTable object. This is a static function.
169 
171 {
172  static Bool_t olock = kFALSE;
173 
174  if (!op) {
175  ::Error("TObjectTable::AddObj", "op is 0");
176  return;
177  }
178  if (olock)
179  return;
180 
181  if (!gObjectTable) {
182  olock = kTRUE;
183  gObjectTable = new TObjectTable(10000);
184  olock = kFALSE;
186  }
187 
188  gObjectTable->Add(op);
189 }
190 
191 ////////////////////////////////////////////////////////////////////////////////
192 /// Delete all objects stored in the TObjectTable.
193 
195 {
196  for (int i = 0; i < fSize; i++) {
197  if (fTable[i]) {
198  delete fTable[i];
199  fTable[i] = 0;
200  }
201  }
202  fTally = 0;
203 }
204 
205 ////////////////////////////////////////////////////////////////////////////////
206 /// Remove an object from the object table.
207 
209 {
210  if (op == 0) {
211  Error("Remove", "remove 0 from TObjectTable");
212  return;
213  }
214 
215  if (!fTable)
216  return;
217 
218  Int_t i = FindElement(op);
219  if (fTable[i] == 0) {
220  Warning("Remove", "0x%lx not found at %d", (Long_t)op, i);
221  for (int j = 0; j < fSize; j++) {
222  if (fTable[j] == op) {
223  Error("Remove", "0x%lx found at %d !!!", (Long_t)op, j);
224  i = j;
225  }
226  }
227  }
228 
229  if (fTable[i]) {
230  fTable[i] = 0;
231  FixCollisions(i);
232  fTally--;
233  }
234 }
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 /// Remove an object from the object table. If op is 0 or not in the table
238 /// don't complain. Currently only used by the TClonesArray dtor. Should not
239 /// be used anywhere else, except in places where "special" allocation and
240 /// de-allocation tricks are performed.
241 
243 {
244  if (op == 0) return;
245 
246  if (!fTable)
247  return;
248 
249  Int_t i = FindElement(op);
250  if (fTable[i] == 0)
251  for (int j = 0; j < fSize; j++)
252  if (fTable[j] == op)
253  i = j;
254 
255  fTable[i] = 0;
256  FixCollisions(i);
257  fTally--;
258 }
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 /// Deletes the object table (this static class function calls the dtor).
262 
264 {
266  delete [] fTable; fTable = 0;
267 }
268 
269 ////////////////////////////////////////////////////////////////////////////////
270 /// Find an object in the object table. Returns the slot where to put
271 /// the object. To test if the object is actually already in the table
272 /// use PtrIsValid().
273 
275 {
276  Int_t slot, n;
277  TObject *slotOp;
278 
279  if (!fTable)
280  return 0;
281 
282  //slot = Int_t(((ULong_t) op >> 2) % fSize);
283  slot = Int_t(TString::Hash(&op, sizeof(TObject*)) % fSize);
284  for (n = 0; n < fSize; n++) {
285  if ((slotOp = fTable[slot]) == 0)
286  break;
287  if (op == slotOp)
288  break;
289  if (++slot == fSize)
290  slot = 0;
291  }
292  return slot;
293 }
294 
295 ////////////////////////////////////////////////////////////////////////////////
296 /// Rehash the object table in case an object has been removed.
297 
299 {
300  Int_t oldIndex, nextIndex;
301  TObject *nextObject;
302 
303  for (oldIndex = index+1; ;oldIndex++) {
304  if (oldIndex >= fSize)
305  oldIndex = 0;
306  nextObject = fTable[oldIndex];
307  if (nextObject == 0)
308  break;
309  nextIndex = FindElement(nextObject);
310  if (nextIndex != oldIndex) {
311  fTable[nextIndex] = nextObject;
312  fTable[oldIndex] = 0;
313  }
314  }
315 }
316 
317 ////////////////////////////////////////////////////////////////////////////////
318 /// Expand the object table.
319 
321 {
322  TObject **oldTable = fTable, *op;
323  int oldsize = fSize;
324  newSize = (Int_t)TMath::NextPrime(newSize);
325  fTable = new TObject* [newSize];
326  memset(fTable, 0, newSize*sizeof(TObject*));
327  fSize = newSize;
328  fTally = 0;
329  for (int i = 0; i < oldsize; i++)
330  if ((op = oldTable[i]))
331  Add(op);
332  delete [] oldTable;
333 }
334 
335 ////////////////////////////////////////////////////////////////////////////////
336 /// Print the object table.
337 
339 {
340  int n, h, s, ncum = 0, hcum = 0, scum = 0, tcum = 0, thcum = 0;
341 
342  if (fTally == 0 || !fTable)
343  return;
344 
345  UpdateInstCount();
346 
347  Printf("\nObject statistics");
348  Printf("class cnt on heap size total size heap size");
349  Printf("================================================================================");
350  TIter next(gROOT->GetListOfClasses());
351  TClass *cl;
352  while ((cl = (TClass*) next())) {
353  n = cl->GetInstanceCount();
354  h = cl->GetHeapInstanceCount();
355  s = cl->Size();
356  if (n > 0) {
357  Printf("%-24s %8d%11d%9d%14d%13d", cl->GetName(), n, h, s, n*s, h*s);
358  ncum += n;
359  hcum += h;
360  scum += s;
361  tcum += n*s;
362  thcum += h*s;
363  }
364  }
365  Printf("--------------------------------------------------------------------------------");
366  Printf("Total: %8d%11d%9d%14d%13d", ncum, hcum, scum, tcum, thcum);
367  Printf("================================================================================\n");
368 }
369 
370 ////////////////////////////////////////////////////////////////////////////////
371 /// Histogram all objects according to their classes.
372 
374 {
375  TObject *op;
376 
377  if (!fTable || !TROOT::Initialized())
378  return;
379 
380  gROOT->GetListOfClasses()->R__FOR_EACH(TClass,ResetInstanceCount)();
381 
382  for (int i = 0; i < fSize; i++)
383  if ((op = fTable[i])) { // attention: no ==
384  if (op->TestBit(TObject::kNotDeleted))
385  op->IsA()->AddInstance(op->IsOnHeap());
386  else
387  Error("UpdateInstCount", "oops 0x%lx\n", (Long_t)op);
388  }
389 }
390 
391 ////////////////////////////////////////////////////////////////////////////////
392 /// Issue a warning in case an object still appears in the table
393 /// while it should not.
394 
395 void *TObjectTable::CheckPtrAndWarn(const char *msg, void *vp)
396 {
397  if (fTable && vp && fTable[FindElement((TObject*)vp)]) {
398  Remove((TObject*)vp);
399  Warning("CheckPtrAndWarn", "%s (0x%lx)\n", msg, (Long_t)vp);
400  }
401  return vp;
402 }
Int_t FindElement(TObject *obj)
Find an object in the object table.
TObjectTable * gObjectTable
const char Option_t
Definition: RtypesCore.h:62
void Expand(Int_t newsize)
Expand the object table.
#define gROOT
Definition: TROOT.h:414
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
void RemoveQuietly(TObject *obj)
Remove an object from the object table.
Basic string class.
Definition: TString.h:131
~TObjectTable()
Delete TObjectTable.
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void UpdateInstCount() const
Histogram all objects according to their classes.
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition: TString.cxx:638
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2861
void Terminate()
Deletes the object table (this static class function calls the dtor).
static constexpr double s
void * CheckPtrAndWarn(const char *msg, void *vp)
Issue a warning in case an object still appears in the table while it should not. ...
TObjectTable(const TObjectTable &)
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition: TObject.h:133
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
This class registers all instances of TObject and its derived classes in a hash table.
Definition: TObjectTable.h:35
static void AddObj(TObject *obj)
Add an object to the global object table gObjectTable.
#define h(i)
Definition: RSha256.hxx:106
Bool_t HighWaterMark()
Definition: TObjectTable.h:75
const Bool_t kFALSE
Definition: RtypesCore.h:88
long Long_t
Definition: RtypesCore.h:50
TObject ** fTable
Definition: TObjectTable.h:38
#define ClassImp(name)
Definition: Rtypes.h:365
void Printf(const char *fmt,...)
void Add(TObject *obj)
Add an object to the object table.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
void FixCollisions(Int_t index)
Rehash the object table in case an object has been removed.
void InstanceStatistics() const
Print the object table.
Mother of all ROOT objects.
Definition: TObject.h:37
Long_t NextPrime(Long_t x)
TMath Base functionsDefine the functions Min, Max, Abs, Sign, Range for all types.
Definition: TMathBase.cxx:30
object has not been deleted
Definition: TObject.h:78
void Delete(Option_t *opt="")
Delete all objects stored in the TObjectTable.
const Bool_t kTRUE
Definition: RtypesCore.h:87
const Int_t n
Definition: legend1.C:16
void Print(Option_t *option="") const
Print the object table.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
void Remove(TObject *obj)
Remove an object from the object table.