Skip to content

Commit

Permalink
Do not use assembly in GC_get_procedure_stack (E2K)
Browse files Browse the repository at this point in the history
(a cherry-pick of commits d3f5bdc, 41d41c3 from 'master')

Issue #411 (bdwgc).

Use E2K_GET_PROCEDURE_STACK_SIZE and E2K_READ_PROCEDURE_STACK_EX
sub-functions (of access_hw_stacks syscall) instead of the legacy
E2K_READ_PROCEDURE_STACK one which required computation of ps_index
manually.  Check the stack size right before reading the stack (to
avoid EINVAL).

* mach_dep.c [E2K] (VA_SIZE, E2K_PSHTP_SIZE, VLIW_CMD_BRACES_PREFIX,
get_stack_index): Remove macro.
* mach_dep.c [E2K] (GC_get_procedure_stack): Initialize new_sz only
if buf is null; define stack_ofs local variable instead of ps; add
assertion that new_sz is non-zero and multiple of word size; use
E2K_GET_PROCEDURE_STACK_SIZE sub-function instead of
E2K_READ_PROCEDURE_STACK to get H/W procedure stack size (call
E2K_GET_PROCEDURE_STACK_SIZE sub-function right before
E2K_READ_PROCEDURE_STACK_EX one to check that the procedure stack size
has not changed since the previous call of
GC_get_procedure_stack(NULL,0)); do not use get_stack_index(); use
E2K_READ_PROCEDURE_STACK_EX sub-function (with stack_ofs=0) instead of
E2K_READ_PROCEDURE_STACK to read H/W procedure stack from the given
stack_ofs; print new_sz (in addition to errno) in case of error and
not EAGAIN; add comment.
* mach_dep.c [E2K && LOG_E2K_ALLOCS] (GC_get_procedure_stack): Remove
code.
* mach_dep.c [E2K && THREADS] (GC_alloc_and_get_procedure_stack): Add
TODO item.
  • Loading branch information
ivmai committed Jul 15, 2022
1 parent 85d959a commit 51fcc9a
Showing 1 changed file with 22 additions and 60 deletions.
82 changes: 22 additions & 60 deletions mach_dep.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,69 +32,33 @@
# include <sys/mman.h>
# include <sys/syscall.h>

# define VA_SIZE 48
# define E2K_PSHTP_SIZE 12

# if defined(__clang__)
# define VLIW_CMD_BRACES_PREFIX "%" /* a workaround for clang-9 */
# else
# define VLIW_CMD_BRACES_PREFIX /* empty */
# endif

# define get_stack_index(ps_ptr) \
do { \
word psp_lo, psp_hi; \
signed_word pshtp; \
char tmp = 0, val; \
\
__asm__ __volatile__ ( \
"1:\n\t" \
"ldb %4, 0, %0, mas = 7\n\t" \
"rrd %%pshtp, %1\n\t" \
"rrd %%psp.lo, %2\n\t" \
"rrd %%psp.hi, %3\n\t" \
VLIW_CMD_BRACES_PREFIX "{\n\t" \
" stb %4, 0, %0, mas = 2\n\t" \
" rbranch 1b\n\t" \
VLIW_CMD_BRACES_PREFIX "}" \
: "=&r" (val), "=&r" (pshtp), \
"=&r" (psp_lo), "=&r" (psp_hi) \
: "r" (&tmp)); \
*(ps_ptr) = (psp_lo & ((1UL<<VA_SIZE)-1)) \
+ (unsigned)psp_hi \
+ (word)((pshtp << (64-E2K_PSHTP_SIZE)) \
>> (63-E2K_PSHTP_SIZE)); \
} while (0)

GC_INNER size_t GC_get_procedure_stack(ptr_t buf, size_t buf_sz) {
word ps;
word new_sz = 0;
word new_sz;

GC_ASSERT(0 == buf_sz || buf != NULL);
for (;;) {
get_stack_index(&ps);
if (syscall(__NR_access_hw_stacks, E2K_READ_PROCEDURE_STACK,
&ps, buf, buf_sz, &new_sz) != -1)
break;

if (ENOMEM == errno && (word)buf_sz < new_sz) {
# ifdef LOG_E2K_ALLOCS
if (buf_sz > 0) /* probably may happen */
GC_log_printf("GC_get_procedure_stack():"
" buffer size/requested %lu/%lu bytes, GC #%lu\n",
(unsigned long)buf_sz, (unsigned long)new_sz,
(unsigned long)GC_gc_no);
# endif
return (size_t)new_sz; /* buffer not enough */
} else if (errno != EAGAIN) {
ABORT_ARG1("Cannot read procedure stack", ": errno= %d", errno);
word 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);
}

if ((word)buf_sz < new_sz)
ABORT_ARG2("Buffer overflow while reading procedure stack",
": buf_sz= %lu, new_sz= %lu",
(unsigned long)buf_sz, (unsigned long)new_sz);
return (size_t)new_sz;
}

Expand Down Expand Up @@ -124,6 +88,7 @@
# ifdef THREADS
GC_INNER size_t GC_alloc_and_get_procedure_stack(ptr_t *pbuf)
{
/* TODO: support saving from non-zero ofs in stack */
ptr_t buf = NULL;
size_t new_sz, buf_sz;

Expand All @@ -142,9 +107,6 @@
return new_sz;
}
# endif /* THREADS */

# undef VLIW_CMD_BRACES_PREFIX
# undef get_stack_index
#endif /* E2K */

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

0 comments on commit 51fcc9a

Please sign in to comment.