alloc.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. * Author: Hans van Staveren
  6. */
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include "param.h"
  11. #include "types.h"
  12. #include "tes.h"
  13. #include "assert.h"
  14. #include "alloc.h"
  15. #include "line.h"
  16. #include "lookup.h"
  17. #include "proinf.h"
  18. #include "util.h"
  19. #ifdef USEMALLOC
  20. short *myalloc(int size);
  21. #define newcore(size) myalloc(size)
  22. #define oldcore(p,size) free(p)
  23. #else
  24. #undef CORECHECK /* if defined tests are made to insure
  25. each block occurs at most once */
  26. #define CCHUNK 1024 /* number of shorts asked from system */
  27. short *newcore(int size);
  28. //short *freshcore();
  29. #ifdef COREDEBUG
  30. int shortsasked=0;
  31. #endif
  32. #endif
  33. /*
  34. * The following two sizetables contain the sizes of the various kinds
  35. * of line and argument structures.
  36. * Care has been taken to make this table implementation independent,
  37. * but if you think very hard you might find a compiler failing the
  38. * assumptions made.
  39. * A wasteful but safe approach is to replace every line of them by
  40. * sizeof(line_t)
  41. * and
  42. * sizeof(arg_t)
  43. * respectively.
  44. */
  45. #define LBASE (sizeof(line_t)-sizeof(un_l_a))
  46. int lsizetab[] = {
  47. LBASE,
  48. LBASE+sizeof(short),
  49. LBASE+sizeof(offset),
  50. LBASE+sizeof(num_p),
  51. LBASE+sizeof(sym_p),
  52. LBASE+sizeof(s_la_sval),
  53. LBASE+sizeof(s_la_lval),
  54. LBASE+sizeof(arg_p),
  55. LBASE
  56. };
  57. #define ABASE (sizeof(arg_t)-sizeof(un_a_a))
  58. int asizetab[] = {
  59. ABASE+sizeof(offset),
  60. ABASE+sizeof(num_p),
  61. ABASE+sizeof(sym_p),
  62. ABASE+sizeof(s_a_val),
  63. ABASE+sizeof(argb_t),
  64. ABASE+sizeof(s_a_con),
  65. ABASE+sizeof(s_a_con),
  66. ABASE+sizeof(s_a_con),
  67. };
  68. void oldline(line_p lnp);
  69. void oldargb(argb_p abp);
  70. void oldreg(reg_p rp);
  71. void oldargs(arg_p ap);
  72. /*
  73. * alloc routines:
  74. * Two parts:
  75. * 1) typed alloc and free routines
  76. * 2) untyped raw core allocation
  77. */
  78. /*
  79. * PART 1
  80. */
  81. line_p newline(int optyp)
  82. {
  83. line_p lnp;
  84. int kind=optyp;
  85. if (kind>OPMINI)
  86. kind = OPMINI;
  87. lnp = (line_p) newcore(lsizetab[kind]);
  88. lnp->l_optyp = optyp;
  89. return(lnp);
  90. }
  91. void oldline(line_p lnp)
  92. {
  93. int kind=lnp->l_optyp&BMASK;
  94. if (kind>OPMINI)
  95. kind = OPMINI;
  96. if (kind == OPLIST)
  97. oldargs(lnp->l_a.la_arg);
  98. oldcore((short *) lnp,lsizetab[kind]);
  99. }
  100. arg_p newarg(int kind)
  101. {
  102. arg_p ap;
  103. ap = (arg_p) newcore(asizetab[kind]);
  104. ap->a_typ = kind;
  105. return(ap);
  106. }
  107. void oldargs(arg_p ap)
  108. {
  109. arg_p next;
  110. while (ap != (arg_p) 0) {
  111. next = ap->a_next;
  112. switch(ap->a_typ) {
  113. case ARGSTR:
  114. oldargb(ap->a_a.a_string.ab_next);
  115. break;
  116. case ARGICN:
  117. case ARGUCN:
  118. case ARGFCN:
  119. oldargb(ap->a_a.a_con.ac_con.ab_next);
  120. break;
  121. }
  122. oldcore((short *) ap,asizetab[ap->a_typ]);
  123. ap = next;
  124. }
  125. }
  126. void oldargb(argb_p abp)
  127. {
  128. argb_p next;
  129. while (abp != (argb_p) 0) {
  130. next = abp->ab_next;
  131. oldcore((short *) abp,sizeof (argb_t));
  132. abp = next;
  133. }
  134. }
  135. reg_p newreg()
  136. {
  137. return((reg_p) newcore(sizeof(reg_t)));
  138. }
  139. void oldreg(reg_p rp)
  140. {
  141. oldcore((short *) rp,sizeof(reg_t));
  142. }
  143. num_p newnum() {
  144. return((num_p) newcore(sizeof(num_t)));
  145. }
  146. void oldnum(num_p lp)
  147. {
  148. oldcore((short *) lp,sizeof(num_t));
  149. }
  150. offset *newrom()
  151. {
  152. return((offset *) newcore(MAXROM*sizeof(offset)));
  153. }
  154. sym_p newsym(int len)
  155. {
  156. /*
  157. * sym_t includes a 2 character s_name at the end
  158. * extend this structure with len-2 characters
  159. */
  160. return((sym_p) newcore(sizeof(sym_t) - 2 + len));
  161. }
  162. argb_p newargb()
  163. {
  164. return((argb_p) newcore(sizeof(argb_t)));
  165. }
  166. #ifndef USEMALLOC
  167. /******************************************************************/
  168. /****** Start of raw core management package *****************/
  169. /******************************************************************/
  170. #define MAXSHORT 30 /* Maximum number of shorts one can ask for */
  171. short *freelist[MAXSHORT];
  172. typedef struct coreblock {
  173. struct coreblock *co_next;
  174. short co_size;
  175. } core_t,*core_p;
  176. #define SINC (sizeof(core_t)/sizeof(short))
  177. #ifdef COREDEBUG
  178. void coreverbose()
  179. {
  180. int size;
  181. short *p;
  182. int sum;
  183. sum = 0;
  184. for(size=1;size<MAXSHORT;size++)
  185. for (p=freelist[size];p!=0;p = *(short **) p)
  186. sum += size;
  187. fprintf(stderr,"Used core %u\n",(shortsasked-sum)*sizeof(short));
  188. }
  189. #endif
  190. #ifdef SEPID
  191. void compactcore()
  192. {
  193. core_p corelist=0,tp,cl;
  194. int size;
  195. #ifdef COREDEBUG
  196. fprintf(stderr,"Almost out of core\n");
  197. #endif
  198. for(size=SINC;size<MAXSHORT;size++) {
  199. while ((tp = (core_p) freelist[size]) != (core_p) 0) {
  200. freelist[size] = (short *) tp->co_next;
  201. tp->co_size = size;
  202. if (corelist==0 || tp<corelist) {
  203. tp->co_next = corelist;
  204. corelist = tp;
  205. } else {
  206. for(cl=corelist;cl->co_next != 0 && tp>cl->co_next;
  207. cl = cl->co_next)
  208. ;
  209. tp->co_next = cl->co_next;
  210. cl->co_next = tp;
  211. }
  212. }
  213. }
  214. while (corelist != 0) {
  215. while ((short *) corelist->co_next ==
  216. (short *) corelist + corelist->co_size) {
  217. corelist->co_size += corelist->co_next->co_size;
  218. corelist->co_next = corelist->co_next->co_next;
  219. }
  220. assert(corelist->co_next==0 ||
  221. (short *) corelist->co_next >
  222. (short *) corelist + corelist->co_size);
  223. while (corelist->co_size >= MAXSHORT+SINC) {
  224. oldcore((short *) corelist + corelist->co_size-(MAXSHORT-1),
  225. sizeof(short)*(MAXSHORT-1));
  226. corelist->co_size -= MAXSHORT;
  227. }
  228. if (corelist->co_size >= MAXSHORT) {
  229. oldcore((short *) corelist + corelist->co_size-SINC,
  230. sizeof(short)*SINC);
  231. corelist->co_size -= SINC;
  232. }
  233. cl = corelist->co_next;
  234. oldcore((short *) corelist, sizeof(short)*corelist->co_size);
  235. corelist = cl;
  236. }
  237. }
  238. short *grabcore(int size)
  239. {
  240. short *p;
  241. int trysize;
  242. /*
  243. * Desperate situation, can't get more core from system.
  244. * Postpone giving up just a little bit by splitting up
  245. * larger free blocks if possible.
  246. * Algorithm is worst fit.
  247. */
  248. assert(size<2*MAXSHORT);
  249. for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2) {
  250. p = freelist[trysize/sizeof(short)];
  251. if ( p != (short *) 0) {
  252. freelist[trysize/sizeof(short)] = *(short **) p;
  253. oldcore(p+size/sizeof(short),trysize-size);
  254. return(p);
  255. }
  256. }
  257. /*
  258. * Can't get more core from the biggies, try to combine the
  259. * little ones. This is expensive but probably better than
  260. * giving up.
  261. */
  262. compactcore();
  263. if ((p=freelist[size/sizeof(short)]) != 0) {
  264. freelist[size/sizeof(short)] = * (short **) p;
  265. return(p);
  266. }
  267. for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2) {
  268. p = freelist[trysize/sizeof(short)];
  269. if ( p != (short *) 0) {
  270. freelist[trysize/sizeof(short)] = *(short **) p;
  271. oldcore(p+size/sizeof(short),trysize-size);
  272. return(p);
  273. }
  274. }
  275. /*
  276. * That's it then. Finished.
  277. */
  278. return(0);
  279. }
  280. #endif /* SEPID */
  281. short *newcore(int size)
  282. {
  283. register short *p,*q;
  284. size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1);
  285. if( size < 2*MAXSHORT ) {
  286. if ((p=freelist[size/sizeof(short)]) != (short *) 0)
  287. freelist[size/sizeof(short)] = *(short **) p;
  288. else {
  289. p = freshcore(size);
  290. #ifdef SEPID
  291. if (p == (short *) 0)
  292. p = grabcore(size);
  293. #endif
  294. }
  295. } else
  296. p = freshcore(size);
  297. if (p == 0)
  298. error("out of memory");
  299. for (q=p; size > 0 ; size -= sizeof(short))
  300. *q++ = 0;
  301. return(p);
  302. }
  303. #ifndef USEMALLOC
  304. /*
  305. * stdio uses malloc and free.
  306. * you can use these as substitutes
  307. */
  308. char *malloc(int size)
  309. {
  310. /*
  311. * malloc(III) is called by stdio,
  312. * this routine is a substitute.
  313. */
  314. return( (char *) newcore(size));
  315. }
  316. void free(void *ptr)
  317. {
  318. }
  319. #endif
  320. void oldcore(short *p, int size)
  321. {
  322. #ifdef CORECHECK
  323. short *cp;
  324. #endif
  325. assert(size<2*MAXSHORT);
  326. #ifdef CORECHECK
  327. for (cp=freelist[size/sizeof(short)]; cp != (short *) 0;
  328. cp = *(short **) cp)
  329. assert(cp != p);
  330. #endif
  331. *(short **) p = freelist[size/sizeof(short)];
  332. freelist[size/sizeof(short)] = p;
  333. }
  334. short *ccur,*cend;
  335. void coreinit(short *p1, short *p2)
  336. {
  337. /*
  338. * coreinit is called with the boundaries of a piece of
  339. * memory that can be used for starters.
  340. */
  341. ccur = p1;
  342. cend = p2;
  343. }
  344. short *freshcore(int size)
  345. {
  346. short *temp;
  347. static int cchunk=CCHUNK;
  348. while(&ccur[size/sizeof(short)] >= cend && cchunk>0) {
  349. do {
  350. temp = (short *) sbrk(cchunk*sizeof(short));
  351. if (temp == (short *) -1)
  352. cchunk >>= 1;
  353. else if (temp != cend)
  354. ccur = cend = temp;
  355. } while (temp == (short *) -1 && cchunk>0);
  356. cend += cchunk;
  357. #ifdef COREDEBUG
  358. shortsasked += cchunk;
  359. #endif
  360. }
  361. if (cchunk==0)
  362. return(0);
  363. temp = ccur;
  364. ccur = &ccur[size/sizeof(short)];
  365. return(temp);
  366. }
  367. #else /* USEMALLOC */
  368. void coreinit(short *p1, short *p2) {
  369. /*
  370. * Empty function, no initialization needed
  371. */
  372. }
  373. short *myalloc(int size)
  374. {
  375. register short *p,*q;
  376. p = (short *)malloc(size);
  377. if (p == 0)
  378. error("out of memory", NULL);
  379. for(q=p;size>0;size -= sizeof(short))
  380. *q++ = 0;
  381. return(p);
  382. }
  383. #endif