|
1 |
| -// An simple arena allocator that provides a `clear_memory` function to reset |
2 |
| -// everything to the initial state. A user must have to make sure that there |
3 |
| -// a no more references to cleared memory. |
| 1 | +// A simple arena allocator that provides a `clear_memory` function to reset |
| 2 | +// the heap to its initial state. A user has to make sure that there are no |
| 3 | +// more references to cleared memory afterwards. Always aligns to 8 bytes. |
4 | 4 |
|
5 | 5 | const ALIGN_LOG2: usize = 3;
|
6 | 6 | const ALIGN_SIZE: usize = 1 << ALIGN_LOG2;
|
7 | 7 | const ALIGN_MASK: usize = ALIGN_SIZE - 1;
|
8 | 8 |
|
9 |
| -var HEAP_OFFSET: usize = HEAP_BASE; // generated by the compiler |
| 9 | +var HEAP_OFFSET: usize = HEAP_BASE; |
10 | 10 |
|
11 | 11 | export function allocate_memory(size: usize): usize {
|
12 | 12 | if (!size) return 0;
|
13 |
| - var len: i32 = current_memory(); |
14 |
| - if (HEAP_OFFSET + size > <usize>len << 16) |
15 |
| - if(grow_memory(max<i32>(<i32>ceil<f64>(<f64>size / 65536), len * 2 - len)) < 0) |
16 |
| - unreachable(); |
17 |
| - var ptr: usize = HEAP_OFFSET; |
18 |
| - if ((HEAP_OFFSET += size) & ALIGN_MASK) // align next offset |
19 |
| - HEAP_OFFSET = (HEAP_OFFSET | ALIGN_MASK) + 1; |
20 |
| - set_memory(ptr, 0, size); |
| 13 | + var ptr = HEAP_OFFSET; |
| 14 | + var off = (ptr + size + ALIGN_MASK) & ~ALIGN_MASK; |
| 15 | + var avail = <usize>current_memory() << 16; |
| 16 | + if (off > avail && grow_memory( |
| 17 | + max( |
| 18 | + (((off + 0xffff) & ~0xffff) - avail) >> 16, // minimum required pages |
| 19 | + avail >> 16 // at least double memory |
| 20 | + ) |
| 21 | + ) < 0) unreachable(); // out of memory |
| 22 | + HEAP_OFFSET = off; |
21 | 23 | return ptr;
|
22 | 24 | }
|
23 | 25 |
|
|
0 commit comments