mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-24 03:52:50 -06:00
a pool where the smallest chunks are memory pages
This commit is contained in:
@@ -8,6 +8,10 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(_MSC_VER)
|
#if !defined(_MSC_VER)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#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);
|
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_API void
|
||||||
gu_mem_buf_free(void* buf)
|
gu_mem_buf_free(void* buf)
|
||||||
{
|
{
|
||||||
@@ -132,6 +169,7 @@ struct GuFinalizerNode {
|
|||||||
enum GuPoolType {
|
enum GuPoolType {
|
||||||
GU_POOL_HEAP,
|
GU_POOL_HEAP,
|
||||||
GU_POOL_LOCAL,
|
GU_POOL_LOCAL,
|
||||||
|
GU_POOL_PAGE,
|
||||||
GU_POOL_MMAP
|
GU_POOL_MMAP
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -180,6 +218,16 @@ gu_new_pool(void)
|
|||||||
return pool;
|
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_API GuPool*
|
||||||
gu_mmap_pool(char* fpath, void* addr, size_t size, void**pptr)
|
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_mem_chunk_max_size));
|
||||||
gu_assert(real_req >= sizeof(GuMemChunk));
|
gu_assert(real_req >= sizeof(GuMemChunk));
|
||||||
size_t size = 0;
|
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;
|
chunk->next = pool->chunks;
|
||||||
pool->chunks = chunk;
|
pool->chunks = chunk;
|
||||||
pool->curr_buf = (uint8_t*) 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),
|
size_t full_size = gu_mem_advance(offsetof(GuMemChunk, data),
|
||||||
pre_align, pre_size, align, size);
|
pre_align, pre_size, align, size);
|
||||||
if (full_size > gu_mem_max_shared_alloc &&
|
if (full_size > gu_mem_max_shared_alloc &&
|
||||||
|
pool->type != GU_POOL_PAGE &&
|
||||||
pool->type != GU_POOL_MMAP) {
|
pool->type != GU_POOL_MMAP) {
|
||||||
GuMemChunk* chunk = gu_mem_alloc(full_size);
|
GuMemChunk* chunk = gu_mem_alloc(full_size);
|
||||||
chunk->next = pool->chunks;
|
chunk->next = pool->chunks;
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ gu_local_pool_(uint8_t* init_buf, size_t sz);
|
|||||||
* should not be used in the bodies of recursive functions.
|
* 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.
|
/// Create a pool stored in a memory mapped file.
|
||||||
GU_API_DECL GuPool*
|
GU_API_DECL GuPool*
|
||||||
gu_mmap_pool(char* fpath, void* addr, size_t size, void**pptr);
|
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 min_size,
|
||||||
size_t* real_size_out);
|
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.
|
/// Free a memory buffer.
|
||||||
GU_API_DECL void
|
GU_API_DECL void
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ gu_seq_free(GuSeq* seq)
|
|||||||
gu_mem_buf_free(seq);
|
gu_mem_buf_free(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gu_dummy_finalizer(GuFinalizer* self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
GU_API void
|
GU_API void
|
||||||
gu_buf_require(GuBuf* buf, size_t req_len)
|
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 req_size = sizeof(GuSeq) + buf->elem_size * req_len;
|
||||||
size_t real_size;
|
size_t real_size;
|
||||||
|
|
||||||
|
gu_require(buf->fin.fn != gu_dummy_finalizer);
|
||||||
|
|
||||||
if (buf->seq == NULL || buf->seq == gu_empty_seq()) {
|
if (buf->seq == NULL || buf->seq == gu_empty_seq()) {
|
||||||
buf->seq = gu_mem_buf_alloc(req_size, &real_size);
|
buf->seq = gu_mem_buf_alloc(req_size, &real_size);
|
||||||
buf->seq->len = 0;
|
buf->seq->len = 0;
|
||||||
@@ -164,6 +171,24 @@ gu_buf_freeze(GuBuf* buf, GuPool* pool)
|
|||||||
return seq;
|
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_API void*
|
||||||
gu_buf_insert(GuBuf* buf, size_t index)
|
gu_buf_insert(GuBuf* buf, size_t index)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -182,6 +182,9 @@ gu_buf_heapify(GuBuf *buf, GuOrder *order);
|
|||||||
|
|
||||||
GU_API_DECL GuSeq*
|
GU_API_DECL GuSeq*
|
||||||
gu_buf_freeze(GuBuf* buf, GuPool* pool);
|
gu_buf_freeze(GuBuf* buf, GuPool* pool);
|
||||||
|
|
||||||
|
GU_API void
|
||||||
|
gu_buf_evacuate(GuBuf* buf, GuPool* pool);
|
||||||
#endif // GU_SEQ_H_
|
#endif // GU_SEQ_H_
|
||||||
|
|
||||||
#ifdef GU_STRING_H_
|
#ifdef GU_STRING_H_
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
#include <pgf/reasoner.h>
|
#include <pgf/reasoner.h>
|
||||||
#include <pgf/reader.h>
|
#include <pgf/reader.h>
|
||||||
#include "lightning.h"
|
#include "lightning.h"
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
|
||||||
#include <malloc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//#define PGF_JIT_DEBUG
|
//#define PGF_JIT_DEBUG
|
||||||
|
|
||||||
@@ -43,18 +40,6 @@ typedef struct {
|
|||||||
#define JIT_VSTATE JIT_V1
|
#define JIT_VSTATE JIT_V1
|
||||||
#define JIT_VCLOS JIT_V2
|
#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
|
static void
|
||||||
pgf_jit_finalize_page(GuFinalizer* self)
|
pgf_jit_finalize_page(GuFinalizer* self)
|
||||||
@@ -65,19 +50,8 @@ pgf_jit_finalize_page(GuFinalizer* self)
|
|||||||
static void
|
static void
|
||||||
pgf_jit_alloc_page(PgfReader* rdr)
|
pgf_jit_alloc_page(PgfReader* rdr)
|
||||||
{
|
{
|
||||||
void *page;
|
size_t page_size;
|
||||||
|
void *page = gu_mem_page_alloc(sizeof(GuFinalizer), &page_size);
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
GuFinalizer* fin = page;
|
GuFinalizer* fin = page;
|
||||||
fin->fn = pgf_jit_finalize_page;
|
fin->fn = pgf_jit_finalize_page;
|
||||||
|
|||||||
Reference in New Issue
Block a user