summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/private/gc_priv.h8
-rw-r--r--include/private/gcconfig.h7
-rw-r--r--mach_dep.c43
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 */
diff --git a/mach_dep.c b/mach_dep.c
index c90f8e02..c596bcb7 100644
--- a/mach_dep.c
+++ b/mach_dep.c
@@ -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) {