home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / RiscOS / APP / DEVS / SMALLT / LITTLS.ZIP / !LittleST / h / MEMORY < prev    next >
Text File  |  1989-03-02  |  6KB  |  184 lines

  1. /*
  2.     Little Smalltalk, version 2
  3.     Written by Tim Budd, Oregon State University, July 1987
  4. */
  5.  
  6. /*
  7.     The first major decision to be made in the memory manager is what
  8. an entity of type object really is.  Two obvious choices are a pointer (to 
  9. the actual object memory) or an index into an object table.  We decided to
  10. use the latter, although either would work.
  11.     Similarly, one can either define the token object using a typedef,
  12. or using a define statement.  Either one will work (check this?)
  13. */
  14.  
  15. typedef short object;
  16.  
  17. /*
  18.     The memory module itself is defined by over a dozen routines.
  19. All of these could be defined by procedures, and indeed this was originally
  20. done.  However, for efficiency reasons, many of these procedures can be
  21. replaced by macros generating in-line code.  For the latter approach
  22. to work, the structure of the object table must be known.  For this reason,
  23. it is given here.  Note, however, that outside of the files memory.c and
  24. unixio.c (or macio.c on the macintosh) ONLY the macros described in this
  25. file make use of this structure: therefore modifications or even complete
  26. replacement is possible as long as the interface remains consistent
  27. */
  28.  
  29. struct objectStruct {
  30.     object class;
  31.     short referenceCount;
  32.     short size;
  33.     object *memory;
  34.     };
  35. # define ObjectTableMax 6500
  36.  
  37. # ifdef obtalloc
  38. extern struct objectStruct *objectTable;
  39. # endif
  40. # ifndef obtalloc
  41. extern struct objectStruct objectTable[];
  42. # endif
  43.  
  44. /*
  45.     The most basic routines to the memory manager are incr and decr,
  46. which increment and decrement reference counts in objects.  By separating
  47. decrement from memory freeing, we could replace these as procedure calls
  48. by using the following macros (thereby saving procedure calls):*/
  49. extern object incrobj;
  50. # define incr(x) if ((incrobj=(x))&&!isInteger(incrobj)) \
  51. objectTable[incrobj>>1].referenceCount++
  52. #  define decr(x) if (((incrobj=(x))&&!isInteger(incrobj))&&\
  53. (--objectTable[incrobj>>1].referenceCount<=0)) sysDecr(incrobj);
  54. /*
  55. notice that the argument x is first assigned to a global variable; this is
  56. in case evaluation of x results in side effects (such as assignment) which
  57. should not be repeated. */
  58.  
  59. # ifndef incr
  60. extern void incr( OBJ );
  61. # endif
  62. # ifndef decr
  63. extern void decr( OBJ );
  64. # endif
  65.  
  66. /*
  67.     The next most basic routines in the memory module are those that
  68. allocate blocks of storage.  There are three routines:
  69.     allocObject(size) - allocate an array of objects
  70.     allocByte(size) - allocate an array of bytes
  71.     allocStr(str) - allocate a string and fill it in
  72. again, these may be macros, or they may be actual procedure calls
  73. */
  74.  
  75. extern object allocObject( INT );
  76. extern object allocByte( INT );
  77. extern object allocStr( STR );
  78.  
  79. /*
  80.     integer objects are (but need not be) treated specially.
  81. In this memory manager, negative integers are just left as is, but
  82. positive integers are changed to x*2+1.  Either a negative or an odd
  83. number is therefore an integer, while a nonzero even number is an
  84. object pointer (multiplied by two).  Zero is reserved for the object ``nil''
  85. Since newInteger does not fill in the class field, it can be given here.
  86. If it was required to use the class field, it would have to be deferred
  87. until names.h
  88. */
  89.  
  90. extern object intobj;
  91. # define isInteger(x) ((x) & 0x8001)
  92. # define newInteger(x) ( (intobj = x)<0 ? intobj : (intobj<<1)+1 )
  93. # define intValue(x) ( (intobj = x)<0 ? intobj : (intobj>>1) )
  94.  
  95. /*
  96.     there are four routines used to access fields within an object.
  97. Again, some of these could be replaced by macros, for efficiency
  98.     basicAt(x, i) - ith field (start at 1) of object x
  99.     basicAtPut(x, i, v) - put value v in object x
  100.     byteAt(x, i) - ith field (start at 0) of object x
  101.     byteAtPut(x, i, v) - put value v in object x*/
  102.  
  103. # define basicAt(x,i) (sysMemPtr(x)[i-1])
  104. # define byteAt(x, i) ((int) ((bytePtr(x)[i-1])))
  105.  
  106. # ifndef basicAt
  107. extern object basicAt(OBJ X INT);
  108. # endif
  109.  
  110. # define simpleAtPut(x,i,y) (sysMemPtr(x)[i-1] = y)
  111. # ifndef simpleAtPut
  112. extern void simpleAtPut(OBJ X INT X OBJ);
  113. # endif
  114.  
  115. # define basicAtPut(x,i,y) incr(simpleAtPut(x, i, y))
  116. # ifndef basicAtPut
  117. extern void basicAtPut(OBJ X INT X OBJ);
  118. # endif
  119. # define fieldAtPut(x,i,y) f_i=i; decr(basicAt(x,f_i)); basicAtPut(x,f_i,y)
  120. # ifdef fieldAtPut
  121. extern int f_i;
  122. #endif
  123. # ifndef fieldAtPut
  124. extern void fieldAtPut(OBJ X INT X OBJ);
  125. # endif
  126.  
  127. # ifndef byteAt
  128. extern int byteAt(OBJ X INT);
  129. # endif
  130. # ifndef byteAtPut
  131. extern void byteAtPut(OBJ X INT X INT);
  132. # endif
  133.  
  134. /*
  135.     Finally, a few routines (or macros) are used to access or set
  136. class fields and size fields of objects
  137. */
  138.  
  139. # define classField(x) objectTable[x>>1].class
  140. # define setClass(x,y) incr(classField(x)=y)
  141. # define sizeField(x) objectTable[x>>1].size
  142.  
  143. # define sysMemPtr(x) objectTable[x>>1].memory
  144. extern object sysobj;
  145. # define memoryPtr(x) (isInteger(sysobj = x)?(object *) 0:sysMemPtr(sysobj))
  146. # define bytePtr(x) ((byte *) memoryPtr(x))
  147. # define charPtr(x) ((char *) memoryPtr(x))
  148.  
  149. # define nilobj (object) 0
  150.  
  151. /*
  152.     There is a large amount of differences in the qualities of malloc
  153.     procedures in the Unix world.  Some perform very badly when asked
  154.     to allocate thousands of very small memory blocks, while others
  155.     take this without any difficulty.  The routine mBlockAlloc is used
  156.     to allocate a small bit of memory; the version given below
  157.     allocates a large block and then chops it up as needed; if desired,
  158.     for versions of malloc that can handle small blocks with ease
  159.     this can be replaced using the following macro: 
  160.  
  161. # define mBlockAlloc(size) (object *) calloc((unsigned) size, sizeof(object))
  162.  
  163.     This can, and should, be replaced by a better memory management
  164.     algorithm.
  165. */
  166. # ifndef mBlockAlloc
  167. extern object *mBlockAlloc(INT);
  168. # endif
  169.  
  170. /*
  171.     the dictionary symbols is the source of all symbols in the system
  172. */
  173. extern object symbols;
  174.  
  175. /*
  176.     finally some external declarations with prototypes
  177. */
  178. extern noreturn sysError(STR X STR);
  179. extern noreturn dspMethod(STR X STR);
  180. extern noreturn initMemoryManager(NOARGS);
  181. extern noreturn imageWrite(FILEP);
  182. extern noreturn imageRead(FILEP);
  183. extern boolean debugging;
  184.