[comp.sys.amiga.programmer] AmigaGCC stack hogging

bojsen@moria.UUCP (Per Bojsen) (01/12/91)

This is a question to the people who ported GCC to the Amiga.  I don't know
if it has been discussed before, but here you are:

What is the precise reason for the large stack needs of GCC?  Is it the
alloca() call?  If this is the case, have you considered using the PD
alloca() by D.A. Gwyn, which comes with (Amiga) `gnused'?  This
implementation of alloca() uses malloc() to allocate memory from the heap
instead of on the stack.  Since the Amiga does not grow stacks automatically
at the moment it is better to allocate from the heap.

Another question regarding GCC: is the source for the Amiga port available?

--
.------------------------------------------------------------------------------.
|  Greetings from Per Bojsen.                                                  |
+-------------------------------+----------------------------------------------+
|  EMail: cbmehq!lenler!bojsen  |"Zen is a feeling.  It's the feeling you get  |
|     Or: bojsen@dc.dth.dk      | when you know you're going to get a feeling."|
`-------------------------------+----------------------------------------------'

swalton@solaria.csun.edu (Stephen Walton) (01/15/91)

In article <1882f287.ARN1979@moria.UUCP>, bojsen@moria (Per Bojsen) writes:

>What is the precise reason for the large stack needs of GCC?

This is not peculiar to GCC.  All of the GNU software is written as if
the amount of available stack was essentially infinite.  The GNU regular
expression routines, for instance, use alloca() extensively.

You will also find that GNU Emacs crashes on an A3000 running AmigaOS,
because it uses the high bits of a 32 bit address to store information
about Emacs Lisp objects.  About the only other Amiga software which does
this is AmigaBasic!
-------------------------------
Stephen Walton, Dept. of Physics & Astronomy, Cal State Univ. Northridge
   I am srw@csun.edu no matter WHAT the stupid From: line says!

himacdon@maytag.uwaterloo.ca (Hamish Macdonald) (01/15/91)

>>>>> In article <1991Jan14.212254.9779@csun.edu>,
>>>>> swalton@solaria.csun.edu (Stephen Walton) writes:

Stephen> In article <1882f287.ARN1979@moria.UUCP>, bojsen@moria (Per Bojsen) writes:

>What is the precise reason for the large stack needs of GCC?

Stephen> This is not peculiar to GCC.  All of the GNU software is
Stephen> written as if the amount of available stack was essentially
Stephen> infinite.  The GNU regular expression routines, for instance,
Stephen> use alloca() extensively.

This is, of course, becuase all of the GNU software is written with
Unices in mind, which provide virtual memory, and allow the stack to
grow to be as big as it wants (in general).  I'd say this is perfectly
reasonable.

Stephen> You will also find that GNU Emacs crashes on an A3000 running
Stephen> AmigaOS, because it uses the high bits of a 32 bit address to
Stephen> store information about Emacs Lisp objects.  About the only
Stephen> other Amiga software which does this is AmigaBasic!

This isn't really the problem, since Emacs masks off the type and GC
bits before doing any address indirection.

The problem is that Emacs relies on address mapping hardware giving it an
address space consisting of the memory from 0-16M.   Usually, 16M _is_
enough for an editor.  Unfortunately, on the A3000, most of the memory
is _not_ in this 16M address space, so there are problems (actually,
you can extend the address space to 64M; I believe the person who
ported Gnu Emacs to the Amiga did this to support the A3000).

The Emacs Lisp implementation does need to be changed to support full
32 bit object addresses, both to solve the problem on the Amiga, and
also to allow Emacs processes to grow larger than 16M (although it is
currently possible.

Hamish.
--
--------------------------------------------------------------------
himacdon@maytag.uwaterloo.ca                 watmath!maytag!himacdon

swalton@solaria.csun.edu (Stephen Walton) (01/16/91)

In article <1991Jan15.154204.10833@maytag.waterloo.edu>,
himacdon@maytag (Hamish Macdonald) writes:

>This isn't really the problem, since Emacs masks off the type and GC
>bits before doing any address indirection.

Thanks for the clarification.

>you can extend the address space to 64M; I believe the person who
>ported Gnu Emacs to the Amiga did this to support the A3000).

