home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 39 / IOPROG_39.ISO / SOFT / sdkjava40.exe / data1.cab / fg_Samples / Samples / Profiler / heapmon / ids.hpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-04  |  8.4 KB  |  335 lines

  1. // ids.hpp
  2. //
  3. // Created 10/02/98
  4. //
  5. // (C)Copyright 1998-1999 Microsoft Corporation, All rights reserved.
  6. //
  7.  
  8. #ifndef __IDS_HPP__
  9. #define __IDS_HPP__
  10.  
  11. #include "utils.hpp"
  12.  
  13.  
  14. // IDWrappers are wrappers for VM UniqueIDs.  Their primary use is to cache
  15. // information from the VM.  The information contained in an IDWrapper is
  16. // heap-monitor-client-independent.  Clients keep separate maps for any
  17. // additional associations needed.
  18.  
  19.  
  20. enum IDType
  21. {
  22.     ID_INVALID = -1,
  23.  
  24.     ID_PACKAGE,
  25.     ID_CLASS,
  26.     ID_THREAD,
  27.     ID_GHOST_THREAD,
  28.     ID_ROOT,
  29.     ID_STACKFRAME,
  30.  
  31.     ID_OBJECT,
  32.  
  33.     ID_FIRST_TRANSIENT = ID_GHOST_THREAD,
  34. };
  35.  
  36. enum IDWrapperFlags
  37. {
  38.     // Discovered during root enumeration.
  39.     ID_FL_DISCOVERED                = 0x0001,
  40.  
  41.     ID_FL_MARKED_EMPTY_ROOT         = 0x0002,
  42.     ID_FL_REPORTED_EMPTY_ROOT       = 0x0004,
  43.  
  44.     ALL_ID_PER_GC_FLAGS             = ID_FL_DISCOVERED
  45. };
  46.  
  47. class IDWrapper
  48. {
  49. public:
  50.  
  51.     IDType type;
  52.     UniqueID vmid;
  53.     PSTR name;
  54.     DWORD flags;
  55.     
  56. protected:
  57.  
  58.     IDWrapper (IDType itype)
  59.     {
  60.         type = itype;
  61.         name = NULL;
  62.         flags = 0;
  63.     }
  64.     
  65.     friend class HeapMonitorManager;
  66.     
  67.     // NOTE: this is not virtualized, we will have lots of these and don't
  68.     // want a vtable ptr per wrapper.
  69.     ~IDWrapper ();
  70. };
  71. typedef IDWrapper *ID;
  72.  
  73. typedef class PackageIDWrapper  *PKGID;
  74. typedef class ClassIDWrapper    *CLASSID;
  75. typedef class ThreadIDWrapper   *THREADID;
  76. typedef class StackIDWrapper    *STACKID;
  77. typedef class RootIDWrapper     *ROOTID;
  78. typedef class ObjectIDWrapper   *OBJID;
  79.  
  80.  
  81. // Packages don't have real UniqueIDs.
  82. class PackageIDWrapper : public IDWrapper
  83. {
  84. public:
  85.     PKGID parent;
  86.     
  87.     PackageIDWrapper () : IDWrapper(ID_PACKAGE) {}
  88. };
  89.  
  90.  
  91. struct FieldInfo {
  92.     FieldID id;
  93.     PSTR name;
  94.     DWORD flags;
  95. };
  96.  
  97. struct FieldInfoHeader {
  98.     ULONG nfields;
  99.     ULONG nreffields;
  100.     FieldInfo fldinfo[1];
  101. };
  102.  
  103. enum {
  104.     // Something went wrong in collecting running information about the class
  105.     // or an instance of the class.
  106.     CID_FL_INACCURATE               = 0x00010000,
  107.  
  108.     // Is an array class (name starts with '[').
  109.     CID_FL_ARRAY                    = 0x00020000,
  110.  
  111.     // Is an array of references (name starts with "[L")
  112.     CID_FL_ARRAY_OF_OBJECTS         = 0x00040000,
  113.  
  114.     // DescribeObject will work on instances of this class.
  115.     CID_FL_HAS_DESCRIPTION          = 0x00080000,
  116.  
  117.     ALL_CID_PER_GC_FLAGS            = CID_FL_INACCURATE
  118. };
  119.  
  120. class ClassIDWrapper : public IDWrapper
  121. {
  122. public:
  123.     PKGID pkg;
  124.     FieldInfoHeader *flds;
  125.     ULONG liveinstances;
  126.     ULONG totalsize;
  127.     ULONG livesize;
  128.     ULONG agesum;
  129.     
  130.     ClassIDWrapper () : IDWrapper(ID_CLASS)
  131.     {
  132.         flds = NULL;
  133.         liveinstances = 0;
  134.         totalsize = 0;
  135.         livesize = 0;
  136.         agesum = 0;
  137.     }
  138. };
  139.  
  140.  
  141. enum {
  142.     // The thread was destroyed while a heap dump was in progress.  The ID is
  143.     // valid until the heap dump completes.
  144.     TID_FL_DEAD                     = 0x00010000,
  145. };
  146.  
  147. class ThreadIDWrapper : public IDWrapper
  148. {
  149. public:
  150.     STACKID curframe;
  151.  
  152.     ThreadIDWrapper () : IDWrapper(ID_THREAD)
  153.     {
  154.         curframe = NULL;
  155.     }
  156. };
  157.  
  158.  
  159. enum {
  160.     // See HeapMonitorManager::ObjectReferences.
  161.     OID_FL_VISITED_BEFORE_REPORTED  = 0x00010000,
  162.  
  163.     // Referenced by at least two objects (possibly including itself or only
  164.     // itself).
  165.     OID_FL_MULTIPLE_REFERENCES      = 0x00020000,
  166.  
  167.     // Immediately referenced by a root (i.e. seen from RootReferences).
  168.     OID_FL_REFERENCED_BY_ROOT       = 0x00040000,
  169.  
  170.     // Object cannot reference any other objects (ex. a class with only
  171.     // primitive fields, a primitive array, a 0-length object array, or a
  172.     // variable-size class with no reported references).
  173.     OID_FL_NO_REFERENCES            = 0x00080000,
  174.  
  175.     // All of the object's references are null.
  176.     OID_FL_NULL_REFERENCES          = 0x00100000,
  177.  
  178.     // The outgoing edges of this object have been explored.  The referents may or
  179.     // may not have OBJIDs.  This is used to record whether or not referents have
  180.     // been checked for multiple references.
  181.     OID_FL_EXPANDED                 = 0x00200000,
  182.  
  183.     // At the user's request, the OBJID will be kept across gc's.
  184.     OID_FL_TRACKED                  = 0x00400000,
  185.  
  186.     // A user-defined string tag for the object can be retrived via HeapMonitorManager::GetObjectTag.
  187.     OID_FL_TAGGED                   = 0x00800000,
  188.  
  189.     // The underlying object was garbage collected.  (One of
  190.     // ALL_OID_NONTRANSIENT_FLAGS must be set for this to occur.)
  191.     OID_FL_DEAD                     = 0x01000000,
  192.  
  193.     // Flags that are cleared when the state of the heap is unknown.
  194.     ALL_OID_TRANSIENT_FLAGS         =   OID_FL_VISITED_BEFORE_REPORTED
  195.                                       | OID_FL_MULTIPLE_REFERENCES
  196.                                       | OID_FL_REFERENCED_BY_ROOT
  197.                                       | OID_FL_NULL_REFERENCES
  198.                                       | OID_FL_EXPANDED,
  199.  
  200.     // Flags that require the OBJID to be kept across gc's (including after
  201.     // the underlying object has been collected).  A handle is allocated and
  202.     // stored in a HeapMonitorManager::TrackedObjectList entry.
  203.     ALL_OID_NONTRANSIENT_FLAGS      =   OID_FL_TRACKED
  204.                                       | OID_FL_TAGGED,
  205. };
  206.  
  207. // Proxies to an ObjectID.  Unless any of ALL_OID_NONTRANSIENT_FLAGS, OBJID's
  208. // should not be used while execution is not suspended.  The vmid field must
  209. // never be used while execution is not suspended.  States variables:
  210. //
  211. // dead:  The object was garbage collected, indicated by OID_FL_DEAD.
  212. // Normally, OBJIDs are simply deleted in this state.  An OBJID will be kept
  213. // in this state if any of ALL_OID_NONTRANSIENT_FLAGS are set.  The vmid field
  214. // is not valid in this state.
  215. //
  216. // tracked:  The object is being followed by the user across gc's, indicated by
  217. // OID_FL_TRACKED.  When a tagged ObjectID is garbage collected, the OBJID is
  218. // kept and OID_FL_DEAD is set.
  219. //
  220. // tagged:  The object was given a description by the user, indicated by
  221. // OID_FL_TAGGED.  When a tagged ObjectID is garbage collected, the OBJID is
  222. // kept and OID_FL_DEAD is set.
  223. //
  224. // Any combination of these variables can occur.  In any states where
  225. // "!(tracked || tagged)", the OBJID will be deleted when execution resumes.
  226. //
  227. // In any states where "tracked || tagged", the vmid field will be updated
  228. // with the possibly-changed ObjectID when execution is suspended.
  229. //
  230. class ObjectIDWrapper : public IDWrapper
  231. {
  232. public:
  233.     ObjectIDWrapper () : IDWrapper(ID_OBJECT)
  234.     {
  235.     }
  236.  
  237.     ObjectID GetObjectID ()
  238.     {
  239.         ASSERT(!(flags & OID_FL_DEAD));
  240.         return vmid;
  241.     }
  242. };
  243.  
  244.  
  245. enum
  246. {
  247.     // Has references to one or more objects
  248.     SID_FL_HAS_REFERENCES           = 0x00010000,
  249. };
  250.  
  251. class StackIDWrapper : public IDWrapper
  252. {
  253. public:
  254.     CONTAINER_TYPE frmtype;
  255.     THREADID thd;
  256.     MethodID methodid;
  257.     STACKID parent;
  258.  
  259.     StackIDWrapper () : IDWrapper(ID_STACKFRAME)
  260.     {
  261.     }
  262. };
  263.  
  264.  
  265. enum
  266. {
  267.     // Has references to one or more objects
  268.     RID_FL_HAS_REFERENCES           = 0x00010000,
  269. };
  270.  
  271. class RootIDWrapper : public IDWrapper {
  272. public:
  273.     CONTAINER_TYPE roottype;
  274.     UniqueID rootid1;
  275.     UniqueID rootid2;
  276.     
  277.     RootIDWrapper () : IDWrapper(ID_ROOT)
  278.     {
  279.     }
  280. };
  281.  
  282.  
  283. class UniqueIDMap
  284. {
  285. private:
  286.  
  287.     CMapPtrToPtr m_map;
  288.  
  289. public:
  290.  
  291.     BOOL AddID (UniqueID vmid, ID id)
  292.     {
  293.         BOOL result;
  294.         ASSERT(vmid != NULL);
  295.         ASSERT(!LookupID(vmid));
  296.         result = SUCCEEDED(m_map.Add((PVOID)vmid, id));
  297.         if (result)
  298.         {
  299.             id->vmid = vmid;
  300.             ASSERT(LookupID(vmid) == id);
  301.         }
  302.             
  303.         return result;
  304.     }
  305.  
  306.     ID LookupID (UniqueID vmid)
  307.     {
  308.         ID id = NULL;
  309.         m_map.Lookup((PVOID)vmid, (PVOID*)&id);
  310.         ASSERT(id == NULL || id->vmid == vmid);
  311.         return id;
  312.     }
  313.  
  314.     VOID DeleteID (UniqueID vmid)
  315.     {
  316.         ASSERT(vmid != NULL);
  317.         EVAL(SUCCEEDED(m_map.Delete((PVOID)vmid)));
  318.         ASSERT(!LookupID(vmid));
  319.     }
  320.  
  321.     VOID FilterIDs (PTRMAPENUMFN *filterfn, PVOID token)
  322.     {
  323.         m_map.Filter(filterfn, token);
  324.     }
  325.  
  326.     int IterateIDs (PTRMAPENUMFN *iterfn, PVOID token)
  327.     {
  328.         return m_map.Iterate(iterfn, token);
  329.     }
  330. };
  331.  
  332.  
  333. #endif /* __IDS_HPP__ */
  334.  
  335.