alloc.c 8.5 KB

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