|
@@ -923,6 +923,14 @@ void *sys_alloc_align( int size, int align );
|
|
void sys_free_align( void *ptr, int size );
|
|
void sys_free_align( void *ptr, int size );
|
|
#elif !defined(HL_WIN)
|
|
#elif !defined(HL_WIN)
|
|
static void *base_addr = (void*)0x40000000;
|
|
static void *base_addr = (void*)0x40000000;
|
|
|
|
+typedef struct _pextra pextra;
|
|
|
|
+struct _pextra {
|
|
|
|
+ void *page_ptr;
|
|
|
|
+ void *base_ptr;
|
|
|
|
+ pextra *next;
|
|
|
|
+};
|
|
|
|
+static pextra *extra_pages = NULL;
|
|
|
|
+#define EXTRA_SIZE (GC_PAGE_SIZE + (4<<10))
|
|
#endif
|
|
#endif
|
|
|
|
|
|
static void *gc_alloc_page_memory( int size ) {
|
|
static void *gc_alloc_page_memory( int size ) {
|
|
@@ -948,6 +956,7 @@ static void *gc_alloc_page_memory( int size ) {
|
|
#elif defined(HL_CONSOLE)
|
|
#elif defined(HL_CONSOLE)
|
|
return sys_alloc_align(size, GC_PAGE_SIZE);
|
|
return sys_alloc_align(size, GC_PAGE_SIZE);
|
|
#else
|
|
#else
|
|
|
|
+ static int recursions = 0;
|
|
int i = 0;
|
|
int i = 0;
|
|
while( gc_will_collide(base_addr,size) ) {
|
|
while( gc_will_collide(base_addr,size) ) {
|
|
base_addr = (char*)base_addr + GC_PAGE_SIZE;
|
|
base_addr = (char*)base_addr + GC_PAGE_SIZE;
|
|
@@ -961,6 +970,17 @@ static void *gc_alloc_page_memory( int size ) {
|
|
return NULL;
|
|
return NULL;
|
|
if( ((int_val)ptr) & (GC_PAGE_SIZE-1) ) {
|
|
if( ((int_val)ptr) & (GC_PAGE_SIZE-1) ) {
|
|
munmap(ptr,size);
|
|
munmap(ptr,size);
|
|
|
|
+ if( recursions >= 5 ) {
|
|
|
|
+ ptr = mmap(base_addr,size+EXTRA_SIZE,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
|
|
|
|
+ int offset = (int)((int_val)ptr) & (GC_PAGE_SIZE-1);
|
|
|
|
+ void *aligned = (char*)ptr + (GC_PAGE_SIZE - offset);
|
|
|
|
+ pextra *inf = (pextra*)(offset > (EXTRA_SIZE>>1) ? ((char*)ptr + EXTRA_SIZE - sizeof(pextra)) : (char*)ptr);
|
|
|
|
+ inf->page_ptr = aligned;
|
|
|
|
+ inf->base_ptr = ptr;
|
|
|
|
+ inf->next = extra_pages;
|
|
|
|
+ extra_pages = inf;
|
|
|
|
+ return aligned;
|
|
|
|
+ }
|
|
void *tmp;
|
|
void *tmp;
|
|
int tmp_size = (int)((int_val)ptr - (int_val)base_addr);
|
|
int tmp_size = (int)((int_val)ptr - (int_val)base_addr);
|
|
if( tmp_size > 0 ) {
|
|
if( tmp_size > 0 ) {
|
|
@@ -971,7 +991,9 @@ static void *gc_alloc_page_memory( int size ) {
|
|
tmp = NULL;
|
|
tmp = NULL;
|
|
}
|
|
}
|
|
if( tmp ) tmp = mmap(tmp,tmp_size,PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
|
|
if( tmp ) tmp = mmap(tmp,tmp_size,PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
|
|
|
|
+ recursions++
|
|
ptr = gc_alloc_page_memory(size);
|
|
ptr = gc_alloc_page_memory(size);
|
|
|
|
+ recursions--;
|
|
if( tmp ) munmap(tmp,tmp_size);
|
|
if( tmp ) munmap(tmp,tmp_size);
|
|
return ptr;
|
|
return ptr;
|
|
}
|
|
}
|
|
@@ -986,6 +1008,19 @@ static void gc_free_page_memory( void *ptr, int size ) {
|
|
#elif defined(HL_CONSOLE)
|
|
#elif defined(HL_CONSOLE)
|
|
sys_free_align(ptr,size);
|
|
sys_free_align(ptr,size);
|
|
#else
|
|
#else
|
|
|
|
+ pextra *e = extra_pages, *prev = NULL;
|
|
|
|
+ while( e ) {
|
|
|
|
+ if( e->page_ptr == ptr ) {
|
|
|
|
+ if( prev )
|
|
|
|
+ prev->next = e->next;
|
|
|
|
+ else
|
|
|
|
+ extra_pages = e->next;
|
|
|
|
+ munmap(e->base_ptr, size + EXTRA_SIZE);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ prev = e;
|
|
|
|
+ e = e->next;
|
|
|
|
+ }
|
|
munmap(ptr,size);
|
|
munmap(ptr,size);
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|