Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH] Probe stack direction at run-time (was Re: Configuring and DOD problems)

8 views
Skip to first unread message

Josh Wilmes

unread,
Oct 23, 2002, 11:23:26 PM10/23/02
to Erik Lechak, perl6-i...@perl.org
At 22:58 on 10/23/2002 EDT, Erik Lechak <ele...@the-small-print.com> wrote:

> I fix the errors then It gets all wierd on the def PARROT_STACK_DIR. So
> I tried to figure out that problem.
>
> Anyways, I am on Win XP using VC++. I look in Config.pm and I see this
> '#define PARROT_STACK_DIR'. It's not defined to anything, but the code
> tries to do math with it. What is this?

It's supposed to be either 1 or -1, determined at build time via config/
auto/stackdir.pl.

Evidently, that didn't work right.

I've got a patch which switches this detection to happen at run-time
instead of at build-time. This is going to be necessary for miniparrot
(which has no "Configure" step) anyway.

Can you try applying this patch and see if it addresses your issue?

With the current state of the tinderbox, i'd rather not commit it just yet.

--Josh


runtime_stackdir.patch

Jason Gloudon

unread,
Oct 24, 2002, 11:57:41 AM10/24/02
to Josh Wilmes, perl6-i...@perl.org, Erik Lechak
On Wed, Oct 23, 2002 at 11:23:26PM -0400, Josh Wilmes wrote:

> I've got a patch which switches this detection to happen at run-time
> instead of at build-time. This is going to be necessary for miniparrot
> (which has no "Configure" step) anyway.

Have you checked how much this affects the performance of stack walking ?

The current stack direction tests make the stack direction a compile time
constant, so that the compiler can optimize away the multiplications in the
stack walking loop which can be pretty expensive.

The original stack direction tests were run-time, and I changed them to be done
at configure time to simplify doing them in a more correct way while also
making the code faster.

One way of simplifying things here is to always walk the stack in the same
direction (lowest address to higher address), and swap the lo and high pointer
as the start and end points of the loop. This eliminates the need for an
explicit stack growth direction test.

One thing that will still remain is that the garbage collector must know the
CPU instruction set so it can use the appropriate means to locate pointers in
registers. I'm not sure if this can be done by testing for preprocessor symbols
alone.

--
Jason

Josh Wilmes

unread,
Oct 24, 2002, 4:47:05 PM10/24/02
to Jason Gloudon, perl6-i...@perl.org, Erik Lechak
At 11:57 on 10/24/2002 EDT, Jason Gloudon <pe...@gloudon.com> wrote:

> On Wed, Oct 23, 2002 at 11:23:26PM -0400, Josh Wilmes wrote:
>
> > I've got a patch which switches this detection to happen at run-time
> > instead of at build-time. This is going to be necessary for miniparrot
> > (which has no "Configure" step) anyway.
>
> Have you checked how much this affects the performance of stack walking ?

It shouldn't at all. It does the check once, when parrot starts up.

> One way of simplifying things here is to always walk the stack in the same
> direction (lowest address to higher address), and swap the lo and high pointe
r
> as the start and end points of the loop. This eliminates the need for an
> explicit stack growth direction test.
>
> One thing that will still remain is that the garbage collector must know the
> CPU instruction set so it can use the appropriate means to locate pointers in
> registers. I'm not sure if this can be done by testing for preprocessor symbo
ls
> alone.

*eyes glazed over*

--Josh


Jason Gloudon

unread,
Oct 24, 2002, 6:16:55 PM10/24/02
to Josh Wilmes, perl6-i...@perl.org, Erik Lechak
On Thu, Oct 24, 2002 at 04:47:05PM -0400, Josh Wilmes wrote:

> > > I've got a patch which switches this detection to happen at run-time
> > > instead of at build-time. This is going to be necessary for miniparrot
> > > (which has no "Configure" step) anyway.
> >
> > Have you checked how much this affects the performance of stack walking ?
>
> It shouldn't at all. It does the check once, when parrot starts up.

It will. If you read the following paragraph I explained why it will be slower,
and it has nothing to do with how often the check is performed.

STACK_DIR is a compile time constant, so the multiplies in the following code
are eliminated by the compiler if it does any optimization. By making
STACK_DIR a variable, the compiler is no longer able to do this and has to
generate code to do multiplies.

