changed the second parameter of vmprim.alloc_heap() to return the actual allocated size
This commit is contained in:
parent
a184bdd55e
commit
c5805b8465
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -1176,7 +1176,7 @@ 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) (
|
||||||
|
114
moo/lib/std.c
114
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)
|
#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)
|
||||||
|
{
|
||||||
|
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;
|
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)
|
||||||
flags &= ~MAP_HUGETLB;
|
if (get_huge_page_size(moo, &align) <= -1) align = 2 * 1024 * 1024; /* default to 2MB */
|
||||||
ptr = (moo_oow_t*)mmap(MOO_NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0);
|
if (req_size > align / 2)
|
||||||
if (ptr == MAP_FAILED)
|
|
||||||
{
|
{
|
||||||
moo_seterrwithsyserr (moo, 0, errno);
|
/* if the requested size is large enough, attempt HUGETLB */
|
||||||
return MOO_NULL;
|
flags |= MAP_HUGETLB;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
align = sysconf(_SC_PAGESIZE);
|
||||||
}
|
}
|
||||||
#else
|
#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;
|
||||||
|
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);
|
moo_seterrwithsyserr (moo, 0, errno);
|
||||||
return MOO_NULL;
|
return MOO_NULL;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
*ptr = actual_size;
|
}
|
||||||
|
#else
|
||||||
|
if (ptr == MAP_FAILED)
|
||||||
|
{
|
||||||
|
moo_seterrwithsyserr (moo, 0, errno);
|
||||||
|
return MOO_NULL;
|
||||||
|
}
|
||||||
|
#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;
|
||||||
|
Loading…
Reference in New Issue
Block a user