gecko-dev/ef/gc/include/sm.h
1999-11-02 06:38:29 +00:00

358 lines
13 KiB
C

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*******************************************************************************
S P O R T M O D E L
_____
____/_____\____
/__o____o____o__\ __
\_______________/ (@@)/
/\_____|_____/\ x~[]~
~~~~~~~~~~~/~~~~~~~|~~~~~~~\~~~~~~~~/\~~~~~~~~~
Advanced Technology Garbage Collector
Copyright (c) 1997 Netscape Communications, Inc. All rights reserved.
Recovered by: Warren Harris
*******************************************************************************/
/*
** SportModel is a hybrid, mark-and-sweep, mostly-copying, card-marking
** generational garbage collector designed for very low level-two cache miss
** rates. The intended use is for the ElectricalFire Java implementation,
** although it is not ElectricalFire or Java specific. It also includes an
** integrated malloc/free package.
*/
#ifndef __SM__
#define __SM__
#include "smpriv.h"
SM_BEGIN_EXTERN_C
/*******************************************************************************
* Types and Constants
******************************************************************************/
typedef struct SMHeap SMHeap;
typedef union SMClass SMClass;
typedef struct SMObjectClass SMObjectClass;
typedef struct SMArrayClass SMArrayClass;
typedef struct SMPrimClass SMPrimClass;
typedef struct SMObject SMObject;
typedef struct SMArray SMArray;
typedef struct SMObjStruct SMObjStruct;
typedef struct SMArrayStruct SMArrayStruct;
typedef enum SMGenNum {
SMGenNum_Freshman = 0, /* for new allocations */
SMGenNum_Sophomore, /* first survivor generation */
SMGenNum_Junior, /* oldest generation for applets */
SMGenNum_Senior, /* oldest generation for system code */
SMGenNum_Static, /* static space -- scanned, but not marked */
SMGenNum_Malloc, /* malloc space -- explicitly freed */
SMGenNum_Free = 7 /* pages unused by malloc or gc */
} SMGenNum;
/******************************************************************************/
SM_DECLARE_ENSURE(SMObject)
SM_DECLARE_ENSURE(SMObjStruct)
SM_DECLARE_ENSURE(SMArray)
SM_DECLARE_ENSURE(SMArrayStruct)
#define SM_ENCRYPT_OBJECT(obj) ((SMObject*)SM_ENCRYPT(SM_ENSURE(SMObjStruct, obj)))
#define SM_DECRYPT_OBJECT(obj) ((SMObjStruct*)SM_DECRYPT(SM_ENSURE(SMObject, obj)))
#define SM_ENCRYPT_ARRAY(arr) ((SMArray*)SM_ENCRYPT(SM_ENSURE(SMArrayStruct, arr)))
#define SM_DECRYPT_ARRAY(arr) ((SMArrayStruct*)SM_DECRYPT(SM_ENSURE(SMArray, arr)))
/* XXX add ifdef SM_COLLECT_CLASSES */
#define SM_ENCRYPT_CLASS(cl) (cl)
#define SM_DECRYPT_CLASS(cl) (cl)
/*******************************************************************************
* Startup/Shutdown Routines
******************************************************************************/
SM_EXTERN(void)
SM_MarkRoots(SMObject** base, PRUword count, PRBool conservative);
/* The user must define a root marking routine with the following signature.
It's job is to call SM_MarkRoots for all roots in the program. This routine
is registered by calling SM_InitHeap. */
typedef void
(*SMMarkRootsProc)(SMGenNum collectingGenNum, PRBool copyCycle, void* closure);
/* This function must be called as the first thing in the user's SMMarkRootsProc
(or _be_ the user's SMMarkRootsProc if there are no other roots) if NSPR
threads are to be scanned conservatively. Failure to call this indicates
either that you know what you're doing, or you have a bug. */
SM_EXTERN(void)
SM_MarkThreadsConservatively(SMGenNum collectingGenNum, PRBool copyCycle,
void* closure);
/* This function allows finer grained control over exactly which threads are
scanned conservatively. */
SM_EXTERN(void)
SM_MarkThreadConservatively(PRThread* thread, SMGenNum collectingGenNum,
PRBool copyCycle, void* closure);
/* The SMGCHookProc defines the signature of the before and after gc hook
procedures. These are called before and after a collection on the thread
which caused the collection. The primary function of these hooks is to allow
any locks needed by the root marking procedure to be entered (and exited)
because once the collection process has started, all other threads are
suspended, and no locks (or monitors) can be waited on. */
typedef void
(*SMGCHookProc)(SMGenNum collectingGenNum, PRUword collectCount,
PRBool copyCycle, void* closure);
/* Initialize the garbage collector system. */
SM_EXTERN(PRStatus)
SM_InitGC(PRUword initialHeapSize, PRUword maxHeapSize,
SMGCHookProc beforeGCHook, void* beforeGCClosure,
SMGCHookProc afterGCHook, void* afterGCClosure,
SMMarkRootsProc markRootsProc, void* markRootsClosure);
/* Shutdown the garbage collector system. */
SM_EXTERN(PRStatus)
SM_CleanupGC(PRBool finalizeOnExit);
/* Initialize the malloc system. This is done implicitly when SM_InitGC is called. */
SM_EXTERN(PRStatus)
SM_InitMalloc(PRUword initialHeapSize, PRUword maxHeapSize);
/* Shutdown the malloc system. This is done implicitly when SM_CleanupGC is called. */
SM_EXTERN(PRStatus)
SM_CleanupMalloc(void);
/*******************************************************************************
* Allocation and Collection
******************************************************************************/
/* Allocates a garbage-collectable object of a given class.
The class must be constructed via SM_InitObjectClass. */
SM_EXTERN(SMObject*)
SM_AllocObject(SMObjectClass* clazz);
/* Allocates a garbage-collectable array object of a given class.
The class must be constructed via SM_InitArrayClass. */
SM_EXTERN(SMArray*)
SM_AllocArray(SMArrayClass* clazz, PRUword size);
/* Allocates a garbage-collectable object of a given class, but with extra space
at the end of the object. The size of the extra space is specified in bytes
and is not examined by the garbage collector. A pointer to the beginning of
the extra space can be obtained by SM_OBJECT_EXTRA(obj);
The class must be constructed via SM_InitObjectClass. */
SM_EXTERN(SMObject*)
SM_AllocObjectExtra(SMObjectClass* clazz, PRUword extraBytes);
/* Returns the size of an object in bytes. This function cannot be used on
malloc'd objects. */
SM_EXTERN(PRUword)
SM_ObjectSize(SMObject* obj);
/* Returns a new object which is a shallow copy of the original. */
SM_EXTERN(SMObject*)
SM_Clone(SMObject* obj);
/* Forces a garbage collection of the entire heap. */
SM_EXTERN(void)
SM_Collect(void);
/* Forces finalization to occur. */
SM_EXTERN(void)
SM_RunFinalization(void);
/*******************************************************************************
* Malloc and Friends
*
* These memory management routines may be used as an alternative to malloc,
* free and associated routines. It is an exercise to the application
* programmer to cause these routines to be linked as _the_ malloc and free
* routines for the application. The garbage collector itself uses these
* routines internally and does not otherwise depend on malloc, free, etc.
******************************************************************************/
SM_EXTERN(void*)
SM_Malloc(PRUword size);
SM_EXTERN(void)
SM_Free(void* ptr);
SM_EXTERN(void*)
SM_Calloc(PRUword size, PRUword count);
SM_EXTERN(void*)
SM_Realloc(void* ptr, PRUword size);
SM_EXTERN(void*)
SM_Strdup(void* str);
SM_EXTERN(void*)
SM_Strndup(void* str, PRUword size);
/*******************************************************************************
* Memory Pool variation of Malloc and Friends
******************************************************************************/
typedef struct SMPool SMPool;
SM_EXTERN(SMPool*)
SM_NewPool(void);
SM_EXTERN(void)
SM_DeletePool(SMPool* pool);
SM_EXTERN(void*)
SM_PoolMalloc(SMPool* pool, PRUword size);
SM_EXTERN(void)
SM_PoolFree(SMPool* pool, void* ptr);
SM_EXTERN(void*)
SM_PoolCalloc(SMPool* pool, PRUword size, PRUword count);
SM_EXTERN(void*)
SM_PoolRealloc(SMPool* pool, void* ptr, PRUword size);
SM_EXTERN(void*)
SM_PoolStrdup(SMPool* pool, void* str);
SM_EXTERN(void*)
SM_PoolStrndup(SMPool* pool, void* str, PRUword size);
/*******************************************************************************
* Write Barrier
*
* All assignments to garbage collected object fields must go through the write
* barrier. This allows the collector to focus on a smaller portion of the heap
* during a collection (a "generation") while remaining informed about changes
* made to objects of other generations.
*
* To set a field of an object or an element of an array, rather than writing:
*
* obj->fieldName = value;
* arr[i] = value;
*
* one must instead write the following:
*
* SM_SET_FIELD(ObjType, obj, fieldName, value);
* SM_SET_ELEMENT(ObjType, arr, i, value);
*
* Failure to use the SM_SET macros for all assignments will ultimately result
* in system failure (i.e. a crash). But in order to aid in tracking down
* problems related to this, the SM_CHECK_PTRS preprocessor symbol may be
* defined which causes all object pointers to be "encrypted" in such a way
* that any attempt to access an object pointer outside of the SM_SET
* macros will cause an immediate crash. Crashes of this sort point to places
* in the code where the macros were forgotten. However, use of this encryption
* technique also requires all read accesses to go through an equivalent pair
* of macros, e.g. rather than writing:
*
* obj->fieldName
* arr[i]
*
* one must instead write the following:
*
* SM_GET_FIELD(ObjType, obj, fieldName)
* SM_GET_ELEMENT(ObjType, arr, i)
*
******************************************************************************/
SM_EXTERN(PRUint8*) SM_CardTable;
/* Accessors for debugging: */
#define SM_GET_ELEMENT(ObjType, obj, index) \
(((ObjType*)SM_DECRYPT(obj))[index]) \
#define SM_GET_FIELD(ObjType, obj, fieldName) \
(((ObjType*)SM_DECRYPT(obj))->fieldName) \
/* Unsafe assignment -- only to be used if you really know what you're
doing, e.g. initializing a newly created object's fields: */
#define SM_SET_ELEMENT_UNSAFE(ObjType, obj, index, value) \
(SM_GET_ELEMENT(ObjType, obj, index) = (value)) \
#define SM_SET_FIELD_UNSAFE(ObjType, obj, fieldName, value) \
(SM_GET_FIELD(ObjType, obj, fieldName) = (value)) \
#ifdef SM_NO_WRITE_BARRIER
#define SM_OBJECT_CARDDESC(obj) NULL
#define SM_DIRTY_PAGE(addr) ((void)0)
#define SM_CLEAN_PAGE(addr) ((void)0)
#else /* !SM_NO_WRITE_BARRIER */
#define SM_OBJECT_CARDDESC(obj) (&SM_CardTable[SM_PAGE_NUMBER(SM_DECRYPT_OBJECT(obj))])
#define SM_CARDDESC_GEN(cd) ((SMGenNum)((cd) - 1))
#define SM_GEN_CARDDESC(genNum) ((PRUint8)(genNum) + 1)
#ifdef DEBUG
SM_EXTERN(void) SM_DirtyPage(void* addr);
SM_EXTERN(void) SM_CleanPage(void* addr);
#define SM_DIRTY_PAGE(addr) SM_DirtyPage(addr)
#define SM_CLEAN_PAGE(addr) SM_CleanPage(addr)
#else /* DEBUG */
#define SM_DIRTY_PAGE(addr) (*SM_OBJECT_CARDDESC(addr) = 0)
#define SM_CLEAN_PAGE(addr) (*SM_OBJECT_CARDDESC(addr) = SM_GEN_CARDDESC(SMGenNum_Free))
#endif /* DEBUG */
#endif /* !SM_NO_WRITE_BARRIER */
/* Safe assignment that uses the write barrier: */
#define SM_SET_ELEMENT(ObjType, obj, index, value) \
{ \
ObjType* _obj = obj; \
SM_SET_ELEMENT_UNSAFE(ObjType, _obj, index, value); \
SM_DIRTY_PAGE(_obj); \
} \
#define SM_SET_FIELD(ObjType, obj, fieldName, value) \
{ \
ObjType* _obj = obj; \
SM_SET_FIELD_UNSAFE(ObjType, _obj, fieldName, value); \
SM_DIRTY_PAGE(_obj); \
} \
/******************************************************************************/
#if defined(DEBUG) || defined(SM_DUMP)
SM_EXTERN(void)
SM_SetTraceOutputFile(FILE* out);
#endif /* defined(DEBUG) || defined(SM_DUMP) */
/******************************************************************************/
SM_END_EXTERN_C
#endif /* __SM__ */
/******************************************************************************/