summaryrefslogtreecommitdiff
path: root/graphics/asymptote/gc/extra/MacOS.c
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/asymptote/gc/extra/MacOS.c')
-rw-r--r--graphics/asymptote/gc/extra/MacOS.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/graphics/asymptote/gc/extra/MacOS.c b/graphics/asymptote/gc/extra/MacOS.c
new file mode 100644
index 0000000000..082ee6ed7c
--- /dev/null
+++ b/graphics/asymptote/gc/extra/MacOS.c
@@ -0,0 +1,169 @@
+/*
+ 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>
+
+#define GC_BUILD
+#include "gc.h"
+#include "private/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(void)
+{
+ 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);
+# if !defined(CPPCHECK)
+ return 0; /* to avoid compiler complain about missing return */
+# endif
+}
+
+#ifdef USE_TEMPORARY_MEMORY
+
+/* 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;
+
+void GC_MacFreeTemporaryMemory(void);
+
+Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory)
+{
+# if !defined(SHARED_LIBRARY_BUILD)
+ static Boolean firstTime = true;
+# endif
+ 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;
+}
+
+static void perform_final_collection(void)
+{
+ 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(void)
+{
+# if defined(SHARED_LIBRARY_BUILD)
+ /* if possible, collect all memory, and invoke all finalizers. */
+ perform_final_collection();
+# endif
+
+ if (theTemporaryMemory != NULL) {
+# if !defined(SHARED_LIBRARY_BUILD)
+ long totalMemoryUsed = 0;
+# endif
+ TemporaryMemoryHandle tempMemBlock = theTemporaryMemory;
+ while (tempMemBlock /* != NULL */) {
+ TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock;
+# if !defined(SHARED_LIBRARY_BUILD)
+ totalMemoryUsed += GetHandleSize((Handle)tempMemBlock);
+# endif
+ DisposeHandle((Handle)tempMemBlock);
+ tempMemBlock = nextBlock;
+ }
+ theTemporaryMemory = NULL;
+
+# if !defined(SHARED_LIBRARY_BUILD)
+ if (GC_print_stats) {
+ fprintf(stdout, "[total memory used: %ld bytes.]\n",
+ totalMemoryUsed);
+ fprintf(stdout, "[total collections: %lu]\n",
+ (unsigned long)GC_gc_no);
+ }
+# endif
+ }
+}
+
+#endif /* USE_TEMPORARY_MEMORY */
+
+#if __option(far_data)
+
+ void* GC_MacGetDataEnd(void)
+ {
+ 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);
+# if !defined(CPPCHECK)
+ return 0;
+# endif
+ }
+
+#endif /* __option(far_data) */