DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Untracked file

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
/*
	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"

void GC_init_MacOS()
{
    int i;
    
    MaxApplZone();
    for (i = 0; i < 8; ++i)
        MoreMasters();
}

// 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
    }
}