From 4eaea0afad5dfd31d1d800138f5afaca1925c775 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Sun, 13 Jul 2014 12:18:16 +0400 Subject: [PATCH] Code refactoring of Emscripten platform support (single-threaded) * alloc.c (min_bytes_allocd): Test STACK_NOT_SCANNED macro instead of __EMSCRIPTEN__ (stack size to scan is zero if STACK_NOT_SCANNED). * include/private/gcconfig.h (ALIGNMENT): Remove duplicate definition for _EMSCRIPTEN__. * include/private/gcconfig.h (STACK_NOT_SCANNED): New macro defined for __EMSCRIPTEN__ target (in addition to OS_TYPE, CPP_WORDSZ, ALIGNMENT, DATASTART, DATAEND). * mach_dep.c (GC_push_regs): Test STACK_NOT_SCANNED macro instead of __EMSCRIPTEN__ (push nothing if STACK_NOT_SCANNED). * mark_rts.c (GC_push_roots): Test STACK_NOT_SCANNED macro instead of __EMSCRIPTEN__ (do not call GC_push_regs_and_stack if STACK_NOT_SCANNED); mark cold_gc_frame argument as potentially unused. * misc.c (GC_clear_stack): Test STACK_NOT_SCANNED macro instead of __EMSCRIPTEN__ (do not clear stack if STACK_NOT_SCANNED). * misc.c (GC_clear_stack): Reformat code. --- alloc.c | 8 ++---- include/private/gcconfig.h | 2 +- mach_dep.c | 14 ++++++---- mark_rts.c | 8 +++--- misc.c | 57 +++++++++++++++++++------------------- 5 files changed, 44 insertions(+), 45 deletions(-) diff --git a/alloc.c b/alloc.c index d8fb954f..2f877fba 100644 --- a/alloc.c +++ b/alloc.c @@ -202,15 +202,13 @@ GC_API GC_stop_func GC_CALL GC_get_stop_func(void) static word min_bytes_allocd(void) { word result; -# ifdef __EMSCRIPTEN__ +# ifdef STACK_NOT_SCANNED word stack_size = 0; -# else -# ifdef STACK_GROWS_UP +# elif defined(STACK_GROWS_UP) word stack_size = GC_approx_sp() - GC_stackbottom; /* GC_stackbottom is used only for a single-threaded case. */ -# else +# else word stack_size = GC_stackbottom - GC_approx_sp(); -# endif # endif word total_root_size; /* includes double stack size, */ diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 4eed1842..744869ff 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -560,7 +560,6 @@ # if defined(__EMSCRIPTEN__) # define I386 -# define ALIGNMENT 4 # define mach_type_known # endif @@ -766,6 +765,7 @@ # define ALIGNMENT 4 # define DATASTART NULL # define DATAEND NULL +# define STACK_NOT_SCANNED # endif # define STACK_GRAN 0x1000000 diff --git a/mach_dep.c b/mach_dep.c index a882c76d..29e0b8a7 100644 --- a/mach_dep.c +++ b/mach_dep.c @@ -103,7 +103,14 @@ # define HAVE_PUSH_REGS #else /* No asm implementation */ -# if defined(M68K) && defined(AMIGA) +# ifdef STACK_NOT_SCANNED + void GC_push_regs(void) + { + /* empty */ + } +# define HAVE_PUSH_REGS + +# elif defined(M68K) && defined(AMIGA) /* This function is not static because it could also be */ /* erroneously defined in .S file, so this error would be caught */ /* by the linker. */ @@ -181,11 +188,6 @@ } # define HAVE_PUSH_REGS # endif /* __MWERKS__ */ -# elif defined(EMSCRIPTEN) - void GC_push_regs(void) - { - } -# define HAVE_PUSH_REGS # endif /* MACOS */ #endif /* !USE_ASM_PUSH_REGS */ diff --git a/mark_rts.c b/mark_rts.c index 53341586..fc1f46c3 100644 --- a/mark_rts.c +++ b/mark_rts.c @@ -751,7 +751,7 @@ STATIC void GC_push_regs_and_stack(ptr_t cold_gc_frame) * A zero value indicates that it's OK to miss some * register values. */ -GC_INNER void GC_push_roots(GC_bool all, ptr_t cold_gc_frame) +GC_INNER void GC_push_roots(GC_bool all, ptr_t cold_gc_frame GC_ATTR_UNUSED) { int i; unsigned kind; @@ -810,9 +810,9 @@ GC_INNER void GC_push_roots(GC_bool all, ptr_t cold_gc_frame) * This is usually done by saving the current context on the * stack, and then just tracing from the stack. */ -#ifndef __EMSCRIPTEN__ - GC_push_regs_and_stack(cold_gc_frame); -#endif +# ifndef STACK_NOT_SCANNED + GC_push_regs_and_stack(cold_gc_frame); +# endif if (GC_push_other_roots != 0) (*GC_push_other_roots)(); /* In the threads case, this also pushes thread stacks. */ diff --git a/misc.c b/misc.c index 526eb989..e76aaafc 100644 --- a/misc.c +++ b/misc.c @@ -349,16 +349,14 @@ GC_INNER void GC_extend_size_map(size_t i) /* another frame. */ GC_API void * GC_CALL GC_clear_stack(void *arg) { -#ifdef __EMSCRIPTEN__ - return arg; -#endif +# ifndef STACK_NOT_SCANNED ptr_t sp = GC_approx_sp(); /* Hotter than actual sp */ # ifdef THREADS word volatile dummy[SMALL_CLEAR_SIZE]; static unsigned random_no = 0; - /* Should be more random than it is ... */ - /* Used to occasionally clear a bigger */ - /* chunk. */ + /* Should be more random than it is ... */ + /* Used to occasionally clear a bigger */ + /* chunk. */ # endif ptr_t limit; @@ -377,53 +375,54 @@ GC_API void * GC_CALL GC_clear_stack(void *arg) /* frequency decreases, thus clearing frequency would decrease, */ /* thus more junk remains accessible, thus the heap gets */ /* larger ... */ -# ifdef THREADS - if (++random_no % 13 == 0) { +# ifdef THREADS + if (++random_no % 13 == 0) { limit = sp; MAKE_HOTTER(limit, BIG_CLEAR_SIZE*sizeof(word)); limit = (ptr_t)((word)limit & ~0xf); /* Make it sufficiently aligned for assembly */ /* implementations of GC_clear_stack_inner. */ return GC_clear_stack_inner(arg, limit); - } else { + } else { BZERO((void *)dummy, SMALL_CLEAR_SIZE*sizeof(word)); - return arg; - } -# else - if (GC_gc_no > GC_stack_last_cleared) { + } +# else + if (GC_gc_no > GC_stack_last_cleared) { /* Start things over, so we clear the entire stack again */ - if (GC_stack_last_cleared == 0) GC_high_water = (ptr_t)GC_stackbottom; + if (GC_stack_last_cleared == 0) + GC_high_water = (ptr_t)GC_stackbottom; GC_min_sp = GC_high_water; GC_stack_last_cleared = GC_gc_no; GC_bytes_allocd_at_reset = GC_bytes_allocd; - } - /* Adjust GC_high_water */ - MAKE_COOLER(GC_high_water, WORDS_TO_BYTES(DEGRADE_RATE) + GC_SLOP); - if ((word)sp HOTTER_THAN (word)GC_high_water) { - GC_high_water = sp; - } - MAKE_HOTTER(GC_high_water, GC_SLOP); - limit = GC_min_sp; - MAKE_HOTTER(limit, SLOP); - if ((word)sp COOLER_THAN (word)limit) { + } + /* Adjust GC_high_water */ + MAKE_COOLER(GC_high_water, WORDS_TO_BYTES(DEGRADE_RATE) + GC_SLOP); + if ((word)sp HOTTER_THAN (word)GC_high_water) { + GC_high_water = sp; + } + MAKE_HOTTER(GC_high_water, GC_SLOP); + limit = GC_min_sp; + MAKE_HOTTER(limit, SLOP); + if ((word)sp COOLER_THAN (word)limit) { limit = (ptr_t)((word)limit & ~0xf); /* Make it sufficiently aligned for assembly */ /* implementations of GC_clear_stack_inner. */ GC_min_sp = sp; - return(GC_clear_stack_inner(arg, limit)); - } else if (GC_bytes_allocd - GC_bytes_allocd_at_reset > CLEAR_THRESHOLD) { + return GC_clear_stack_inner(arg, limit); + } else if (GC_bytes_allocd - GC_bytes_allocd_at_reset + > CLEAR_THRESHOLD) { /* Restart clearing process, but limit how much clearing we do. */ GC_min_sp = sp; MAKE_HOTTER(GC_min_sp, CLEAR_THRESHOLD/4); if ((word)GC_min_sp HOTTER_THAN (word)GC_high_water) GC_min_sp = GC_high_water; GC_bytes_allocd_at_reset = GC_bytes_allocd; - } - return(arg); + } +# endif # endif + return arg; } - /* Return a pointer to the base address of p, given a pointer to a */ /* an address within an object. Return 0 o.w. */ GC_API void * GC_CALL GC_base(void * p) -- 2.40.0