1
2
3
4
5
6 namespace System
7 {
8
9
10 private long pageSize = -1;
11 private Block empty;
12 private Block* free = null;
13
14 public nothrow ulong FreeAddr()
15 {
16 return cast<ulong>(cast<void*>(free));
17 }
18
19 internal class Block
20 {
21 public nothrow Block() : next(null), size(0) {}
22 public Block* next;
23 public long size;
24 }
25
26 internal Block* MoreCore(long nb)
27 {
28 long bigBlock = Align(nb, pageSize);
29 int numPages = cast<int>(bigBlock / pageSize);
30 long addr = heap_start() + heap_length();
31 long sizeAllocated = allocate_memory_pages(numPages);
32 if (sizeAllocated == -1)
33 {
34 exit(254);
35 }
36 long allocatedUnits = sizeAllocated / sizeof(Block);
37 Block* a = cast<Block*>(cast<void*>(cast<ulong>(addr)));
38 a->size = allocatedUnits;
39 MemFree(a + 1);
40 return free;
41 }
42
43 public nothrow void* MemAlloc(long numBytes)
44 {
45 Block* prev = free;
46 if (free == null)
47 {
48 pageSize = memory_page_size();
49 empty.next = ∅
50 prev = ∅
51 free = prev;
52 }
53 long nb = Align(numBytes, sizeof(Block)) + sizeof(Block);
54 long numUnits = nb / sizeof(Block);
55 Block* p = prev->next;
56 while (true)
57 {
58 if (p->size >= numUnits)
59 {
60 if (p->size == numUnits)
61 {
62 prev->next = p->next;
63 }
64 else
65 {
66 p->size = p->size - numUnits;
67 p = p + p->size;
68 p->size = numUnits;
69 }
70 free = prev;
71 return p + 1;
72 }
73 if (p == free)
74 {
75 p = MoreCore(nb);
76 }
77 prev = p;
78 p = p->next;
79 }
80 }
81
82 public nothrow void MemFree(void* ptr)
83 {
84 Block* bp = cast<Block*>(ptr) - 1;
85 Block* p;
86 for (p = free; !(bp > p && bp < p->next); p = p->next;)
87 {
88 if (p >= p->next && (bp > p || bp < p->next))
89 {
90 break;
91 }
92 }
93 if (bp + bp->size == p->next)
94 {
95 bp->size = bp->size + p->next->size;
96 bp->next = p->next->next;
97 }
98 else
99 {
100 bp->next = p->next;
101 }
102 if (p + p->size == bp)
103 {
104 p->size = p->size + bp->size;
105 p->next = bp->next;
106 }
107 else
108 {
109 p->next = bp;
110 }
111 free = p;
112 }
113 }