Doesn't work.  The A3000 I'm using right now goes down in flames when
Amiga GNU Emacs 0.9 is brought up.

Steve

jesup@cbmvax.commodore.com (Randell Jesup) (01/16/91)

In article <1991Jan16.014951.5670@csun.edu> swalton@solaria.csun.edu (Stephen Walton) writes:
>In article <1991Jan15.154204.10833@maytag.waterloo.edu>,
>himacdon@maytag (Hamish Macdonald) writes:
>>you can extend the address space to 64M; I believe the person who
>>ported Gnu Emacs to the Amiga did this to support the A3000).
>
>Doesn't work.  The A3000 I'm using right now goes down in flames when
>Amiga GNU Emacs 0.9 is brought up.

	The ram on the A3000 is at around 7*16Meg = 112 meg (0x07xxxxxx).

-- 
Randell Jesup, Keeper of AmigaDos, Commodore Engineering.
{uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.commodore.com  BIX: rjesup  
The compiler runs
Like a swift-flowing river
I wait in silence.  (From "The Zen of Programming")  ;-)

bojsen@moria.UUCP (Per Bojsen) (01/17/91)

In article <1991Jan14.212254.9779@csun.edu>, Stephen Walton writes:

> In article <1882f287.ARN1979@moria.UUCP>, bojsen@moria (Per Bojsen) writes:
>
> >What is the precise reason for the large stack needs of GCC?
>
> This is not peculiar to GCC.  All of the GNU software is written as if
> the amount of available stack was essentially infinite.  The GNU regular
> expression routines, for instance, use alloca() extensively.
>
As I pointed out in my previous article, along with the GNU sed, flex, diff,
and gawk Amiga ports followed a version of alloca() that does _not_ allocate
on the stack, _but_ uses malloc()!  The other day I just checked, and this
alloca.c module is also included with the gcc-1.37.1 distribution.

Using this special version of alloca() should make it possible to reduce
the stack needs of the GNU utilities substantially, so my question stands:
does the Amiga ports of gcc use this non-stack-allocating alloca(), or do
they allocate _on_ the stack?

--
.------------------------------------------------------------------------------.
|  Greetings from Per Bojsen.                                                  |
+-------------------------------+----------------------------------------------+
|  EMail: cbmehq!lenler!bojsen  |"Zen is a feeling.  It's the feeling you get  |
|     Or: bojsen@dc.dth.dk      | when you know you're going to get a feeling."|
`-------------------------------+----------------------------------------------'

jesup@cbmvax.commodore.com (Randell Jesup) (01/18/91)

In article <1991Jan17.141218.19953@zorch.SF-Bay.ORG> xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) writes:
>Maybe I'm missing the point here.  The _purpose_ of alloca() is to
>allow extremely low overhead grabbing and releasing of extremely
>temporary memory, and to do a super cheap form of resource tracking.
>
>Why replace it by putting back something that installs the very same
>problems alloca() was trying to solve, and possibly gets you into other
>trouble if code makes assumptions that things pushed on the stack and
>things alloca()ed on the stack are in consecutive storage locations?

	The problem is that GCC (and other gnu code) allocates LARGE
amounts of memory using alloca, and holds it for a long time.  For example,
I'm told that the preprocessor or compiler pulls entire files into a
single alloca and then operates on that structure.  this is a killer on
any OS without automatic stack extension.  Modifying alloca is far easier
when porting gnu code than trying to get the GNU people to modify the
original gnu source.

-- 
Randell Jesup, Keeper of AmigaDos, Commodore Engineering.
{uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.commodore.com  BIX: rjesup  
The compiler runs
Like a swift-flowing river
I wait in silence.  (From "The Zen of Programming")  ;-)

bojsen@moria.UUCP (Per Bojsen) (01/18/91)

In article <1991Jan16.014951.5670@csun.edu>, Stephen Walton writes:

> In article <1991Jan15.154204.10833@maytag.waterloo.edu>,
> himacdon@maytag (Hamish Macdonald) writes:
>
> >you can extend the address space to 64M; I believe the person who
> >ported Gnu Emacs to the Amiga did this to support the A3000).
>
> Doesn't work.  The A3000 I'm using right now goes down in flames when
> Amiga GNU Emacs 0.9 is brought up.
>
As Dave Haynie pointed out some time ago this is because the standard fast
ram on the A3000 lies in the $07000000-$07ffffff range, i.e., you would
need an address space of at least 128M---but even that would not be
sufficient in the long run, since further expansion memory may go up to
$7fffffff, i.e, 2G.  So, GNU Emacs will not be properly programmed for the
Amiga before it uses full 32 bit addressing (why use bit 31 for anything
but an address?).  Does anyone know how difficult this would be to implement?

--
.------------------------------------------------------------------------------.
|  Greetings from Per Bojsen.                                                  |
+-------------------------------+----------------------------------------------+
|  EMail: cbmehq!lenler!bojsen  |"Zen is a feeling.  It's the feeling you get  |
|     Or: bojsen@dc.dth.dk      | when you know you're going to get a feeling."|
`-------------------------------+----------------------------------------------'