for (cur_var_ptr = lo_var_ptr;
(ptrdiff_t)(cur_var_ptr * PARROT_STACK_DIR) <
(ptrdiff_t)(hi_var_ptr * PARROT_STACK_DIR);
cur_var_ptr = (size_t)( (ptrdiff_t)cur_var_ptr +
PARROT_STACK_DIR * PARROT_PTR_ALIGNMENT )

--
Jason

Josh Wilmes

unread,
Oct 24, 2002, 8:41:14 PM10/24/02
to Jason Gloudon, perl6-i...@perl.org, Erik Lechak

At 18:16 on 10/24/2002 EDT, Jason Gloudon <pe...@gloudon.com> wrote:

> STACK_DIR is a compile time constant, so the multiplies in the following code
> are eliminated by the compiler if it does any optimization. By making
> STACK_DIR a variable, the compiler is no longer able to do this and has to
> generate code to do multiplies.

Fair enough. I suspected it had to be something like that, but I was
kind of dense and didn't follow what you were saying.

If I rejigger my code to make it work both ways (run-time
for miniparrot, compiled-in elsewise), will that be OK?

(I can do this by #defining PARROT_STACK_DIR to either a number or a
variable name in stackdir.pl)

--Josh


Nicholas Clark

unread,
Oct 25, 2002, 8:01:16 AM10/25/02
to Jason Gloudon, Josh Wilmes, perl6-i...@perl.org, Erik Lechak

What is wrong with any of

1: Duplicating the above loop (which isn't large), one for upwards stack,
the other for downwards stack, and switching (outside) between the two
based on an if statement on a global stack direction variable.
(Globals bad, I know, but I assume that no-one has yet made an
INTERCAL-eqse OS where the stack direction can change between threads of
the same process)
That gets the if test outside the loop, and keeps the loop construction
optimisable at compile time
2: Pulling all of trace_system_stack out into its own source file, compiling
it twice (once for up, once for down) with different names, and choosing the
correct function pointer once based on a run time test
3: Keeping things as it is, and having miniparrot #define PARROT_STACK_DIR
as a global variable containing the (run time determined) stack direction,
whereas configured parrot #defines it as -1 or +1

Nicholas Clark
--
INTERCAL better than perl? http://www.perl.org/advocacy/spoofathon/

Jason Gloudon

unread,
Oct 25, 2002, 6:21:47 PM10/25/02
to Nicholas Clark, Josh Wilmes, perl6-i...@perl.org, Erik Lechak
On Fri, Oct 25, 2002 at 01:01:16PM +0100, Nicholas Clark wrote:

> What is wrong with any of
>
> 1: Duplicating the above loop (which isn't large), one for upwards stack,
> the other for downwards stack, and switching (outside) between the two
> based on an if statement on a global stack direction variable.

Here is what I suggested in a previous email. Always walk the stack in the same
direction, regardless of the direction in which it grows. PARROT_STACK_DIR is
not used.

Non-contiguous stack systems will have to use an entirely different version of
the stack walking function. This is left as an exercise for the reader.

--
Jason

dod.patch

Dan Sugalski

unread,
Oct 26, 2002, 12:23:54 PM10/26/02
to Nicholas Clark, Jason Gloudon, Josh Wilmes, perl6-i...@perl.org, Erik Lechak
At 1:01 PM +0100 10/25/02, Nicholas Clark wrote:
>On Thu, Oct 24, 2002 at 06:16:55PM -0400, Jason Gloudon wrote:
>> On Thu, Oct 24, 2002 at 04:47:05PM -0400, Josh Wilmes wrote:
>
>> > It shouldn't at all. It does the check once, when parrot starts up.
>>
>> It will. If you read the following paragraph I explained why it
>>will be slower,
>> and it has nothing to do with how often the check is performed.
>>
>> STACK_DIR is a compile time constant, so the multiplies in the
>>following code
>> are eliminated by the compiler if it does any optimization. By making
>> STACK_DIR a variable, the compiler is no longer able to do this and has to
>> generate code to do multiplies.
>>
>> for (cur_var_ptr = lo_var_ptr;
>> (ptrdiff_t)(cur_var_ptr * PARROT_STACK_DIR) <
>> (ptrdiff_t)(hi_var_ptr * PARROT_STACK_DIR);
>> cur_var_ptr = (size_t)( (ptrdiff_t)cur_var_ptr +
>> PARROT_STACK_DIR * PARROT_PTR_ALIGNMENT )
>
>What is wrong with any of
>
>1: Duplicating the above loop (which isn't large), one for upwards stack,
> the other for downwards stack,
>2: Pulling all of trace_system_stack out into its own source file, compiling
> it twice (once for up, once for down) with different names, and
>choosing the
> correct function pointer once based on a run time test
>3: Keeping things as it is, and having miniparrot #define PARROT_STACK_DIR
> as a global variable containing the (run time determined) stack direction,
> whereas configured parrot #defines it as -1 or +1

Absolutely nothing. #3 is probably the best of the lot, as these things go.

The one issue we will have is in probing the registers, but I think
we can get around that if we're willing to be sufficiently evil in
places.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

0 new messages