From eb2211217858d97256c802739531547c52d328a5 Mon Sep 17 00:00:00 2001 From: krangelov Date: Sun, 16 Dec 2018 07:46:14 +0100 Subject: [PATCH] a pool where the smallest chunks are memory pages --- src/runtime/c/gu/mem.c | 54 ++++++++++++++++++++++++++++++++++++++++- src/runtime/c/gu/mem.h | 8 ++++++ src/runtime/c/gu/seq.c | 27 ++++++++++++++++++++- src/runtime/c/gu/seq.h | 3 +++ src/runtime/c/pgf/jit.c | 30 ++--------------------- 5 files changed, 92 insertions(+), 30 deletions(-) diff --git a/src/runtime/c/gu/mem.c b/src/runtime/c/gu/mem.c index 3e5bd57a2..80e99242e 100644 --- a/src/runtime/c/gu/mem.c +++ b/src/runtime/c/gu/mem.c @@ -8,6 +8,10 @@ #include #include #endif +#if defined(__MINGW32__) || defined(_MSC_VER) +#include +#endif + #if !defined(_MSC_VER) #include #endif @@ -108,6 +112,39 @@ gu_mem_buf_alloc(size_t min_size, size_t* real_size_out) return gu_mem_buf_realloc(NULL, min_size, real_size_out); } +#if defined(__MINGW32__) || defined(_MSC_VER) +#include + +static int +getpagesize() +{ + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + return system_info.dwPageSize; +} +#endif + +GU_API void* +gu_mem_page_alloc(size_t min_size, size_t* real_size_out) +{ + size_t page_size = getpagesize(); + size_t size = ((min_size + page_size - 1) / page_size) * page_size; + void *page = NULL; + +#if defined(ANDROID) + if ((page = memalign(page_size, size)) == NULL) { +#elif defined(__MINGW32__) || defined(_MSC_VER) + if ((page = malloc(size)) == NULL) { +#else + if (posix_memalign(&page, page_size, size) != 0) { +#endif + gu_fatal("Memory allocation failed"); + } + + *real_size_out = size; + return page; +} + GU_API void gu_mem_buf_free(void* buf) { @@ -132,6 +169,7 @@ struct GuFinalizerNode { enum GuPoolType { GU_POOL_HEAP, GU_POOL_LOCAL, + GU_POOL_PAGE, GU_POOL_MMAP }; @@ -180,6 +218,16 @@ gu_new_pool(void) return pool; } +GU_API GuPool* +gu_new_page_pool(void) +{ + size_t sz = GU_FLEX_SIZE(GuPool, init_buf, gu_mem_pool_initial_size); + uint8_t* buf = gu_mem_page_alloc(sz, &sz); + GuPool* pool = gu_init_pool(buf, sz); + pool->type = GU_POOL_PAGE; + return pool; +} + GU_API GuPool* gu_mmap_pool(char* fpath, void* addr, size_t size, void**pptr) { @@ -238,7 +286,10 @@ gu_pool_expand(GuPool* pool, size_t req) gu_mem_chunk_max_size)); gu_assert(real_req >= sizeof(GuMemChunk)); size_t size = 0; - GuMemChunk* chunk = gu_mem_buf_alloc(real_req, &size); + GuMemChunk* chunk = + (pool->type == GU_POOL_PAGE) + ? gu_mem_page_alloc(real_req, &size) + : gu_mem_buf_alloc(real_req, &size); chunk->next = pool->chunks; pool->chunks = chunk; pool->curr_buf = (uint8_t*) chunk; @@ -309,6 +360,7 @@ gu_malloc_prefixed(GuPool* pool, size_t pre_align, size_t pre_size, size_t full_size = gu_mem_advance(offsetof(GuMemChunk, data), pre_align, pre_size, align, size); if (full_size > gu_mem_max_shared_alloc && + pool->type != GU_POOL_PAGE && pool->type != GU_POOL_MMAP) { GuMemChunk* chunk = gu_mem_alloc(full_size); chunk->next = pool->chunks; diff --git a/src/runtime/c/gu/mem.h b/src/runtime/c/gu/mem.h index 3f16a6a1c..f26e4d3a4 100644 --- a/src/runtime/c/gu/mem.h +++ b/src/runtime/c/gu/mem.h @@ -55,6 +55,11 @@ gu_local_pool_(uint8_t* init_buf, size_t sz); * should not be used in the bodies of recursive functions. */ +/// Create a pool where each chunk is corresponds to one or +/// more pages. +GU_API GuPool* +gu_new_page_pool(void); + /// Create a pool stored in a memory mapped file. GU_API_DECL GuPool* gu_mmap_pool(char* fpath, void* addr, size_t size, void**pptr); @@ -198,6 +203,9 @@ gu_mem_buf_realloc( size_t min_size, size_t* real_size_out); +/// Allocate enough memory pages to contain min_size bytes. +GU_API void* +gu_mem_page_alloc(size_t min_size, size_t* real_size_out); /// Free a memory buffer. GU_API_DECL void diff --git a/src/runtime/c/gu/seq.c b/src/runtime/c/gu/seq.c index 72ccc3fae..33e49066b 100644 --- a/src/runtime/c/gu/seq.c +++ b/src/runtime/c/gu/seq.c @@ -100,6 +100,11 @@ gu_seq_free(GuSeq* seq) gu_mem_buf_free(seq); } +static void +gu_dummy_finalizer(GuFinalizer* self) +{ +} + GU_API void gu_buf_require(GuBuf* buf, size_t req_len) { @@ -109,7 +114,9 @@ gu_buf_require(GuBuf* buf, size_t req_len) size_t req_size = sizeof(GuSeq) + buf->elem_size * req_len; size_t real_size; - + + gu_require(buf->fin.fn != gu_dummy_finalizer); + if (buf->seq == NULL || buf->seq == gu_empty_seq()) { buf->seq = gu_mem_buf_alloc(req_size, &real_size); buf->seq->len = 0; @@ -164,6 +171,24 @@ gu_buf_freeze(GuBuf* buf, GuPool* pool) return seq; } +GU_API void +gu_buf_evacuate(GuBuf* buf, GuPool* pool) +{ + if (buf->seq != gu_empty_seq()) { + size_t len = gu_buf_length(buf); + + GuSeq* seq = gu_make_seq(buf->elem_size, len, pool); + void* bufdata = gu_buf_data(buf); + void* seqdata = gu_seq_data(seq); + memcpy(seqdata, bufdata, buf->elem_size * len); + gu_mem_buf_free(buf->seq); + + buf->seq = seq; + buf->fin.fn = gu_dummy_finalizer; + buf->avail_len = len; + } +} + GU_API void* gu_buf_insert(GuBuf* buf, size_t index) { diff --git a/src/runtime/c/gu/seq.h b/src/runtime/c/gu/seq.h index c19a23d1c..3b345be61 100644 --- a/src/runtime/c/gu/seq.h +++ b/src/runtime/c/gu/seq.h @@ -182,6 +182,9 @@ gu_buf_heapify(GuBuf *buf, GuOrder *order); GU_API_DECL GuSeq* gu_buf_freeze(GuBuf* buf, GuPool* pool); + +GU_API void +gu_buf_evacuate(GuBuf* buf, GuPool* pool); #endif // GU_SEQ_H_ #ifdef GU_STRING_H_ diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c index 1eda95a0d..6c8679523 100644 --- a/src/runtime/c/pgf/jit.c +++ b/src/runtime/c/pgf/jit.c @@ -5,9 +5,6 @@ #include #include #include "lightning.h" -#if defined(__MINGW32__) || defined(_MSC_VER) -#include -#endif //#define PGF_JIT_DEBUG @@ -43,18 +40,6 @@ typedef struct { #define JIT_VSTATE JIT_V1 #define JIT_VCLOS JIT_V2 -#if defined(__MINGW32__) || defined(_MSC_VER) -#include - -static int -getpagesize() -{ - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - return system_info.dwPageSize; -} -#endif - static void pgf_jit_finalize_page(GuFinalizer* self) @@ -65,19 +50,8 @@ pgf_jit_finalize_page(GuFinalizer* self) static void pgf_jit_alloc_page(PgfReader* rdr) { - void *page; - - size_t page_size = getpagesize(); - -#if defined(ANDROID) - if ((page = memalign(page_size, page_size)) == NULL) { -#elif defined(__MINGW32__) || defined(_MSC_VER) - if ((page = malloc(page_size)) == NULL) { -#else - if (posix_memalign(&page, page_size, page_size) != 0) { -#endif - gu_fatal("Memory allocation failed"); - } + size_t page_size; + void *page = gu_mem_page_alloc(sizeof(GuFinalizer), &page_size); GuFinalizer* fin = page; fin->fn = pgf_jit_finalize_page;