TObjectTable.cxx

Go to the documentation of this file.
00001 // @(#)root/cont:$Id: TObjectTable.cxx 34286 2010-07-01 20:38:57Z rdm $
00002 // Author: Fons Rademakers   11/08/95
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // This class registers all instances of TObject and its derived        //
00015 // classes in a hash table. The Add() and Remove() members are called   //
00016 // from the TObject ctor and dtor, repectively. Using the Print()       //
00017 // member one can see all currently active objects in the system.       //
00018 // Using the resource (in .rootrc): Root.ObjectStat one can toggle this //
00019 // feature on or off.                                                   //
00020 // Using the compile option R__NOSTATS one can de-active this feature   //
00021 // for the entire system (for maximum performance in highly time        //
00022 // critical applications).                                              //
00023 //                                                                      //
00024 // The following output has been produced in a ROOT interactive session
00025 // via the command gObjectTable->Print()
00026 //   class                     cnt    on heap     size    total size    heap size
00027 //   ============================================================================
00028 //   TKey                        4          4       72           288          288
00029 //   TClass                     84         84       80          6720         6720
00030 //   TDataMember               276        276       24          6624         6624
00031 //   TObject                    11         11       12           132          132
00032 //   TMethod                  1974       1974       64        126336       126336
00033 //   TDataType                  34         34       56          1904         1904
00034 //   TList                    2328       2328       36         83808        83808
00035 //   TH1F                        1          1      448           448          448
00036 //   TText                    2688       2688       56        150528       150528
00037 //   TGaxis                      1          0      120           120            0
00038 //   TAxis                       6          3       88           528          264
00039 //   TBox                       57         57       52          2964         2964
00040 //   TLine                     118        118       40          4720         4720
00041 //   TWbox                       1          1       56            56           56
00042 //   TArrow                      1          1       64            64           64
00043 //   TPaveText                  59         59      124          7316         7316
00044 //   TPave                       1          1       92            92           92
00045 //   TFile                       1          1      136           136          136
00046 //   TCanvas                     3          3      444          1332         1332
00047 //   TPad                        1          1      312           312          312
00048 //   TContextMenu                3          3       48           144          144
00049 //   TMethodArg               2166       2166       44         95304        95304
00050 //   TPaveLabel                  1          1      120           120          120
00051 //   THtml                       1          1       32            32           32
00052 //   TROOT                       1          0      208           208            0
00053 //   TApplication                1          1       28            28           28
00054 //   TFileHandler                1          1       20            20           20
00055 //   TColor                    163        163       40          6520         6520
00056 //   TStyle                      1          1      364           364          364
00057 //   TRealData                 117        117       28          3276         3276
00058 //   TBaseClass                 88         88       36          3168         3168
00059 //   THashList                   5          5       40           200          200
00060 //   THashTable                  5          5       36           180          180
00061 //   TGeometry                   1          1       64            64           64
00062 //   TLink                       7          7       60           420          420
00063 //   TPostScript                 1          1      764           764          764
00064 //   TMinuit                     1          1      792           792          792
00065 //   TStopwatch                  1          0       56            56            0
00066 //   TRootGuiFactory             1          1       28            28           28
00067 //   TGX11                       1          1      172           172          172
00068 //   TUnixSystem                 1          1      252           252          252
00069 //   TSignalHandler              1          1       20            20           20
00070 //   TOrdCollection              3          3       40           120          120
00071 //   TEnv                        1          1       24            24           24
00072 //   TCint                       1          1      208           208          208
00073 //   TBenchmark                  1          1       52            52           52
00074 //   TClassTable                 1          1       12            12           12
00075 //   TObjectTable                1          1       12            12           12
00076 //   ----------------------------------------------------------------------------
00077 //   Total:                  10225      10219     5976        506988       506340
00078 //   ============================================================================
00079 //////////////////////////////////////////////////////////////////////////
00080 
00081 #include "TObjectTable.h"
00082 #include "TROOT.h"
00083 #include "TClass.h"
00084 #include "TError.h"
00085 
00086 
00087 TObjectTable *gObjectTable;
00088 
00089 
00090 ClassImp(TObjectTable)
00091 
00092 //______________________________________________________________________________
00093 TObjectTable::TObjectTable(Int_t tableSize)
00094 {
00095    // Create an object table.
00096 
00097    fSize  = (Int_t)TMath::NextPrime(tableSize);
00098    fTable = new TObject* [fSize];
00099    memset(fTable, 0, fSize*sizeof(TObject*));
00100    fTally = 0;
00101 }
00102 
00103 //______________________________________________________________________________
00104 TObjectTable::~TObjectTable()
00105 {
00106    // Delete TObjectTable.
00107 
00108    delete [] fTable; fTable = 0;
00109 }
00110 
00111 //______________________________________________________________________________
00112 void TObjectTable::Print(Option_t *option) const
00113 {
00114    // Print the object table.
00115    // If option ="all" prints the list of all objects with the format
00116    // object number, pointer, class name, object name
00117 
00118    TString opt = option;
00119    opt.ToLower();
00120    if (opt.Contains("all")) {
00121       TObject *obj;
00122       int i, num = 0;
00123       Printf("\nList of all objects");
00124       Printf("object   address            class                    name");
00125       Printf("================================================================================");
00126       for (i = 0; i < fSize; i++) {
00127          if (!fTable[i]) continue;
00128          num++;
00129          obj = fTable[i];
00130          printf("%-8d 0x%-16lx %-24s %s\n", num, (Long_t)obj, obj->ClassName(),
00131                 obj->GetName());
00132       }
00133       Printf("================================================================================\n");
00134    }
00135 
00136    //print the number of instances per class
00137    InstanceStatistics();
00138 }
00139 
00140 //______________________________________________________________________________
00141 void TObjectTable::Add(TObject *op)
00142 {
00143    // Add an object to the object table.
00144 
00145    if (!op) {
00146       Error("Add", "op is 0");
00147       return;
00148    }
00149    if (!fTable)
00150       return;
00151 
00152    Int_t slot = FindElement(op);
00153    if (fTable[slot] == 0) {
00154       fTable[slot] = op;
00155       fTally++;
00156       if (HighWaterMark())
00157          Expand(2 * fSize);
00158    }
00159 }
00160 
00161 //______________________________________________________________________________
00162 void TObjectTable::AddObj(TObject *op)
00163 {
00164    // Add an object to the global object table gObjectTable. If the global
00165    // table does not exist create it first. This member function may only
00166    // be used by TObject::TObject. Use Add() to add objects to any other
00167    // TObjectTable object. This is a static function.
00168 
00169    static Bool_t olock = kFALSE;
00170 
00171    if (!op) {
00172       ::Error("TObjectTable::AddObj", "op is 0");
00173       return;
00174    }
00175    if (olock)
00176       return;
00177 
00178    if (!gObjectTable) {
00179       olock = kTRUE;
00180       gObjectTable = new TObjectTable(10000);
00181       olock = kFALSE;
00182       gObjectTable->Add(gObjectTable);
00183    }
00184 
00185    gObjectTable->Add(op);
00186 }
00187 
00188 //______________________________________________________________________________
00189 void TObjectTable::Delete(Option_t *)
00190 {
00191    // Delete all objects stored in the TObjectTable.
00192 
00193    for (int i = 0; i < fSize; i++) {
00194       if (fTable[i]) {
00195          delete fTable[i];
00196          fTable[i] = 0;
00197       }
00198    }
00199    fTally = 0;
00200 }
00201 
00202 //______________________________________________________________________________
00203 void TObjectTable::Remove(TObject *op)
00204 {
00205    // Remove an object from the object table.
00206 
00207    if (op == 0) {
00208       Error("Remove", "remove 0 from TObjectTable");
00209       return;
00210    }
00211 
00212    if (!fTable)
00213       return;
00214 
00215    Int_t i = FindElement(op);
00216    if (fTable[i] == 0) {
00217       Warning("Remove", "0x%lx not found at %d", (long)op, i);
00218       for (int j = 0; j < fSize; j++) {
00219          if (fTable[j] == op) {
00220             Error("Remove", "0x%lx found at %d !!!", (long)op, j);
00221             i = j;
00222          }
00223       }
00224    }
00225 
00226    if (fTable[i]) {
00227       fTable[i] = 0;
00228       FixCollisions(i);
00229       fTally--;
00230    }
00231 }
00232 
00233 //______________________________________________________________________________
00234 void TObjectTable::RemoveQuietly(TObject *op)
00235 {
00236    // Remove an object from the object table. If op is 0 or not in the table
00237    // don't complain. Currently only used by the TClonesArray dtor. Should not
00238    // be used anywhere else, except in places where "special" allocation and
00239    // de-allocation tricks are performed.
00240 
00241    if (op == 0) return;
00242 
00243    if (!fTable)
00244       return;
00245 
00246    Int_t i = FindElement(op);
00247    if (fTable[i] == 0)
00248       for (int j = 0; j < fSize; j++)
00249          if (fTable[j] == op)
00250             i = j;
00251 
00252    fTable[i] = 0;
00253    FixCollisions(i);
00254    fTally--;
00255 }
00256 
00257 //______________________________________________________________________________
00258 void TObjectTable::Terminate()
00259 {
00260    // Deletes the object table (this static class function calls the dtor).
00261 
00262    InstanceStatistics();
00263    delete [] fTable; fTable = 0;
00264 }
00265 
00266 //______________________________________________________________________________
00267 Int_t TObjectTable::FindElement(TObject *op)
00268 {
00269    // Find an object in the object table. Returns the slot where to put
00270    // the object. To test if the object is actually already in the table
00271    // use PtrIsValid().
00272 
00273    Int_t    slot, n;
00274    TObject *slotOp;
00275 
00276    if (!fTable)
00277       return 0;
00278 
00279    //slot = Int_t(((ULong_t) op >> 2) % fSize);
00280    slot = Int_t(TString::Hash(&op, sizeof(TObject*)) % fSize);
00281    for (n = 0; n < fSize; n++) {
00282       if ((slotOp = fTable[slot]) == 0)
00283          break;
00284       if (op == slotOp)
00285          break;
00286       if (++slot == fSize)
00287          slot = 0;
00288    }
00289    return slot;
00290 }
00291 
00292 //______________________________________________________________________________
00293 void TObjectTable::FixCollisions(Int_t index)
00294 {
00295    // Rehash the object table in case an object has been removed.
00296 
00297    Int_t oldIndex, nextIndex;
00298    TObject *nextObject;
00299 
00300    for (oldIndex = index+1; ;oldIndex++) {
00301       if (oldIndex >= fSize)
00302          oldIndex = 0;
00303       nextObject = fTable[oldIndex];
00304       if (nextObject == 0)
00305          break;
00306       nextIndex = FindElement(nextObject);
00307       if (nextIndex != oldIndex) {
00308          fTable[nextIndex] = nextObject;
00309          fTable[oldIndex] = 0;
00310       }
00311    }
00312 }
00313 
00314 //______________________________________________________________________________
00315 void TObjectTable::Expand(Int_t newSize)
00316 {
00317    // Expand the object table.
00318 
00319    TObject **oldTable = fTable, *op;
00320    int oldsize = fSize;
00321    newSize = (Int_t)TMath::NextPrime(newSize);
00322    fTable  = new TObject* [newSize];
00323    memset(fTable, 0, newSize*sizeof(TObject*));
00324    fSize   = newSize;
00325    fTally  = 0;
00326    for (int i = 0; i < oldsize; i++)
00327       if ((op = oldTable[i]))
00328          Add(op);
00329    delete [] oldTable;
00330 }
00331 
00332 //______________________________________________________________________________
00333 void TObjectTable::InstanceStatistics() const
00334 {
00335    // Print the object table.
00336 
00337    int n, h, s, ncum = 0, hcum = 0, scum = 0, tcum = 0, thcum = 0;
00338 
00339    if (fTally == 0 || !fTable)
00340       return;
00341 
00342    UpdateInstCount();
00343 
00344    Printf("\nObject statistics");
00345    Printf("class                         cnt    on heap     size    total size    heap size");
00346    Printf("================================================================================");
00347    TIter next(gROOT->GetListOfClasses());
00348    TClass *cl;
00349    while ((cl = (TClass*) next())) {
00350       n = cl->GetInstanceCount();
00351       h = cl->GetHeapInstanceCount();
00352       s = cl->Size();
00353       if (n > 0) {
00354          Printf("%-24s %8d%11d%9d%14d%13d", cl->GetName(), n, h, s, n*s, h*s);
00355          ncum  += n;
00356          hcum  += h;
00357          scum  += s;
00358          tcum  += n*s;
00359          thcum += h*s;
00360       }
00361    }
00362    Printf("--------------------------------------------------------------------------------");
00363    Printf("Total:                   %8d%11d%9d%14d%13d", ncum, hcum, scum, tcum, thcum);
00364    Printf("================================================================================\n");
00365 }
00366 
00367 //______________________________________________________________________________
00368 void TObjectTable::UpdateInstCount() const
00369 {
00370    // Histogram all objects according to their classes.
00371 
00372    TObject *op;
00373 
00374    if (!fTable || !TROOT::Initialized())
00375       return;
00376 
00377    gROOT->GetListOfClasses()->R__FOR_EACH(TClass,ResetInstanceCount)();
00378 
00379    for (int i = 0; i < fSize; i++)
00380       if ((op = fTable[i])) {                // attention: no ==
00381          if (op->TestBit(TObject::kNotDeleted))
00382             op->IsA()->AddInstance(op->IsOnHeap());
00383          else
00384             Error("UpdateInstCount", "oops 0x%lx\n", (Long_t)op);
00385       }
00386 }
00387 
00388 //______________________________________________________________________________
00389 void *TObjectTable::CheckPtrAndWarn(const char *msg, void *vp)
00390 {
00391    // Issue a warning in case an object still appears in the table
00392    // while it should not.
00393 
00394    if (fTable && vp && fTable[FindElement((TObject*)vp)]) {
00395       Remove((TObject*)vp);
00396       Warning("CheckPtrAndWarn", "%s (0x%lx)\n", msg, (Long_t)vp);
00397    }
00398    return vp;
00399 }

Generated on Tue Jul 5 14:11:37 2011 for ROOT_528-00b_version by  doxygen 1.5.1