bojsen@moria.UUCP (Per Bojsen) (01/20/91)

In article <1991Jan17.141218.19953@zorch.SF-Bay.ORG>, Kent Paul Dolan writes:

> bojsen@moria.UUCP writes:
>
> > Using this special version of alloca() should make it possible to
> > reduce the stack needs of the GNU utilities substantially, so my
> > question stands: does the Amiga ports of gcc use this
> > non-stack-allocating alloca(), or do they allocate _on_ the stack?
>
> Maybe I'm missing the point here.  The _purpose_ of alloca() is to
> allow extremely low overhead grabbing and releasing of extremely
> temporary memory, and to do a super cheap form of resource tracking.
>
Yes, I understand that!  However, in the case of Amiga, see below.

> Why replace it by putting back something that installs the very same
> problems alloca() was trying to solve, and possibly gets you into other
> trouble if code makes assumptions that things pushed on the stack and
> things alloca()ed on the stack are in consecutive storage locations?
>
Ok, Gwyn's alloca() implementation will break if the code makes such `nasty'
assumptions . . .  Are you aware of any such code in GNU?

> If the gnu code is doing inappropriate things with alloca() replace the
> calls with malloc() calls explicitly.  Otherwise you are just creating
> big performance hits that will have to be cleared up by still further
> efforts later on.
>
Here is why I think Gwyn's alloca() would be better on the Amiga under the
current OS versions (including 2.0):

    * The stack does not grow automatically.

    * It is _dangerous_ to fall off the bottom of the stack.

    * It is usually difficult to predict how much stack a specific
      invocation of a command, like gcc, needs.  So you'll have to
      allocate `enough' stack, which usually is too much, i.e.,
      there is some amount of resource wasting, although it's possible
      to live with if you have RAM enough.

    * Gwyn's alloca() _does_ track memory resources, and releases
      memory previously allocated in the way one would expect (almost).

So, for the time being---when the AmigaOS does not grow stacks---I would
prefer Gwyn's approach.  I don't think your point about the `bad'
assumptions on relative alignment of alloca()'ed blocks is valid for the
various GNU programs, because Gwyn's alloca() is distributed with most
GNU products including gcc, gawk, diff, and gnused; I assume FSF wouldn't
distribute this module with the programs if it didn't work.

Well, that's just my opinion, and given that I have the source, I can
allways recompile the different programs using the alloca() that I want,
so there's really no problem!

