summaryrefslogtreecommitdiff
path: root/mach_dep.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-01-19 22:07:41 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-01-19 22:15:37 +0300
commit9027a0b429ad3f2f3f0eb77210f22c4a1d21ee4a (patch)
tree57fcc8f153f1e0388b522eaf085e8a868fa7ddb6 /mach_dep.c
parent26b2fb160670314200c6a5792b40ee21b585cf8f (diff)
downloadbdwgc-9027a0b429ad3f2f3f0eb77210f22c4a1d21ee4a.tar.gz
Support malloc redirection on E2K (single-threaded mode only)
Issue #413 (bdwgc). * include/private/gc_priv.h [E2K_USE_SCRATCH] (GC_e2k_ps_buffer, GC_e2k_ps_capacity): Define macro. * include/private/gcconfig.h [E2K && LINUX && REDIRECT_MALLOC && !GC_LINUX_THREADS] (E2K_USE_SCRATCH): Likewise. * include/private/gc_priv.h [E2K_USE_SCRATCH] (_GC_arrays): Add _e2k_ps_buffer and _e2k_ps_capacity fields; add comment. * include/private/gcconfig.h [E2K && LINUX && REDIRECT_MALLOC && GC_LINUX_THREADS && !CPPCHECK]: Issue an error directive. * mach_dep.c [E2K && E2K_USE_SCRATCH] (GC_free_procedure_stack): Do not call free(); assert that buf is non-null but GC_e2k_ps_buffer is null; set GC_e2k_ps_buffer to buf. * mach_dep.c [E2K && E2K_USE_SCRATCH] (GC_get_procedure_stack): Initialize buf local variable to GC_e2k_ps_buffer; initialize buf_sz local variable to GC_e2k_ps_capacity; clear GC_e2k_ps_buffer value; change FIXME item to TODO one; pass buf to GC_scratch_recycle_no_gww() instead of free(); call GC_scratch_alloc() instead of malloc(). * mach_dep.c [E2K && LOG_E2K_ALLOCS] (GC_get_procedure_stack): Call GC_log_printf() to print buf_sz, new_sz and GC_gc_no values if errno is ENOMEM. * mach_dep.c [E2K] (GC_get_procedure_stack): Ensure buf_sz<new_sz (instead of buf_sz!=new_sz) after the loop; return new_sz instead of buf_sz.
Diffstat (limited to 'mach_dep.c')
-rw-r--r--mach_dep.c43
1 files changed, 35 insertions, 8 deletions
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) {