From c5805b8465f131c9a581944ed67c670dea7b89ba Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Tue, 9 Feb 2021 17:37:45 +0000 Subject: [PATCH] changed the second parameter of vmprim.alloc_heap() to return the actual allocated size --- moo/lib/heap.c | 16 +++++--- moo/lib/moo.c | 4 +- moo/lib/moo.h | 4 +- moo/lib/std.c | 108 +++++++++++++++++++++++++++++++++++++------------ 4 files changed, 97 insertions(+), 35 deletions(-) diff --git a/moo/lib/heap.c b/moo/lib/heap.c index 7e1689e..d7abd31 100644 --- a/moo/lib/heap.c +++ b/moo/lib/heap.c @@ -47,11 +47,12 @@ static void xma_free (moo_mmgr_t* mmgr, void* ptr) moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size) { moo_heap_t* heap; - moo_oow_t space_size; + moo_oow_t space_size, alloc_size; if (size < MIN_HEAP_SIZE && moo->gc_type != MOO_GC_TYPE_MARK_SWEEP) size = MIN_HEAP_SIZE; - heap = (moo_heap_t*)moo->vmprim.alloc_heap(moo, MOO_SIZEOF(*heap) + size); + alloc_size = MOO_SIZEOF(*heap) + size; + heap = (moo_heap_t*)moo->vmprim.alloc_heap(moo, &alloc_size); if (MOO_UNLIKELY(!heap)) { const moo_ooch_t* oldmsg = moo_backuperrmsg(moo); @@ -59,9 +60,12 @@ moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size) return MOO_NULL; } - MOO_MEMSET (heap, 0, MOO_SIZEOF(*heap) + size); + /* the vmprim.alloc_heap() function is allowed to create a bigger heap than the requested size. + * if the created heap is bigger than requested, the heap will be utilized in full. */ + MOO_ASSERT (moo, alloc_size >= MOO_SIZEOF(*heap) + size); + MOO_MEMSET (heap, 0, alloc_size); heap->base = (moo_uint8_t*)(heap + 1); - heap->size = size; + heap->size = alloc_size; if (moo->gc_type == MOO_GC_TYPE_MARK_SWEEP) { @@ -77,7 +81,7 @@ moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size) if (MOO_UNLIKELY(!heap->xma)) { moo->vmprim.free_heap (moo, heap); - moo_seterrbfmt (moo, MOO_ESYSMEM, "unable to allocate xma"); + moo_seterrbfmt (moo, MOO_ESYSMEM, "unable to allocate a memory manager over a heap"); return MOO_NULL; } @@ -91,7 +95,7 @@ moo_heap_t* moo_makeheap (moo_t* moo, moo_oow_t size) { MOO_ASSERT (moo, moo->gc_type == MOO_GC_TYPE_SEMISPACE); - space_size = (size - PERM_SPACE_SIZE) / 2; + space_size = (alloc_size - PERM_SPACE_SIZE) / 2; /* TODO: consider placing permspace in a separate memory chunk in case we have to grow * other spaces. we may be able to realloc() the entire heap region without affecting the separately diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 0724b19..bf7d3cf 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -86,9 +86,9 @@ static void fill_bigint_tables (moo_t* moo) } } -static MOO_INLINE void* alloc_heap (moo_t* moo, moo_oow_t size) +static MOO_INLINE void* alloc_heap (moo_t* moo, moo_oow_t* size) { - return moo_allocmem(moo, size); + return moo_allocmem(moo, *size); } static MOO_INLINE void free_heap (moo_t* moo, void* ptr) diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 086897b..166e8d9 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -1175,8 +1175,8 @@ typedef enum moo_log_mask_t moo_log_mask_t; * ========================================================================= */ typedef void* (*moo_alloc_heap_t) ( - moo_t* moo, - moo_oow_t size + moo_t* moo, + moo_oow_t* size ); typedef void (*moo_free_heap_t) ( diff --git a/moo/lib/std.c b/moo/lib/std.c index 1e637b4..eafffd7 100644 --- a/moo/lib/std.c +++ b/moo/lib/std.c @@ -681,11 +681,42 @@ static moo_ooi_t input_handler (moo_t* moo, moo_iocmd_t cmd, moo_ioarg_t* arg) } /* ========================================================================= */ -static void* alloc_heap (moo_t* moo, moo_oow_t size) + + +static int get_huge_page_size (moo_t* moo, moo_oow_t* page_size) +{ + FILE* fp; + char buf[256]; + + fp = fopen("/proc/meminfo", "r"); + if (!fp) return -1; + + while (!feof(fp)) + { + if (fgets(buf, sizeof(buf) - 1, fp) == NULL) goto oops; + + if (strncmp(buf, "Hugepagesize: ", 13) == 0) + { + unsigned long int tmp; + tmp = strtoul(&buf[13], NULL, 10); + if (tmp == MOO_TYPE_MAX(unsigned long int) && errno == ERANGE) goto oops; + + *page_size = tmp * 1024; /* KBytes to Bytes */ + fclose (fp); + return 0; + } + } + +oops: + fclose (fp); + return -1; +} + +static void* alloc_heap (moo_t* moo, moo_oow_t* size) { #if defined(_WIN32) moo_oow_t* ptr; - moo_oow_t actual_size, align_size; + moo_oow_t req_size, align, aligned_size; HINSTANCE k32; SIZE_T (*k32_GetLargePageMinimum) (void); HANDLE token = MOO_NULL; @@ -694,13 +725,13 @@ static void* alloc_heap (moo_t* moo, moo_oow_t size) DWORD prev_state_reqsize = 0; int token_adjusted = 0; - align_size = 2 * 1024 * 1024; + align = 2 * 1024 * 1024; /* default 2MB */ k32 = LoadLibrary(TEXT("kernel32.dll")); if (k32) { k32_GetLargePageMinimum = (SIZE_T(*)(void))GetProcAddress (k32, "GetLargePageMinimum"); - if (k32_GetLargePageMinimum) align_size = k32_GetLargePageMinimum(); + if (k32_GetLargePageMinimum) align = k32_GetLargePageMinimum(); FreeLibrary (k32); } /* the standard page size shouldn't help. so let me comment out this part. @@ -708,11 +739,11 @@ static void* alloc_heap (moo_t* moo, moo_oow_t size) { SYSTEM_INFO si; GetSystemInfo (&si); - align_size = si.dwPageSize; + align = si.dwPageSize; }*/ - actual_size = MOO_SIZEOF(moo_oow_t) + size; - actual_size = MOO_ALIGN(actual_size, align_size); + req_size = MOO_SIZEOF(moo_oow_t) + size; + aligned_size = MOO_ALIGN(req_size, align); if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) goto oops; if (!LookupPrivilegeValue(MOO_NULL, TEXT("SeLockMemoryPrivilege"), &new_state.Privileges[0].Luid)) goto oops; @@ -736,12 +767,22 @@ static void* alloc_heap (moo_t* moo, moo_oow_t size) #if !defined(MEM_LARGE_PAGES) # define MEM_LARGE_PAGES (0x20000000) #endif - ptr = VirtualAlloc(MOO_NULL, actual_size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE); - if (!ptr) goto oops; + ptr = VirtualAlloc(MOO_NULL, aligned_size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE); + if (!ptr) + { + SYSTEM_INFO si; + GetSystemInfo (&si); + align = si.dwPageSize; + aligned_size = MOO_ALIGN(req_size, align); + ptr = VirtualAlloc(MOO_NULL, aligned_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (!ptr) goto oops; + } AdjustTokenPrivileges (token, FALSE, prev_state_ptr, 0, MOO_NULL, 0); CloseHandle (token); if (prev_state_ptr && prev_state_ptr != &prev_state) HeapFree (GetProcessHeap(), 0, prev_state_ptr); + + *size = aligned_size; return ptr; oops: @@ -767,42 +808,59 @@ oops: moo_oow_t* ptr; int flags; - moo_oow_t actual_size; + moo_oow_t req_size, align, aligned_size; + req_size = MOO_SIZEOF(moo_oow_t) + *size; flags = MAP_PRIVATE | MAP_ANONYMOUS; - #if defined(MAP_HUGETLB) - flags |= MAP_HUGETLB; - #endif - #if defined(MAP_UNINITIALIZED) flags |= MAP_UNINITIALIZED; #endif - actual_size = MOO_SIZEOF(moo_oow_t) + size; - actual_size = MOO_ALIGN_POW2(actual_size, 2 * 1024 * 1024); - ptr = (moo_oow_t*)mmap(MOO_NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); - if (ptr == MAP_FAILED) - { #if defined(MAP_HUGETLB) + if (get_huge_page_size(moo, &align) <= -1) align = 2 * 1024 * 1024; /* default to 2MB */ + if (req_size > align / 2) + { + /* if the requested size is large enough, attempt HUGETLB */ + flags |= MAP_HUGETLB; + } + else + { + align = sysconf(_SC_PAGESIZE); + } + #else + align = sysconf(_SC_PAGESIZE); + #endif + + aligned_size = MOO_ALIGN_POW2(req_size, align); + ptr = (moo_oow_t*)mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, flags, -1, 0); + #if defined(MAP_HUGETLB) + if (ptr == MAP_FAILED && (flags & MAP_HUGETLB)) + { flags &= ~MAP_HUGETLB; - ptr = (moo_oow_t*)mmap(MOO_NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0); + align = sysconf(_SC_PAGESIZE); + aligned_size = MOO_ALIGN_POW2(req_size, align); + ptr = (moo_oow_t*)mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, flags, -1, 0); if (ptr == MAP_FAILED) { moo_seterrwithsyserr (moo, 0, errno); return MOO_NULL; } + } #else + if (ptr == MAP_FAILED) + { moo_seterrwithsyserr (moo, 0, errno); return MOO_NULL; - #endif } - *ptr = actual_size; + #endif + *ptr = aligned_size; + *size = aligned_size - MOO_SIZEOF(moo_oow_t); return (void*)(ptr + 1); #else - return MOO_MMGR_ALLOC(moo->_mmgr, size); + return MOO_MMGR_ALLOC(moo->_mmgr, *size); #endif } @@ -3843,7 +3901,7 @@ static struct static int parse_logoptb (moo_t* moo, const moo_bch_t* str, moo_oow_t* xpathlen, moo_bitmask_t* xlogmask) { - xtn_t* xtn = GET_XTN(moo); + /*xtn_t* xtn = GET_XTN(moo);*/ const moo_bch_t* cm, * flt; moo_bitmask_t logmask; moo_oow_t i, len, pathlen; @@ -3901,7 +3959,7 @@ static int parse_logoptb (moo_t* moo, const moo_bch_t* str, moo_oow_t* xpathlen, static int parse_logoptu (moo_t* moo, const moo_uch_t* str, moo_oow_t* xpathlen, moo_bitmask_t* xlogmask) { - xtn_t* xtn = GET_XTN(moo); + /*xtn_t* xtn = GET_XTN(moo);*/ const moo_uch_t* cm, * flt; moo_bitmask_t logmask; moo_oow_t i, len, pathlen;