--
.------------------------------------------------------------------------------.
|  Greetings from Per Bojsen.                                                  |
+-------------------------------+----------------------------------------------+
|  EMail: cbmehq!lenler!bojsen  |"Zen is a feeling.  It's the feeling you get  |
|     Or: bojsen@dc.dth.dk      | when you know you're going to get a feeling."|
`-------------------------------+----------------------------------------------'

himacdon@maytag.uwaterloo.ca (Hamish Macdonald) (01/22/91)

>>>>> In article <188a0681.ARN1bc1@moria.UUCP>, bojsen@moria.UUCP (Per Bojsen) writes:

Per> [...]  So, GNU Emacs will not be properly programmed for the
Per> Amiga before it uses full 32 bit addressing (why use bit 31 for
Per> anything but an address?).  Does anyone know how difficult this
Per> would be to implement?

Emacs uses the top 6-8 bits of a word for Lisp type and garbage
collection marking bits.

I don't think the changes are incredibly difficult.  Just very
time-consuming.  The Emacs lisp object is currently defined to be a
union of an integer and a number of structures.  There is an _awful_
lot of code in Gnu Emacs which depends on being able to pass a lisp
object around as an integer.

One way to change this would be to get rid of the integer/structure
union and make the lisp object a 64 bit structure.  Everything would
then have to be changed to support passing the larger structure
around.

Another approach suggested is to make the lisp object a 32 bit pointer
to the actual contents of the object (i.e. a 64 bit structure
containing the type and garbage collection bits and a pointer/integer
field.).  This requires an extra indirection to access the object.

These changes are going to affect the performance of Emacs, since it
would use more memory and would be slower.

--
--------------------------------------------------------------------
himacdon@maytag.uwaterloo.ca                 watmath!maytag!himacdon

jkh@bambam.pcs.com (Jordan K. Hubbard) (01/29/91)

>> As I pointed out in my previous article, along with the GNU sed, flex,
>> diff, and gawk Amiga ports followed a version of alloca() that does
>> _not_ allocate on the stack, _but_ uses malloc()! The other day I just
>> checked, and this alloca.c module is also included with the gcc-1.37.1
>>
>Maybe I'm missing the point here.  The _purpose_ of alloca() is to
>allow extremely low overhead grabbing and releasing of extremely
>.. [etc etc]
>Why replace it by putting back something that installs the very same
>problems alloca() was trying to solve, and possibly gets you into other
>trouble if code makes assumptions that things pushed on the stack and
>things alloca()ed on the stack are in consecutive storage locations?
>
>If the gnu code is doing inappropriate things with alloca() replace the
>calls with malloc() calls explicitly.  Otherwise you are just creating

ARGH! NO! NO!

I'm afraid you _are_ missing the point, Kent.  While you're right in
saying that the primary purpose of alloca() is to provide low overhead
you-don't-need-to-worry-about-freeing-it-afterwards allocation of
memory, just replacing the calls to alloca() with malloc() IS NOT a
good solution to the problem! Unless you then take the time to track
the memory so allocated and explicitly free() it at the appropriate
time, you've just introduced a memory leak. Tracking the memory
properly may not be all that easy if the original programmer used
alloca() specifically because such tracking was highly non-trivial
otherwise.

The alloca.c file that Per mentions was written in an attempt to
emulate alloca() for machines that don't support the actual stack
manipulation for some reason. While it's true that it actually uses
malloc() to do its work, it would be a mistake to assume that it's
simply a lexical replacement. It actually tries quite hard to keep
track of what was allocated at what time so that it can free things
automatically for you when it's quite sure that you've returned from
an "alloca()" using routine.  The algorithm isn't perfect, given the
constraints it has to work under, but it's a whole lot better than a
simply dropping malloc() in place of alloca(). Performance certainly
won't be the same as with a _real_ alloca(), sure, but I find memory
leaks a whole lot more objectionable than lost CPU cycles!

					Jordan

--
			PCS Computer Systeme GmbH, Munich, West Germany
	UUCP:		pyramid!pcsbst!jkh jkh@meepmeep.pcs.com
	EUNET:		unido!pcsbst!jkh
	ARPA:		jkh@violet.berkeley.edu or hubbard@decwrl.dec.com

jkh@bambam.pcs.com (Jordan K. Hubbard) (01/29/91)

>	The problem is that GCC (and other gnu code) allocates LARGE
>amounts of memory using alloca, and holds it for a long time.  For example,
>I'm told that the preprocessor or compiler pulls entire files into a

The pre-processor does this. And it doesn't hold it that long, remember:
alloca()'d data goes away the minute the calling procedure returns.
This whole scheme works very nicely under UNIX - It's a pity that processes's
can't seem to automatically grow their stacks during run time. Why is this?

I could even see a scheme where a process was halted completely and
copied to a new (larger) chunk of memory in order to "grow its stack"
if such mastication were necessary - it would still be better than
nuking it entirely.

					Jordan
--
			PCS Computer Systeme GmbH, Munich, West Germany
	UUCP:		pyramid!pcsbst!jkh jkh@meepmeep.pcs.com
	EUNET:		unido!pcsbst!jkh
	ARPA:		jkh@violet.berkeley.edu or hubbard@decwrl.dec.com

jesup@cbmvax.commodore.com (Randell Jesup) (01/30/91)

In article <JKH.91Jan29041002@bambam.pcs.com> jkh@bambam.pcs.com (Jordan K. Hubbard) writes:
>>	The problem is that GCC (and other gnu code) allocates LARGE
>>amounts of memory using alloca, and holds it for a long time.  For example,
>>I'm told that the preprocessor or compiler pulls entire files into a
>
>The pre-processor does this. And it doesn't hold it that long, remember:
>alloca()'d data goes away the minute the calling procedure returns.
>This whole scheme works very nicely under UNIX - It's a pity that processes's
>can't seem to automatically grow their stacks during run time. Why is this?

	Simple: how do we know that a program overran it's stack?  Don't
forget 1.5+ million A500's and A2000's.

>I could even see a scheme where a process was halted completely and
>copied to a new (larger) chunk of memory in order to "grow its stack"
>if such mastication were necessary - it would still be better than
>nuking it entirely.

	Sounds like you're talking about a VM system here...  Also, what if
a driver was in the process of DMAing to part of the stack?  (A Read(), for
example.)

	alloca() is NOT suited for a non-VM system.  It's purpose is to
implement a heap allocation scheme with heap allocation pushed off on the
OS VM system.  A typical Stallman-esque hack that's rather tied to a 
restrictive model of the system (witness GNUEmacs and tag bits for another
example), and basicly a non-portable contruct.

-- 
Randell Jesup, Keeper of AmigaDos, Commodore Engineering.
{uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.commodore.com  BIX: rjesup  
The compiler runs
Like a swift-flowing river
I wait in silence.  (From "The Zen of Programming")  ;-)

peter@sugar.hackercorp.com (Peter da Silva) (01/31/91)

In article <JKH.91Jan29041002@bambam.pcs.com> jkh@bambam.pcs.com (Jordan K. Hubbard) writes:
> This whole scheme works very nicely under UNIX - It's a pity that processes's
> can't seem to automatically grow their stacks during run time. Why is this?

The 68000 does not support memory management. You can't detect a stack
overflow, or for that matter move a program around (not that that has any
breaking on growing a stack on the Amiga: programs are not contiguous)
unless you can map memory and trap memory references.
-- 
Peter da Silva.   `-_-'
<peter@sugar.hackercorp.com>.

