summaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorkrangelov <kr.angelov@gmail.com>2018-12-16 07:46:14 +0100
committerkrangelov <kr.angelov@gmail.com>2018-12-16 07:46:14 +0100
commiteb2211217858d97256c802739531547c52d328a5 (patch)
tree578060a42d79a4a7c12a60d964b7df7cbb051b02 /src/runtime
parent083aa96e575554518dee32d03f579ad6cac26722 (diff)
a pool where the smallest chunks are memory pages
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/c/gu/mem.c54
-rw-r--r--src/runtime/c/gu/mem.h8
-rw-r--r--src/runtime/c/gu/seq.c27
-rw-r--r--src/runtime/c/gu/seq.h3
-rw-r--r--src/runtime/c/pgf/jit.c30
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 <sys/mman.h>
#include <sys/stat.h>
#endif
+#if defined(__MINGW32__) || defined(_MSC_VER)
+#include <malloc.h>
+#endif
+
#if !defined(_MSC_VER)
#include <unistd.h>
#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 <windows.h>
+
+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 <pgf/reasoner.h>
#include <pgf/reader.h>
#include "lightning.h"
-#if defined(__MINGW32__) || defined(_MSC_VER)
-#include <malloc.h>
-#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 <windows.h>
-
-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;