adaptive future-nursery size
svn: r17252
This commit is contained in:
parent
4e6117b9d8
commit
d4aaa9cf6f
|
@ -410,9 +410,16 @@ GC2_EXTERN void GC_switch_back_from_master(void *gc);
|
|||
Switches to back to gc from the master GC
|
||||
*/
|
||||
|
||||
GC2_EXTERN unsigned long GC_make_jit_nursery_page();
|
||||
GC2_EXTERN long GC_alloc_alignment();
|
||||
/*
|
||||
Obtains a nursery page from the GC for thread local allocation.
|
||||
Guaranteeed alignment for nusery pages. Returns a constant, and
|
||||
can be called from any thread.
|
||||
*/
|
||||
|
||||
GC2_EXTERN unsigned long GC_make_jit_nursery_page(int count);
|
||||
/*
|
||||
Obtains nursery pages from the GC for thread local allocation;
|
||||
resulting space is count times the allocation alignment.
|
||||
The result is an unsigned long because it's not a valid
|
||||
pointer to a GCable object. The result becomes invalid (i.e. it's collected)
|
||||
with the next GC.
|
||||
|
|
|
@ -814,6 +814,7 @@ inline static mpage *gen0_create_new_nursery_mpage(NewGC *gc, const size_t page_
|
|||
newmpage->addr = malloc_dirty_pages(gc, page_size, APAGE_SIZE);
|
||||
newmpage->size_class = 0;
|
||||
newmpage->size = PREFIX_SIZE;
|
||||
newmpage->previous_size = page_size;
|
||||
pagemap_add_with_size(gc->page_maps, newmpage, page_size);
|
||||
GCVERBOSEPAGE("NEW gen0", newmpage);
|
||||
|
||||
|
@ -829,18 +830,19 @@ inline static void gen0_free_nursery_mpage(NewGC *gc, mpage *page, size_t page_s
|
|||
/* Needs to be consistent with GC_alloc_alignment(): */
|
||||
#define THREAD_LOCAL_PAGE_SIZE APAGE_SIZE
|
||||
|
||||
unsigned long GC_make_jit_nursery_page() {
|
||||
unsigned long GC_make_jit_nursery_page(int count) {
|
||||
NewGC *gc = GC_get_GC();
|
||||
mpage *new_mpage;
|
||||
long size = count * THREAD_LOCAL_PAGE_SIZE;
|
||||
|
||||
if((gc->gen0.current_size + THREAD_LOCAL_PAGE_SIZE) >= gc->gen0.max_size) {
|
||||
if((gc->gen0.current_size + size) >= gc->gen0.max_size) {
|
||||
if (!gc->dumping_avoid_collection)
|
||||
garbage_collect(gc, 0);
|
||||
}
|
||||
gc->gen0.current_size += THREAD_LOCAL_PAGE_SIZE;
|
||||
gc->gen0.current_size += size;
|
||||
|
||||
{
|
||||
new_mpage = gen0_create_new_nursery_mpage(gc, THREAD_LOCAL_PAGE_SIZE);
|
||||
new_mpage = gen0_create_new_nursery_mpage(gc, size);
|
||||
|
||||
/* push page */
|
||||
new_mpage->next = gc->thread_local_pages;
|
||||
|
@ -865,7 +867,7 @@ unsigned long GC_make_jit_nursery_page() {
|
|||
}
|
||||
|
||||
inline static void gen0_free_jit_nursery_page(NewGC *gc, mpage *page) {
|
||||
gen0_free_nursery_mpage(gc, page, THREAD_LOCAL_PAGE_SIZE);
|
||||
gen0_free_nursery_mpage(gc, page, page->previous_size);
|
||||
}
|
||||
|
||||
inline static mpage *gen0_create_new_mpage(NewGC *gc) {
|
||||
|
@ -1211,7 +1213,7 @@ inline static int marked(NewGC *gc, void *p)
|
|||
if (page->size_class > 1) {
|
||||
return (page->size_class > 2);
|
||||
}
|
||||
} else {
|
||||
} else if (page->generation) {
|
||||
if((NUM(page->addr) + page->previous_size) > NUM(p))
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ typedef struct mpage {
|
|||
struct mpage *next;
|
||||
struct mpage *prev;
|
||||
void *addr;
|
||||
unsigned long previous_size; /* for med page, points to place to search for available block */
|
||||
unsigned long size; /* big page size or med page element size */
|
||||
unsigned long previous_size; /* for med page, place to search for available block; for jit nursery, allocated size */
|
||||
unsigned long size; /* big page size, med page element size, or nursery starting point */
|
||||
unsigned char generation;
|
||||
/*
|
||||
unsigned char back_pointers :1;
|
||||
|
|
|
@ -199,6 +199,10 @@ typedef struct Scheme_Future_Thread_State {
|
|||
volatile int *fuel_pointer;
|
||||
volatile unsigned long *stack_boundary_pointer;
|
||||
volatile int *need_gc_pointer;
|
||||
|
||||
unsigned long gen0_start;
|
||||
unsigned long gen0_size;
|
||||
unsigned long gen0_initial_offset;
|
||||
} Scheme_Future_Thread_State;
|
||||
|
||||
THREAD_LOCAL_DECL(static Scheme_Future_State *scheme_future_state);
|
||||
|
@ -411,6 +415,8 @@ static void init_future_thread(Scheme_Future_State *fs, int i)
|
|||
sema_destroy(¶ms.ready_sema);
|
||||
|
||||
fts->threadid = threadid;
|
||||
|
||||
fts->gen0_size = 1;
|
||||
|
||||
scheme_register_static(&fts->current_ft, sizeof(void*));
|
||||
scheme_register_static(params.scheme_current_runstack_ptr, sizeof(void*));
|
||||
|
@ -434,6 +440,9 @@ static void start_gc_not_ok(Scheme_Future_State *fs)
|
|||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
if (fts->worker_gc_counter != *fs->gc_counter_ptr) {
|
||||
GC_gen0_alloc_page_ptr = 0; /* forces future to ask for memory */
|
||||
fts->gen0_start = 0;
|
||||
if (fts->gen0_size > 1)
|
||||
fts->gen0_size >>= 1;
|
||||
fts->worker_gc_counter = *fs->gc_counter_ptr;
|
||||
}
|
||||
}
|
||||
|
@ -959,9 +968,8 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Functions for primitive invocation */
|
||||
/* Functions for primitive invocation */
|
||||
/**********************************************************************/
|
||||
void scheme_rtcall_void_void_3args(const char *who, int src_type, prim_void_void_3args_t f)
|
||||
XFORM_SKIP_PROC
|
||||
|
@ -983,7 +991,9 @@ void scheme_rtcall_void_void_3args(const char *who, int src_type, prim_void_void
|
|||
future->arg_S0 = NULL;
|
||||
}
|
||||
|
||||
unsigned long scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, prim_alloc_void_pvoid_t f)
|
||||
#ifdef MZ_PRECISE_GC
|
||||
|
||||
unsigned long scheme_rtcall_alloc(const char *who, int src_type)
|
||||
XFORM_SKIP_PROC
|
||||
/* Called in future thread */
|
||||
{
|
||||
|
@ -991,21 +1001,43 @@ unsigned long scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, prim
|
|||
unsigned long retval;
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
Scheme_Future_State *fs = scheme_future_state;
|
||||
long align;
|
||||
|
||||
align = GC_alloc_alignment();
|
||||
|
||||
/* Do we actually still have space? */
|
||||
if (fts->gen0_start) {
|
||||
long cur;
|
||||
cur = GC_gen0_alloc_page_ptr;
|
||||
if (cur < (fts->gen0_start + (fts->gen0_size - 1) * align)) {
|
||||
cur &= ~(align - 1);
|
||||
cur += align + fts->gen0_initial_offset;
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
|
||||
/* Grow nursery size as long as we don't trigger a GC */
|
||||
if (fts->gen0_size < 16)
|
||||
fts->gen0_size <<= 1;
|
||||
|
||||
while (1) {
|
||||
future = fts->current_ft;
|
||||
future->time_of_request = 0; /* takes too long?: scheme_get_inexact_milliseconds(); */
|
||||
future->time_of_request = scheme_get_inexact_milliseconds();
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
|
||||
future->prim_protocol = SIG_ALLOC_VOID_PVOID;
|
||||
future->prim_protocol = SIG_ALLOC;
|
||||
future->arg_i0 = fts->gen0_size;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 1);
|
||||
future_do_runtimecall(fts, (void*)GC_make_jit_nursery_page, 1);
|
||||
|
||||
future = fts->current_ft;
|
||||
retval = future->alloc_retval;
|
||||
future->alloc_retval = 0;
|
||||
|
||||
fts->gen0_start = retval;
|
||||
fts->gen0_initial_offset = retval & (align - 1);
|
||||
|
||||
if (*fs->gc_counter_ptr == future->alloc_retval_counter)
|
||||
break;
|
||||
}
|
||||
|
@ -1013,6 +1045,8 @@ unsigned long scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, prim
|
|||
return retval;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void receive_special_result(future_t *f, Scheme_Object *retval, int clear)
|
||||
XFORM_SKIP_PROC
|
||||
/* Called in future or runtime thread */
|
||||
|
@ -1108,15 +1142,16 @@ static void do_invoke_rtcall(Scheme_Future_State *fs, future_t *future)
|
|||
|
||||
break;
|
||||
}
|
||||
case SIG_ALLOC_VOID_PVOID:
|
||||
#ifdef MZ_PRECISE_GC
|
||||
case SIG_ALLOC:
|
||||
{
|
||||
unsigned long ret;
|
||||
prim_alloc_void_pvoid_t func = (prim_alloc_void_pvoid_t)future->prim_func;
|
||||
ret = func();
|
||||
ret = GC_make_jit_nursery_page(future->arg_i0);
|
||||
future->alloc_retval = ret;
|
||||
future->alloc_retval_counter = scheme_did_gc_count;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
# include "jit_ts_runtime_glue.c"
|
||||
default:
|
||||
scheme_signal_error("unknown protocol %d", future->prim_protocol);
|
||||
|
|
|
@ -24,7 +24,6 @@ int scheme_make_prim_w_arity(prim_t func, char *name, int arg1, int arg2);
|
|||
#include <stdio.h>
|
||||
|
||||
typedef void (*prim_void_void_3args_t)(Scheme_Object **);
|
||||
typedef unsigned long (*prim_alloc_void_pvoid_t)();
|
||||
typedef Scheme_Object* (*prim_obj_int_pobj_obj_t)(Scheme_Object*, int, Scheme_Object**);
|
||||
typedef Scheme_Object* (*prim_int_pobj_obj_t)(int, Scheme_Object**);
|
||||
typedef Scheme_Object* (*prim_int_pobj_obj_obj_t)(int, Scheme_Object**, Scheme_Object*);
|
||||
|
@ -105,7 +104,7 @@ typedef struct future_t {
|
|||
//Signature flags for primitive invocations
|
||||
//Here the convention is SIG_[arg1type]_[arg2type]..._[return type]
|
||||
#define SIG_VOID_VOID_3ARGS 1 //void -> void, copy 3 args from runstack
|
||||
#define SIG_ALLOC_VOID_PVOID 2 //void -> void*
|
||||
#define SIG_ALLOC 2 //void -> void*
|
||||
|
||||
# include "jit_ts_protos.h"
|
||||
|
||||
|
@ -122,7 +121,7 @@ extern Scheme_Object *scheme_ts_scheme_force_value_same_mark(Scheme_Object *v);
|
|||
}
|
||||
|
||||
extern void scheme_rtcall_void_void_3args(const char *who, int src_type, prim_void_void_3args_t f);
|
||||
extern unsigned long scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, prim_alloc_void_pvoid_t f);
|
||||
extern unsigned long scheme_rtcall_alloc(const char *who, int src_type);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -136,7 +135,7 @@ extern unsigned long scheme_rtcall_alloc_void_pvoid(const char *who, int src_typ
|
|||
#define LOG_THISCALL LOG(__FUNCTION__)
|
||||
|
||||
#define LOG_RTCALL_VOID_VOID_3ARGS(f) LOG("(function=%p)", f)
|
||||
#define LOG_RTCALL_ALLOC_VOID_PVOID(f) LOG("(function=%p)", f)
|
||||
#define LOG_RTCALL_ALLOC(f) LOG("(function=%p)", f)
|
||||
#define LOG_RTCALL_OBJ_INT_POBJ_OBJ(f,a,b,c) LOG("(function = %p, a=%p, b=%d, c=%p)", f, a, b, c)
|
||||
#define LOG_RTCALL_OBJ_INT_POBJ_VOID(a,b,c) LOG("(%p, %d, %p)", a, b,c)
|
||||
#define LOG_RTCALL_INT_OBJARR_OBJ(a,b) LOG("(%d, %p)", a, b)
|
||||
|
@ -159,7 +158,7 @@ extern unsigned long scheme_rtcall_alloc_void_pvoid(const char *who, int src_typ
|
|||
#define LOG_THISCALL
|
||||
|
||||
#define LOG_RTCALL_VOID_VOID_3ARGS(f)
|
||||
#define LOG_RTCALL_ALLOC_VOID_PVOID(f)
|
||||
#define LOG_RTCALL_ALLOC(f)
|
||||
#define LOG_RTCALL_OBJ_INT_POBJ_OBJ(f,a,b,c)
|
||||
#define LOG_RTCALL_OBJ_INT_POBJ_VOID(a,b,c)
|
||||
#define LOG_RTCALL_INT_OBJARR_OBJ(a,b)
|
||||
|
|
|
@ -1394,7 +1394,6 @@ THREAD_LOCAL_DECL(extern unsigned long GC_gen0_alloc_page_ptr);
|
|||
long GC_initial_word(int sizeb);
|
||||
void GC_initial_words(char *buffer, int sizeb);
|
||||
long GC_compute_alloc_size(long sizeb);
|
||||
long GC_alloc_alignment(void);
|
||||
|
||||
static void *retry_alloc_code;
|
||||
static void *retry_alloc_code_keep_r0_r1;
|
||||
|
@ -2257,7 +2256,7 @@ static void *ts_prepare_retry_alloc(void *p, void *p2) XFORM_SKIP_PROC
|
|||
if (scheme_use_rtcall) {
|
||||
jit_future_storage[0] = p;
|
||||
jit_future_storage[1] = p2;
|
||||
ret = scheme_rtcall_alloc_void_pvoid("[acquire_gc_page]", FSRC_OTHER, GC_make_jit_nursery_page);
|
||||
ret = scheme_rtcall_alloc("[acquire_gc_page]", FSRC_OTHER);
|
||||
GC_gen0_alloc_page_ptr = ret;
|
||||
retry_alloc_r1 = jit_future_storage[1];
|
||||
p = jit_future_storage[0];
|
||||
|
|
Loading…
Reference in New Issue
Block a user