ronbo@vixen.uucp (Ron Hitchens) (02/03/91)

>>Maybe I'm missing the point here.  The _purpose_ of alloca() is to
>>allow extremely low overhead grabbing and releasing of extremely
>>.. [etc etc]
>>Why replace it by putting back something that installs the very same
>>problems alloca() was trying to solve, ...
>>
>>If the gnu code is doing inappropriate things with alloca() replace the
>>calls with malloc() calls explicitly.  Otherwise you are just creating
>
>ARGH! NO! NO!
>
>I'm afraid you _are_ missing the point, Kent.  While you're right in
>saying that the primary purpose of alloca() is to provide low overhead
>you-don't-need-to-worry-about-freeing-it-afterwards allocation of
>memory, just replacing the calls to alloca() with malloc() IS NOT a
>good solution to the problem! Unless you then take the time to track
>the memory so allocated and explicitly free() it at the appropriate
>time, you've just introduced a memory leak. 

    I've been thinking about this problem since it came up in this group
and I think I may have a good compromise solution.

    The "problem", for those who may be unclear on what it is, is that
the gcc compiler makes extensive use of the alloca() function which means
that it requires a huge stack in order to run without crashing on the Amiga.
The alloca() function allocates memory, similar to the more common malloc()
function, but it allocates the memory from the top of the stack rather than
from the general memory pool.  This usually means it is quite fast, but
more importantly it means that the allocated memory automatically disappears
when the function from which it was called exits.  Now, this works fine and
dandy on a unix system which can detect stack overruns, via an MMU, and
transparently grow the stack as needed.  Unfortunately the Amiga cannot
grow the stack for a task once it has started, so therefore gcc's heavy use
of alloca() means humungous amounts of stack space must be used when running
gcc to guard against the worst possible case.

    On the Amiga, we'd like to move all these alloca() calls off the stack,
