Skip to content

Commit

Permalink
Call syscall() to get E2K procedure stack directly in caller function
Browse files Browse the repository at this point in the history
Move code of GC_get_procedure_stack() into GET_PROCEDURE_STACK_LOCAL(),
so that syscall(E2K_GET_PROCEDURE_STACK_SIZE) and
syscall(E2K_READ_PROCEDURE_STACK_EX) are invoked directly in the
function which uses GET_PROCEDURE_STACK_LOCAL() macro.

Also, do not expect anymore that syscall(E2K_GET_PROCEDURE_STACK_SIZE)
could be interrupted (resulting in a syscall fail with EAGAIN), and
do not call syscall(E2K_GET_PROCEDURE_STACK_SIZE) again after
syscall(E2K_READ_PROCEDURE_STACK_EX) is interrupted.

* include/private/gc_priv.h [E2K] (GC_get_procedure_stack): Do not
declare.
* include/private/gc_priv.h [E2K]: Move include errno.h,
sys/e2k_syswork.h, sys/syscall.h from mach_dep.c.
* include/private/gc_priv.h [E2K] (GET_PROCEDURE_STACK_LOCAL): Remove
capacity local variable; do not call GC_get_procedure_stack() (call
syscall() directly instead); define ofs_sz_ll local variable; move
syscall() with E2K_GET_PROCEDURE_STACK_SIZE out of the for loop (i.e.
do not retry it if syscall() fails with EAGAIN).
* mach_dep.c [E2K] (GC_get_procedure_stack): Do not define.
  • Loading branch information
ivmai committed Nov 21, 2023
1 parent d9f2cc7 commit 92abef5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 51 deletions.
42 changes: 27 additions & 15 deletions include/private/gc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2016,11 +2016,9 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
#endif

#ifdef E2K
/* Copy the full procedure stack to the provided buffer (with the */
/* given capacity). Returns either the required buffer size if it */
/* is bigger than the provided buffer capacity, otherwise the amount */
/* of copied bytes. May be called from a signal handler. */
GC_INNER size_t GC_get_procedure_stack(ptr_t, size_t);
# include <errno.h>
# include <asm/e2k_syswork.h>
# include <sys/syscall.h>

# if defined(CPPCHECK)
# define PS_ALLOCA_BUF(sz) __builtin_alloca(sz)
Expand All @@ -2031,16 +2029,30 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
/* Copy procedure (register) stack to a stack-allocated buffer. */
/* Usable from a signal handler. The buffer is valid only within */
/* the current function. */
# define GET_PROCEDURE_STACK_LOCAL(pbuf, psz) \
do { \
size_t capacity = 0; \
\
for (*(pbuf) = NULL; ; capacity = *(psz)) { \
*(psz) = GC_get_procedure_stack(*(pbuf), capacity); \
if (*(psz) <= capacity) break; \
/* Allocate buffer on the stack; cannot return NULL. */ \
*(pbuf) = PS_ALLOCA_BUF(*(psz)); \
} \
# define GET_PROCEDURE_STACK_LOCAL(pbuf, psz) \
do { \
unsigned long long ofs_sz_ll = 0; \
\
/* Determine buffer size to store the procedure stack. */ \
if (syscall(__NR_access_hw_stacks, E2K_GET_PROCEDURE_STACK_SIZE, \
NULL, NULL, 0, &ofs_sz_ll) == -1) \
ABORT_ARG1("Cannot get size of procedure stack", \
": errno= %d", errno); \
GC_ASSERT(ofs_sz_ll > 0 && ofs_sz_ll % sizeof(word) == 0); \
*(psz) = (size_t)ofs_sz_ll; \
/* Allocate buffer on the stack; cannot return NULL. */ \
*(pbuf) = PS_ALLOCA_BUF(*(psz)); \
/* Read the procedure stack to the buffer. */ \
for (;;) { \
ofs_sz_ll = 0; \
if (syscall(__NR_access_hw_stacks, E2K_READ_PROCEDURE_STACK_EX, \
&ofs_sz_ll, *(pbuf), *(psz), NULL) != -1) \
break; \
if (errno != EAGAIN) \
ABORT_ARG2("Cannot read procedure stack", \
": sz= %lu, errno= %d", \
(unsigned long)(*(psz)), errno); \
} \
} while (0)
#endif /* E2K */

Expand Down
36 changes: 0 additions & 36 deletions mach_dep.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,6 @@
# endif
#endif

#ifdef E2K
# include <errno.h>
# include <asm/e2k_syswork.h>
# include <sys/syscall.h>

GC_INNER size_t GC_get_procedure_stack(ptr_t buf, size_t buf_sz) {
unsigned long long new_sz;

GC_ASSERT(0 == buf_sz || buf != NULL);
for (;;) {
unsigned long long stack_ofs;

new_sz = 0;
if (syscall(__NR_access_hw_stacks, E2K_GET_PROCEDURE_STACK_SIZE,
NULL, NULL, 0, &new_sz) == -1) {
if (errno != EAGAIN)
ABORT_ARG1("Cannot get size of procedure stack",
": errno= %d", errno);
continue;
}
GC_ASSERT(new_sz > 0 && new_sz % sizeof(word) == 0);
if (new_sz > buf_sz)
break;
/* Immediately read the stack right after checking its size. */
stack_ofs = 0;
if (syscall(__NR_access_hw_stacks, E2K_READ_PROCEDURE_STACK_EX,
&stack_ofs, buf, new_sz, NULL) != -1)
break;
if (errno != EAGAIN)
ABORT_ARG2("Cannot read procedure stack",
": new_sz= %lu, errno= %d", (unsigned long)new_sz, errno);
}
return (size_t)new_sz;
}
#endif /* E2K */

#if defined(MACOS) && defined(__MWERKS__)

#if defined(POWERPC)
Expand Down

0 comments on commit 92abef5

Please sign in to comment.