Synopsis - Cross-Reference

File: /src/Synopsis/gc/MacOS.c
  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
 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) */