From: Vsevolod Stakhov Date: Mon, 3 Jun 2019 16:09:15 +0000 (+0100) Subject: [Minor] Arm64: Implement poor man slabs X-Git-Tag: 2.0~829 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6dbf2e4e35b7be68774ae4a87e582742cb1258f5;p=rspamd.git [Minor] Arm64: Implement poor man slabs Issue: #2906 --- diff --git a/contrib/lua-lpeg/lpvm.c b/contrib/lua-lpeg/lpvm.c index 711fe026d..441712826 100644 --- a/contrib/lua-lpeg/lpvm.c +++ b/contrib/lua-lpeg/lpvm.c @@ -19,6 +19,20 @@ #include +#define MAX_PIECES (1u << 2u) + +/* 64 bytes, 1 cache line */ +struct poor_slab { + struct slab_piece { + unsigned char *ptr; + uint32_t sz; + uint32_t occupied; + } pieces[MAX_PIECES]; +}; + +/* Used to optimize pages allocation */ +struct poor_slab slabs; + static uint64_t xorshifto_seed[2] = {0xdeadbabe, 0xdeadbeef}; static inline uint64_t @@ -33,6 +47,15 @@ lpeg_allocate_mem_low (size_t sz) unsigned flags = MAP_PRIVATE | MAP_ANON; void *base_addr = NULL; + /* Check slabs */ + for (unsigned i = 0; i < MAX_PIECES; i ++) { + if (!slabs.pieces[i].occupied && slabs.pieces[i].sz == sz) { + /* Reuse, short path */ + slabs.pieces[i].occupied = 1; + return slabs.pieces[i].ptr + sizeof (size_t); + } + } + #ifdef MAP_32BIT flags |= MAP_32BIT; #else @@ -52,6 +75,25 @@ lpeg_allocate_mem_low (size_t sz) assert (cp != NULL); memcpy (cp, &sz, sizeof (sz)); + for (unsigned i = 0; i < MAX_PIECES; i ++) { + if (slabs.pieces[i].sz == 0) { + /* Store piece */ + slabs.pieces[i].sz = sz; + slabs.pieces[i].ptr = cp; + slabs.pieces[i].occupied = 1; + + return cp + sizeof (sz); + } + } + + /* Not enough free pieces, pop some */ + unsigned sel = ((uintptr_t)cp) & ((MAX_PIECES * 2) - 1); + /* Here we free memory in fact */ + munmap (slabs.pieces[sel].ptr, slabs.pieces[sel].sz); + slabs.pieces[sel].sz = sz; + slabs.pieces[sel].ptr = cp; + slabs.pieces[sel].occupied = 1; + return cp + sizeof (sz); } @@ -61,8 +103,20 @@ lpeg_free_mem_low(void *p) unsigned char *cp = (unsigned char *)p; size_t sz; - memcpy (&sz, cp - sizeof (sz), sizeof (sz)); - munmap (cp - sizeof (sz), sz + sizeof (sz)); + /* Base address */ + cp -= sizeof (sz); + memcpy (&sz, cp, sizeof (sz)); + + for (unsigned i = 0; i < MAX_PIECES; i ++) { + if (slabs.pieces[i].occupied && slabs.pieces[i].ptr == cp) { + /* Return back */ + slabs.pieces[i].occupied = 0; + + return; + } + } + + /* No match, unmapped by allocation */ } /* initial size for call/backtrack stack */