123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- /*
- 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) */
|