Skip to content

Commit c62af02

Browse files
committed
Implement bump pointer allocator for allocTmp()
Replace individual calloc() calls with efficient block-based allocation: - Allocate from larger blocks (4KB initial, grows to 64KB max) - O(1) pointer bump for allocations within block - 8-byte alignment for structure safety - Blocks freed per-frame in flushAllocTmp() Benefits: - Fewer malloc calls: 1-2 blocks vs 20-30 individual allocations/frame - Better cache locality with contiguous allocations - Simpler cleanup: free 1-2 blocks instead of looping 20-30 times
1 parent 1d4fc88 commit c62af02

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

lib/imgui-unit/asciiz.js

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,18 +118,58 @@ function tmpAsciiz(s: any): c_ptr {
118118
}
119119

120120

121-
let _allocas: c_ptr[] = [];
121+
// Bump pointer allocator for temporary allocations
122+
const INITIAL_BLOCK_SIZE = 4096;
123+
const MAX_BLOCK_SIZE = 65536;
124+
const ALIGNMENT = 8;
125+
126+
let _blocks: c_ptr[] = [];
127+
let _currentBlock: c_ptr = c_null;
128+
let _currentOffset: number = 0;
129+
let _currentSize: number = 0;
130+
let _nextBlockSize: number = INITIAL_BLOCK_SIZE;
122131

123132
function allocTmp(size: number): c_ptr {
124-
let res = calloc(size);
125-
_allocas.push(res);
126-
return res;
133+
// Round up to alignment boundary
134+
size = (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1);
135+
136+
// Check if allocation fits in current block
137+
if (_currentOffset + size <= _currentSize) {
138+
let ptr = _sh_ptr_add(_currentBlock, _currentOffset);
139+
_currentOffset += size;
140+
return ptr;
141+
}
142+
143+
// Need a new block
144+
let blockSize = _nextBlockSize;
145+
// Large allocation - allocate exact size but don't grow block size
146+
if (size > blockSize)
147+
blockSize = size;
148+
149+
let newBlock = calloc(blockSize);
150+
_blocks.push(newBlock);
151+
_currentBlock = newBlock;
152+
_currentSize = blockSize;
153+
_currentOffset = size;
154+
155+
// Grow next block size
156+
if (_nextBlockSize < MAX_BLOCK_SIZE)
157+
_nextBlockSize = _nextBlockSize * 2;
158+
159+
return newBlock;
127160
}
128161

129162
function flushAllocTmp(): void {
130-
for (let i = 0; i < _allocas.length; ++i) {
131-
_free(_allocas[i]);
163+
// Free all blocks
164+
for (let i = 0; i < _blocks.length; ++i) {
165+
_free(_blocks[i]);
132166
}
167+
168+
// Reset all state
133169
let empty: c_ptr[] = [];
134-
_allocas = empty;
135-
}
170+
_blocks = empty;
171+
_currentBlock = c_null;
172+
_currentOffset = 0;
173+
_currentSize = 0;
174+
_nextBlockSize = INITIAL_BLOCK_SIZE;
175+
}

0 commit comments

Comments
 (0)