Synopsis - Cross-Reference
File: /src/Synopsis/gc/MacOS.c1/* 2 MacOS.c 3 4 Some routines for the Macintosh OS port of the Hans-J. Boehm, Alan J. Demers 5 garbage collector. 6 7 <Revision History> 8 9 11/22/94 pcb StripAddress the temporary memory handle for 24-bit mode. 10 11/30/94 pcb Tracking all memory usage so we can deallocate it all at once. 11 02/10/96 pcb Added routine to perform a final collection when 12unloading shared library. 13 14 by Patrick C. Beard. 15 */ 16/* Boehm, February 15, 1996 2:55 pm PST */ 17 18#include <Resources.h> 19#include <Memory.h> 20#include <LowMem.h> 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24 25#include "gc.h" 26#include "gc_priv.h" 27 28// use 'CODE' resource 0 to get exact location of the beginning of global space. 29 30typedef struct { 31 unsigned long aboveA5; 32 unsigned long belowA5; 33 unsigned long JTSize; 34 unsigned long JTOffset; 35} *CodeZeroPtr, **CodeZeroHandle; 36 37void* GC_MacGetDataStart() 38{ 39 CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0); 40 if (code0) { 41 long belowA5Size = (**code0).belowA5; 42 ReleaseResource((Handle)code0); 43 return (LMGetCurrentA5() - belowA5Size); 44 } 45 fprintf(stderr, "Couldn't load the jump table."); 46 exit(-1); 47 return 0; 48} 49 50/* track the use of temporary memory so it can be freed all at once. */ 51 52typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle; 53 54struct TemporaryMemoryBlock { 55 TemporaryMemoryHandle nextBlock; 56 char data[]; 57}; 58 59static TemporaryMemoryHandle theTemporaryMemory = NULL; 60static Boolean firstTime = true; 61 62void GC_MacFreeTemporaryMemory(void); 63 64Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory) 65{ 66 static Boolean firstTime = true; 67 OSErr result; 68 TemporaryMemoryHandle tempMemBlock; 69 Ptr tempPtr = nil; 70 71 tempMemBlock = (TemporaryMemoryHandle)TempNewHandle(size + sizeof(TemporaryMemoryBlock), &result); 72 if (tempMemBlock && result == noErr) { 73 HLockHi((Handle)tempMemBlock); 74 tempPtr = (**tempMemBlock).data; 75 if (clearMemory) memset(tempPtr, 0, size); 76 tempPtr = StripAddress(tempPtr); 77 78 // keep track of the allocated blocks. 79 (**tempMemBlock).nextBlock = theTemporaryMemory; 80 theTemporaryMemory = tempMemBlock; 81 } 82 83# if !defined(SHARED_LIBRARY_BUILD) 84 // install an exit routine to clean up the memory used at the end. 85 if (firstTime) { 86 atexit(&GC_MacFreeTemporaryMemory); 87 firstTime = false; 88 } 89# endif 90 91 return tempPtr; 92} 93 94extern word GC_fo_entries; 95 96static void perform_final_collection() 97{ 98 unsigned i; 99 word last_fo_entries = 0; 100 101 /* adjust the stack bottom, because CFM calls us from another stack 102 location. */ 103 GC_stackbottom = (ptr_t)&i; 104 105 /* try to collect and finalize everything in sight */ 106 for (i = 0; i < 2 || GC_fo_entries < last_fo_entries; i++) { 107 last_fo_entries = GC_fo_entries; 108 GC_gcollect(); 109 } 110} 111 112 113void GC_MacFreeTemporaryMemory() 114{ 115# if defined(SHARED_LIBRARY_BUILD) 116 /* if possible, collect all memory, and invoke all finalizers. */ 117 perform_final_collection(); 118# endif 119 120 if (theTemporaryMemory != NULL) { 121 long totalMemoryUsed = 0; 122 TemporaryMemoryHandle tempMemBlock = theTemporaryMemory; 123 while (tempMemBlock != NULL) { 124 TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock; 125 totalMemoryUsed += GetHandleSize((Handle)tempMemBlock); 126 DisposeHandle((Handle)tempMemBlock); 127 tempMemBlock = nextBlock; 128 } 129 theTemporaryMemory = NULL; 130 131# if !defined(SHARED_LIBRARY_BUILD) 132 if (GC_print_stats) { 133 fprintf(stdout, "[total memory used: %ld bytes.]\n", 134 totalMemoryUsed); 135 fprintf(stdout, "[total collections: %ld.]\n", GC_gc_no); 136 } 137# endif 138 } 139} 140 141#if __option(far_data) 142 143 void* GC_MacGetDataEnd() 144 { 145 CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0); 146 if (code0) { 147 long aboveA5Size = (**code0).aboveA5; 148 ReleaseResource((Handle)code0); 149 return (LMGetCurrentA5() + aboveA5Size); 150 } 151 fprintf(stderr, "Couldn't load the jump table."); 152 exit(-1); 153 return 0; 154 } 155 156#endif /* __option(far_data) */