heap.inc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993-99 by the Free Pascal development team.
  5. functions for heap management in the data segment
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {****************************************************************************}
  13. { Reuse bigger blocks instead of allocating a new block at freelist/heapptr.
  14. the tried bigger blocks are always multiple sizes of the current block }
  15. {$define REUSEBIGGER}
  16. { Allocate small blocks at heapptr instead of walking the freelist }
  17. {$define SMALLATHEAPPTR}
  18. { Try to find the best matching block in general freelist }
  19. {$define BESTMATCH}
  20. { DEBUG: Dump info when the heap needs to grow }
  21. { define DUMPGROW}
  22. { Default heap settings }
  23. const
  24. blocksize = 16; { at least size of freerecord }
  25. blockshr = 4; { shr value for blocksize=2^blockshr}
  26. maxblocksize = 512+blocksize; { 1024+8 needed for heaprecord }
  27. maxblock = maxblocksize div blocksize;
  28. maxreusebigger = 8; { max reuse bigger tries }
  29. usedmask = $80000000;
  30. sizemask = not usedmask;
  31. {****************************************************************************}
  32. {$ifdef DUMPGROW}
  33. {$define DUMPBLOCKS}
  34. {$endif}
  35. { Memory manager }
  36. const
  37. MemoryManager: TMemoryManager = (
  38. GetMem: SysGetMem;
  39. FreeMem: SysFreeMem;
  40. FreeMemSize: SysFreeMemSize;
  41. AllocMem: SysAllocMem;
  42. ReAllocMem: SysReAllocMem;
  43. MemSize: SysMemSize;
  44. MemAvail: SysMemAvail;
  45. MaxAvail: SysMaxAvail;
  46. HeapSize: SysHeapSize;
  47. );
  48. type
  49. ppfreerecord = ^pfreerecord;
  50. pfreerecord = ^tfreerecord;
  51. tfreerecord = record
  52. size : longint;
  53. next,
  54. prev : pfreerecord;
  55. end; { 12 bytes }
  56. pheaprecord = ^theaprecord;
  57. theaprecord = record
  58. { this should overlap with tfreerecord }
  59. size : longint;
  60. end; { 4 bytes }
  61. tfreelists = array[0..maxblock] of pfreerecord;
  62. pfreelists = ^tfreelists;
  63. var
  64. internal_memavail : longint;
  65. internal_heapsize : longint;
  66. freelists : tfreelists;
  67. {*****************************************************************************
  68. Memory Manager
  69. *****************************************************************************}
  70. procedure GetMemoryManager(var MemMgr:TMemoryManager);
  71. begin
  72. MemMgr:=MemoryManager;
  73. end;
  74. procedure SetMemoryManager(const MemMgr:TMemoryManager);
  75. begin
  76. MemoryManager:=MemMgr;
  77. end;
  78. function IsMemoryManagerSet:Boolean;
  79. begin
  80. IsMemoryManagerSet:=(MemoryManager.GetMem<>@SysGetMem) or
  81. (MemoryManager.FreeMem<>@SysFreeMem);
  82. end;
  83. procedure GetMem(Var p:pointer;Size:Longint);{$ifndef NEWMM}[public,alias:'FPC_GETMEM'];{$endif}
  84. begin
  85. p:=MemoryManager.GetMem(Size);
  86. end;
  87. procedure FreeMem(Var p:pointer;Size:Longint);{$ifndef NEWMM}[public,alias:'FPC_FREEMEM'];{$endif}
  88. begin
  89. MemoryManager.FreeMemSize(p,Size);
  90. p:=nil;
  91. end;
  92. function MaxAvail:Longint;
  93. begin
  94. MaxAvail:=MemoryManager.MaxAvail();
  95. end;
  96. function MemAvail:Longint;
  97. begin
  98. MemAvail:=MemoryManager.MemAvail();
  99. end;
  100. { FPC Additions }
  101. function HeapSize:Longint;
  102. begin
  103. HeapSize:=MemoryManager.HeapSize();
  104. end;
  105. function MemSize(p:pointer):Longint;
  106. begin
  107. MemSize:=MemoryManager.MemSize(p);
  108. end;
  109. { Delphi style }
  110. function FreeMem(var p:pointer):Longint;
  111. begin
  112. Freemem:=MemoryManager.FreeMem(p);
  113. end;
  114. function GetMem(size:longint):pointer;
  115. begin
  116. GetMem:=MemoryManager.GetMem(Size);
  117. end;
  118. function AllocMem(Size:Longint):pointer;
  119. begin
  120. AllocMem:=MemoryManager.AllocMem(size);
  121. end;
  122. function ReAllocMem(var p:pointer;Size:Longint):pointer;
  123. begin
  124. ReAllocMem:=MemoryManager.ReAllocMem(p,size);
  125. end;
  126. { Needed for calls from Assembler }
  127. procedure AsmGetMem(var p:pointer;size:longint);{$ifdef NEWMM}[public,alias:'FPC_GETMEM'];{$endif}
  128. begin
  129. p:=MemoryManager.GetMem(size);
  130. end;
  131. procedure AsmFreeMem(var p:pointer);{$ifdef NEWMM}[public,alias:'FPC_FREEMEM'];{$endif}
  132. begin
  133. if p <> nil then
  134. begin
  135. MemoryManager.FreeMem(p);
  136. p:=nil;
  137. end;
  138. end;
  139. {*****************************************************************************
  140. Heapsize,Memavail,MaxAvail
  141. *****************************************************************************}
  142. function SysHeapsize : longint;
  143. begin
  144. Sysheapsize:=internal_heapsize;
  145. end;
  146. function SysMemavail : longint;
  147. begin
  148. Sysmemavail:=internal_memavail;
  149. end;
  150. function SysMaxavail : longint;
  151. var
  152. hp : pfreerecord;
  153. begin
  154. Sysmaxavail:=heapend-heapptr;
  155. hp:=freelists[0];
  156. while assigned(hp) do
  157. begin
  158. if hp^.size>Sysmaxavail then
  159. Sysmaxavail:=hp^.size;
  160. hp:=hp^.next;
  161. end;
  162. end;
  163. {$ifdef DUMPBLOCKS}
  164. procedure DumpBlocks;
  165. var
  166. s,i,j : longint;
  167. hp : pfreerecord;
  168. begin
  169. for i:=1 to maxblock do
  170. begin
  171. hp:=freelists[i];
  172. j:=0;
  173. while assigned(hp) do
  174. begin
  175. inc(j);
  176. hp:=hp^.next;
  177. end;
  178. writeln('Block ',i*blocksize,': ',j);
  179. end;
  180. { freelist 0 }
  181. hp:=freelists[0];
  182. j:=0;
  183. s:=0;
  184. while assigned(hp) do
  185. begin
  186. inc(j);
  187. if hp^.size>s then
  188. s:=hp^.size;
  189. hp:=hp^.next;
  190. end;
  191. writeln('Main: ',j,' maxsize: ',s);
  192. end;
  193. {$endif}
  194. {*****************************************************************************
  195. SysGetMem
  196. *****************************************************************************}
  197. function SysGetMem(size : longint):pointer;
  198. type
  199. heaperrorproc=function(size:longint):integer;
  200. var
  201. proc : heaperrorproc;
  202. pcurr : pfreerecord;
  203. again : boolean;
  204. s,s1,i,
  205. sizeleft : longint;
  206. {$ifdef BESTMATCH}
  207. pbest : pfreerecord;
  208. {$endif}
  209. begin
  210. { Something to allocate ? }
  211. if size<=0 then
  212. begin
  213. { give an error for < 0 }
  214. if size<0 then
  215. HandleError(204);
  216. { we always need to allocate something, using heapend is not possible,
  217. because heappend can be changed by growheap (PFV) }
  218. size:=1;
  219. end;
  220. { calc to multiply of 16 after adding the needed 8 bytes heaprecord }
  221. size:=(size+sizeof(theaprecord)+(blocksize-1)) and (not (blocksize-1));
  222. dec(internal_memavail,size);
  223. { try to find a block in one of the freelists per size }
  224. s:=size shr blockshr;
  225. if s<=maxblock then
  226. begin
  227. pcurr:=freelists[s];
  228. { correct size match ? }
  229. if assigned(pcurr) then
  230. begin
  231. { create the block we should return }
  232. sysgetmem:=pointer(pcurr)+sizeof(theaprecord);
  233. { fix size }
  234. pcurr^.size:=pcurr^.size or usedmask;
  235. { update freelist }
  236. freelists[s]:=pcurr^.next;
  237. if assigned(freelists[s]) then
  238. freelists[s]^.prev:=nil;
  239. exit;
  240. end;
  241. {$ifdef SMALLATHEAPPTR}
  242. if heapend-heapptr>size then
  243. begin
  244. sysgetmem:=heapptr;
  245. pheaprecord(sysgetmem)^.size:=size or usedmask;
  246. inc(sysgetmem,sizeof(theaprecord));
  247. inc(heapptr,size);
  248. exit;
  249. end;
  250. {$endif}
  251. {$ifdef REUSEBIGGER}
  252. { try a bigger block }
  253. s1:=s+s;
  254. i:=0;
  255. while (s1<=maxblock) and (i<maxreusebigger) do
  256. begin
  257. pcurr:=freelists[s1];
  258. if assigned(pcurr) then
  259. begin
  260. s:=s1;
  261. break;
  262. end;
  263. inc(s1);
  264. inc(i);
  265. end;
  266. {$endif}
  267. end
  268. else
  269. pcurr:=nil;
  270. { not found, then check the main freelist for the first match }
  271. if not(assigned(pcurr)) then
  272. begin
  273. s:=0;
  274. {$ifdef BESTMATCH}
  275. pbest:=nil;
  276. {$endif}
  277. pcurr:=freelists[0];
  278. while assigned(pcurr) do
  279. begin
  280. {$ifdef BESTMATCH}
  281. if pcurr^.size=size then
  282. break
  283. else
  284. begin
  285. if (pcurr^.size>size) then
  286. begin
  287. if (not assigned(pbest)) or
  288. (pcurr^.size<pbest^.size) then
  289. pbest:=pcurr;
  290. end;
  291. end;
  292. {$else}
  293. if pcurr^.size>=size then
  294. break;
  295. {$endif}
  296. pcurr:=pcurr^.next;
  297. end;
  298. {$ifdef BESTMATCH}
  299. if not assigned(pcurr) then
  300. pcurr:=pbest;
  301. {$endif}
  302. end;
  303. { have we found a block, then get it and free up the other left part,
  304. if no blocks are found then allocated at the heapptr or grow the heap }
  305. if assigned(pcurr) then
  306. begin
  307. { get pointer of the block we should return }
  308. sysgetmem:=pointer(pcurr);
  309. { remove the current block from the freelist }
  310. if assigned(pcurr^.next) then
  311. pcurr^.next^.prev:=pcurr^.prev;
  312. if assigned(pcurr^.prev) then
  313. pcurr^.prev^.next:=pcurr^.next
  314. else
  315. freelists[s]:=pcurr^.next;
  316. { create the left over freelist block, if at least 16 bytes are free }
  317. sizeleft:=pcurr^.size-size;
  318. if sizeleft>sizeof(tfreerecord) then
  319. begin
  320. pcurr:=pfreerecord(pointer(pcurr)+size);
  321. pcurr^.size:=sizeleft;
  322. { insert the block in the freelist }
  323. pcurr^.prev:=nil;
  324. s1:=sizeleft shr blockshr;
  325. if s1>maxblock then
  326. s1:=0;
  327. pcurr^.next:=freelists[s1];
  328. if assigned(freelists[s1]) then
  329. freelists[s1]^.prev:=pcurr;
  330. freelists[s1]:=pcurr;
  331. end;
  332. { create the block we need to return }
  333. pheaprecord(sysgetmem)^.size:=size or usedmask;
  334. inc(sysgetmem,sizeof(theaprecord));
  335. exit;
  336. end;
  337. { Lastly, the top of the heap is checked, to see if there is }
  338. { still memory available. }
  339. repeat
  340. again:=false;
  341. if heapend-heapptr>size then
  342. begin
  343. sysgetmem:=heapptr;
  344. pheaprecord(sysgetmem)^.size:=size or usedmask;
  345. inc(sysgetmem,sizeof(theaprecord));
  346. inc(heapptr,size);
  347. exit;
  348. end;
  349. { Call the heaperror proc }
  350. if assigned(heaperror) then
  351. begin
  352. proc:=heaperrorproc(heaperror);
  353. case proc(size) of
  354. 0 : HandleError(203);
  355. 1 : sysgetmem:=nil;
  356. 2 : again:=true;
  357. end;
  358. end
  359. else
  360. HandleError(203);
  361. until not again;
  362. end;
  363. {*****************************************************************************
  364. SysFreeMem
  365. *****************************************************************************}
  366. Function SysFreeMem(var p : pointer):Longint;
  367. var
  368. s : longint;
  369. pcurr : pfreerecord;
  370. begin
  371. if p=nil then
  372. HandleError(204);
  373. { fix p to point to the heaprecord }
  374. pcurr:=pfreerecord(pointer(p)-sizeof(theaprecord));
  375. pcurr^.size:=pcurr^.size and sizemask;
  376. inc(internal_memavail,pcurr^.size);
  377. { insert the block in it's freelist }
  378. pcurr^.prev:=nil;
  379. s:=pcurr^.size shr blockshr;
  380. if s>maxblock then
  381. s:=0;
  382. pcurr^.next:=freelists[s];
  383. if assigned(pcurr^.next) then
  384. pcurr^.next^.prev:=pcurr;
  385. freelists[s]:=pcurr;
  386. p:=nil;
  387. SysFreeMem:=pcurr^.size;
  388. end;
  389. {*****************************************************************************
  390. SysFreeMemSize
  391. *****************************************************************************}
  392. Function SysFreeMemSize(var p : pointer;size : longint):longint;
  393. var
  394. s : longint;
  395. pcurr : pfreerecord;
  396. begin
  397. SysFreeMemSize:=0;
  398. if size<=0 then
  399. begin
  400. if size<0 then
  401. HandleError(204);
  402. p:=nil;
  403. exit;
  404. end;
  405. if p=nil then
  406. HandleError(204);
  407. { fix p to point to the heaprecord }
  408. pcurr:=pfreerecord(pointer(p)-sizeof(theaprecord));
  409. pcurr^.size:=pcurr^.size and sizemask;
  410. inc(internal_memavail,pcurr^.size);
  411. { size check }
  412. size:=(size+sizeof(theaprecord)+(blocksize-1)) and (not (blocksize-1));
  413. if size<>pcurr^.size then
  414. HandleError(204);
  415. { insert the block in it's freelist }
  416. pcurr^.prev:=nil;
  417. s:=pcurr^.size shr blockshr;
  418. if s>maxblock then
  419. s:=0;
  420. pcurr^.next:=freelists[s];
  421. if assigned(pcurr^.next) then
  422. pcurr^.next^.prev:=pcurr;
  423. freelists[s]:=pcurr;
  424. p:=nil;
  425. SysFreeMemSize:=pcurr^.size;
  426. end;
  427. {*****************************************************************************
  428. SysMemSize
  429. *****************************************************************************}
  430. function SysMemSize(p:pointer):longint;
  431. begin
  432. SysMemSize:=(pheaprecord(pointer(p)-sizeof(theaprecord))^.size-sizeof(theaprecord)) and sizemask;
  433. end;
  434. {*****************************************************************************
  435. SysAllocMem
  436. *****************************************************************************}
  437. function SysAllocMem(size : longint):pointer;
  438. begin
  439. sysallocmem:=MemoryManager.GetMem(size);
  440. if sysallocmem<>nil then
  441. FillChar(sysallocmem^,size,0);
  442. end;
  443. {*****************************************************************************
  444. SysReAllocMem
  445. *****************************************************************************}
  446. function SysReAllocMem(var p:pointer;size : longint):pointer;
  447. var
  448. currsize,
  449. foundsize,
  450. sizeleft,
  451. s : longint;
  452. p2 : pointer;
  453. hp,
  454. pnew,
  455. pcurr : pfreerecord;
  456. begin
  457. { Allocate a new block? }
  458. if p=nil then
  459. begin
  460. p:=MemoryManager.GetMem(size);
  461. SysReallocmem:=P;
  462. exit;
  463. end;
  464. { fix needed size }
  465. size:=(size+sizeof(theaprecord)+(blocksize-1)) and (not (blocksize-1));
  466. { fix p to point to the heaprecord }
  467. pcurr:=pfreerecord(pointer(p)-sizeof(theaprecord));
  468. currsize:=pcurr^.size and sizemask;
  469. { is the allocated block still correct? }
  470. if currsize=size then
  471. begin
  472. SysReAllocMem:=p;
  473. exit;
  474. end;
  475. { do we need to allocate more memory ? }
  476. if size>currsize then
  477. begin
  478. { the size is bigger than the previous size, we need to allocated more mem.
  479. We first check if the blocks after the current block are free. If not we
  480. simply call getmem/freemem to get the new block }
  481. foundsize:=pcurr^.size and sizemask;
  482. hp:=pcurr;
  483. repeat
  484. { get next block }
  485. hp:=pfreerecord(pointer(hp)+(hp^.size and sizemask));
  486. { when we're at heapptr then we can stop }
  487. if (hp=heapptr) then
  488. begin
  489. inc(foundsize,heapend-heapptr);
  490. break;
  491. end;
  492. { block used? }
  493. if (hp^.size and usedmask)<>0 then
  494. break;
  495. inc(foundsize,hp^.size and sizemask);
  496. until (foundsize>=size);
  497. { found enough free blocks? }
  498. if foundsize>=size then
  499. begin
  500. { we walk the list again and remove all blocks }
  501. foundsize:=pcurr^.size and sizemask;
  502. hp:=pcurr;
  503. repeat
  504. { get next block }
  505. hp:=pfreerecord(pointer(hp)+(hp^.size and sizemask));
  506. { when we're at heapptr then we can increase it, if there is enough
  507. room is already checked }
  508. if (hp=heapptr) then
  509. begin
  510. inc(heapptr,size-foundsize);
  511. foundsize:=size;
  512. break;
  513. end;
  514. s:=hp^.size and sizemask;
  515. inc(foundsize,s);
  516. s:=s shr blockshr;
  517. if s>maxblock then
  518. s:=0;
  519. { remove block from freelist }
  520. if assigned(hp^.next) then
  521. hp^.next^.prev:=hp^.prev;
  522. if assigned(hp^.prev) then
  523. hp^.prev^.next:=hp^.next
  524. else
  525. freelists[s]:=hp^.next;
  526. until (foundsize>=size);
  527. pcurr^.size:=foundsize or usedmask;
  528. end
  529. else
  530. begin
  531. { we need to call getmem/move/freemem }
  532. p2:=MemoryManager.GetMem(size);
  533. if p2<>nil then
  534. Move(p^,p2^,size);
  535. MemoryManager.Freemem(p);
  536. p:=p2;
  537. SysReAllocMem:=p;
  538. exit;
  539. end;
  540. currsize:=pcurr^.size and sizemask;
  541. end;
  542. { is the size smaller then we can adjust the block to that size and insert
  543. the other part into the freelist }
  544. if size<currsize then
  545. begin
  546. { create the left over freelist block, if at least 16 bytes are free }
  547. sizeleft:=currsize-size;
  548. if sizeleft>sizeof(tfreerecord) then
  549. begin
  550. pnew:=pfreerecord(pointer(pcurr)+size);
  551. pnew^.size:=sizeleft;
  552. { insert the block in the freelist }
  553. pnew^.prev:=nil;
  554. s:=sizeleft shr blockshr;
  555. if s>maxblock then
  556. s:=0;
  557. pnew^.next:=freelists[s];
  558. if assigned(freelists[s]) then
  559. freelists[s]^.prev:=pnew;
  560. freelists[s]:=pnew;
  561. end;
  562. { fix the size of the current block and leave }
  563. pcurr^.size:=size or usedmask;
  564. end;
  565. SysReAllocMem:=p;
  566. end;
  567. {*****************************************************************************
  568. Mark/Release
  569. *****************************************************************************}
  570. procedure release(var p : pointer);
  571. begin
  572. end;
  573. procedure mark(var p : pointer);
  574. begin
  575. end;
  576. {*****************************************************************************
  577. Grow Heap
  578. *****************************************************************************}
  579. function growheap(size :longint) : integer;
  580. var
  581. sizeleft,
  582. NewPos,
  583. wantedsize : longint;
  584. pcurr : pfreerecord;
  585. begin
  586. {$ifdef DUMPGROW}
  587. writeln('grow ',size);
  588. DumpBlocks;
  589. {$endif}
  590. wantedsize:=size;
  591. { Allocate by 64K size }
  592. size:=(size+$ffff) and $ffff0000;
  593. { first try 256K (default) }
  594. if size<=GrowHeapSize1 then
  595. begin
  596. NewPos:=Sbrk(GrowHeapSize1);
  597. if NewPos>0 then
  598. size:=GrowHeapSize1;
  599. end
  600. else
  601. { second try 1024K (default) }
  602. if size<=GrowHeapSize2 then
  603. begin
  604. NewPos:=Sbrk(GrowHeapSize2);
  605. if NewPos>0 then
  606. size:=GrowHeapSize2;
  607. end
  608. { else alloate the needed bytes }
  609. else
  610. NewPos:=SBrk(size);
  611. { try again }
  612. if NewPos=-1 then
  613. begin
  614. NewPos:=Sbrk(size);
  615. if NewPos=-1 then
  616. begin
  617. GrowHeap:=0;
  618. Exit;
  619. end;
  620. end;
  621. { increase heapend or add to freelist }
  622. if heapend=pointer(newpos) then
  623. begin
  624. heapend:=pointer(newpos+size);
  625. end
  626. else
  627. begin
  628. { create freelist entry for old heapptr-heapend }
  629. sizeleft:=heapend-heapptr;
  630. if sizeleft>sizeof(tfreerecord) then
  631. begin
  632. pcurr:=pfreerecord(heapptr);
  633. pcurr^.size:=sizeleft;
  634. { insert the block in the freelist }
  635. pcurr^.next:=freelists[0];
  636. pcurr^.prev:=nil;
  637. if assigned(freelists[0]) then
  638. freelists[0]^.prev:=pcurr;
  639. freelists[0]:=pcurr;
  640. end;
  641. { now set the new heapptr,heapend to the new block }
  642. heapptr:=pointer(newpos);
  643. heapend:=pointer(newpos+size);
  644. end;
  645. { set the total new heap size }
  646. inc(internal_memavail,size);
  647. inc(internal_heapsize,size);
  648. { try again }
  649. GrowHeap:=2;
  650. end;
  651. {*****************************************************************************
  652. InitHeap
  653. *****************************************************************************}
  654. { This function will initialize the Heap manager and need to be called from
  655. the initialization of the system unit }
  656. procedure InitHeap;
  657. begin
  658. FillChar(FreeLists,sizeof(TFreeLists),0);
  659. internal_heapsize:=GetHeapSize;
  660. internal_memavail:=internal_heapsize;
  661. HeapOrg:=GetHeapStart;
  662. HeapPtr:=HeapOrg;
  663. HeapEnd:=HeapOrg+internal_memavail;
  664. HeapError:=@GrowHeap;
  665. end;
  666. {
  667. $Log$
  668. Revision 1.23 1999-11-10 22:29:51 michael
  669. + Fixed sysreallocmem
  670. Revision 1.22 1999/11/01 13:56:50 peter
  671. * freemem,reallocmem now get var argument
  672. Revision 1.21 1999/10/30 17:39:05 peter
  673. * memorymanager expanded with allocmem/reallocmem
  674. Revision 1.20 1999/10/22 22:03:07 sg
  675. * FreeMem(p) is ignored if p is NIL, instead of throwing an
  676. runtime error 204. (Delphi ignores NIL FreeMem's, too)
  677. Revision 1.19 1999/10/01 07:55:54 peter
  678. * fixed memsize which forgot the sizemask
  679. Revision 1.18 1999/09/22 21:59:02 peter
  680. * best match for main freelist
  681. * removed root field, saves 4 bytes per block
  682. * fixed crash in dumpblocks
  683. Revision 1.17 1999/09/20 14:17:37 peter
  684. * fixed growheap freelist addition when heapend-heapptr<blocksize
  685. Revision 1.16 1999/09/17 17:14:12 peter
  686. + new heap manager supporting delphi freemem(pointer)
  687. }