Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:57:55

0001 // @(#)root/base:$Id$
0002 // Author: Fons Rademakers   29/07/95
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TStorage
0013 #define ROOT_TStorage
0014 
0015 
0016 //////////////////////////////////////////////////////////////////////////
0017 //                                                                      //
0018 // TStorage                                                             //
0019 //                                                                      //
0020 // Storage manager.                                                     //
0021 //                                                                      //
0022 //////////////////////////////////////////////////////////////////////////
0023 
0024 // #include "RConfigure.h" // included via Rtypes.h
0025 #include "Rtypes.h"
0026 
0027 typedef void (*FreeHookFun_t)(void*, void *addr, size_t);
0028 typedef void *(*ReAllocFun_t)(void*, size_t);
0029 typedef void *(*ReAllocCFun_t)(void*, size_t, size_t);
0030 typedef char *(*ReAllocCharFun_t)(char*, size_t, size_t);
0031 
0032 
0033 class TStorage {
0034 
0035 private:
0036    static size_t         fgMaxBlockSize;       // largest block allocated
0037    static FreeHookFun_t  fgFreeHook;           // function called on free
0038    static void          *fgFreeHookData;       // data used by this function
0039    static ReAllocCFun_t  fgReAllocCHook;       // custom ReAlloc with length check
0040    static Bool_t         fgHasCustomNewDelete; // true if using ROOT's new/delete
0041 
0042    //----- Private bits, clients can only test but not change them
0043    enum {
0044       kIsOnHeap      = 0x01000000,    ///< object is on heap
0045    };
0046 
0047 public:
0048    static const UInt_t   kObjectAllocMemValue = 0x99999999;
0049                                                // magic number for ObjectAlloc
0050 
0051 public:
0052    virtual ~TStorage() { }
0053 
0054    static FreeHookFun_t  GetFreeHook();
0055    static void          *GetFreeHookData();
0056    static size_t         GetMaxBlockSize();
0057    static void          *Alloc(size_t size);
0058    static void           Dealloc(void *ptr);
0059    static void          *ReAlloc(void *vp, size_t size, size_t oldsize);
0060    static char          *ReAllocChar(char *vp, size_t size, size_t oldsize);
0061    static Int_t         *ReAllocInt(Int_t *vp, size_t size, size_t oldsize);
0062    static void          *ObjectAlloc(size_t size);
0063    static void          *ObjectAllocArray(size_t size);
0064    static void          *ObjectAlloc(size_t size, void *vp);
0065    static void           ObjectDealloc(void *vp);
0066 #ifdef R__SIZEDDELETE
0067    static void           ObjectDealloc(void *vp, size_t size);
0068 #endif
0069    static void           ObjectDealloc(void *vp, void *ptr);
0070 
0071    static void EnterStat(size_t size, void *p);
0072    static void RemoveStat(void *p);
0073    static void PrintStatistics();
0074    static void SetMaxBlockSize(size_t size);
0075    static void SetFreeHook(FreeHookFun_t func, void *data);
0076    static void SetReAllocHooks(ReAllocFun_t func1, ReAllocCFun_t func2);
0077    static void SetCustomNewDelete();
0078    static void EnableStatistics(int size= -1, int ix= -1);
0079 
0080    static Bool_t HasCustomNewDelete();
0081 
0082    static Bool_t FilledByObjectAlloc(volatile const UInt_t* const member);
0083    static void UpdateIsOnHeap(volatile const UInt_t &uniqueID, volatile UInt_t &bits);
0084 
0085    ClassDef(TStorage,0)  //Storage manager class
0086 };
0087 
0088 inline Bool_t TStorage::FilledByObjectAlloc(volatile const UInt_t *const member) {
0089    //called by TObject's constructor to determine if object was created by call to new
0090 
0091    // This technique is necessary as there is one stack per thread
0092    // and we can not rely on comparison with the current stack memory position.
0093    // Note that a false positive (this routine returning true for an object
0094    // created on the stack) requires the previous stack value to have been
0095    // set to exactly kObjectAllocMemValue at exactly the right position (i.e.
0096    // where this object's fUniqueID is located.
0097    // The consequence of a false positive will be visible if and only if
0098    //   the object is auto-added to a TDirectory (i.e. TTree, TH*, TGraph,
0099    //      TEventList) or explicitly added to the directory by the user
0100    // and
0101    //   the TDirectory (or TFile) object is created on the stack *before*
0102    //      the object.
0103    // The consequence would be that those objects would be deleted twice, once
0104    // by the TDirectory and once automatically when going out of scope
0105    // (and thus quite visible).  A false negative (which is not possible with
0106    // this implementation) would have been a silent memory leak.
0107 
0108    // This will be reported by valgrind as uninitialized memory reads for
0109    // object created on the stack, use $ROOTSYS/etc/valgrind-root.supp
0110 R__INTENTIONALLY_UNINIT_BEGIN
0111    return *member == kObjectAllocMemValue; // NOLINT
0112 R__INTENTIONALLY_UNINIT_END
0113 }
0114 
0115 // Assign the kIsOnHeap bit in 'bits' based on the pattern seen in uniqueID.
0116 // See Storage::FilledByObjectAlloc for details.
0117 // This routine is marked as inline with attribute noinline so that it never
0118 // inlined and thus can be used in a valgrind suppression file to suppress
0119 // the known/intentional uninitialized memory read but still be a 'quick'
0120 // function call to avoid losing performance at object creation.
0121 // Moving the function into the source file, results in doubling of the
0122 // overhead (compared to inlining)
0123 R__NEVER_INLINE void TStorage::UpdateIsOnHeap(volatile const UInt_t &uniqueID, volatile UInt_t &bits) {
0124    if (TStorage::FilledByObjectAlloc(&uniqueID))
0125       bits = bits | kIsOnHeap;
0126    else
0127       bits = bits & ~kIsOnHeap;
0128 }
0129 
0130 
0131 inline size_t TStorage::GetMaxBlockSize() { return fgMaxBlockSize; }
0132 
0133 inline void TStorage::SetMaxBlockSize(size_t size) { fgMaxBlockSize = size; }
0134 
0135 inline FreeHookFun_t TStorage::GetFreeHook() { return fgFreeHook; }
0136 
0137 namespace ROOT {
0138 namespace Internal {
0139 using FreeIfTMapFile_t = bool(void*);
0140 R__EXTERN FreeIfTMapFile_t *gFreeIfTMapFile;
0141 R__EXTERN void *gMmallocDesc;
0142 }
0143 }
0144 
0145 #endif