but preserve the automatic-free behaviour to avoid having to rewrite huge
chunks of the compiler to do memory tracking.  Well, I think I have a way
to do that, which is possible because gcc is so configurable.

    In order to have alloca()'ed memory automatically disappear at function
exit it either needs to be incorporated into the current stack frame, as it
commonly is on unix, or you need some sort of hook that can reliably be
called whenever the function exits.  Such a hook exists in gcc, the config
headers for gcc allow you to define function prologue and epilogue code
that is generated at the beginning and end of every function.  It seems to
me that this is the place to hook in an alloca()-like scheme which actually
does malloc()-like allocations.

    It should be fairly simple to do with some code like the following:


typedef struct
	struct MinNode	node;		/* node struct for chaining */
	short		level;		/* nesting level when alloced */
	short		pad;		/* maintain longword alignment */
} AllocaNode;

static struct List	alloca_list = {		/* stack of malloc'ed blocks */
	(struct Node *) &alloca_list.lh_Tail, NULL,
	(struct Node *) &alloca_list.lh_Head, 0, 0
};

static int		alloca_level = 0;

/*	Called at function entry, increments current nesting level */
void
push_alloca (void)
{
	alloca_level++;
}

/*	Called at function exit, zaps blocks malloc'ed at current level */
void
pop_alloca (void)
{
	AllocaNode	*node;

	while ((node = (AllocaNode *) RemHead (&alloca_list)) != NULL) {
		if (node->level < alloca_level) {
			/* alloced below this level, put it back */
			AddHead (&alloca_list, (struct Node *) node);
			break;
		}
		free (node);
	}

	alloca_level--;
}

/*	Alternate alloca, mallocs and flags blocks with current nest level */
void *
alloca (size_t size)
{
	AllocaNode	*node = malloc (size + sizeof (AllocaNode));

	if (node == NULL) {
		return (NULL);
	}

	node->level = alloca_level;
	AddHead (&alloca_list, (struct Node *) node);

	node++;			/* bump past AllocaNode header */

	return (node);
}


    This code is not tested, I just now typed it in, but should be mostly
right.  The way it would work is this: when every function is entered it
would call push_alloca() to increment the current notion of the nesting
level for alloca's purposes.  When the function exits it would call
pop_alloca() which will free all the memory blocks that have been malloc'ed
at that level, then decrement the nesting level.  The alternate version
of alloca() will use malloc() to allocate the requested amount of space plus
a small header for a list node and a field to indicate what the nesting
level was at the time it was allocated, for unwinding the allocation stack.

    The calls to push_alloca() and pop_alloca() would be automatically 
generated as part of the FUNCTION_PROLOGUE and FUNCTION_EPILOGUE macros
which are defined in the tm.h header file in gcc, preferably conditional
on a run-time switch.

    This example code is in C, but if implemented would probably be done
in assembler for efficency.  The call to push_alloc() could even be replaced
by an inline add if the nesting variable is made global.  You could
probably get a performance increase by using AllocMem() rather than malloc,
but you'd have a memory leak if the program didn't exit by returning from
main() (ie by calling exit()).  Also, setjmp/longjmp would cause problems.

    Anyway, that's my suggestion for a workaround for gcc's stack gluttony.
Others are welcome to build on it.  Personally, I generally run a version
of gcc on my Sun which cross-compiles for the Amiga, so it doesn't present
much of a problem for me.

-- 
Ron Hitchens    /-O-O   | ronbo@vixen.uucp			- Smart uucp
  Sleepless     C  >    | ...!cs.utah.edu!caeco!vixen!ronbo	- Stupid uucp
    Software       ~    | hitchens@cs.utexas.edu		- Internet
"To be is to do" -Socrates  "To do is to be" -Sartre  "Do be do be do" -Sinatra

markv@kuhub.cc.ukans.edu (02/06/91)

>     In order to have alloca()'ed memory automatically disappear at function
> exit it either needs to be incorporated into the current stack frame, as it
> commonly is on unix, or you need some sort of hook that can reliably be
> called whenever the function exits.  Such a hook exists in gcc, the config
> headers for gcc allow you to define function prologue and epilogue code
> that is generated at the beginning and end of every function.  It seems to
> me that this is the place to hook in an alloca()-like scheme which actually
> does malloc()-like allocations.
> 
>     It should be fairly simple to do with some code like the following:
> ...extensive and nice code managing a memory list...

