mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-06 15:40:29 +02:00
Avoid variable stack use in scm_array_for_each_cell()
* libguile/arrays.c (scm_array_for_each_cell): Allocate all variable sized data at the top of the function using scm_gc_malloc_pointerless().
This commit is contained in:
parent
b854d0f34a
commit
2ce48a3f46
1 changed files with 40 additions and 13 deletions
|
@ -592,13 +592,46 @@ SCM_DEFINE (scm_array_for_each_cell, "array-for-each-cell", 2, 0, 1,
|
||||||
"@end lisp")
|
"@end lisp")
|
||||||
#define FUNC_NAME s_scm_array_for_each_cell
|
#define FUNC_NAME s_scm_array_for_each_cell
|
||||||
{
|
{
|
||||||
// FIXME replace stack by scm_gc_malloc_pointerless()
|
|
||||||
int const N = scm_ilength (a_);
|
int const N = scm_ilength (a_);
|
||||||
int const frank = scm_to_int (frank_);
|
int const frank = scm_to_int (frank_);
|
||||||
scm_t_array_handle ah[N];
|
|
||||||
SCM a[N];
|
// wish C had better stack support
|
||||||
scm_t_array_dim * as[N];
|
|
||||||
int rank[N];
|
size_t stack_size = 0;
|
||||||
|
stack_size += N*sizeof (scm_t_array_handle);
|
||||||
|
stack_size += N*sizeof (SCM);
|
||||||
|
stack_size += N*sizeof (scm_t_array_dim *);
|
||||||
|
stack_size += N*sizeof (int);
|
||||||
|
stack_size += frank*sizeof (ssize_t);
|
||||||
|
|
||||||
|
stack_size += N*sizeof (SCM);
|
||||||
|
stack_size += N*sizeof (SCM *);
|
||||||
|
stack_size += frank*sizeof (ssize_t);
|
||||||
|
stack_size += frank*sizeof (int);
|
||||||
|
|
||||||
|
stack_size += N*sizeof(size_t);
|
||||||
|
char * stack = scm_gc_malloc_pointerless (stack_size, "stack");
|
||||||
|
|
||||||
|
#define AFIC_ALLOC_ADVANCE(stack, count, type, name) \
|
||||||
|
type * name = (void *)stack; \
|
||||||
|
stack += count*sizeof(type);
|
||||||
|
|
||||||
|
char * stack0 = stack;
|
||||||
|
AFIC_ALLOC_ADVANCE (stack, N, scm_t_array_handle, ah);
|
||||||
|
AFIC_ALLOC_ADVANCE (stack, N, SCM, a);
|
||||||
|
AFIC_ALLOC_ADVANCE (stack, N, scm_t_array_dim *, as);
|
||||||
|
AFIC_ALLOC_ADVANCE (stack, N, int, rank);
|
||||||
|
AFIC_ALLOC_ADVANCE (stack, frank, ssize_t, s);
|
||||||
|
|
||||||
|
AFIC_ALLOC_ADVANCE (stack, N, SCM, ai);
|
||||||
|
AFIC_ALLOC_ADVANCE (stack, N, SCM *, dargs);
|
||||||
|
AFIC_ALLOC_ADVANCE (stack, frank, ssize_t, i);
|
||||||
|
AFIC_ALLOC_ADVANCE (stack, frank, int, order);
|
||||||
|
|
||||||
|
AFIC_ALLOC_ADVANCE(stack, N, size_t, base);
|
||||||
|
assert((stack0+stack_size==stack) && "internal error");
|
||||||
|
#undef AFIC_ALLOC_ADVANCE
|
||||||
|
|
||||||
for (int n=0; scm_is_pair(a_); a_=scm_cdr(a_), ++n)
|
for (int n=0; scm_is_pair(a_); a_=scm_cdr(a_), ++n)
|
||||||
{
|
{
|
||||||
a[n] = scm_car(a_);
|
a[n] = scm_car(a_);
|
||||||
|
@ -607,7 +640,6 @@ SCM_DEFINE (scm_array_for_each_cell, "array-for-each-cell", 2, 0, 1,
|
||||||
rank[n] = scm_array_handle_rank(ah+n);
|
rank[n] = scm_array_handle_rank(ah+n);
|
||||||
}
|
}
|
||||||
// checks.
|
// checks.
|
||||||
ssize_t s[frank];
|
|
||||||
char const * msg = NULL;
|
char const * msg = NULL;
|
||||||
if (frank<0)
|
if (frank<0)
|
||||||
{
|
{
|
||||||
|
@ -641,7 +673,6 @@ SCM_DEFINE (scm_array_for_each_cell, "array-for-each-cell", 2, 0, 1,
|
||||||
scm_misc_error("array-for-each-cell", msg, scm_cons_star(frank_, a_));
|
scm_misc_error("array-for-each-cell", msg, scm_cons_star(frank_, a_));
|
||||||
}
|
}
|
||||||
// prepare moving cells.
|
// prepare moving cells.
|
||||||
SCM ai[N];
|
|
||||||
scm_t_array_dim * ais[N];
|
scm_t_array_dim * ais[N];
|
||||||
for (int n=0; n!=N; ++n)
|
for (int n=0; n!=N; ++n)
|
||||||
{
|
{
|
||||||
|
@ -656,7 +687,6 @@ SCM_DEFINE (scm_array_for_each_cell, "array-for-each-cell", 2, 0, 1,
|
||||||
}
|
}
|
||||||
// prepare rest list for callee.
|
// prepare rest list for callee.
|
||||||
SCM dargs_ = SCM_EOL;
|
SCM dargs_ = SCM_EOL;
|
||||||
SCM * dargs[N];
|
|
||||||
{
|
{
|
||||||
SCM *p = &dargs_;
|
SCM *p = &dargs_;
|
||||||
for (int n=0; n<N; ++n) {
|
for (int n=0; n<N; ++n) {
|
||||||
|
@ -680,8 +710,6 @@ SCM_DEFINE (scm_array_for_each_cell, "array-for-each-cell", 2, 0, 1,
|
||||||
return SCM_UNSPECIFIED;
|
return SCM_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
// FIXME determine best looping order.
|
// FIXME determine best looping order.
|
||||||
ssize_t i[frank];
|
|
||||||
int order[frank];
|
|
||||||
for (int k=0; k!=frank; ++k)
|
for (int k=0; k!=frank; ++k)
|
||||||
{
|
{
|
||||||
i[k] = 0;
|
i[k] = 0;
|
||||||
|
@ -700,7 +728,6 @@ SCM_DEFINE (scm_array_for_each_cell, "array-for-each-cell", 2, 0, 1,
|
||||||
}
|
}
|
||||||
ocd_reached: ;
|
ocd_reached: ;
|
||||||
// rank loop.
|
// rank loop.
|
||||||
size_t base[N];
|
|
||||||
for (int n=0; n!=N; ++n)
|
for (int n=0; n!=N; ++n)
|
||||||
{
|
{
|
||||||
base[n] = SCM_I_ARRAY_BASE(ai[n]);
|
base[n] = SCM_I_ARRAY_BASE(ai[n]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue