T.R | Title | User | Personal Name | Date | Lines |
---|
2088.1 | A risky workaround??? | HPCGRP::MANLEY | | Mon Feb 10 1997 11:40 | 9 |
|
> Or any possible workarounds?
Within the customers alloca, perhaps the call frame and everything between
it and the previous frame can be relocated, leaving the alloca'd space above
the relocated data. This may work, and then again it may not. It certainly
won't work if pointers to stack allocated data are loaded before alloca is
called.
|
2088.2 | VAX MACRO my_alloca | HNDYMN::MCCARTHY | A Quinn Martin Production | Mon Feb 10 1997 12:12 | 87 |
| Try this (I think it modifies the stack in the way you want) - I think it still
compiles (I cut it down from another example).
This is UNSUPPORTED !!
Brian J.
#define alloca my_alloca
s = alloca (size);
--------------------------------------
File: my_alloca.mar
--------------------------------------
.TITLE my_alloca
.page
.SBTTL DECLARATIONS
$SFDEF ; stack frame symbols
.DSABL GBL ; Force all external symbols to be declared
.PSECT $CODE,PIC,RD,SHR,NOWRT,LONG
.ENTRY __my_alloca, ^M<R2,R3,R4,R5>
;
; What we want to do here is adjust the stack pointer ahead by the value
; in 4(ap) and return the pointer to the adjusted stack to the caller in r0
; Note:
; We do not add the size of this call frame to the
; adjusted value because when this routine is called,
; this frame is created on the stack, that means we already
; have 44 bytes allocated (that is:
; Handler - Address 0
; PSL 4
; AP 8
; FP 16
; PC 20
; R2 SAVE 24
; R3 SAVE 28
; R4 SAVE 32
; R5 SAVE 36
; ARG COUNT 40
; FIRST ARG 44
;
; When we move the SP down
; by the requested amount, and then point FP at that new location,
; when the RET pops things off the stack, it is taking that
; 44 bytes back off off from the newly adjusted stack. We are left with
; exactly the amount requested (plus any padding)
;
;
; Add 3 to requested value, then use the BICL2 instruction to
; make sure the request is a multiple of 4 (longword aligned).
; Me, think of using the BICL2 instruction myself? nope. I checked
; other sources for the word align and found several examples.
;
ADDL3 #3, 4(AP), R0
BICL2 #3, R0
;
; Move the stack down requested amount
;
SUBL R0, SP
;
; Move the contents of the current frame into the area we just
; allocated on the stack.
;
MOVC3 #44, (FP), (SP)
;
; Subtract the size of this frame (44 bytes) from the current FP and
; that is the address of the stack storage requested. (since this
; routine has no local storage, FP and SP were equal when we entered)
;
SUBL3 #44, FP, R0
;
; The last thing to do is to change the frame pointer to be where we
; moved the SP to. This will cause the RET statement to clear this
; "new" stack off the frame and set SP to the location at the bottom
; of the stack.
;
MOVL SP, FP
RET
.END
|
2088.3 | Great example! | TAVENG::BORIS | Boris Gubenko, ISE | Mon Feb 10 1997 13:33 | 9 |
|
Great example! Worked like a champ for me.
(vfork() on VAX does similar manipulations with stack frames).
btw, I could never understand what alloca() is good for and why allocation
a memory from the stack is better than allocation from heap (I mean malloc()).
Boris
|
2088.4 | | HPCGRP::MANLEY | | Mon Feb 10 1997 13:42 | 6 |
|
Re: .2
It shouldn't be hard to convince yourself that R0 is always returns the address
44 bytes below the current FP. ;-)
|
2088.5 | Why alloca() ? | SUBPAC::FARICELLI | | Mon Feb 10 1997 14:01 | 15 |
|
>> btw, I could never understand what alloca() is good for and why allocation
>> a memory from the stack is better than allocation from heap
1) Dynamic memory allocated via alloca() is automatically freed at the
exit of the routine.
2) Some malloc() implementations may incur a lot of overhead
when allocating and deallocating lots of small pieces of memory.
Some poorly implemented malloc()'s maintained free()'d memory on
a linear linked list, for example.
One piece of ancient wisdom was to always roll your own memory
management if you had this situation and you needed performance.
-- John Faricelli
|
2088.6 | .2 doesn't work for me... | RDGENG::WOOD_J | [email protected] | Tue Feb 11 1997 03:50 | 113 |
| I tried the Macro example from .2, but it didn't work for me.
Whilst I appreciate the discaimer in .2 about it being unsupported,
I wonder if I'm doing something wrong since the .3 reply implied
it worked.
Below is my test program. I compile with /debug/noopt using DEC C v5.5
on OpenVMS VAX v6.2. When I run using the debugger I get an access
violation when sub() tries to initialize the 23rd element of the
ip[] array. I don't understand why. I did change the Macro32 code
so that the call-entry of __my_alloca becomes my_alloca.
Thanks,
John Wood
-------------
From debugger:
728: /* initialize array allocated on stack */
729: ip = p;
730: for (j = 0; j < i; j++)
-> 731: ip[j] = j;
732:
Line 731: MOVL B^-12(FP),R0
-> MOVL B^-12(FP),@B^-16(FP)[R0]
ADDL3 B^-12(FP),S^#1,R0
MOVL R0,B^-12(FP)DBG> Step
%SYSTEM-F-ACCVIO, access violation, reason mask=04, virtual address=00000072,
PC=00000390, PSL=03C00011
DBG>
---------
test program:
/*
test_alloca.c - example program to call alloca()
VAX:
$ cc/debug/noopt/lis/mach test_alloca.c
$ macro/debug/lis my_alloca.mar
$ link/debug/map/full test_alloca, my_alloca
*/
#include <stdio.h>
/* DEC C on OpenVMS Alpha */
#if defined (__VMS) && defined (__alpha)
#include <builtins.h>
#endif
/* DEC C on OpenVMS VAX : use VAX Macro routine my_alloca() for alloca() */
#if defined (__VMS) && defined (__vax)
#define alloca my_alloca
void *my_alloca( int size );
#endif
/* cc on Digital UNIX v4.0 */
#if defined (__DECC) && defined (__alpha) && defined (__unix__)
#include <alloca.h>
#endif
void sub2( int i, int *ip )
{
int j;
printf( "sub2: i = %d\n", i );
/* display contents of array */
for (j = 0; j < i; j++)
{
printf( " %5d", ip[j] );
if (((j+1) % 10) == 0)
printf( "\n" );
}
printf( "\n" );
}
void sub( int i )
{
void *p;
int j;
int *ip;
/* check value of "j" before & after call to alloca to ensure local */
/* variables are being preserved */
j = i;
printf( "sub(): value of j before calling alloca() is %d\n", j );
p = alloca( i*sizeof(int) );
printf( "sub(): value of j after calling alloca() is %d\n", j );
printf( "sub(): addr from alloca() is %p; (j = %d)\n", p, j );
/* initialize array allocated on stack */
ip = p;
for (j = 0; j < i; j++)
ip[j] = j;
/* now call subroutine to manipulate alloca'd data */
sub2( i, ip );
}
int main()
{
sub( 123 );
}
|
2088.7 | easy for DEC C to implement on OpenVMS VAX? | RDGENG::WOOD_J | [email protected] | Tue Feb 11 1997 05:20 | 5 |
| Are there no plans for DEC C for VAX to implement alloca()?
Wouldn't a built-in __ALLOCA for VAX just have to decrement
the SP by the required amount (-whilst keeping stack longword-
aligned) ? I.e. wouldn't this be easy to implement?
|
2088.8 | there were no plans two years ago | HNDYMN::MCCARTHY | A Quinn Martin Production | Tue Feb 11 1997 05:53 | 7 |
| >>Are there no plans for DEC C for VAX to implement alloca()?
The previous example was written several years ago and at that time there were
no plans to add alloca() to OpenVMS VAX. I don't think that position has
changed.
bjm
|
2088.9 | known failing case | HNDYMN::MCCARTHY | A Quinn Martin Production | Tue Feb 11 1997 05:57 | 9 |
| As to why it does not work (but a work around was sent to me via mail) may
be the layout of the local variables by the compiler.
The example assumes that all stack space that will be used by the compiler has
been pre-allocated prior to calling the routine. If that is not the case, and
the compiler tries to allocate more memory after the function prologue, then
the example will fail - that's the one case that I know of, there may be more.
bjm
|
2088.10 | c-alloca | MUCTEC::BECKER | Hartmut B., VMS & Languages, Munich | Tue Feb 11 1997 07:57 | 8 |
| In the recent kits of gnu emacs and gcc there is a c implementation of alloca.
It allocates memory on the heap, keeps track of the allocated memeory and in
each call checks and cleans up unused memory. As one can see it's different
from the original idea but should be portable. Also I assume it is more
expensive than simple stack manipulation. Maybe it can serve as a
workaround.
Hartmut
|
2088.11 | macro my_alloca example | HNDYMN::MCCARTHY | A Quinn Martin Production | Tue Feb 11 1997 09:11 | 92 |
| A fix to .2 (that has been deleted to avoid bad hacks from getting out :-))
Brian
Try this (I think it modifies the stack in the way you want) - I think it still
compiles (I cut it down from another example).
This is UNSUPPORTED !!
Brian J.
#define alloca my_alloca
s = alloca (size);
--------------------------------------
File: my_alloca.mar
--------------------------------------
.TITLE my_alloca
.page
.SBTTL DECLARATIONS
$SFDEF ; stack frame symbols
.DSABL GBL ; Force all external symbols to be declared
.PSECT $CODE,PIC,RD,SHR,NOWRT,LONG
.ENTRY __my_alloca, ^M<R2,R3,R4,R5>
;
; What we want to do here is adjust the stack pointer ahead by the value
; in 4(ap) and return the pointer to the adjusted stack to the caller in r0
; Note:
; We do not add the size of this call frame to the
; adjusted value because when this routine is called,
; this frame is created on the stack, that means we already
; have 44 bytes allocated (that is:
; Handler - Address 0
; PSL 4
; AP 8
; FP 16
; PC 20
; R2 SAVE 24
; R3 SAVE 28
; R4 SAVE 32
; R5 SAVE 36
; ARG COUNT 40
; FIRST ARG 44
;
; When we move the SP down
; by the requested amount, and then point FP at that new location,
; when the RET pops things off the stack, it is taking that
; 44 bytes back off off from the newly adjusted stack. We are left with
; exactly the amount requested (plus any padding)
;
;
; Add 3 to requested value, then use the BICL2 instruction to
; make sure the request is a multiple of 4 (longword aligned).
; Me, think of using the BICL2 instruction myself? nope. I checked
; other sources for the word align and found several examples.
;
ADDL3 #3, 4(AP), R0
BICL2 #3, R0
;
; Move the stack down requested amount
;
SUBL R0, SP
;
; Move the contents of the current frame into the area we just
; allocated on the stack.
;
MOVC3 #44, (FP), (SP)
;
; Add the size of this frame (44 bytes) to the current SP and
; that is the address of the stack storage requested.
;
ADDL3 #44, SP, R0
;
; The last thing to do is to change the frame pointer to be where we
; moved the SP to. This will cause the RET statement to clear this
; "new" stack off the frame and set SP to the location at the bottom
; of the stack.
;
MOVL SP, FP
RET
.END
|
2088.12 | Currently no plans for alloca on VAX | CXXC::REPETE | Rich Peterson 381-1802 ZKO2-3/N30 | Tue Feb 11 1997 15:42 | 15 |
| If it were as easy for the compiler to do as decrementing SP, then the
original idea of having a little macro routine do just that would have
worked. But of course this showed the problem that the compiled code
bases its addressing of locals off of SP, assuming a compile-time
fixed size stack frame. So the "easy" fix in the compiler is to
implement and test a different addressing model that sets up and
addresses locals off of FP instead of SP in any function containing
a call to (builtin) alloca. This is exactly what the GEM-based Alpha
compiler does.
Given the length of time that VAX C and DEC C on VAX have have survived
without an alloca, and given the VAX-specific engineering and testing
investment needed to get this on VAX safely (this part of the compiler
is written in MACRO), there would have to be some major commitment to
new VAX orders hinging on it to make it worthwhile...
|
2088.13 | thanks | RDGENG::WOOD_J | [email protected] | Wed Feb 12 1997 03:19 | 6 |
| Thanks for all the replies.
Hopefully the Macro workaround will be adequate for the s/w vendor.
Regards,
John
|
2088.14 | A C version of alloca ... uses a private stack ... | HPCGRP::MANLEY | | Wed Feb 12 1997 13:01 | 95 |
|
John,
> Hopefully the Macro workaround will be adequate for the s/w vendor.
If the generated code uses SP as a base register for temporary local stack
resident data, as .0 and some of the replies seem to indicate, the macro
workaround will not fix the problem.
The code below mimics alloca behavior by creating (and managing?) a private
stack. Its operation should not interfere with the compiler's use of SP. It
seems to work fine with your test program.
- Dwight -
--------------------------------------------------------------------------------
/*
Written: 12-February-1997, D.P Manley, Digital Equipment Corporation.
This subroutine was written to mimic the behavior of alloca on OpenVMS
VAX. It creates and manages a 1MB private stack apart from the real
stack, and will not interfere with compiler use of SP as a base address.
NOTE - The technique used to reclaim stack space assigned to inactive
call frames is imperfect and you may need to adjust stack size
accordingly.
*/
#pragma builtins
#define ALLOCA_STACK_SIZE 262144 /* A 1MB private stack */
#define ALLOCA_CALL_DEPTH 1024 /* A 1024 deep call tree */
#define FP 13 /* R13 is the Frame Pointer */
/*
The first call frame is forced to be located at the top of P1 space.
It's stack index is set to the top of the stack.
*/
static long *ALLOCA_FP[ ALLOCA_CALL_DEPTH+1 ] = {0x7ffffff0,0};
static long ALLOCA_SP[ ALLOCA_CALL_DEPTH+1 ] = {ALLOCA_STACK_SIZE,0};
static long ALLOCA_STACK[ ALLOCA_STACK_SIZE ];
void *alloca( int size )
{ int i,index;
long *alloca_frame,current_frame;
/*
Longword count requested
*/
index = ( size+3 >> 2 );
/*
Get alloca's frame pointer, and from it, get caller's frame pointer.
*/
alloca_frame = _READ_GPR(FP);
current_frame = alloca_frame[3];
/*
Search the FP stack for the caller's frame pointer or the correct
place to insert it.
*/
for( i=0;i<ALLOCA_CALL_DEPTH, current_frame<ALLOCA_FP[i];i++ );
/*
If the exceeded frame stack depth has been exceeded, return a null
pointer.
*/
if( i == ALLOCA_CALL_DEPTH ) return( 0 );
/*
If the current frame is found on the frame stack, then adjust its
stack index. Otherwise, push the current frame onto the frame stack
and generate its stack index from the previous stack index and the
request size.
*/
if( current_frame == ALLOCA_FP[i] )
ALLOCA_SP[i]-=index;
else{
ALLOCA_FP[i] = current_frame;
ALLOCA_SP[i] = ALLOCA_SP[i-1]-index;
}
/*
The next two fields are cleared, because no active call frames exist
below the current frame. Clearing these fields ensures that no future
frame gets inserted below an inactive frame.
*/
ALLOCA_FP[i+1] = 0;
ALLOCA_SP[i+1] = 0;
/*
If the stack index for the current frame has been decremented below
zero, return a null pointer. Otherwise, return the address of the
allocated stack entry.
*/
if( ALLOCA_SP[i] < 0 )
return( 0 );
else
return(&ALLOCA_STACK[ALLOCA_SP[i]]);
}
|
2088.15 | product manager for DEC C for OpenVMS VAX? | RDGENG::WOOD_J | [email protected] | Mon Feb 17 1997 04:44 | 8 |
| The s/w vendor is not happy with any of the proposed solutions.
Who is the Product Manager for DEC C for OpenVMS VAX, so that
I can get an official response please?
Thanks,
John Wood
Software Partner Engineering
|
2088.16 | VTX IR Has PM Information | XDELTA::HOFFMAN | Steve, OpenVMS Engineering | Mon Feb 17 1997 11:01 | 22 |
| :The s/w vendor is not happy with any of the proposed solutions.
Interesting -- the customer is objecting to a non-standard feature
that's known to cause problems in most implementations that even
have it. (I can understand their, uh, disappointment here -- they
might want to look at C++ constructor and destructors, or at recoding
their application(s) to use standard interfaces and routines.)
:Who is the Product Manager for DEC C for OpenVMS VAX, so that
:I can get an official response please?
From VTX IR:
DEC C V5.2 for OpenVMS
CONTACTS:
Corporate: Anne Persels (Product Manager), DTN 381-0992, (603) 881-0992,
ZKO, [email protected]
Alan Belancik (Product Marketing), DTN 381-0363, (603) 881-0363,
ZKO, [email protected]
|
2088.17 | | DECCXL::OUELLETTE | | Wed Feb 19 1997 17:35 | 4 |
| Anne Persels is the DEC C for VMS product manager.
Alan Belancik is doing something different now (data warehousing?).
R.
|