#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "spvm_memory_pool.h"
#include "spvm_util_allocator.h"
#include "spvm_value.h"
SPVM_MEMORY_POOL* SPVM_MEMORY_POOL_new(int32_t page_byte_size) {
SPVM_MEMORY_POOL* memory_pool = (SPVM_MEMORY_POOL*) SPVM_UTIL_ALLOCATOR_safe_malloc_zero(sizeof(SPVM_MEMORY_POOL));
if (page_byte_size == 0) {
memory_pool->page_byte_size = 0xFFFF;
}
else {
memory_pool->page_byte_size = page_byte_size;
}
char* page = SPVM_UTIL_ALLOCATOR_safe_malloc_zero(memory_pool->page_byte_size);
memory_pool->pages_length = 1;
int64_t memory_pool_pages_byte_size = (int64_t)memory_pool->pages_length * (int64_t)sizeof(char*);
memory_pool->pages = SPVM_UTIL_ALLOCATOR_safe_malloc_zero(memory_pool_pages_byte_size);
memory_pool->pages[0] = page;
memory_pool->current_page = 0;
memory_pool->current_offset = 0;
return memory_pool;
}
void* SPVM_MEMORY_POOL_alloc(SPVM_MEMORY_POOL* memory_pool, int32_t byte_size) {
assert(byte_size > 0);
if (byte_size > memory_pool->page_byte_size) {
fprintf(stderr, "Very lerge memory byte size is specified(SPVM_MEMORY_POOL_alloc())\n");
abort();
}
// Adjust alignment
int32_t aligned_byte_size = (byte_size - 1) + ((int32_t)sizeof(SPVM_VALUE) - ((byte_size - 1) % (int32_t)sizeof(SPVM_VALUE)));
// Move to next page
if (memory_pool->current_offset + aligned_byte_size > memory_pool->page_byte_size) {
// Next page is not yet allocated
memory_pool->current_page++;
memory_pool->current_offset = 0;
if (memory_pool->current_page == memory_pool->pages_length) {
int32_t new_memory_pool_pages_length = memory_pool->pages_length * 2;
int64_t new_pages_byte_size = (int64_t)new_memory_pool_pages_length * (int64_t)sizeof(char*);
char** new_pages = SPVM_UTIL_ALLOCATOR_safe_malloc_zero(new_pages_byte_size);
memcpy(new_pages, memory_pool->pages, memory_pool->pages_length * sizeof(char*));
free(memory_pool->pages);
memory_pool->pages = new_pages;
{
int32_t i;
for (i = memory_pool->pages_length; i < new_memory_pool_pages_length; i++) {
memory_pool->pages[i] = SPVM_UTIL_ALLOCATOR_safe_malloc_zero(memory_pool->page_byte_size);
}
}
memory_pool->pages_length = new_memory_pool_pages_length;
}
}
// Allocated address
char* alloc_address = memory_pool->pages[memory_pool->current_page] + memory_pool->current_offset;
memory_pool->current_offset += aligned_byte_size;
return alloc_address;
}
void SPVM_MEMORY_POOL_free(SPVM_MEMORY_POOL* memory_pool) {
{
int32_t i;
for (i = 0; i < memory_pool->pages_length; i++) {
free(memory_pool->pages[i]);
}
}
free(memory_pool->pages);
free(memory_pool);
}