Back to index

lightning-sunbird  0.9+nobinonly
prgc.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef prgc_h___
00039 #define prgc_h___
00040 
00041 /*
00042 ** API to NSPR gc memory system.
00043 */
00044 #include "prtypes.h"
00045 #include "prmon.h"
00046 #include "prthread.h"
00047 #include <stdio.h>
00048 
00049 #if defined(WIN16)
00050 #define GCPTR __far
00051 #else
00052 #define GCPTR
00053 #endif
00054 
00055 
00056 PR_BEGIN_EXTERN_C
00057 
00058 /*
00059 ** Initialize the garbage collector.
00060 **     "flags" is the trace flags (see below).
00061 **     "initialHeapSize" is the initial size of the heap and may be zero
00062 **        if the default is desired.
00063 **    "segmentSize" is the size of each segment of memory added to the
00064 **       heap when the heap is grown.
00065 */
00066 PR_EXTERN(void) PR_InitGC(
00067     PRWord flags, PRInt32 initialHeapSize, PRInt32 segmentSize, PRThreadScope scope);
00068 
00069 /*
00070 ** Shuts down gc and frees up all memory associated with it. 
00071 */
00072 PR_EXTERN(void) PR_ShutdownGC(PRBool finalizeOnExit);
00073 
00074 /*
00075 ** This walk function will be called for every gc object in the
00076 ** heap as it is walked. If it returns non-zero, the walk is terminated.
00077 */
00078 typedef PRInt32 (*PRWalkFun)(void GCPTR* obj, void* data);
00079 
00080 /*
00081 ** GC Type record. This defines all of the GC operations used on a
00082 ** particular object type. These structures are passed to
00083 ** PR_RegisterType.
00084 */
00085 typedef struct GCType {
00086     /*
00087     ** Scan an object that is in the GC heap and call GCInfo.livePointer
00088     ** on all of the pointers in it. If this slot is null then the object
00089     ** won't be scanned (i.e. it has no embedded pointers).
00090     */
00091     void (PR_CALLBACK *scan)(void GCPTR *obj);
00092 
00093     /*
00094     ** Finalize an object that has no references. This is called by the
00095     ** GC after it has determined where the object debris is but before
00096     ** it has moved the debris to the logical "free list". The object is
00097     ** marked alive for this call and removed from the list of objects
00098     ** that need finalization (finalization only happens once for an
00099     ** object). If this slot is null then the object doesn't need
00100     ** finalization.
00101     */
00102     void (PR_CALLBACK *finalize)(void GCPTR *obj);
00103 
00104     /*
00105     ** Dump out an object during a PR_DumpGCHeap(). This is used as a
00106     ** debugging tool.
00107     */
00108     void (PR_CALLBACK *dump)(FILE *out, void GCPTR *obj, PRBool detailed, PRIntn indentLevel);
00109 
00110     /*
00111     ** Add object to summary table.
00112     */
00113     void (PR_CALLBACK *summarize)(void GCPTR *obj, PRUint32 bytes);
00114 
00115     /*
00116     ** Free hook called by GC when the object is being freed.
00117     */
00118     void (PR_CALLBACK *free)(void *obj);
00119 
00120     /* Weak pointer support: If the object has a weak pointer (Note:
00121        at most one), this function is used to get the weak link's
00122        offset from the start of the body of a gc object */
00123     PRUint32 (PR_CALLBACK *getWeakLinkOffset)(void *obj);
00124 
00125     /* Descriptive character for dumping this GCType */
00126     char kindChar;
00127 
00128     /*
00129     ** Walker routine. This routine should apply fun(obj->ptr, data)
00130     ** for every gc pointer within the object.
00131     */
00132     PRInt32 (PR_CALLBACK *walk)(void GCPTR *obj, PRWalkFun fun, void* data);
00133 } GCType;
00134 
00135 /*
00136 ** This data structure must be added as the hash table passed to 
00137 ** the summarize method of GCType.
00138 */ 
00139 typedef struct PRSummaryEntry {
00140     void* clazz;
00141     PRInt32 instancesCount;
00142     PRInt32 totalSize;
00143 } PRSummaryEntry;
00144 
00145 /*
00146 ** This function pointer must be registered by users of nspr
00147 ** to produce the finally summary after all object in the
00148 ** heap have been visited.
00149 */
00150 typedef void (PR_CALLBACK *PRSummaryPrinter)(FILE *out, void* closure);
00151 
00152 PR_EXTERN(void) PR_CALLBACK PR_RegisterSummaryPrinter(PRSummaryPrinter fun, void* closure);
00153 
00154 typedef void PR_CALLBACK GCRootFinder(void *arg);
00155 typedef void PR_CALLBACK GCBeginFinalizeHook(void *arg);
00156 typedef void PR_CALLBACK GCEndFinalizeHook(void *arg);
00157 typedef void PR_CALLBACK GCBeginGCHook(void *arg);
00158 typedef void PR_CALLBACK GCEndGCHook(void *arg);
00159 
00160 typedef enum { PR_GCBEGIN, PR_GCEND } GCLockHookArg;
00161 
00162 typedef void PR_CALLBACK GCLockHookFunc(GCLockHookArg arg1, void *arg2);
00163 
00164 typedef struct GCLockHook GCLockHook;
00165 
00166 struct GCLockHook {
00167   GCLockHookFunc* func;
00168   void* arg;
00169   GCLockHook* next;
00170   GCLockHook* prev;
00171 };
00172 
00173 
00174 /*
00175 ** Hooks which are called at the beginning and end of the GC process.
00176 ** The begin hooks are called before the root finding step. The hooks are
00177 ** called with threading disabled, so it is now allowed to re-enter the
00178 ** kernel. The end hooks are called after the gc has finished but before
00179 ** the finalizer has run.
00180 */
00181 PR_EXTERN(void) PR_CALLBACK PR_SetBeginGCHook(GCBeginGCHook *hook, void *arg);
00182 PR_EXTERN(void) PR_CALLBACK PR_GetBeginGCHook(GCBeginGCHook **hook, void **arg);
00183 PR_EXTERN(void) PR_CALLBACK PR_SetEndGCHook(GCBeginGCHook *hook, void *arg);
00184 PR_EXTERN(void) PR_CALLBACK PR_GetEndGCHook(GCEndGCHook **hook, void **arg);
00185 
00186 /*
00187 ** Called before SuspendAll is called by dogc, so that GC thread can hold
00188 ** all the locks before hand to avoid any deadlocks
00189 */
00190 
00191 /*
00192 PR_EXTERN(void) PR_SetGCLockHook(GCLockHook *hook, void *arg);
00193 PR_EXTERN(void) PR_GetGCLockHook(GCLockHook **hook, void **arg);
00194 */
00195 
00196 PR_EXTERN(int) PR_RegisterGCLockHook(GCLockHookFunc *hook, void *arg);
00197 
00198 /*
00199 ** Hooks which are called at the beginning and end of the GC finalization
00200 ** process. After the GC has identified all of the dead objects in the
00201 ** heap, it looks for objects that need finalization. Before it calls the
00202 ** first finalization proc (see the GCType structure above) it calls the
00203 ** begin hook. When it has finalized the last object it calls the end
00204 ** hook.
00205 */
00206 PR_EXTERN(void) PR_SetBeginFinalizeHook(GCBeginFinalizeHook *hook, void *arg);
00207 PR_EXTERN(void) PR_GetBeginFinalizeHook(GCBeginFinalizeHook **hook, void **arg);
00208 PR_EXTERN(void) PR_SetEndFinalizeHook(GCBeginFinalizeHook *hook, void *arg);
00209 PR_EXTERN(void) PR_GetEndFinalizeHook(GCEndFinalizeHook **hook, void **arg);
00210 
00211 /*
00212 ** Register a GC type. Return's the index into the GC internal type
00213 ** table. The returned value is passed to PR_AllocMemory. After the call,
00214 ** the "type" memory belongs to the GC (the caller must not free it or
00215 ** change it).
00216 */
00217 PR_EXTERN(PRInt32) PR_RegisterType(GCType *type);
00218 
00219 /*
00220 ** Register a root finder with the collector. The collector will call
00221 ** these functions to identify all of the roots before collection
00222 ** proceeds. "arg" is passed to the function when it is called.
00223 */
00224 PR_EXTERN(PRStatus) PR_RegisterRootFinder(GCRootFinder func, char *name, void *arg);
00225 
00226 /*
00227 ** Allocate some GC'able memory. The object must be at least bytes in
00228 ** size. The type index function for the object is specified. "flags"
00229 ** specifies some control flags. If PR_ALLOC_CLEAN is set then the memory
00230 ** is zero'd before being returned. If PR_ALLOC_DOUBLE is set then the
00231 ** allocated memory is double aligned.
00232 **
00233 ** Any memory cell that you store a pointer to something allocated by
00234 ** this call must be findable by the GC. Use the PR_RegisterRootFinder to
00235 ** register new places where the GC will look for pointers into the heap.
00236 ** The GC already knows how to scan any NSPR threads or monitors.
00237 */
00238 PR_EXTERN(PRWord GCPTR *)PR_AllocMemory(
00239     PRWord bytes, PRInt32 typeIndex, PRWord flags);
00240 PR_EXTERN(PRWord GCPTR *)PR_AllocSimpleMemory(
00241     PRWord bytes, PRInt32 typeIndex);
00242 
00243 /*
00244 ** This function can be used to cause PR_AllocMemory to always return
00245 ** NULL. This may be useful in low memory situations when we're trying to
00246 ** shutdown applets.
00247 */
00248 PR_EXTERN(void) PR_EnableAllocation(PRBool yesOrNo);
00249 
00250 /* flags bits */
00251 #define PR_ALLOC_CLEAN 0x1
00252 #define PR_ALLOC_DOUBLE 0x2
00253 #define PR_ALLOC_ZERO_HANDLE 0x4              /* XXX yes, it's a hack */
00254 
00255 /*
00256 ** Force a garbage collection right now. Return when it completes.
00257 */
00258 PR_EXTERN(void) PR_GC(void);
00259 
00260 /*
00261 ** Force a finalization right now. Return when finalization has
00262 ** completed. Finalization completes when there are no more objects
00263 ** pending finalization. This does not mean there are no objects in the
00264 ** gc heap that will need finalization should a collection be done after
00265 ** this call.
00266 */
00267 PR_EXTERN(void) PR_ForceFinalize(void);
00268 
00269 /*
00270 ** Dump the GC heap out to the given file. This will stop the system dead
00271 ** in its tracks while it is occuring.
00272 */
00273 PR_EXTERN(void) PR_DumpGCHeap(FILE *out, PRBool detailed);
00274 
00275 /*
00276 ** Wrapper for PR_DumpGCHeap
00277 */
00278 PR_EXTERN(void) PR_DumpMemory(PRBool detailed);
00279 
00280 /*
00281 ** Dump summary of objects allocated.
00282 */
00283 PR_EXTERN(void) PR_DumpMemorySummary(void);
00284 
00285 /*
00286 ** Dump the application heaps.
00287 */
00288 PR_EXTERN(void) PR_DumpApplicationHeaps(void);
00289 
00290 /*
00291 ** Helper function used by dump routines to do the indentation in a
00292 ** consistent fashion.
00293 */
00294 PR_EXTERN(void) PR_DumpIndent(FILE *out, PRIntn indent);
00295 
00296 /*
00297 ** The GCInfo structure contains all of the GC state...
00298 **
00299 ** busyMemory:
00300 **    The amount of GC heap memory that is busy at this instant. Busy
00301 **    doesn't mean alive, it just means that it has been
00302 **    allocated. Immediately after a collection busy means how much is
00303 **    alive.
00304 **
00305 ** freeMemory:
00306 **    The amount of GC heap memory that is as yet unallocated.
00307 **
00308 ** allocMemory:
00309 **    The sum of free and busy memory in the GC heap.
00310 **
00311 ** maxMemory:
00312 **    The maximum size that the GC heap is allowed to grow.
00313 **
00314 ** lowSeg:
00315 **    The lowest segment currently used in the GC heap.
00316 **
00317 ** highSeg:
00318 **    The highest segment currently used in the GC heap.  
00319 **    The lowSeg and highSeg members are used for a "quick test" of whether 
00320 **    a pointer falls within the GC heap. [ see GC_IN_HEAP(...) ]
00321 **
00322 ** lock:
00323 **    Monitor used for synchronization within the GC.
00324 **
00325 ** finalizer:
00326 **    Thread in which the GC finalizer is running.
00327 **
00328 ** liveBlock:
00329 **    Object scanning functions call through this function pointer to
00330 **    register a potential block of pointers with the collector. (This is
00331 **    currently not at all different than processRoot.)
00332 **
00333 ** livePointer:
00334 **    Object scanning functions call through this function pointer to
00335 **    register a single pointer with the collector.
00336 **
00337 ** processRootBlock:
00338 **    When a root finder identifies a root it should call through this
00339 **    function pointer so that the GC can process the root. The call takes
00340 **    a base address and count which the gc will examine for valid heap
00341 **    pointers.
00342 **
00343 ** processRootPointer:
00344 **    When a root finder identifies a root it should call through this
00345 **    function pointer so that the GC can process the root. The call takes
00346 **    a single pointer value.
00347 */
00348 typedef struct GCInfoStr {
00349     PRWord  flags;         /* trace flags (see below)               */
00350     PRWord  busyMemory;    /* memory in use right now               */
00351     PRWord  freeMemory;    /* memory free right now                 */
00352     PRWord  allocMemory;   /* sum of busy & free memory             */
00353     PRWord  maxMemory;     /* max memory we are allowed to allocate */
00354     PRWord *lowSeg;        /* lowest segment in the GC heap         */
00355     PRWord *highSeg;       /* highest segment in the GC heap         */
00356 
00357     PRMonitor *lock;
00358     PRThread  *finalizer;
00359 
00360     void (PR_CALLBACK *liveBlock)(void **base, PRInt32 count);
00361     void (PR_CALLBACK *livePointer)(void *ptr);
00362     void (PR_CALLBACK *processRootBlock)(void **base, PRInt32 count);
00363     void (PR_CALLBACK *processRootPointer)(void *ptr);
00364     FILE* dumpOutput;
00365 #ifdef GCTIMINGHOOK
00366     void (*gcTimingHook)(int32 gcTime);
00367 #endif
00368 } GCInfo;
00369 
00370 PR_EXTERN(GCInfo *) PR_GetGCInfo(void);
00371 PR_EXTERN(PRBool) PR_GC_In_Heap(void GCPTR *object);
00372 
00373 /*
00374 ** Simple bounds check to see if a pointer is anywhere near the GC heap.
00375 ** Used to avoid calls to PR_ProcessRoot and GCInfo.livePointer by object
00376 ** scanning code.
00377 */
00378 #if !defined(XP_PC) || defined(_WIN32)
00379 #define GC_IN_HEAP(_info, _p) (((PRWord*)(_p) >= (_info)->lowSeg) && \
00380                                ((PRWord*)(_p) <  (_info)->highSeg))
00381 #else
00382 /*
00383 ** The simple bounds check, above, doesn't work in Win16, because we don't
00384 ** maintain: lowSeg == MIN(all segments) and highSeg == MAX(all segments).
00385 ** So we have to do a little better.
00386 */
00387 #define GC_IN_HEAP(_info, _p) PR_GC_In_Heap(_p)
00388 #endif
00389 
00390 PR_EXTERN(PRWord) PR_GetObjectHeader(void *ptr);
00391 
00392 PR_EXTERN(PRWord) PR_SetObjectHeader(void *ptr, PRWord newUserBits);
00393 
00394 /************************************************************************/
00395 
00396 /* Trace flags (passed to PR_InitGC or in environment GCLOG) */
00397 #define GC_TRACE    0x0001
00398 #define GC_ROOTS    0x0002
00399 #define GC_LIVE     0x0004
00400 #define GC_ALLOC    0x0008
00401 #define GC_MARK     0x0010
00402 #define GC_SWEEP    0x0020
00403 #define GC_DEBUG    0x0040
00404 #define GC_FINAL    0x0080
00405 
00406 #if defined(DEBUG_kipp) || defined(DEBUG_warren)
00407 #define GC_CHECK    0x0100
00408 #endif
00409 
00410 #ifdef DEBUG
00411 #define GCTRACE(x, y) if (PR_GetGCInfo()->flags & x) GCTrace y
00412 PR_EXTERN(void) GCTrace(char *fmt, ...);
00413 #else
00414 #define GCTRACE(x, y)
00415 #endif
00416 
00417 PR_END_EXTERN_C
00418 
00419 #endif /* prgc_h___ */