root/gc/MacOS.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. CodeZeroPtr
  2. CodeZeroHandle
  3. GC_MacGetDataStart
  4. GC_MacTemporaryNewPtr
  5. perform_final_collection
  6. GC_MacFreeTemporaryMemory
  7. GC_MacGetDataEnd

   1 /*
   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
  12 unloading 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 
  30 typedef struct {
  31         unsigned long aboveA5;
  32         unsigned long belowA5;
  33         unsigned long JTSize;
  34         unsigned long JTOffset;
  35 } *CodeZeroPtr, **CodeZeroHandle;
  36 
  37 void* 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 
  52 typedef struct TemporaryMemoryBlock TemporaryMemoryBlock, **TemporaryMemoryHandle;
  53 
  54 struct TemporaryMemoryBlock {
  55         TemporaryMemoryHandle nextBlock;
  56         char data[];
  57 };
  58 
  59 static TemporaryMemoryHandle theTemporaryMemory = NULL;
  60 static Boolean firstTime = true;
  61 
  62 void GC_MacFreeTemporaryMemory(void);
  63 
  64 Ptr 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 
  94 extern word GC_fo_entries; 
  95 
  96 static 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 
 113 void 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(SILENT) && !defined(SHARED_LIBRARY_BUILD)
 132           fprintf(stdout, "[total memory used:  %ld bytes.]\n",
 133                   totalMemoryUsed);
 134           fprintf(stdout, "[total collections:  %ld.]\n", GC_gc_no);
 135 #       endif
 136     }
 137 }
 138 
 139 #if __option(far_data)
 140 
 141   void* GC_MacGetDataEnd()
 142   {
 143         CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0);
 144         if (code0) {
 145                 long aboveA5Size = (**code0).aboveA5;
 146                 ReleaseResource((Handle)code0);
 147                 return (LMGetCurrentA5() + aboveA5Size);
 148         }
 149         fprintf(stderr, "Couldn't load the jump table.");
 150         exit(-1);
 151         return 0;
 152   }
 153 
 154 #endif /* __option(far_data) */

/* [<][>][^][v][top][bottom][index][help] */