Initial revision
This commit is contained in:
154
gc/MacOS.c
Normal file
154
gc/MacOS.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
MacOS.c
|
||||
|
||||
Some routines for the Macintosh OS port of the Hans-J. Boehm, Alan J. Demers
|
||||
garbage collector.
|
||||
|
||||
<Revision History>
|
||||
|
||||
11/22/94 pcb StripAddress the temporary memory handle for 24-bit mode.
|
||||
11/30/94 pcb Tracking all memory usage so we can deallocate it all at once.
|
||||
02/10/96 pcb Added routine to perform a final collection when
|
||||
unloading shared library.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
/* Boehm, February 15, 1996 2:55 pm PST */
|
||||
|
||||
#include <Resources.h>
|
||||
#include <Memory.h>
|
||||
#include <LowMem.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gc.h"
|
||||
#include "gc_priv.h"
|
||||
|
||||
// use 'CODE' resource 0 to get exact location of the beginning of global space.
|
||||
|
||||
typedef struct {
|
||||
unsigned long aboveA5;
|
||||
unsigned long belowA5;
|
||||
unsigned long JTSize;
|
||||
unsigned long JTOffset;
|
||||
} *CodeZeroPtr, **CodeZeroHandle;
|
||||
|
||||
void* GC_MacGetDataStart()
|
||||
{
|
||||
CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
|
||||
if (code0) {
|
||||
long belowA5Size = (**code0).belowA5;
|
||||
ReleaseResource((Handle)code0);
|
||||
return (LMGetCurrentA5() - belowA5Size);
|
||||
}
|
||||
fprintf(stderr, "Couldn't load the jump table.");
|
||||
exit(-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* track the use of temporary memory so it can be freed all at once. */
|
||||
|
||||
typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle;
|
||||
|
||||
struct TemporaryMemoryBlock {
|
||||
TemporaryMemoryHandle nextBlock;
|
||||
char data[];
|
||||
};
|
||||
|
||||
static TemporaryMemoryHandle theTemporaryMemory = NULL;
|
||||
static Boolean firstTime = true;
|
||||
|
||||
void GC_MacFreeTemporaryMemory(void);
|
||||
|
||||
Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory)
|
||||
{
|
||||
static Boolean firstTime = true;
|
||||
OSErr result;
|
||||
TemporaryMemoryHandle tempMemBlock;
|
||||
Ptr tempPtr = nil;
|
||||
|
||||
tempMemBlock = (TemporaryMemoryHandle)TempNewHandle(size + sizeof(TemporaryMemoryBlock), &result);
|
||||
if (tempMemBlock && result == noErr) {
|
||||
HLockHi((Handle)tempMemBlock);
|
||||
tempPtr = (**tempMemBlock).data;
|
||||
if (clearMemory) memset(tempPtr, 0, size);
|
||||
tempPtr = StripAddress(tempPtr);
|
||||
|
||||
// keep track of the allocated blocks.
|
||||
(**tempMemBlock).nextBlock = theTemporaryMemory;
|
||||
theTemporaryMemory = tempMemBlock;
|
||||
}
|
||||
|
||||
# if !defined(SHARED_LIBRARY_BUILD)
|
||||
// install an exit routine to clean up the memory used at the end.
|
||||
if (firstTime) {
|
||||
atexit(&GC_MacFreeTemporaryMemory);
|
||||
firstTime = false;
|
||||
}
|
||||
# endif
|
||||
|
||||
return tempPtr;
|
||||
}
|
||||
|
||||
extern word GC_fo_entries;
|
||||
|
||||
static void perform_final_collection()
|
||||
{
|
||||
unsigned i;
|
||||
word last_fo_entries = 0;
|
||||
|
||||
/* adjust the stack bottom, because CFM calls us from another stack
|
||||
location. */
|
||||
GC_stackbottom = (ptr_t)&i;
|
||||
|
||||
/* try to collect and finalize everything in sight */
|
||||
for (i = 0; i < 2 || GC_fo_entries < last_fo_entries; i++) {
|
||||
last_fo_entries = GC_fo_entries;
|
||||
GC_gcollect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GC_MacFreeTemporaryMemory()
|
||||
{
|
||||
# if defined(SHARED_LIBRARY_BUILD)
|
||||
/* if possible, collect all memory, and invoke all finalizers. */
|
||||
perform_final_collection();
|
||||
# endif
|
||||
|
||||
if (theTemporaryMemory != NULL) {
|
||||
long totalMemoryUsed = 0;
|
||||
TemporaryMemoryHandle tempMemBlock = theTemporaryMemory;
|
||||
while (tempMemBlock != NULL) {
|
||||
TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock;
|
||||
totalMemoryUsed += GetHandleSize((Handle)tempMemBlock);
|
||||
DisposeHandle((Handle)tempMemBlock);
|
||||
tempMemBlock = nextBlock;
|
||||
}
|
||||
theTemporaryMemory = NULL;
|
||||
|
||||
# if !defined(SILENT) && !defined(SHARED_LIBRARY_BUILD)
|
||||
fprintf(stdout, "[total memory used: %ld bytes.]\n",
|
||||
totalMemoryUsed);
|
||||
fprintf(stdout, "[total collections: %ld.]\n", GC_gc_no);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
#if __option(far_data)
|
||||
|
||||
void* GC_MacGetDataEnd()
|
||||
{
|
||||
CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
|
||||
if (code0) {
|
||||
long aboveA5Size = (**code0).aboveA5;
|
||||
ReleaseResource((Handle)code0);
|
||||
return (LMGetCurrentA5() + aboveA5Size);
|
||||
}
|
||||
fprintf(stderr, "Couldn't load the jump table.");
|
||||
exit(-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __option(far_data) */
|
||||
Reference in New Issue
Block a user