Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sysio::vm::growable_allocator Class Reference

#include <allocator.hpp>

Collaboration diagram for sysio::vm::growable_allocator:

Public Member Functions

 growable_allocator (size_t size)
 
 ~growable_allocator ()
 
template<typename T >
Talloc (size_t size=0)
 
void * start_code ()
 
template<bool IsJit>
void end_code (void *code_base)
 
void enable_code (bool is_jit)
 
void disable_code ()
 
const void * get_code_start () const
 
template<typename T >
void reclaim (const T *ptr, size_t size=0)
 
void finalize ()
 
void free ()
 
void reset ()
 
 growable_allocator (size_t size)
 
 ~growable_allocator ()
 
template<typename T >
Talloc (size_t size=0)
 
void * start_code ()
 
template<bool IsJit>
void end_code (void *code_base)
 
void enable_code (bool is_jit)
 
void disable_code ()
 
const void * get_code_start () const
 
template<typename T >
void reclaim (const T *ptr, size_t size=0)
 
void finalize ()
 
void free ()
 
void reset ()
 

Static Public Member Functions

template<std::size_t align_amt>
static constexpr size_t align_offset (size_t offset)
 
static std::size_t align_to_page (std::size_t offset)
 
template<std::size_t align_amt>
static constexpr size_t align_offset (size_t offset)
 
static std::size_t align_to_page (std::size_t offset)
 

Public Attributes

size_t _offset = 0
 
size_t _size = 0
 
std::size_t _capacity = 0
 
char * _base
 
char * _code_base = nullptr
 
size_t _code_size = 0
 
bool is_jit = false
 

Static Public Attributes

static constexpr size_t max_memory_size = 1024 * 1024 * 1024
 
static constexpr size_t chunk_size = 128 * 1024
 

Detailed Description

Definition at line 267 of file allocator.hpp.

Constructor & Destructor Documentation

◆ growable_allocator() [1/2]

sysio::vm::growable_allocator::growable_allocator ( size_t size)
inline

Definition at line 281 of file allocator.hpp.

