mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Refactor allocator locations.
This commit is contained in:
@@ -1,5 +1,32 @@
|
||||
module std::core::mem::allocator;
|
||||
|
||||
struct ArenaAllocator
|
||||
{
|
||||
inline Allocator allocator;
|
||||
char[] data;
|
||||
usz used;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a memory arena for use using the provided bytes.
|
||||
*
|
||||
* @require this != null
|
||||
**/
|
||||
fn void ArenaAllocator.init(ArenaAllocator* this, char[] data)
|
||||
{
|
||||
this.function = &arena_allocator_function;
|
||||
this.data = data;
|
||||
this.used = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require this != null
|
||||
**/
|
||||
fn void ArenaAllocator.reset(ArenaAllocator* this)
|
||||
{
|
||||
this.used = 0;
|
||||
}
|
||||
|
||||
struct ArenaAllocatorHeader
|
||||
{
|
||||
usz size;
|
||||
|
||||
@@ -1,5 +1,50 @@
|
||||
module std::core::mem::allocator;
|
||||
|
||||
struct DynamicArenaAllocator
|
||||
{
|
||||
inline Allocator allocator;
|
||||
Allocator* backing_allocator;
|
||||
DynamicArenaPage* page;
|
||||
DynamicArenaPage* unused_page;
|
||||
usz page_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require page_size >= 128
|
||||
* @require this != null
|
||||
**/
|
||||
fn void DynamicArenaAllocator.init(DynamicArenaAllocator* this, usz page_size, Allocator* backing_allocator = mem::current_allocator())
|
||||
{
|
||||
this.function = &dynamic_arena_allocator_function;
|
||||
this.page = null;
|
||||
this.unused_page = null;
|
||||
this.page_size = page_size;
|
||||
this.backing_allocator = backing_allocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require this != null
|
||||
**/
|
||||
fn void DynamicArenaAllocator.destroy(DynamicArenaAllocator* this)
|
||||
{
|
||||
DynamicArenaPage* page = this.page;
|
||||
while (page)
|
||||
{
|
||||
DynamicArenaPage* next_page = page.prev_arena;
|
||||
this.backing_allocator.free(page)!!;
|
||||
page = next_page;
|
||||
}
|
||||
page = this.unused_page;
|
||||
while (page)
|
||||
{
|
||||
DynamicArenaPage* next_page = page.prev_arena;
|
||||
this.backing_allocator.free(page)!!;
|
||||
page = next_page;
|
||||
}
|
||||
this.page = null;
|
||||
this.unused_page = null;
|
||||
}
|
||||
|
||||
struct DynamicArenaPage
|
||||
{
|
||||
void* memory;
|
||||
|
||||
@@ -107,105 +107,5 @@ fn usz alignment_for_allocation(usz alignment) @inline @private
|
||||
return alignment;
|
||||
}
|
||||
|
||||
struct DynamicArenaAllocator
|
||||
{
|
||||
inline Allocator allocator;
|
||||
Allocator* backing_allocator;
|
||||
DynamicArenaPage* page;
|
||||
DynamicArenaPage* unused_page;
|
||||
usz page_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require page_size >= 128
|
||||
* @require this != null
|
||||
**/
|
||||
fn void DynamicArenaAllocator.init(DynamicArenaAllocator* this, usz page_size, Allocator* backing_allocator = mem::current_allocator())
|
||||
{
|
||||
this.function = &dynamic_arena_allocator_function;
|
||||
this.page = null;
|
||||
this.unused_page = null;
|
||||
this.page_size = page_size;
|
||||
this.backing_allocator = backing_allocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require this != null
|
||||
**/
|
||||
fn void DynamicArenaAllocator.destroy(DynamicArenaAllocator* this)
|
||||
{
|
||||
DynamicArenaPage* page = this.page;
|
||||
while (page)
|
||||
{
|
||||
DynamicArenaPage* next_page = page.prev_arena;
|
||||
this.backing_allocator.free(page)!!;
|
||||
page = next_page;
|
||||
}
|
||||
page = this.unused_page;
|
||||
while (page)
|
||||
{
|
||||
DynamicArenaPage* next_page = page.prev_arena;
|
||||
this.backing_allocator.free(page)!!;
|
||||
page = next_page;
|
||||
}
|
||||
this.page = null;
|
||||
this.unused_page = null;
|
||||
}
|
||||
|
||||
|
||||
struct ArenaAllocator
|
||||
{
|
||||
inline Allocator allocator;
|
||||
char[] data;
|
||||
usz used;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a memory arena for use using the provided bytes.
|
||||
*
|
||||
* @require this != null
|
||||
**/
|
||||
fn void ArenaAllocator.init(ArenaAllocator* this, char[] data)
|
||||
{
|
||||
this.function = &arena_allocator_function;
|
||||
this.data = data;
|
||||
this.used = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require this != null
|
||||
**/
|
||||
fn void ArenaAllocator.reset(ArenaAllocator* this)
|
||||
{
|
||||
this.used = 0;
|
||||
}
|
||||
|
||||
const usz WASM_BLOCK_SIZE = 65536;
|
||||
|
||||
WasmMemory wasm_memory;
|
||||
|
||||
struct WasmMemory
|
||||
{
|
||||
usz allocation;
|
||||
uptr use;
|
||||
}
|
||||
|
||||
fn char[]! WasmMemory.allocate_block(WasmMemory* this, usz bytes)
|
||||
{
|
||||
if (!this.allocation)
|
||||
{
|
||||
this.allocation = $$wasm_memory_size(0) * WASM_BLOCK_SIZE;
|
||||
}
|
||||
isz bytes_required = bytes + this.use - this.allocation;
|
||||
if (bytes_required <= 0)
|
||||
{
|
||||
defer this.use += bytes;
|
||||
return ((char*)this.use)[:bytes];
|
||||
}
|
||||
|
||||
usz blocks_required = (bytes_required + WASM_BLOCK_SIZE + 1) / WASM_BLOCK_SIZE;
|
||||
if ($$wasm_memory_grow(0, blocks_required) == -1) return AllocationFailure.OUT_OF_MEMORY!;
|
||||
this.allocation = $$wasm_memory_size(0) * WASM_BLOCK_SIZE;
|
||||
defer this.use += bytes;
|
||||
return ((char*)this.use)[:bytes];
|
||||
}
|
||||
32
lib/std/core/os/wasm_memory.c3
Normal file
32
lib/std/core/os/wasm_memory.c3
Normal file
@@ -0,0 +1,32 @@
|
||||
module std::core::mem::allocator;
|
||||
|
||||
|
||||
const usz WASM_BLOCK_SIZE = 65536;
|
||||
|
||||
WasmMemory wasm_memory;
|
||||
|
||||
struct WasmMemory
|
||||
{
|
||||
usz allocation;
|
||||
uptr use;
|
||||
}
|
||||
|
||||
fn char[]! WasmMemory.allocate_block(WasmMemory* this, usz bytes)
|
||||
{
|
||||
if (!this.allocation)
|
||||
{
|
||||
this.allocation = $$wasm_memory_size(0) * WASM_BLOCK_SIZE;
|
||||
}
|
||||
isz bytes_required = bytes + this.use - this.allocation;
|
||||
if (bytes_required <= 0)
|
||||
{
|
||||
defer this.use += bytes;
|
||||
return ((char*)this.use)[:bytes];
|
||||
}
|
||||
|
||||
usz blocks_required = (bytes_required + WASM_BLOCK_SIZE + 1) / WASM_BLOCK_SIZE;
|
||||
if ($$wasm_memory_grow(0, blocks_required) == -1) return AllocationFailure.OUT_OF_MEMORY!;
|
||||
this.allocation = $$wasm_memory_size(0) * WASM_BLOCK_SIZE;
|
||||
defer this.use += bytes;
|
||||
return ((char*)this.use)[:bytes];
|
||||
}
|
||||
Reference in New Issue
Block a user