📄 garbage.h
字号:
#else
#define GCT_LASTVALIDTAG GCT_WEAKPOINTERLIST
#endif /* CLDC11 */
#ifdef CLDC11
#define GCT_TYPENAMES { \
"FREE", \
"NOPOINTERS", \
"INSTANCE", \
"ARRAY", \
"OBJECTARRAY", \
"METHODTABLE", \
"POINTERLIST", \
"EXECSTACK", \
"THREAD", \
"MONITOR", \
"WEAKPOINTERLIST", \
"WEAKREFERENCE" \
}
#else
#define GCT_TYPENAMES { \
"FREE", \
"NOPOINTERS", \
"INSTANCE", \
"ARRAY", \
"OBJECTARRAY", \
"METHODTABLE", \
"POINTERLIST", \
"EXECSTACK", \
"THREAD", \
"MONITOR", \
"WEAKPOINTERLIST" \
}
#endif /* CLDC11 */
/*=========================================================================
* Dynamic heap variables
*=======================================================================*/
extern cell* AllHeapStart; /* Lower limits of any heap space */
extern cell* AllHeapEnd;
extern cell* CurrentHeap; /* Current limits of heap space */
extern cell* CurrentHeapEnd; /* Current heap top */
/*=========================================================================
* Garbage collection operations
*=======================================================================*/
/* Memory system initialization */
void InitializeGlobals(void);
void InitializeMemoryManagement(void);
void FinalizeMemoryManagement(void);
void InitializeHeap(void);
void FinalizeHeap(void);
/* Garbage collection operations */
void garbageCollect(int moreMemory);
void garbageCollectForReal(int moreMemory);
int garbageCollecting(void);
/*=========================================================================
* Memory allocation operations
*=======================================================================*/
/* Memory allocation operations */
cell* mallocHeapObject(long size, GCT_ObjectType type);
cell* mallocObject(long size, GCT_ObjectType type);
cell* callocObject(long size, GCT_ObjectType type);
char* mallocBytes(long size);
cell* callocPermanentObject(long size);
/* Printing and debugging operations */
long getHeapSize(void);
long memoryFree(void);
long memoryUsage(void);
/* Operations on individual heap objects */
unsigned long getObjectSize(cell* object);
GCT_ObjectType getObjectType(cell* object);
/*=========================================================================
* Printing and debugging operations
*=======================================================================*/
#if INCLUDEDEBUGCODE
void printHeapContents(void);
#else
#define printHeapContents()
#endif
#if INCLUDEDEBUGCODE
void checkHeap(void);
void printObject(cell *object);
void rollTheHeap();
#else
#define checkHeap()
#define printObject(object)
#define rollTheHeap()
#endif
/*=========================================================================
* Memory management operations on static memory
*=======================================================================*/
/*=========================================================================
* These operations are really needed only in the Palm
* implementation of the KVM. Read the description of the
* static memory system earlier in this file.
*=======================================================================*/
#if USESTATIC
void FinalizeStaticMemory(void);
void modifyStaticMemory(void *staticMemory, int offset, void *newVal, int size);
void *mallocStaticBytes(int size);
#else
#define FinalizeStaticMemory()
#define modifyStaticMemory(staticMemory, offset, newVal, size) \
(((void)offset), ((void)newVal))
#define mallocStaticBytes(size)
#endif /* USESTATIC */
/*=========================================================================
* Temporary root operations
*=======================================================================*/
/*=========================================================================
* COMMENT:
* Temporary roots are structures that can be used for
* "pinning down" temporary objects and other structures
* that have been allocated from the Java heap, but that
* haven't yet been stored permanently to any Java object
* or other VM runtime structure.
*
* Temporary roots MUST be used in situations when you
* have a native C routine that allocates two objects
* from the Java heap and does not store the first of
* these objects to any other runtime structure before
* allocating the second object. Otherwise, a garbage
* collection might occur when the second object is
* allocated, invalidating the first pointer!
*
* TYPICAL PROBLEM SCENARIO:
*
* void yourNativeRoutineWrittenInC() {
*
* // Allocate 100 bytes from Java heap
* char* foo = mallocBytes(100);
*
* // Allocate another 100 bytes from Java heap
* char* bar = mallocBytes(100);
* ^
* +--- THE SECOND ALLOCATION ABOVE MAY CAUSE A
* GARBAGE COLLECTION TO OCCUR AND THEREFORE
* INVALIDATE 'foo' !!!
* }
*
*
* To verify that all the native functions have been
* written in a GC-safe way, you should try the mode
* EXCESSIVE_GARBAGE_COLLECTION on, and see if you
* encounter any problems. In that mode, the KVM will
* run very slowly, as it will do a full garbage collection
* upon every object allocation, but you are guaranteed
* to find the possible problems with missing temporary
* root operations.
*=======================================================================*/
#define MAXIMUM_TEMPORARY_ROOTS (128)
#define MAXIMUM_GLOBAL_ROOTS (20)
extern int TemporaryRootsLength;
extern int GlobalRootsLength;
extern union cellOrPointer TemporaryRoots[];
extern union cellOrPointer GlobalRoots[];
/* Handling of temporary roots */
#if INCLUDEDEBUGCODE
#define VERIFY_INSIDE_TEMPORARY_ROOTS (_tmp_roots_ = _tmp_roots_),
#define INDICATE_DYNAMICALLY_INSIDE_TEMPORARY_ROOTS int _tmp_roots_ = 0;
#define VERIFY_TEMPORARY_ROOT_SPACE(size) verifyTemporaryRootSpace(size),
void verifyTemporaryRootSpace(int size);
#else
#define VERIFY_INSIDE_TEMPORARY_ROOTS
#define INDICATE_DYNAMICALLY_INSIDE_TEMPORARY_ROOTS
#define VERIFY_TEMPORARY_ROOT_SPACE(size)
#endif /* INCLUDEDEBUGCODE */
#define START_TEMPORARY_ROOTS { int _tmp_roots_ = TemporaryRootsLength;
#define END_TEMPORARY_ROOTS TemporaryRootsLength = _tmp_roots_; }
#if INCLUDEDEBUGCODE
extern int NoAllocation;
#define ASSERTING_NO_ALLOCATION { NoAllocation++; {
#define END_ASSERTING_NO_ALLOCATION } NoAllocation--; }
#else
#define ASSERTING_NO_ALLOCATION {
#define END_ASSERTING_NO_ALLOCATION }
#endif /* INCLUDEDEBUGCODE */
void makeGlobalRoot(cell** object);
#define unhand(x) (*(x))
#define IS_TEMPORARY_ROOT(_var_, _value_) \
_var_ = (VERIFY_INSIDE_TEMPORARY_ROOTS \
_var_ = _value_, \
VERIFY_TEMPORARY_ROOT_SPACE(1) \
TemporaryRoots[TemporaryRootsLength++].cellp = (cell *)&_var_, \
_var_)
#define IS_TEMPORARY_ROOT_FROM_BASE(_var_, _value_, _base_) \
_var_ = (VERIFY_INSIDE_TEMPORARY_ROOTS \
VERIFY_TEMPORARY_ROOT_SPACE(3) \
_var_ = _value_, \
TemporaryRoots[TemporaryRootsLength].cell = -1, \
TemporaryRoots[TemporaryRootsLength+1].cellpp = (cell **)&_var_, \
TemporaryRoots[TemporaryRootsLength+2].cellp = (cell *)_base_, \
TemporaryRootsLength = TemporaryRootsLength + 3, \
_var_)
#define DECLARE_TEMPORARY_ROOT(_type_, _var_, _value_) \
_type_ IS_TEMPORARY_ROOT(_var_, _value_)
#define DECLARE_TEMPORARY_ROOT_FROM_BASE(_type_, _var_, _value_, _base_) \
_type_ IS_TEMPORARY_ROOT_FROM_BASE(_var_, _value_, _base_)
#define DECLARE_TEMPORARY_METHOD_ROOT(_var_, _table_, _index_) \
DECLARE_TEMPORARY_ROOT_FROM_BASE(METHOD, _var_, \
&_table_->methods[_index_], _table_)
#define DECLARE_TEMPORARY_FRAME_ROOT(_var_, _value_) \
DECLARE_TEMPORARY_ROOT_FROM_BASE(FRAME, _var_, _value_, _value_->stack)
/*=========================================================================
* Functions that are called only if you are using the
* JavaCodeCompact tool (a.k.a. romizer)
*=======================================================================*/
#if ROMIZING
/* Initialize the ROM image. Clean up the ROM image when you're done */
extern void InitializeROMImage(void);
extern void FinalizeROMImage(void);
/* The pointer to the all the static variables that need to be relocated.
* It's a pointer when using relocation rom, and an actual array when
* using fixed rom */
#if RELOCATABLE_ROM
extern long *KVM_staticDataPtr;
#else
extern long KVM_staticData[];
#endif
#else /* !ROMIZING */
#define InitializeROMImage()
#define FinalizeROMImage()
#endif /* ROMIZING */
/* This function creates the ROM image out of its relocatable pieces */
#if ROMIZING && RELOCATABLE_ROM
void CreateROMImage(void);
void DestroyROMImage(void);
#else
#define CreateROMImage()
#define DestroyROMImage()
#endif
/* When dealing with relocatable, preloaded classes, we can read preloaded
* memory directly, but we have to use special functions to write them.
*
* We must call the following functions when there is a chance that the
* object/class/method might be part of a preloaded class.
*/
#if ROMIZING && RELOCATABLE_ROM
void setClassInitialThread(INSTANCE_CLASS clazz, THREAD thread);
void setClassStatus(INSTANCE_CLASS clazz, int status);
void setBreakpoint(METHOD, long, char *, unsigned char);
#else
#define setClassInitialThread(iclazz, thread) \
((iclazz)->initThread = (thread))
#define setClassStatus(iclazz, stat) ((iclazz)->status = (stat))
#define setBreakpoint(method, offset, start, val) \
if (USESTATIC) { \
long offset1 = (char*)(&method->u.java.code[offset]) - start; \
modifyStaticMemory(start, offset1, &val, 1); \
} else { \
method->u.java.code[offset] = val; \
}
#endif
#if INCLUDEDEBUGCODE || RELOCATABLE_ROM
#if ROMIZING
extern bool_t isROMString(void *), isROMClass(void *), isROMMethod(void *);
#else
#define isROMClass(X) FALSE
#define isROMString(X) FALSE
#define isROMMethod(X) FALSE
#endif /* ROMIZING */
#endif
/*=========================================================================
* Stackmap-related operations
*=======================================================================*/
/* The following are defined in stackmap.c, but are really part of the
* garbage collection system.
*/
STACKMAP rewriteVerifierStackMapsAsPointerMaps(METHOD);
unsigned int getGCRegisterMask(METHOD, unsigned char *targetIP, char *map);
/*=========================================================================
* Native function cleanup registration
*=======================================================================*/
/*=========================================================================
* COMMENT:
* Since version 1.0.3, KVM garbage collector includes a special
* callback mechanism that allows each KVM port to register
* implementation-specific cleanup routines that get called
* automatically upon system exit (FinalizeMemoryManagement()).
* This mechanism can be used, e.g., for adding network or UI-widget
* cleanup routines to the system. For instance, all MIDP
* implementations typically need to take advantage of this
* feature.
*
* New callback routines are registered by calling the function
* 'registerCleanup' defined below.
*
* NOTE: In KVM 1.0.4 and 1.1, the types 'INSTANCE_HANDLE' and
* the KNI type 'jobject' are identical. Therefore, it is
* acceptable to use a jobject in these cleanup routines
* whenever an INSTANCE_HANDLE is required. In order to make
* the native finalization code more compliant with KNI, the
* callback routine now takes an INSTANCE_HANDLE parameter
* instead of INSTANCE (in KVM 1.0.3).
*=======================================================================*/
/* The function type of a cleanup callback function */
typedef void (*CleanupCallback)(INSTANCE_HANDLE);
/*
* Register a cleanup function for the instance.
* When the gc finds the object unreachable it will see if there is
* an associated cleanup function and if so will call it with the instance.
*/
extern void registerCleanup(INSTANCE_HANDLE, CleanupCallback);
/* The maximum number of callback functions that can be registered */
#ifndef CLEANUP_ROOT_SIZE
#define CLEANUP_ROOT_SIZE 16
#endif
/* The initial size of each cleanup array */
#ifndef CLEANUP_ARRAY_SIZE
#define CLEANUP_ARRAY_SIZE 3
#endif
#ifndef CLEANUP_ARRAY_GROW
#define CLEANUP_ARRAY_GROW 3
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -