mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-13 23:11:41 +00:00
Make TLSF always align to 8 bytes, see #15
This commit is contained in:
@ -1,8 +1,9 @@
|
|||||||
/////////////// A simple yet effective Arena Memory Allocator /////////////////
|
/**
|
||||||
|
* @file Arena Memory Allocator
|
||||||
// Provides a `reset_memory` function to reset the heap to its initial state. A
|
*
|
||||||
// user has to make sure that there are no more references to cleared memory
|
* Provides a `reset_memory` function to reset the heap to its initial state. A user has to make
|
||||||
// afterwards. Always aligns to 8 bytes.
|
* sure that there are no more references to cleared memory afterwards. Always aligns to 8 bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
const ALIGN_LOG2: usize = 3;
|
const ALIGN_LOG2: usize = 3;
|
||||||
const ALIGN_SIZE: usize = 1 << ALIGN_LOG2;
|
const ALIGN_SIZE: usize = 1 << ALIGN_LOG2;
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
///////////////////////// Emscripten Memory Allocator //////////////////////////
|
/**
|
||||||
|
* @file Emscripten Memory Allocator
|
||||||
// Uses Emscripten's exported _malloc and _free implementations, i.e., when
|
*
|
||||||
// linking with Emscripten-compiled programs that already provide these.
|
* Uses Emscripten's exported _malloc and _free implementations, i.e., when linking with
|
||||||
// Differs from 'system' in that their names are prefixed with an underscore.
|
* Emscripten-compiled programs that already provide these. Differs from 'system' in that their
|
||||||
|
* names are prefixed with an underscore.
|
||||||
|
*/
|
||||||
|
|
||||||
declare function _malloc(size: usize): usize;
|
declare function _malloc(size: usize): usize;
|
||||||
declare function _free(ptr: usize): void;
|
declare function _free(ptr: usize): void;
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @file Memory Allocator Stub
|
||||||
|
*/
|
||||||
|
|
||||||
export function allocate_memory(size: usize): usize {
|
export function allocate_memory(size: usize): usize {
|
||||||
throw new Error("not supported");
|
throw new Error("not supported");
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
/////////////////////////// System Memory Allocator ////////////////////////////
|
/**
|
||||||
|
* @file System Memory Allocator
|
||||||
// Uses the environment's malloc and free implementations, i.e., when linking
|
*
|
||||||
// with other C-like programs that already provide these.
|
* Uses the environment's malloc and free implementations, i.e., when linking with other C-like
|
||||||
|
* programs that already provide these.
|
||||||
|
*/
|
||||||
|
|
||||||
declare function malloc(size: usize): usize;
|
declare function malloc(size: usize): usize;
|
||||||
declare function free(ptr: usize): void;
|
declare function free(ptr: usize): void;
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
////////////// TLSF (Two-Level Segregate Fit) Memory Allocator ////////////////
|
/**
|
||||||
|
* @file Two-Level Segregate Fit Memory Allocator
|
||||||
|
*
|
||||||
|
* A general purpose dynamic memory allocator specifically designed to meet real-time requirements.
|
||||||
|
* Always aligns to 8 bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
// ╒══════════════ Block size interpretation (32-bit) ═════════════╕
|
// ╒══════════════ Block size interpretation (32-bit) ═════════════╕
|
||||||
// 3 2 1
|
// 3 2 1
|
||||||
@ -8,7 +13,7 @@
|
|||||||
// └───────────────────────────────────────────────┴─────────╨─────┘
|
// └───────────────────────────────────────────────┴─────────╨─────┘
|
||||||
// FL: first level, SL: second level, AL: alignment, SB: small block
|
// FL: first level, SL: second level, AL: alignment, SB: small block
|
||||||
|
|
||||||
const AL_BITS: u32 = sizeof<usize>() == sizeof<u32>() ? 2 : 3;
|
const AL_BITS: u32 = 3; // always align to 8 bytes
|
||||||
const AL_SIZE: usize = 1 << <usize>AL_BITS;
|
const AL_SIZE: usize = 1 << <usize>AL_BITS;
|
||||||
const AL_MASK: usize = AL_SIZE - 1;
|
const AL_MASK: usize = AL_SIZE - 1;
|
||||||
|
|
||||||
@ -46,8 +51,6 @@ const LEFT_FREE: usize = 1 << 1;
|
|||||||
/** Mask to obtain all tags. */
|
/** Mask to obtain all tags. */
|
||||||
const TAGS: usize = FREE | LEFT_FREE;
|
const TAGS: usize = FREE | LEFT_FREE;
|
||||||
|
|
||||||
assert(AL_BITS >= 2); // alignment must be large enough to store all tags
|
|
||||||
|
|
||||||
/** Block structure. */
|
/** Block structure. */
|
||||||
@unmanaged
|
@unmanaged
|
||||||
class Block {
|
class Block {
|
||||||
@ -56,7 +59,7 @@ class Block {
|
|||||||
info: usize;
|
info: usize;
|
||||||
|
|
||||||
/** End offset of the {@link Block#info} field. User data starts here. */
|
/** End offset of the {@link Block#info} field. User data starts here. */
|
||||||
static readonly INFO: usize = sizeof<usize>();
|
static readonly INFO: usize = (sizeof<usize>() + AL_MASK) & ~AL_MASK;
|
||||||
|
|
||||||
/** Previous free block, if any. Only valid if free. */
|
/** Previous free block, if any. Only valid if free. */
|
||||||
prev: Block | null;
|
prev: Block | null;
|
||||||
@ -64,7 +67,7 @@ class Block {
|
|||||||
next: Block | null;
|
next: Block | null;
|
||||||
|
|
||||||
/** Minimum size of a block, excluding {@link Block#info}. */
|
/** Minimum size of a block, excluding {@link Block#info}. */
|
||||||
static readonly MIN_SIZE: usize = 3 * sizeof<usize>(); // prev + next + jump
|
static readonly MIN_SIZE: usize = (3 * sizeof<usize>() + AL_MASK) & ~AL_MASK;// prev + next + jump
|
||||||
|
|
||||||
/** Maximum size of a used block, excluding {@link Block#info}. */
|
/** Maximum size of a used block, excluding {@link Block#info}. */
|
||||||
static readonly MAX_SIZE: usize = 1 << (FL_BITS + SB_BITS);
|
static readonly MAX_SIZE: usize = 1 << (FL_BITS + SB_BITS);
|
||||||
@ -445,7 +448,7 @@ export function allocate_memory(size: usize): usize {
|
|||||||
root.setHead(fl, sl, null);
|
root.setHead(fl, sl, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root.addMemory(rootOffset + Root.SIZE, current_memory() << 16);
|
root.addMemory((rootOffset + Root.SIZE + AL_MASK) & ~AL_MASK, current_memory() << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
// search for a suitable block
|
// search for a suitable block
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @file Buddy Memory Allocator
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2018 Evan Wallace
|
Copyright 2018 Evan Wallace
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,8 @@ function runner(allocator, runs, allocs) {
|
|||||||
size = (size + 3) & ~3;
|
size = (size + 3) & ~3;
|
||||||
var ptr = allocator.allocate_memory(size);
|
var ptr = allocator.allocate_memory(size);
|
||||||
if (!ptr) throw Error();
|
if (!ptr) throw Error();
|
||||||
if (ptrs.indexOf(ptr) >= 0) throw Error();
|
if ((ptr & 7) != 0) throw Error("invalid alignment: " + (ptr & 7) + " on " + ptr);
|
||||||
|
if (ptrs.indexOf(ptr) >= 0) throw Error("duplicate pointer");
|
||||||
if (allocator.set_memory)
|
if (allocator.set_memory)
|
||||||
allocator.set_memory(ptr, 0xdc, size);
|
allocator.set_memory(ptr, 0xdc, size);
|
||||||
ptrs.push(ptr);
|
ptrs.push(ptr);
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user