| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #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 |
| |
|