home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1997: The Complete Utilities Toolkit / macworld-complete-utilities-1997.iso / Programming / Little Smalltalk v3.1.5 / C Source / Headers / memory.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-06  |  6.0 KB  |  194 lines  |  [TEXT/KAHL]

  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 - JRB) 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 13000
  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. #ifndef THINKC
  76. extern object allocObject( INT );
  77. extern object allocByte( INT );
  78. extern object allocStr( STR );
  79. #endif
  80.  
  81. /*
  82.     integer objects are (but need not be) treated specially.
  83. In this memory manager, negative integers are just left as is, but
  84. positive integers are changed to x*2+1.  Either a negative or an odd
  85. number is therefore an integer, while a nonzero even number is an
  86. object pointer (multiplied by two).  Zero is reserved for the object ``nil''
  87. Since newInteger does not fill in the class field, it can be given here.
  88. If it was required to use the class field, it would have to be deferred
  89. until names.h
  90. */
  91.  
  92. extern object intobj;
  93. # define isInteger(x) ((x) & 0x8001)
  94. # define newInteger(x) ( (intobj = x)<0 ? intobj : (intobj<<1)+1 )
  95. # define intValue(x) ( (intobj = x)<0 ? intobj : (intobj>>1) )
  96.  
  97. /*
  98.     there are four routines used to access fields within an object.
  99. Again, some of these could be replaced by macros, for efficiency
  100.     basicAt(x, i) - ith field (start at 1) of object x
  101.     basicAtPut(x, i, v) - put value v in object x
  102.     byteAt(x, i) - ith field (start at 0) of object x
  103.     byteAtPut(x, i, v) - put value v in object x*/
  104.  
  105. # define basicAt(x,i) (sysMemPtr(x)[i-1])
  106. # define byteAt(x, i) ((int) ((bytePtr(x)[i-1])))
  107.  
  108. # ifndef basicAt
  109. extern object basicAt(OBJ X INT);
  110. # endif
  111.  
  112. # define simpleAtPut(x,i,y) (sysMemPtr(x)[i-1] = y)
  113. # ifndef simpleAtPut
  114. extern void simpleAtPut(OBJ X INT X OBJ);
  115. # endif
  116.  
  117. # define basicAtPut(x,i,y) incr(simpleAtPut(x, i, y))
  118. # ifndef basicAtPut
  119. extern void basicAtPut(OBJ X INT X OBJ);
  120. # endif
  121. # define fieldAtPut(x,i,y) f_i=i; decr(basicAt(x,f_i)); basicAtPut(x,f_i,y)
  122. # ifdef fieldAtPut
  123. extern int f_i;
  124. #endif
  125. # ifndef fieldAtPut
  126. extern void fieldAtPut(OBJ X INT X OBJ);
  127. # endif
  128.  
  129. # ifndef byteAt
  130. extern int byteAt(OBJ X INT);
  131. # endif
  132.  
  133. #ifndef THINKC
  134. # ifndef byteAtPut
  135. extern void byteAtPut(OBJ X INT X INT);
  136. # endif
  137. #endif
  138. /*
  139.     Finally, a few routines (or macros) are used to access or set
  140. class fields and size fields of objects
  141. */
  142.  
  143. # define classField(x) objectTable[x>>1].class
  144. # define setClass(x,y) incr(classField(x)=y)
  145. # define sizeField(x) objectTable[x>>1].size
  146.  
  147. # define sysMemPtr(x) objectTable[x>>1].memory
  148. extern object sysobj;
  149. # define memoryPtr(x) (isInteger(sysobj = x)?(object *) 0:sysMemPtr(sysobj))
  150. # define bytePtr(x) ((byte *) memoryPtr(x))
  151. # define charPtr(x) ((char *) memoryPtr(x))
  152.  
  153. # define nilobj (object) 0
  154.  
  155. /*
  156.     There is a large amount of differences in the qualities of malloc
  157.     procedures in the Unix world.  Some perform very badly when asked
  158.     to allocate thousands of very small memory blocks, while others
  159.     take this without any difficulty.  The routine mBlockAlloc is used
  160.     to allocate a small bit of memory; the version given below
  161.     allocates a large block and then chops it up as needed; if desired,
  162.     for versions of malloc that can handle small blocks with ease
  163.     this can be replaced using the following macro: 
  164.  
  165. # define mBlockAlloc(size) (object *) calloc((unsigned) size, sizeof(object))
  166.  
  167.     This can, and should, be replaced by a better memory management
  168.     algorithm.
  169. */
  170. #ifndef THINKC
  171. # ifndef mBlockAlloc
  172. extern object *mBlockAlloc(INT);
  173. # endif
  174. #endif
  175.  
  176. /*
  177.     the dictionary symbols is the source of all symbols in the system
  178. */
  179. extern object symbols;
  180.  
  181. /*
  182.     finally some external declarations with prototypes
  183. */
  184. #ifndef THINKC
  185. extern noreturn sysError(STR X STR);
  186. extern noreturn dspMethod(STR X STR);
  187. extern noreturn initMemoryManager(NOARGS);
  188. extern noreturn imageWrite(FILEP);
  189. extern noreturn imageRead(FILEP);
  190. #endif
  191.  
  192. extern boolean debugging;
  193.  
  194.