changed the second parameter of vmprim.alloc_heap() to return the actual allocated size

This commit is contained in:
hyunghwan.chung 2021-02-09 17:37:45 +00:00
parent a184bdd55e
commit c5805b8465
4 changed files with 97 additions and 35 deletions

View File

@ -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* moo_makeheap (moo_t* moo, moo_oow_t size)
{ {
moo_heap_t* heap; 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; 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)) if (MOO_UNLIKELY(!heap))
{ {
const moo_ooch_t* oldmsg = moo_backuperrmsg(moo); 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; 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->base = (moo_uint8_t*)(heap + 1);
heap->size = size; heap->size = alloc_size;
if (moo->gc_type == MOO_GC_TYPE_MARK_SWEEP) 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)) if (MOO_UNLIKELY(!heap->xma))
{ {
moo->vmprim.free_heap (moo, heap); 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; 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); 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 /* 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 * other spaces. we may be able to realloc() the entire heap region without affecting the separately

View File

@ -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) static MOO_INLINE void free_heap (moo_t* moo, void* ptr)

View File

@ -1175,8 +1175,8 @@ typedef enum moo_log_mask_t moo_log_mask_t;
* ========================================================================= */ * ========================================================================= */
typedef void* (*moo_alloc_heap_t) ( typedef void* (*moo_alloc_heap_t) (
moo_t* moo, moo_t* moo,
moo_oow_t size moo_oow_t* size
); );
typedef void (*moo_free_heap_t) ( typedef void (*moo_free_heap_t) (

View File

@ -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) #if defined(_WIN32)
moo_oow_t* ptr; moo_oow_t* ptr;
moo_oow_t actual_size, align_size; moo_oow_t req_size, align, aligned_size;
HINSTANCE k32; HINSTANCE k32;
SIZE_T (*k32_GetLargePageMinimum) (void); SIZE_T (*k32_GetLargePageMinimum) (void);
HANDLE token = MOO_NULL; HANDLE token = MOO_NULL;
@ -694,13 +725,13 @@ static void* alloc_heap (moo_t* moo, moo_oow_t size)
DWORD prev_state_reqsize = 0; DWORD prev_state_reqsize = 0;
int token_adjusted = 0; int token_adjusted = 0;
align_size = 2 * 1024 * 1024; align = 2 * 1024 * 1024; /* default 2MB */
k32 = LoadLibrary(TEXT("kernel32.dll")); k32 = LoadLibrary(TEXT("kernel32.dll"));
if (k32) if (k32)
{ {
k32_GetLargePageMinimum = (SIZE_T(*)(void))GetProcAddress (k32, "GetLargePageMinimum"); k32_GetLargePageMinimum = (SIZE_T(*)(void))GetProcAddress (k32, "GetLargePageMinimum");
if (k32_GetLargePageMinimum) align_size = k32_GetLargePageMinimum(); if (k32_GetLargePageMinimum) align = k32_GetLargePageMinimum();
FreeLibrary (k32); FreeLibrary (k32);
} }
/* the standard page size shouldn't help. so let me comment out this part. /* 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; SYSTEM_INFO si;
GetSystemInfo (&si); GetSystemInfo (&si);
align_size = si.dwPageSize; align = si.dwPageSize;
}*/ }*/
actual_size = MOO_SIZEOF(moo_oow_t) + size; req_size = MOO_SIZEOF(moo_oow_t) + size;
actual_size = MOO_ALIGN(actual_size, align_size); aligned_size = MOO_ALIGN(req_size, align);
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) goto oops; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) goto oops;
if (!LookupPrivilegeValue(MOO_NULL, TEXT("SeLockMemoryPrivilege"), &new_state.Privileges[0].Luid)) 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) #if !defined(MEM_LARGE_PAGES)
# define MEM_LARGE_PAGES (0x20000000) # define MEM_LARGE_PAGES (0x20000000)
#endif #endif
ptr = VirtualAlloc(MOO_NULL, actual_size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE); ptr = VirtualAlloc(MOO_NULL, aligned_size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE);
if (!ptr) goto oops; 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); AdjustTokenPrivileges (token, FALSE, prev_state_ptr, 0, MOO_NULL, 0);
CloseHandle (token); CloseHandle (token);
if (prev_state_ptr && prev_state_ptr != &prev_state) HeapFree (GetProcessHeap(), 0, prev_state_ptr); if (prev_state_ptr && prev_state_ptr != &prev_state) HeapFree (GetProcessHeap(), 0, prev_state_ptr);
*size = aligned_size;
return ptr; return ptr;
oops: oops:
@ -767,42 +808,59 @@ oops:
moo_oow_t* ptr; moo_oow_t* ptr;
int flags; 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; flags = MAP_PRIVATE | MAP_ANONYMOUS;
#if defined(MAP_HUGETLB)
flags |= MAP_HUGETLB;
#endif
#if defined(MAP_UNINITIALIZED) #if defined(MAP_UNINITIALIZED)
flags |= MAP_UNINITIALIZED; flags |= MAP_UNINITIALIZED;
#endif #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 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; 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) if (ptr == MAP_FAILED)
{ {
moo_seterrwithsyserr (moo, 0, errno); moo_seterrwithsyserr (moo, 0, errno);
return MOO_NULL; return MOO_NULL;
} }
}
#else #else
if (ptr == MAP_FAILED)
{
moo_seterrwithsyserr (moo, 0, errno); moo_seterrwithsyserr (moo, 0, errno);
return MOO_NULL; return MOO_NULL;
#endif
} }
*ptr = actual_size; #endif
*ptr = aligned_size;
*size = aligned_size - MOO_SIZEOF(moo_oow_t);
return (void*)(ptr + 1); return (void*)(ptr + 1);
#else #else
return MOO_MMGR_ALLOC(moo->_mmgr, size); return MOO_MMGR_ALLOC(moo->_mmgr, *size);
#endif #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) 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; const moo_bch_t* cm, * flt;
moo_bitmask_t logmask; moo_bitmask_t logmask;
moo_oow_t i, len, pathlen; 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) 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; const moo_uch_t* cm, * flt;
moo_bitmask_t logmask; moo_bitmask_t logmask;
moo_oow_t i, len, pathlen; moo_oow_t i, len, pathlen;