Rather than roll all this yourself, how about AllocRemember() and
FreeRemember().  Have each function have a hidden variable in the
prologue that gets initialized to NULL (the RememberKey), then use it.
At function exit call FreeRemember() with key and it all goes away.

struct Remember	*FuncKey = NULL;

#define alloca(x)	AllocRemember(x, 0L, &FuncKey)

Then at exit just call FreeRemember(&FuncKey, TRUE);

For more details, look in the RKMs under Misc. Intuition functions.

>     The calls to push_alloca() and pop_alloca() would be automatically 
> generated as part of the FUNCTION_PROLOGUE and FUNCTION_EPILOGUE macros
> which are defined in the tm.h header file in gcc, preferably conditional
> on a run-time switch.
> 
>     This example code is in C, but if implemented would probably be done
> in assembler for efficency.  The call to push_alloc() could even be replaced
> by an inline add if the nesting variable is made global.  You could
> probably get a performance increase by using AllocMem() rather than malloc,
> but you'd have a memory leak if the program didn't exit by returning from
> main() (ie by calling exit()).  Also, setjmp/longjmp would cause problems.

Huh?  There is no difference in C level cleanup between returning from
main() and exit().  (abort() is a different matter though).  Note that
a cleanup function could be defined and installed with atexit().
setjmp() longjmp() would still be problematic.  However, one could
slightly redefine the AllocRemember() call to a macro that also
stuffed the Remember key in a static holder.

AllocRemember() has very good performance.  It only uses a singly
linked list.  It takes a pointer to a pointer because it always links
onto the head of the list, so it doesn't have to traverse to the end.
 
>     Anyway, that's my suggestion for a workaround for gcc's stack gluttony.
> Others are welcome to build on it.  Personally, I generally run a version
> of gcc on my Sun which cross-compiles for the Amiga, so it doesn't present
> much of a problem for me.
-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark Gooderum			Only...		\    Good Cheer !!!
Academic Computing Services	       ///	  \___________________________
University of Kansas		     ///  /|         __    _
Bix:	  mgooderum	      \\\  ///  /__| |\/| | | _   /_\  makes it
Bitnet:   MARKV@UKANVAX		\/\/  /    | |  | | |__| /   \ possible...
Internet: markv@kuhub.cc.ukans.edu
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

bojsen@moria.UUCP (Per Bojsen) (02/07/91)

In article <390@vixen.uucp>, Ron Hitchens writes:

>
>     I've been thinking about this problem since it came up in this group
> and I think I may have a good compromise solution.
>
Unfortunately, I think your solution won't work!  See below.

>
> [A large description of Ron's proposed scheme deleted]
>
>     The calls to push_alloca() and pop_alloca() would be automatically
> generated as part of the FUNCTION_PROLOGUE and FUNCTION_EPILOGUE macros
> which are defined in the tm.h header file in gcc, preferably conditional
> on a run-time switch.
>
I believe you've misunderstood the purpose of the prologue/epilogue macros!
They are _not_ used for the functions in `gcc', _but_ are used in the code
generator part of `gcc' to generate the code for function entry/exit.  I.e.,
these two macros are the instructions to generate the assembly code that
constitutes function prologue/epilogue in code _generated_ by `gcc', _not_
in `gcc' itself!

Besides, there already exists a version of alloca() which does a fair amount
of resource tracking and which uses malloc().  This alloca.c module is
distributed with most (if not all) GNU programs, including `gcc'.

Since I did my original posting (which started this thread) I have done some
investigation on the reasons for `gcc's stack hogging.  It unfortunately
turned out that the reported stack usage of 100-200K was for versions using
the malloc'ing alloca()!!!  So `gcc' has a real need for a lot of stack!

--
.------------------------------------------------------------------------------.
|  Greetings from Per Bojsen.                                                  |
+-------------------------------+----------------------------------------------+
|  EMail: cbmehq!lenler!bojsen  |"Zen is a feeling.  It's the feeling you get  |
|     Or: bojsen@dc.dth.dk      | when you know you're going to get a feeling."|
`-------------------------------+----------------------------------------------'