Heap.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. /* voc 2.1.0 [2019/11/01]. Bootstrapping compiler for address size 8, alignment 8. rtsSF */
  2. #define SHORTINT INT8
  3. #define INTEGER INT16
  4. #define LONGINT INT32
  5. #define SET UINT32
  6. #include "SYSTEM.h"
  7. struct Heap__1 {
  8. CHAR ch;
  9. SYSTEM_PTR p;
  10. };
  11. typedef
  12. struct Heap_CmdDesc *Heap_Cmd;
  13. typedef
  14. CHAR Heap_CmdName[24];
  15. typedef
  16. void (*Heap_Command)(void);
  17. typedef
  18. struct Heap_CmdDesc {
  19. Heap_Cmd next;
  20. Heap_CmdName name;
  21. Heap_Command cmd;
  22. } Heap_CmdDesc;
  23. typedef
  24. void (*Heap_EnumProc)(void(*)(SYSTEM_PTR));
  25. typedef
  26. struct Heap_FinDesc *Heap_FinNode;
  27. typedef
  28. void (*Heap_Finalizer)(SYSTEM_PTR);
  29. typedef
  30. struct Heap_FinDesc {
  31. Heap_FinNode next;
  32. INT64 obj;
  33. BOOLEAN marked;
  34. Heap_Finalizer finalize;
  35. } Heap_FinDesc;
  36. typedef
  37. struct Heap_ModuleDesc *Heap_Module;
  38. typedef
  39. CHAR Heap_ModuleName[20];
  40. typedef
  41. struct Heap_ModuleDesc {
  42. Heap_Module next;
  43. Heap_ModuleName name;
  44. INT32 refcnt;
  45. Heap_Cmd cmds;
  46. INT64 types;
  47. Heap_EnumProc enumPtrs;
  48. INT32 reserved1, reserved2;
  49. } Heap_ModuleDesc;
  50. export SYSTEM_PTR Heap_modules;
  51. static INT64 Heap_freeList[10];
  52. static INT64 Heap_bigBlocks;
  53. export INT64 Heap_allocated;
  54. static BOOLEAN Heap_firstTry;
  55. static INT16 Heap_ldUnit;
  56. export INT64 Heap_heap;
  57. static INT64 Heap_heapMin, Heap_heapMax;
  58. export INT64 Heap_heapsize, Heap_heapMinExpand;
  59. static Heap_FinNode Heap_fin;
  60. static INT16 Heap_lockdepth;
  61. static BOOLEAN Heap_interrupted;
  62. export INT16 Heap_FileCount;
  63. export ADDRESS *Heap_ModuleDesc__typ;
  64. export ADDRESS *Heap_CmdDesc__typ;
  65. export ADDRESS *Heap_FinDesc__typ;
  66. export ADDRESS *Heap__1__typ;
  67. static void Heap_CheckFin (void);
  68. static void Heap_ExtendHeap (INT64 blksz);
  69. export void Heap_FINALL (void);
  70. static void Heap_Finalize (void);
  71. export INT32 Heap_FreeModule (CHAR *name, ADDRESS name__len);
  72. export void Heap_GC (BOOLEAN markStack);
  73. static void Heap_HeapSort (INT32 n, INT64 *a, ADDRESS a__len);
  74. export void Heap_INCREF (Heap_Module m);
  75. export void Heap_InitHeap (void);
  76. export void Heap_Lock (void);
  77. static void Heap_Mark (INT64 q);
  78. static void Heap_MarkCandidates (INT32 n, INT64 *cand, ADDRESS cand__len);
  79. static void Heap_MarkP (SYSTEM_PTR p);
  80. static void Heap_MarkStack (INT64 n, INT64 *cand, ADDRESS cand__len);
  81. export SYSTEM_PTR Heap_NEWBLK (INT64 size);
  82. export SYSTEM_PTR Heap_NEWREC (INT64 tag);
  83. static INT64 Heap_NewChunk (INT64 blksz);
  84. export void Heap_REGCMD (Heap_Module m, Heap_CmdName name, Heap_Command cmd);
  85. export SYSTEM_PTR Heap_REGMOD (Heap_ModuleName name, Heap_EnumProc enumPtrs);
  86. export void Heap_REGTYP (Heap_Module m, INT64 typ);
  87. export void Heap_RegisterFinalizer (SYSTEM_PTR obj, Heap_Finalizer finalize);
  88. static void Heap_Scan (void);
  89. static void Heap_Sift (INT32 l, INT32 r, INT64 *a, ADDRESS a__len);
  90. export void Heap_Unlock (void);
  91. extern void *Heap__init();
  92. extern ADDRESS Modules_MainStackFrame;
  93. extern ADDRESS Platform_OSAllocate(ADDRESS size);
  94. #define Heap_HeapModuleInit() Heap__init()
  95. #define Heap_ModulesHalt(code) Modules_Halt(code)
  96. #define Heap_ModulesMainStackFrame() Modules_MainStackFrame
  97. #define Heap_OSAllocate(size) Platform_OSAllocate(size)
  98. #define Heap_uLE(x, y) ((size_t)x <= (size_t)y)
  99. #define Heap_uLT(x, y) ((size_t)x < (size_t)y)
  100. void Heap_Lock (void)
  101. {
  102. Heap_lockdepth += 1;
  103. }
  104. void Heap_Unlock (void)
  105. {
  106. Heap_lockdepth -= 1;
  107. if ((Heap_interrupted && Heap_lockdepth == 0)) {
  108. Heap_ModulesHalt(-9);
  109. }
  110. }
  111. SYSTEM_PTR Heap_REGMOD (Heap_ModuleName name, Heap_EnumProc enumPtrs)
  112. {
  113. Heap_Module m;
  114. if (__STRCMP(name, "Heap") == 0) {
  115. __SYSNEW(m, 64);
  116. } else {
  117. __NEW(m, Heap_ModuleDesc);
  118. }
  119. m->types = 0;
  120. m->cmds = NIL;
  121. __COPY(name, m->name, 20);
  122. m->refcnt = 0;
  123. m->enumPtrs = enumPtrs;
  124. m->next = (Heap_Module)(ADDRESS)Heap_modules;
  125. Heap_modules = (SYSTEM_PTR)m;
  126. return (void*)m;
  127. }
  128. INT32 Heap_FreeModule (CHAR *name, ADDRESS name__len)
  129. {
  130. Heap_Module m, p;
  131. __DUP(name, name__len, CHAR);
  132. m = (Heap_Module)(ADDRESS)Heap_modules;
  133. while ((m != NIL && __STRCMP(m->name, name) != 0)) {
  134. p = m;
  135. m = m->next;
  136. }
  137. if ((m != NIL && m->refcnt == 0)) {
  138. if (m == (Heap_Module)(ADDRESS)Heap_modules) {
  139. Heap_modules = (SYSTEM_PTR)m->next;
  140. } else {
  141. p->next = m->next;
  142. }
  143. __DEL(name);
  144. return 0;
  145. } else {
  146. if (m == NIL) {
  147. __DEL(name);
  148. return -1;
  149. } else {
  150. __DEL(name);
  151. return m->refcnt;
  152. }
  153. }
  154. __RETCHK;
  155. }
  156. void Heap_REGCMD (Heap_Module m, Heap_CmdName name, Heap_Command cmd)
  157. {
  158. Heap_Cmd c;
  159. if (__STRCMP(m->name, "Heap") == 0) {
  160. __SYSNEW(c, 40);
  161. } else {
  162. __NEW(c, Heap_CmdDesc);
  163. }
  164. __COPY(name, c->name, 24);
  165. c->cmd = cmd;
  166. c->next = m->cmds;
  167. m->cmds = c;
  168. }
  169. void Heap_REGTYP (Heap_Module m, INT64 typ)
  170. {
  171. __PUT(typ, m->types, INT64);
  172. m->types = typ;
  173. }
  174. void Heap_INCREF (Heap_Module m)
  175. {
  176. m->refcnt += 1;
  177. }
  178. static INT64 Heap_NewChunk (INT64 blksz)
  179. {
  180. INT64 chnk, blk, end;
  181. chnk = Heap_OSAllocate(blksz + 24);
  182. if (chnk != 0) {
  183. blk = chnk + 24;
  184. end = blk + blksz;
  185. __PUT(chnk + 8, end, INT64);
  186. __PUT(blk, blk + 8, INT64);
  187. __PUT(blk + 8, blksz, INT64);
  188. __PUT(blk + 16, -8, INT64);
  189. __PUT(blk + 24, Heap_bigBlocks, INT64);
  190. Heap_bigBlocks = blk;
  191. Heap_heapsize += blksz;
  192. if (Heap_uLT(blk + 8, Heap_heapMin)) {
  193. Heap_heapMin = blk + 8;
  194. }
  195. if (Heap_uLT(Heap_heapMax, end)) {
  196. Heap_heapMax = end;
  197. }
  198. }
  199. return chnk;
  200. }
  201. static void Heap_ExtendHeap (INT64 blksz)
  202. {
  203. INT64 size, chnk, j, next;
  204. if (Heap_uLT(Heap_heapMinExpand, blksz)) {
  205. size = blksz;
  206. } else {
  207. size = Heap_heapMinExpand;
  208. }
  209. chnk = Heap_NewChunk(size);
  210. if (chnk != 0) {
  211. if (Heap_uLT(chnk, Heap_heap)) {
  212. __PUT(chnk, Heap_heap, INT64);
  213. Heap_heap = chnk;
  214. } else {
  215. j = Heap_heap;
  216. __GET(j, next, INT64);
  217. while ((next != 0 && Heap_uLT(next, chnk))) {
  218. j = next;
  219. __GET(j, next, INT64);
  220. }
  221. __PUT(chnk, next, INT64);
  222. __PUT(j, chnk, INT64);
  223. }
  224. } else if (!Heap_firstTry) {
  225. Heap_heapMinExpand = 32;
  226. }
  227. }
  228. SYSTEM_PTR Heap_NEWREC (INT64 tag)
  229. {
  230. INT64 i, i0, di, blksz, restsize, t, adr, end, next, prev;
  231. SYSTEM_PTR new;
  232. Heap_Lock();
  233. __GET(tag, blksz, INT64);
  234. i0 = __LSH(blksz, -Heap_ldUnit, 64);
  235. i = i0;
  236. if (i < 9) {
  237. adr = Heap_freeList[i];
  238. while (adr == 0) {
  239. i += 1;
  240. adr = Heap_freeList[i];
  241. }
  242. }
  243. if (i < 9) {
  244. __GET(adr + 24, next, INT64);
  245. Heap_freeList[i] = next;
  246. if (i != i0) {
  247. di = i - i0;
  248. restsize = __ASHL(di, 5);
  249. end = adr + restsize;
  250. __PUT(end + 8, blksz, INT64);
  251. __PUT(end + 16, -8, INT64);
  252. __PUT(end, end + 8, INT64);
  253. __PUT(adr + 8, restsize, INT64);
  254. __PUT(adr + 24, Heap_freeList[di], INT64);
  255. Heap_freeList[di] = adr;
  256. adr += restsize;
  257. }
  258. } else {
  259. adr = Heap_bigBlocks;
  260. prev = 0;
  261. for (;;) {
  262. if (adr == 0) {
  263. if (Heap_firstTry) {
  264. Heap_GC(1);
  265. blksz += 32;
  266. t = __LSH(Heap_allocated + blksz, -(2 + Heap_ldUnit), 64) * 160;
  267. if (Heap_uLT(Heap_heapsize, t)) {
  268. Heap_ExtendHeap(t - Heap_heapsize);
  269. }
  270. Heap_firstTry = 0;
  271. new = Heap_NEWREC(tag);
  272. if (new == NIL) {
  273. Heap_ExtendHeap(blksz);
  274. new = Heap_NEWREC(tag);
  275. }
  276. Heap_firstTry = 1;
  277. Heap_Unlock();
  278. return new;
  279. } else {
  280. Heap_Unlock();
  281. return NIL;
  282. }
  283. }
  284. __GET(adr + 8, t, INT64);
  285. if (Heap_uLE(blksz, t)) {
  286. break;
  287. }
  288. prev = adr;
  289. __GET(adr + 24, adr, INT64);
  290. }
  291. restsize = t - blksz;
  292. end = adr + restsize;
  293. __PUT(end + 8, blksz, INT64);
  294. __PUT(end + 16, -8, INT64);
  295. __PUT(end, end + 8, INT64);
  296. if (Heap_uLT(288, restsize)) {
  297. __PUT(adr + 8, restsize, INT64);
  298. } else {
  299. __GET(adr + 24, next, INT64);
  300. if (prev == 0) {
  301. Heap_bigBlocks = next;
  302. } else {
  303. __PUT(prev + 24, next, INT64);
  304. }
  305. if (restsize != 0) {
  306. di = __ASHR(restsize, 5);
  307. __PUT(adr + 8, restsize, INT64);
  308. __PUT(adr + 24, Heap_freeList[di], INT64);
  309. Heap_freeList[di] = adr;
  310. }
  311. }
  312. adr += restsize;
  313. }
  314. i = adr + 32;
  315. end = adr + blksz;
  316. while (Heap_uLT(i, end)) {
  317. __PUT(i, 0, INT64);
  318. __PUT(i + 8, 0, INT64);
  319. __PUT(i + 16, 0, INT64);
  320. __PUT(i + 24, 0, INT64);
  321. i += 32;
  322. }
  323. __PUT(adr + 24, 0, INT64);
  324. __PUT(adr, tag, INT64);
  325. __PUT(adr + 8, 0, INT64);
  326. __PUT(adr + 16, 0, INT64);
  327. Heap_allocated += blksz;
  328. Heap_Unlock();
  329. return (SYSTEM_PTR)(ADDRESS)(adr + 8);
  330. }
  331. SYSTEM_PTR Heap_NEWBLK (INT64 size)
  332. {
  333. INT64 blksz, tag;
  334. SYSTEM_PTR new;
  335. Heap_Lock();
  336. blksz = __ASHL(__ASHR(size + 63, 5), 5);
  337. new = Heap_NEWREC((ADDRESS)&blksz);
  338. tag = ((INT64)(ADDRESS)new + blksz) - 24;
  339. __PUT(tag - 8, 0, INT64);
  340. __PUT(tag, blksz, INT64);
  341. __PUT(tag + 8, -8, INT64);
  342. __PUT((INT64)(ADDRESS)new - 8, tag, INT64);
  343. Heap_Unlock();
  344. return new;
  345. }
  346. static void Heap_Mark (INT64 q)
  347. {
  348. INT64 p, tag, offset, fld, n, tagbits;
  349. if (q != 0) {
  350. __GET(q - 8, tagbits, INT64);
  351. if (!__ODD(tagbits)) {
  352. __PUT(q - 8, tagbits + 1, INT64);
  353. p = 0;
  354. tag = tagbits + 8;
  355. for (;;) {
  356. __GET(tag, offset, INT64);
  357. if (offset < 0) {
  358. __PUT(q - 8, (tag + offset) + 1, INT64);
  359. if (p == 0) {
  360. break;
  361. }
  362. n = q;
  363. q = p;
  364. __GET(q - 8, tag, INT64);
  365. tag -= 1;
  366. __GET(tag, offset, INT64);
  367. fld = q + offset;
  368. __GET(fld, p, INT64);
  369. __PUT(fld, (SYSTEM_PTR)(ADDRESS)n, SYSTEM_PTR);
  370. } else {
  371. fld = q + offset;
  372. __GET(fld, n, INT64);
  373. if (n != 0) {
  374. __GET(n - 8, tagbits, INT64);
  375. if (!__ODD(tagbits)) {
  376. __PUT(n - 8, tagbits + 1, INT64);
  377. __PUT(q - 8, tag + 1, INT64);
  378. __PUT(fld, (SYSTEM_PTR)(ADDRESS)p, SYSTEM_PTR);
  379. p = q;
  380. q = n;
  381. tag = tagbits;
  382. }
  383. }
  384. }
  385. tag += 8;
  386. }
  387. }
  388. }
  389. }
  390. static void Heap_MarkP (SYSTEM_PTR p)
  391. {
  392. Heap_Mark((INT64)(ADDRESS)p);
  393. }
  394. static void Heap_Scan (void)
  395. {
  396. INT64 chnk, adr, end, start, tag, i, size, freesize;
  397. Heap_bigBlocks = 0;
  398. i = 1;
  399. while (i < 9) {
  400. Heap_freeList[i] = 0;
  401. i += 1;
  402. }
  403. freesize = 0;
  404. Heap_allocated = 0;
  405. chnk = Heap_heap;
  406. while (chnk != 0) {
  407. adr = chnk + 24;
  408. __GET(chnk + 8, end, INT64);
  409. while (Heap_uLT(adr, end)) {
  410. __GET(adr, tag, INT64);
  411. if (__ODD(tag)) {
  412. if (freesize != 0) {
  413. start = adr - freesize;
  414. __PUT(start, start + 8, INT64);
  415. __PUT(start + 8, freesize, INT64);
  416. __PUT(start + 16, -8, INT64);
  417. i = __LSH(freesize, -Heap_ldUnit, 64);
  418. freesize = 0;
  419. if (Heap_uLT(i, 9)) {
  420. __PUT(start + 24, Heap_freeList[i], INT64);
  421. Heap_freeList[i] = start;
  422. } else {
  423. __PUT(start + 24, Heap_bigBlocks, INT64);
  424. Heap_bigBlocks = start;
  425. }
  426. }
  427. tag -= 1;
  428. __PUT(adr, tag, INT64);
  429. __GET(tag, size, INT64);
  430. Heap_allocated += size;
  431. adr += size;
  432. } else {
  433. __GET(tag, size, INT64);
  434. freesize += size;
  435. adr += size;
  436. }
  437. }
  438. if (freesize != 0) {
  439. start = adr - freesize;
  440. __PUT(start, start + 8, INT64);
  441. __PUT(start + 8, freesize, INT64);
  442. __PUT(start + 16, -8, INT64);
  443. i = __LSH(freesize, -Heap_ldUnit, 64);
  444. freesize = 0;
  445. if (Heap_uLT(i, 9)) {
  446. __PUT(start + 24, Heap_freeList[i], INT64);
  447. Heap_freeList[i] = start;
  448. } else {
  449. __PUT(start + 24, Heap_bigBlocks, INT64);
  450. Heap_bigBlocks = start;
  451. }
  452. }
  453. __GET(chnk, chnk, INT64);
  454. }
  455. }
  456. static void Heap_Sift (INT32 l, INT32 r, INT64 *a, ADDRESS a__len)
  457. {
  458. INT32 i, j;
  459. INT64 x;
  460. j = l;
  461. x = a[j];
  462. for (;;) {
  463. i = j;
  464. j = __ASHL(j, 1) + 1;
  465. if ((j < r && Heap_uLT(a[j], a[j + 1]))) {
  466. j += 1;
  467. }
  468. if (j > r || Heap_uLE(a[j], x)) {
  469. break;
  470. }
  471. a[i] = a[j];
  472. }
  473. a[i] = x;
  474. }
  475. static void Heap_HeapSort (INT32 n, INT64 *a, ADDRESS a__len)
  476. {
  477. INT32 l, r;
  478. INT64 x;
  479. l = __ASHR(n, 1);
  480. r = n - 1;
  481. while (l > 0) {
  482. l -= 1;
  483. Heap_Sift(l, r, (void*)a, a__len);
  484. }
  485. while (r > 0) {
  486. x = a[0];
  487. a[0] = a[r];
  488. a[r] = x;
  489. r -= 1;
  490. Heap_Sift(l, r, (void*)a, a__len);
  491. }
  492. }
  493. static void Heap_MarkCandidates (INT32 n, INT64 *cand, ADDRESS cand__len)
  494. {
  495. INT64 chnk, end, adr, tag, next, i, ptr, size;
  496. chnk = Heap_heap;
  497. i = 0;
  498. while (chnk != 0) {
  499. __GET(chnk + 8, end, INT64);
  500. adr = chnk + 24;
  501. while (Heap_uLT(adr, end)) {
  502. __GET(adr, tag, INT64);
  503. if (__ODD(tag)) {
  504. __GET(tag - 1, size, INT64);
  505. adr += size;
  506. ptr = adr + 8;
  507. while (Heap_uLT(cand[i], ptr)) {
  508. i += 1;
  509. if (i == (INT64)n) {
  510. return;
  511. }
  512. }
  513. } else {
  514. __GET(tag, size, INT64);
  515. ptr = adr + 8;
  516. adr += size;
  517. while (Heap_uLT(cand[i], ptr)) {
  518. i += 1;
  519. if (i == (INT64)n) {
  520. return;
  521. }
  522. }
  523. if (Heap_uLT(cand[i], adr)) {
  524. Heap_Mark(ptr);
  525. }
  526. }
  527. if (Heap_uLE(end, cand[i])) {
  528. adr = end;
  529. }
  530. }
  531. __GET(chnk, chnk, INT64);
  532. }
  533. }
  534. static void Heap_CheckFin (void)
  535. {
  536. Heap_FinNode n;
  537. INT64 tag;
  538. n = Heap_fin;
  539. while (n != NIL) {
  540. __GET(n->obj - 8, tag, INT64);
  541. if (!__ODD(tag)) {
  542. n->marked = 0;
  543. Heap_Mark(n->obj);
  544. } else {
  545. n->marked = 1;
  546. }
  547. n = n->next;
  548. }
  549. }
  550. static void Heap_Finalize (void)
  551. {
  552. Heap_FinNode n, prev;
  553. n = Heap_fin;
  554. prev = NIL;
  555. while (n != NIL) {
  556. if (!n->marked) {
  557. if (n == Heap_fin) {
  558. Heap_fin = Heap_fin->next;
  559. } else {
  560. prev->next = n->next;
  561. }
  562. (*n->finalize)((SYSTEM_PTR)(ADDRESS)n->obj);
  563. if (prev == NIL) {
  564. n = Heap_fin;
  565. } else {
  566. n = n->next;
  567. }
  568. } else {
  569. prev = n;
  570. n = n->next;
  571. }
  572. }
  573. }
  574. void Heap_FINALL (void)
  575. {
  576. Heap_FinNode n;
  577. while (Heap_fin != NIL) {
  578. n = Heap_fin;
  579. Heap_fin = Heap_fin->next;
  580. (*n->finalize)((SYSTEM_PTR)(ADDRESS)n->obj);
  581. }
  582. }
  583. static void Heap_MarkStack (INT64 n, INT64 *cand, ADDRESS cand__len)
  584. {
  585. SYSTEM_PTR frame;
  586. INT32 nofcand;
  587. INT64 inc, sp, p, stack0;
  588. struct Heap__1 align;
  589. if (n > 0) {
  590. Heap_MarkStack(n - 1, cand, cand__len);
  591. if (n > 100) {
  592. return;
  593. }
  594. }
  595. if (n == 0) {
  596. nofcand = 0;
  597. sp = (ADDRESS)&frame;
  598. stack0 = Heap_ModulesMainStackFrame();
  599. inc = (ADDRESS)&align.p - (ADDRESS)&align;
  600. if (Heap_uLT(stack0, sp)) {
  601. inc = -inc;
  602. }
  603. while (sp != stack0) {
  604. __GET(sp, p, INT64);
  605. if ((Heap_uLE(Heap_heapMin, p) && Heap_uLT(p, Heap_heapMax))) {
  606. if (nofcand == cand__len) {
  607. Heap_HeapSort(nofcand, (void*)cand, cand__len);
  608. Heap_MarkCandidates(nofcand, (void*)cand, cand__len);
  609. nofcand = 0;
  610. }
  611. cand[nofcand] = p;
  612. nofcand += 1;
  613. }
  614. sp += inc;
  615. }
  616. if (nofcand > 0) {
  617. Heap_HeapSort(nofcand, (void*)cand, cand__len);
  618. Heap_MarkCandidates(nofcand, (void*)cand, cand__len);
  619. }
  620. }
  621. }
  622. void Heap_GC (BOOLEAN markStack)
  623. {
  624. Heap_Module m;
  625. INT64 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23;
  626. INT64 cand[10000];
  627. if (Heap_lockdepth == 0 || (Heap_lockdepth == 1 && !markStack)) {
  628. Heap_Lock();
  629. m = (Heap_Module)(ADDRESS)Heap_modules;
  630. while (m != NIL) {
  631. if (m->enumPtrs != NIL) {
  632. (*m->enumPtrs)(Heap_MarkP);
  633. }
  634. m = m->next;
  635. }
  636. if (markStack) {
  637. i0 = -100;
  638. i1 = -101;
  639. i2 = -102;
  640. i3 = -103;
  641. i4 = -104;
  642. i5 = -105;
  643. i6 = -106;
  644. i7 = -107;
  645. i8 = 1;
  646. i9 = 2;
  647. i10 = 3;
  648. i11 = 4;
  649. i12 = 5;
  650. i13 = 6;
  651. i14 = 7;
  652. i15 = 8;
  653. i16 = 9;
  654. i17 = 10;
  655. i18 = 11;
  656. i19 = 12;
  657. i20 = 13;
  658. i21 = 14;
  659. i22 = 15;
  660. i23 = 16;
  661. for (;;) {
  662. i0 += 1;
  663. i1 += 2;
  664. i2 += 3;
  665. i3 += 4;
  666. i4 += 5;
  667. i5 += 6;
  668. i6 += 7;
  669. i7 += 8;
  670. i8 += 9;
  671. i9 += 10;
  672. i10 += 11;
  673. i11 += 12;
  674. i12 += 13;
  675. i13 += 14;
  676. i14 += 15;
  677. i15 += 16;
  678. i16 += 17;
  679. i17 += 18;
  680. i18 += 19;
  681. i19 += 20;
  682. i20 += 21;
  683. i21 += 22;
  684. i22 += 23;
  685. i23 += 24;
  686. if ((i0 == -99 && i15 == 24)) {
  687. Heap_MarkStack(32, (void*)cand, 10000);
  688. break;
  689. }
  690. }
  691. if (((((((((((((((((((((((i0 + i1) + i2) + i3) + i4) + i5) + i6) + i7) + i8) + i9) + i10) + i11) + i12) + i13) + i14) + i15) + i16) + i17) + i18) + i19) + i20) + i21) + i22) + i23 > 10000) {
  692. return;
  693. }
  694. }
  695. Heap_CheckFin();
  696. Heap_Scan();
  697. Heap_Finalize();
  698. Heap_Unlock();
  699. }
  700. }
  701. void Heap_RegisterFinalizer (SYSTEM_PTR obj, Heap_Finalizer finalize)
  702. {
  703. Heap_FinNode f;
  704. __NEW(f, Heap_FinDesc);
  705. f->obj = (INT64)(ADDRESS)obj;
  706. f->finalize = finalize;
  707. f->marked = 1;
  708. f->next = Heap_fin;
  709. Heap_fin = f;
  710. }
  711. void Heap_InitHeap (void)
  712. {
  713. Heap_heap = 0;
  714. Heap_heapsize = 0;
  715. Heap_allocated = 0;
  716. Heap_lockdepth = 0;
  717. Heap_heapMin = -1;
  718. Heap_heapMax = 0;
  719. Heap_bigBlocks = 0;
  720. Heap_heapMinExpand = 256000;
  721. Heap_ldUnit = 5;
  722. Heap_heap = Heap_NewChunk(256000);
  723. __PUT(Heap_heap, 0, INT64);
  724. Heap_firstTry = 1;
  725. Heap_freeList[9] = 1;
  726. Heap_FileCount = 0;
  727. Heap_modules = NIL;
  728. Heap_fin = NIL;
  729. Heap_interrupted = 0;
  730. Heap_HeapModuleInit();
  731. }
  732. static void EnumPtrs(void (*P)(void*))
  733. {
  734. P(Heap_modules);
  735. P(Heap_fin);
  736. }
  737. __TDESC(Heap_ModuleDesc, 1, 2) = {__TDFLDS("ModuleDesc", 64), {0, 32, -24}};
  738. __TDESC(Heap_CmdDesc, 1, 1) = {__TDFLDS("CmdDesc", 40), {0, -16}};
  739. __TDESC(Heap_FinDesc, 1, 1) = {__TDFLDS("FinDesc", 32), {0, -16}};
  740. __TDESC(Heap__1, 1, 1) = {__TDFLDS("", 16), {8, -16}};
  741. export void *Heap__init(void)
  742. {
  743. __DEFMOD;
  744. __REGMOD("Heap", EnumPtrs);
  745. __REGCMD("FINALL", Heap_FINALL);
  746. __REGCMD("InitHeap", Heap_InitHeap);
  747. __REGCMD("Lock", Heap_Lock);
  748. __REGCMD("Unlock", Heap_Unlock);
  749. __INITYP(Heap_ModuleDesc, Heap_ModuleDesc, 0);
  750. __INITYP(Heap_CmdDesc, Heap_CmdDesc, 0);
  751. __INITYP(Heap_FinDesc, Heap_FinDesc, 0);
  752. __INITYP(Heap__1, Heap__1, 0);
  753. /* BEGIN */
  754. __ENDMOD;
  755. }