281 {
282 SYS_VM_ASSERT(size <= max_memory_size, wasm_bad_alloc, "Too large initial memory size");
283 _base = (char*)mmap(NULL, max_memory_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
284 SYS_VM_ASSERT(_base != MAP_FAILED, wasm_bad_alloc, "mmap failed.");
285 if (size != 0) {
286 size_t chunks_to_alloc = (align_offset<chunk_size>(size) / chunk_size);
287 _size += (chunk_size * chunks_to_alloc);
288 mprotect((char*)_base, _size, PROT_READ | PROT_WRITE);
289 }
291 }
static constexpr size_t max_memory_size
static constexpr size_t align_offset(size_t offset)
static constexpr size_t chunk_size
#define SYS_VM_ASSERT(expr, exc_type, msg)
Definition exceptions.hpp:8
Here is the call graph for this function:

◆ ~growable_allocator() [1/2]

sysio::vm::growable_allocator::~growable_allocator ( )
inline

Definition at line 293 of file allocator.hpp.

293 {
294 munmap(_base, _capacity);
295 if (is_jit) {
297 }
298 }
static jit_allocator & instance()
void free(void *ptr) noexcept
Here is the call graph for this function:

◆ growable_allocator() [2/2]

sysio::vm::growable_allocator::growable_allocator ( size_t size)
inline

Definition at line 281 of file allocator.hpp.

281 {
282 SYS_VM_ASSERT(size <= max_memory_size, wasm_bad_alloc, "Too large initial memory size");
283 _base = (char*)mmap(NULL, max_memory_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
284 SYS_VM_ASSERT(_base != MAP_FAILED, wasm_bad_alloc, "mmap failed.");
285 if (size != 0) {
286 size_t chunks_to_alloc = (align_offset<chunk_size>(size) / chunk_size);
287 _size += (chunk_size * chunks_to_alloc);
288 mprotect((char*)_base, _size, PROT_READ | PROT_WRITE);
289 }
291 }
Here is the call graph for this function:

◆ ~growable_allocator() [2/2]

sysio::vm::growable_allocator::~growable_allocator ( )
inline

Definition at line 293 of file allocator.hpp.

293 {
294 munmap(_base, _capacity);
295 if (is_jit) {
297 }
298 }
Here is the call graph for this function:

Member Function Documentation

◆ align_offset() [1/2]

template<std::size_t align_amt>
static constexpr size_t sysio::vm::growable_allocator::align_offset ( size_t offset)
inlinestaticconstexpr

Definition at line 272 of file allocator.hpp.

272{ return (offset + align_amt - 1) & ~(align_amt - 1); }
Here is the caller graph for this function:

◆ align_offset() [2/2]

template<std::size_t align_amt>
static constexpr size_t sysio::vm::growable_allocator::align_offset ( size_t offset)
inlinestaticconstexpr

Definition at line 272 of file allocator.hpp.

272{ return (offset + align_amt - 1) & ~(align_amt - 1); }

◆ align_to_page() [1/2]

static std::size_t sysio::vm::growable_allocator::align_to_page ( std::size_t offset)
inlinestatic

Definition at line 274 of file allocator.hpp.

274 {
275 std::size_t pagesize = static_cast<std::size_t>(::sysconf(_SC_PAGESIZE));
276 assert(max_memory_size % page_size == 0);
277 return (offset + pagesize - 1) & ~(pagesize - 1);
278 }
Here is the caller graph for this function:

◆ align_to_page() [2/2]

static std::size_t sysio::vm::growable_allocator::align_to_page ( std::size_t offset)
inlinestatic

Definition at line 274 of file allocator.hpp.

274 {
275 std::size_t pagesize = static_cast<std::size_t>(::sysconf(_SC_PAGESIZE));
276 assert(max_memory_size % page_size == 0);
277 return (offset + pagesize - 1) & ~(pagesize - 1);
278 }

◆ alloc() [1/2]

template<typename T >
T * sysio::vm::growable_allocator::alloc ( size_t size = 0)
inline

Definition at line 302 of file allocator.hpp.

302 {
303 static_assert(max_memory_size % alignof(T) == 0, "alignment must divide max_memory_size.");
305 // Evaluating the inequality in this form cannot cause integer overflow.
306 // Once this assertion passes, the rest of the function is safe.
307 SYS_VM_ASSERT ((max_memory_size - _offset) / sizeof(T) >= size, wasm_bad_alloc, "Allocated too much memory");
308 size_t aligned = (sizeof(T) * size) + _offset;
309 if (aligned > _size) {
310 size_t chunks_to_alloc = align_offset<chunk_size>(aligned - _size) / chunk_size;
311 mprotect((char*)_base + _size, (chunk_size * chunks_to_alloc), PROT_READ | PROT_WRITE);
312 _size += (chunk_size * chunks_to_alloc);
313 }
314
315 T* ptr = (T*)(_base + _offset);
316 _offset = aligned;
317 return ptr;
318 }
#define T(meth, val, expected)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ alloc() [2/2]

template<typename T >
T * sysio::vm::growable_allocator::alloc ( size_t size = 0)
inline

Definition at line 302 of file allocator.hpp.

302 {
303 static_assert(max_memory_size % alignof(T) == 0, "alignment must divide max_memory_size.");
305 // Evaluating the inequality in this form cannot cause integer overflow.
306 // Once this assertion passes, the rest of the function is safe.
307 SYS_VM_ASSERT ((max_memory_size - _offset) / sizeof(T) >= size, wasm_bad_alloc, "Allocated too much memory");
308 size_t aligned = (sizeof(T) * size) + _offset;
309 if (aligned > _size) {
310 size_t chunks_to_alloc = align_offset<chunk_size>(aligned - _size) / chunk_size;
311 mprotect((char*)_base + _size, (chunk_size * chunks_to_alloc), PROT_READ | PROT_WRITE);
312 _size += (chunk_size * chunks_to_alloc);
313 }
314
315 T* ptr = (T*)(_base + _offset);
316 _offset = aligned;
317 return ptr;
318 }
Here is the call graph for this function:

◆ disable_code() [1/2]

void sysio::vm::growable_allocator::disable_code ( )
inline

Definition at line 349 of file allocator.hpp.

349 {
350 mprotect(_code_base, _code_size, PROT_NONE);
351 }

◆ disable_code() [2/2]

void sysio::vm::growable_allocator::disable_code ( )
inline

Definition at line 349 of file allocator.hpp.

349 {
350 mprotect(_code_base, _code_size, PROT_NONE);
351 }

◆ enable_code() [1/2]

void sysio::vm::growable_allocator::enable_code ( bool is_jit)
inline

Definition at line 345 of file allocator.hpp.

345 {
346 mprotect(_code_base, _code_size, is_jit?PROT_EXEC:(PROT_READ|PROT_WRITE));
347 }
Here is the caller graph for this function:

◆ enable_code() [2/2]

void sysio::vm::growable_allocator::enable_code ( bool is_jit)
inline

Definition at line 345 of file allocator.hpp.

345 {
346 mprotect(_code_base, _code_size, is_jit?PROT_EXEC:(PROT_READ|PROT_WRITE));
347 }

◆ end_code() [1/2]

template<bool IsJit>
void sysio::vm::growable_allocator::end_code ( void * code_base)
inline

Definition at line 325 of file allocator.hpp.

325 {
326 assert((char*)code_base >= _base);
327 assert((char*)code_base <= (_base+_offset));
329 _code_base = (char*)code_base;
330 _code_size = _offset - ((char*)code_base - _base);
331 if constexpr (IsJit) {
332 auto & jit_alloc = jit_allocator::instance();
333 void * executable_code = jit_alloc.alloc(_code_size);
334 int err = mprotect(executable_code, _code_size, PROT_READ | PROT_WRITE);
335 SYS_VM_ASSERT(err == 0, wasm_bad_alloc, "mprotect failed");
336 std::memcpy(executable_code, _code_base, _code_size);
337 is_jit = true;
338 _code_base = (char*)executable_code;
339 _offset = (char*)code_base - _base;
340 }
341 enable_code(IsJit);
342 }
void enable_code(bool is_jit)
static std::size_t align_to_page(std::size_t offset)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ end_code() [2/2]

template<bool IsJit>
void sysio::vm::growable_allocator::end_code ( void * code_base)
inline

Definition at line 325 of file allocator.hpp.

325 {
326 assert((char*)code_base >= _base);
327 assert((char*)code_base <= (_base+_offset));
329 _code_base = (char*)code_base;
330 _code_size = _offset - ((char*)code_base - _base);
331 if constexpr (IsJit) {
332 auto & jit_alloc = jit_allocator::instance();
333 void * executable_code = jit_alloc.alloc(_code_size);
334 int err = mprotect(executable_code, _code_size, PROT_READ | PROT_WRITE);
335 SYS_VM_ASSERT(err == 0, wasm_bad_alloc, "mprotect failed");
336 std::memcpy(executable_code, _code_base, _code_size);
337 is_jit = true;
338 _code_base = (char*)executable_code;
339 _offset = (char*)code_base - _base;
340 }
341 enable_code(IsJit);
342 }
Here is the call graph for this function:

◆ finalize() [1/2]

void sysio::vm::growable_allocator::finalize ( )
inline

Definition at line 369 of file allocator.hpp.

369 {
370 if(_capacity != _offset) {
371 std::size_t final_size = align_to_page(_offset);
372 SYS_VM_ASSERT(munmap(_base + final_size, _capacity - final_size) == 0, wasm_bad_alloc, "failed to finalize growable_allocator");
373 _capacity = _size = _offset = final_size;
374 }
375 }
Here is the call graph for this function:

◆ finalize() [2/2]

void sysio::vm::growable_allocator::finalize ( )
inline

Definition at line 369 of file allocator.hpp.

369 {
370 if(_capacity != _offset) {
371 std::size_t final_size = align_to_page(_offset);
372 SYS_VM_ASSERT(munmap(_base + final_size, _capacity - final_size) == 0, wasm_bad_alloc, "failed to finalize growable_allocator");
373 _capacity = _size = _offset = final_size;
374 }
375 }
Here is the call graph for this function:

◆ free() [1/2]

void sysio::vm::growable_allocator::free ( )
inline

Definition at line 377 of file allocator.hpp.

377{ SYS_VM_ASSERT(false, wasm_bad_alloc, "unimplemented"); }

◆ free() [2/2]

void sysio::vm::growable_allocator::free ( )
inline

Definition at line 377 of file allocator.hpp.

377{ SYS_VM_ASSERT(false, wasm_bad_alloc, "unimplemented"); }

◆ get_code_start() [1/2]

const void * sysio::vm::growable_allocator::get_code_start ( ) const
inline

Definition at line 353 of file allocator.hpp.

353{ return _code_base; }

◆ get_code_start() [2/2]

const void * sysio::vm::growable_allocator::get_code_start ( ) const
inline

Definition at line 353 of file allocator.hpp.

353{ return _code_base; }

◆ reclaim() [1/2]

template<typename T >
void sysio::vm::growable_allocator::reclaim ( const T * ptr,
size_t size = 0 )
inline

Definition at line 359 of file allocator.hpp.

359 {
360 SYS_VM_ASSERT( _offset / sizeof(T) >= size, wasm_bad_alloc, "reclaimed too much memory" );
361 SYS_VM_ASSERT( size == 0 || (char*)(ptr + size) == (_base + _offset), wasm_bad_alloc, "reclaiming memory must be strictly LIFO");
362 if ( size != 0 )
363 _offset = ((char*)ptr - _base);
364 }
Here is the caller graph for this function:

◆ reclaim() [2/2]

template<typename T >
void sysio::vm::growable_allocator::reclaim ( const T * ptr,
size_t size = 0 )
inline

Definition at line 359 of file allocator.hpp.

359 {
360 SYS_VM_ASSERT( _offset / sizeof(T) >= size, wasm_bad_alloc, "reclaimed too much memory" );
361 SYS_VM_ASSERT( size == 0 || (char*)(ptr + size) == (_base + _offset), wasm_bad_alloc, "reclaiming memory must be strictly LIFO");
362 if ( size != 0 )
363 _offset = ((char*)ptr - _base);
364 }

◆ reset() [1/2]

void sysio::vm::growable_allocator::reset ( )
inline

Definition at line 379 of file allocator.hpp.

379{ _offset = 0; }

◆ reset() [2/2]

void sysio::vm::growable_allocator::reset ( )
inline

Definition at line 379 of file allocator.hpp.

379{ _offset = 0; }

◆ start_code() [1/2]

void * sysio::vm::growable_allocator::start_code ( )
inline

Definition at line 320 of file allocator.hpp.

320 {
322 return _base + _offset;
323 }
Here is the call graph for this function:

◆ start_code() [2/2]

void * sysio::vm::growable_allocator::start_code ( )
inline

Definition at line 320 of file allocator.hpp.

320 {
322 return _base + _offset;
323 }
Here is the call graph for this function:

Member Data Documentation

◆ _base

char * sysio::vm::growable_allocator::_base

Definition at line 384 of file allocator.hpp.

◆ _capacity

std::size_t sysio::vm::growable_allocator::_capacity = 0

Definition at line 383 of file allocator.hpp.

◆ _code_base

char * sysio::vm::growable_allocator::_code_base = nullptr

Definition at line 385 of file allocator.hpp.

◆ _code_size

size_t sysio::vm::growable_allocator::_code_size = 0

Definition at line 386 of file allocator.hpp.

◆ _offset

size_t sysio::vm::growable_allocator::_offset = 0

Definition at line 381 of file allocator.hpp.

◆ _size

size_t sysio::vm::growable_allocator::_size = 0

Definition at line 382 of file allocator.hpp.

◆ chunk_size

static constexpr size_t sysio::vm::growable_allocator::chunk_size = 128 * 1024
staticconstexpr

Definition at line 270 of file allocator.hpp.

◆ is_jit

bool sysio::vm::growable_allocator::is_jit = false

Definition at line 387 of file allocator.hpp.

◆ max_memory_size

static constexpr size_t sysio::vm::growable_allocator::max_memory_size = 1024 * 1024 * 1024
staticconstexpr

Definition at line 269 of file allocator.hpp.


The documentation for this class was generated from the following files: