|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#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" |
|
|
|
|
|
|
|
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; |
|
} |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
(**tempMemBlock).nextBlock = theTemporaryMemory; |
|
theTemporaryMemory = tempMemBlock; |
|
} |
|
|
|
# if !defined(SHARED_LIBRARY_BUILD) |
|
|
|
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; |
|
|
|
|
|
|
|
GC_stackbottom = (ptr_t)&i; |
|
|
|
|
|
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) |
|
|
|
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(SHARED_LIBRARY_BUILD) |
|
if (GC_print_stats) { |
|
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 |
|
|