diff options
-rw-r--r-- | include/private/gc_priv.h | 8 | ||||
-rw-r--r-- | include/private/gcconfig.h | 7 | ||||
-rw-r--r-- | mach_dep.c | 43 |
3 files changed, 50 insertions, 8 deletions
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 25aa8175..70741b0b 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1471,6 +1471,14 @@ struct _GC_arrays { # define GC_trace_addr GC_arrays._trace_addr ptr_t _trace_addr; # endif +# ifdef E2K_USE_SCRATCH +# define GC_e2k_ps_buffer GC_arrays._e2k_ps_buffer +# define GC_e2k_ps_capacity GC_arrays._e2k_ps_capacity + ptr_t _e2k_ps_buffer; + size_t _e2k_ps_capacity; + /* A buffer allocated by GC_scratch_alloc() and used repeatedly */ + /* by GC_get_procedure_stack() in the single-threaded mode. */ +# endif # define GC_capacity_heap_sects GC_arrays._capacity_heap_sects size_t _capacity_heap_sects; # define GC_n_heap_sects GC_arrays._n_heap_sects diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 4b027aa9..d671a9c6 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -2063,6 +2063,13 @@ EXTERN_C_BEGIN # ifdef LINUX extern int __dso_handle[]; # define DATASTART ((ptr_t)__dso_handle) +# ifdef REDIRECT_MALLOC +# if !defined(GC_LINUX_THREADS) +# define E2K_USE_SCRATCH +# elif !defined(CPPCHECK) +# error malloc redirection with threads is not supported on E2K yet +# endif +# endif # endif # endif /* E2K */ @@ -67,15 +67,29 @@ } while (0) GC_INNER void GC_free_procedure_stack(ptr_t buf) { - free(buf); +# ifdef E2K_USE_SCRATCH + GC_ASSERT(buf != NULL); + GC_ASSERT(NULL == GC_e2k_ps_buffer); + GC_e2k_ps_buffer = buf; /* the buffer could be reused */ +# else + free(buf); +# endif } GC_INNER size_t GC_get_procedure_stack(ptr_t *buf_ptr) { word ps; - ptr_t buf = NULL; - word buf_sz = 0; + ptr_t buf; + word buf_sz; word new_sz = 0; +# ifdef E2K_USE_SCRATCH + buf = GC_e2k_ps_buffer; + buf_sz = (word)GC_e2k_ps_capacity; + GC_e2k_ps_buffer = NULL; /* indicate the buffer is in use */ +# else + buf = NULL; + buf_sz = 0; +# endif get_stack_index(&ps); for (;;) { int res = syscall(__NR_access_hw_stacks, E2K_READ_PROCEDURE_STACK, @@ -83,9 +97,22 @@ if (res != -1) break; if (ENOMEM == errno && buf_sz != new_sz) { - /* FIXME: use GC_scratch_alloc to support malloc redirection? */ - free(buf); - buf = malloc((size_t)new_sz); +# ifdef LOG_E2K_ALLOCS + GC_log_printf("GC_get_procedure_stack(): free/alloc %lu/%lu bytes," + " GC #%lu\n", + (unsigned long)buf_sz, (unsigned long)new_sz, + (unsigned long)GC_gc_no); +# endif +# ifdef E2K_USE_SCRATCH + GC_ASSERT(new_sz > (word)GC_e2k_ps_capacity); + GC_scratch_recycle_no_gww(buf, GC_e2k_ps_capacity); + buf = GC_scratch_alloc((size_t)new_sz); + GC_e2k_ps_capacity = (size_t)new_sz; + /* TODO: support malloc redirection if multi-threaded */ +# else + free(buf); + buf = malloc((size_t)new_sz); +# endif if (NULL == buf) ABORT_ARG1("Could not allocate memory for procedure stack", ", %lu bytes requested", (unsigned long)new_sz); @@ -100,13 +127,13 @@ get_stack_index(&ps); } - if (buf_sz != new_sz) + if (buf_sz < new_sz) ABORT_ARG2("Buffer size mismatch while reading procedure stack", ": buf_sz= %lu, new_sz= %lu", (unsigned long)buf_sz, (unsigned long)new_sz); GC_ASSERT(buf != NULL); *buf_ptr = buf; - return (size_t)buf_sz; + return (size_t)new_sz; } ptr_t GC_save_regs_in_stack(void) { |