home *** CD-ROM | disk | FTP | other *** search
/ BMUG PD-ROM 1995 Fall / PD-ROM F95.toast / Programming / Programming Languages / UCB Logo 3.0 ƒ / sources / standard source / mem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-14  |  4.5 KB  |  217 lines  |  [TEXT/ttxt]

  1. /*
  2.  *      mem.c           logo memory management module           dvb 6/28/88
  3.  *
  4.  *    Copyright (C) 1993 by the Regents of the University of California
  5.  *
  6.  *      This program is free software; you can redistribute it and/or modify
  7.  *      it under the terms of the GNU General Public License as published by
  8.  *      the Free Software Foundation; either version 2 of the License, or
  9.  *      (at your option) any later version.
  10.  *  
  11.  *      This program is distributed in the hope that it will be useful,
  12.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *      GNU General Public License for more details.
  15.  *  
  16.  *      You should have received a copy of the GNU General Public License
  17.  *      along with this program; if not, write to the Free Software
  18.  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include "logo.h"
  22. #include "globals.h"
  23. #ifdef ibm
  24. #ifndef __ZTC__
  25. #include <alloc.h>
  26. #endif
  27. #endif
  28.  
  29. NODE *free_list = NIL;                /* global ptr to free node list */
  30. struct segment *segment_list = NULL;  /* global ptr to segment list */
  31.  
  32. #ifdef PUNY
  33. #define GCMAX 1000
  34. #else
  35. #ifdef THINK_C
  36. #define GCMAX 8000
  37. #else
  38. #ifdef __ZTC__
  39. #define GCMAX 6000
  40. #else
  41. #define GCMAX 16000
  42. #endif
  43. #endif
  44. #endif
  45.  
  46. #ifdef THINK_C
  47. extern NODE *gcstack[];
  48. #else
  49. NODE *gcstack[GCMAX];
  50. #endif
  51.  
  52. #ifdef MEM_DEBUG
  53. long int mem_allocated = 0, mem_freed = 0;
  54. #endif
  55.  
  56. NODE **gctop = gcstack;
  57.  
  58. NODETYPES nodetype(NODE *nd)
  59. {
  60.     if (nd == NIL) return (PNIL);
  61.     return((NODETYPES)nd->node_type);
  62. }
  63.  
  64. void setobject(NODE *nd, NODE *newobj)
  65. {
  66.     NODE *oldobj = getobject(nd);
  67.  
  68.     if (newobj != NIL) increfcnt(newobj);
  69.     if (oldobj != NIL && decrefcnt(oldobj) == 0)
  70.     gc(oldobj);
  71.     nd->n_obj = newobj;
  72. }
  73.  
  74. void setcar(NODE *nd, NODE *newcar)
  75. {
  76.     NODE *oldcar = car(nd);
  77.  
  78.     if (newcar != NIL) increfcnt(newcar);
  79.     if (oldcar != NIL && decrefcnt(oldcar) == 0)
  80.     gc(oldcar);
  81.     nd->n_car = newcar;
  82. }
  83.  
  84. void setcdr(NODE *nd, NODE *newcdr)
  85. {
  86.     NODE *oldcdr = cdr(nd);
  87.  
  88.     if (newcdr != NIL) increfcnt(newcdr);
  89.     if (oldcdr != NIL && decrefcnt(oldcdr) == 0)
  90.     gc(oldcdr);
  91.     nd->n_cdr = newcdr;
  92. }
  93.  
  94. NODE *_reref(NODE *proc_var, NODE *newval)
  95. {
  96.     if (newval != NIL) increfcnt(newval);
  97.     if (proc_var != NIL && decrefcnt(proc_var) == 0)
  98.     gc(proc_var);
  99.     return(newval);
  100. }
  101.  
  102. NODE *unref(NODE *ret_var)
  103. {
  104.     if (ret_var != NIL) decrefcnt(ret_var);
  105.     return(ret_var);
  106. }
  107.  
  108. void addseg()
  109. {
  110.     int p;
  111.     struct segment *newseg;
  112.  
  113.     if ((newseg = (struct segment *) malloc((size_t)sizeof(struct segment)))
  114.         != NULL) {
  115.     newseg->next = segment_list;
  116.     segment_list = newseg;
  117.     for (p = 0; p < SEG_SIZE; p++) {
  118.         newseg->nodes[p].n_cdr = free_list;
  119.         free_list = &newseg->nodes[p];
  120.     }
  121.     }
  122. }
  123.  
  124. NODE *newnode(NODETYPES type)
  125. {
  126.     NODE *newnd;
  127.  
  128.     if ((newnd = free_list) == NIL) {
  129.     addseg();
  130.     if ((newnd = free_list) == NIL)
  131.         err_logo(OUT_OF_MEM, NIL);
  132.     }
  133.     free_list = cdr(newnd);
  134.     settype(newnd, type);
  135.     setrefcnt(newnd, 0);
  136.     newnd->n_car = NIL;
  137.     newnd->n_cdr = NIL;
  138.     newnd->n_obj = NIL;
  139. #ifdef MEM_DEBUG
  140.     mem_allocated++;
  141. #endif
  142.     return(newnd);
  143. }
  144.  
  145. NODE *cons(NODE *x, NODE *y)
  146. {
  147.     NODE *val = newnode(CONS);
  148.  
  149.     setcar(val, x);
  150.     setcdr(val, y);
  151.     return(val);
  152. }
  153.  
  154. void gc(NODE *nd)
  155. {
  156.     NODE *tcar, *tcdr, *tobj;
  157.     int i;
  158.     NODE **pp;
  159.  
  160.     for (;;) {
  161.     switch (nodetype(nd)) {
  162.         case PUNBOUND:
  163.         setrefcnt(nd,10000);    /* save some time */
  164.         case PNIL:
  165.         if (gctop == gcstack) return;
  166.         nd = *--gctop;
  167.         continue;
  168.         case LINE:
  169.         nd->n_obj = NIL;
  170.         case CONS:
  171.         case CASEOBJ:
  172.         case RUN_PARSE:
  173.         case QUOTE:
  174.         case COLON:
  175.         case TREE:
  176.         case CONT:
  177.         tcdr = cdr(nd);
  178.         tcar = car(nd);
  179.         tobj = getobject(nd);
  180.         break;
  181.         case ARRAY:
  182.         pp = getarrptr(nd);
  183.         i = getarrdim(nd);
  184.         while (--i >= 0) {
  185.             tobj = *pp++;
  186.             deref(tobj);
  187.         }
  188.         free((char *)getarrptr(nd));
  189.         tcar = tcdr = tobj = NIL;
  190.         break;
  191.         case STRING:
  192.         case BACKSLASH_STRING:
  193.         case VBAR_STRING:
  194.         if (getstrhead(nd) != NULL && decstrrefcnt(getstrhead(nd)) == 0)
  195.             free(getstrhead(nd));
  196.         default:
  197.         tcar = tcdr = tobj = NIL;
  198.     }
  199.     nd->n_cdr = free_list;
  200.     free_list = nd;
  201. #ifdef MEM_DEBUG
  202.     mem_freed++;
  203. #endif
  204.     if (tcdr != NIL && decrefcnt(tcdr) == 0)
  205.         if (gctop < &gcstack[GCMAX])
  206.         *gctop++ = tcdr;
  207.     if (tcar != NIL && decrefcnt(tcar) == 0)
  208.         if (gctop < &gcstack[GCMAX])
  209.         *gctop++ = tcar;
  210.     if (tobj != NIL && decrefcnt(tobj) == 0)
  211.         if (gctop < &gcstack[GCMAX])
  212.         *gctop++ = tobj;
  213.     if (gctop == gcstack) return;
  214.     nd = *--gctop;
  215.     }
  216. }
  217.