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

Supporting C static storage

0 views
Skip to first unread message

Leopold Toetsch

unread,
Jan 30, 2006, 9:54:51 AM1/30/06
to Perl 6 Internals
Below are some thoughts WRT C static vars and Perl6 INIT blocks.

Comments welcome,
leo

static.txt

Joshua Isom

unread,
Jan 30, 2006, 3:54:02 PM1/30/06
to Leopold Toetsch, Perl 6 Internals
Currently, the .global directive for pir is unimplemented. Other than
being in the source code for the imcc compiler, it's absent. Is
.global intended to truely store to global, or be more like a mutable
constant, applicable to only that file(and then perhaps any that
.include it). If it's intended to be more like a macro, "global"
statics already have a a method to access them. For localized statics,
i.e. [3], I like the .static int var = 123 most for familiarity. As
for values, I'd say strings, floats, and ints can have a default value
writing in plain sight for them, but for pmcs they would need to be
initialized in an :immediate sub. E.g.

.global int foo = 42
.global pmc bar
.sub init :immediate
bar = new .FixedIntegerArray
bar = 4
.end

> Supporting C static storage
>
> There are some related Perl6 features, namely INIT and FIRST closure
> traits [1], which aren't really covered by Parrot yet.
>
> Parrot supports INIT blocks via :immediate, which allows e.g.
> translation of:
>
> constant Num pi = { atan(1,1)*4 }; # [2]
>
> But C statics can of course change. The problems is, where to
> store the static variable, especially native integers.
>
> double gen_random(double max) { # [3]
> static long last = 42;
> ...
> }
>
> We could use closures, coroutines [4], or globals. The former provide
> a persistent register frame, where the static can be kept. Translating
> a sub with a C static to a coroutine seems to be a bit unnatural
> though. And all these solutions are a bit slow and lexicals/globals
> are only providing PMC support.
>
> I think, we should use the constant table and allow storing into
> the constant table.
>
> E.g.
>
> .static int last = 42 # ldc_i_ic
>
> (We can't use the C<set_i_ic> opcode, as this is loading constants
> from the bytecode, which, when mmaped, is readonly and doesn't allow
> storing)
>
> last += 10 # add_i_ic / set_ic_i
>
> .static float f = 3.14 # set_n_nc
> f += 2.0 # add_n_nc / set_nc_n
> f = 5.0 # set_n_nc / set_nc_n
>
> .static .Integer i = "42" # set_p_pc
>
> The 'static' variables are therefore working mostly like constants,
> except that they are modifyable. One difference is of course, that
> there would be no constant folding, each .static needs a distinct
> storage in the constant table.
>
> We'd need a few new opcodes:
>
> ldc_i_ic # load int constant from constant table
> set_ic_i # store int into constant table
> set_nc_n # store num
> assign_pc_p # assign to PMC static value
>
> And maybe some permutations like set_pc_i.
>
> What do you think?
> leo
>
>
> [1] S04 / Closure traits
>
> [2] # t/pmc/sub_38.pir
> .sub make_pi :immediate, :anon
> $N0 = atan 1.0, 1.0
> $N0 *= 4
> $P0 = new .Float
> $P0 = $N0
> .return ($P0)
> .end
>
> .sub main :main
> .const .Sub pi = "make_pi"
> print pi
> print "\n"
> .end
>
> [3]
> http://shootout.alioth.debian.org/sandbox/benchmark.php?
> test=random&lang=icc&id=0
>
> [4] examples/shootout/random.pir

Nicholas Clark

unread,
Jan 30, 2006, 4:00:34 PM1/30/06
to Leopold Toetsch, Perl 6 Internals
On Mon, Jan 30, 2006 at 03:54:51PM +0100, Leopold Toetsch wrote:

> I think, we should use the constant table and allow storing into
> the constant table.

I don't know the parrot source code well enough to know whether the constant
table is static const at the C level. (Or capable of being compiled that way).
But my comment is that Jarkko recently put considerable effort into cleaning
up the Perl 5 core so that as much data as possible was static const, so that
it facilitated shared library use. (In this case for Symbian)

So I (mis)interpret "storing to the constant table" as "aaargh, can't be static
const" which feels bad to me. So if the constant table can be static const,
does this mean that parrot would benefit from a compile time initialised
constant table, and a "run time" initialised constant table? With your
proposed writable C static variables in the run time initialised table.

Nicholas Clark

Leopold Toetsch

unread,
Jan 30, 2006, 5:23:56 PM1/30/06
to Nicholas Clark, Perl 6 Internals

On Jan 30, 2006, at 22:00, Nicholas Clark wrote:

> On Mon, Jan 30, 2006 at 03:54:51PM +0100, Leopold Toetsch wrote:
>
>> I think, we should use the constant table and allow storing into
>> the constant table.
>
> I don't know the parrot source code well enough to know whether the
> constant
> table is static const at the C level. (Or capable of being compiled
> that way).

No it's not a C static const and it can't be considered a such. It's
built at compile/PBC load time incrementally by appending e.g. doubles
or PMC constants, like subroutine PMC, or STRING constants. A C static
const alike is e.g. used for STRING constants in the source code, via
the CONST_STRING macro.

> But my comment is that Jarkko recently put considerable effort into
> cleaning
> up the Perl 5 core so that as much data as possible was static const,
> so that
> it facilitated shared library use. (In this case for Symbian)

Good point, albeit it doesn't apply to the thing currently called
constant table.

> So I (mis)interpret "storing to the constant table" as "aaargh, can't
> be static
> const" which feels bad to me. So if the constant table can be static
> const,
> does this mean that parrot would benefit from a compile time
> initialised
> constant table, and a "run time" initialised constant table? With your
> proposed writable C static variables in the run time initialised table.

The constant table is currently a list of pointers to unions of
'constant' values. It's created when loading a bytecode file (or
equivalently during compile/run cycle). *If* the the constant table
were split into more dedicated parts, a const list of doubles could be
part of the PBC and be considered as read-only/shared because it would
be just mmaped, if possible.

The 'constant' part of the table means for Parrot internals that it
isn't marked being alive by the GC, because these items (STRINGs, PMCs)
in the constant table have a dedicated storage arena, which is only
freed at program end (and possibly with --leak-test enabled).

> Nicholas Clark

leo

Leopold Toetsch

unread,
Feb 2, 2006, 6:51:36 AM2/2/06
to Leopold Toetsch, Perl 6 Internals
Leopold Toetsch wrote:

> But C statics can of course change. The problems is, where to
> store the static variable, especially native integers.

Another idea:

We keep the call frame of subs with statics (or Perl6 INIT and FIRST
blocks) after returning from the sub. Additionally, we can set a new
entrypoint for the sub after running the INIT code (or static
initializer). The entrypoint would be reset for cloning closures to
achieve perl6 FIRST block semantics.

The draw backs are increased memory usage and it doesn't work together
with recursive subroutines easily, albeit I don't know, if recursive
subs with statics are really meaningful.

E.g.

.sub "gen_random"
.param float max
.static int last # just an alias for .local maybe
last = 42
after_init gen_random_init_done # move sub entry point
goto gen_rand_2 # after_init could branch too
gen_random_init_done: # automatically
.param float max # duplicated get_params
gen_rand_2
....
.end

Comments welcome,
leo

Larry Wall

unread,
Feb 2, 2006, 11:59:01 AM2/2/06
to Perl 6 Internals
On Thu, Feb 02, 2006 at 12:51:36PM +0100, Leopold Toetsch wrote:
: Another idea:

:
: We keep the call frame of subs with statics (or Perl6 INIT and FIRST
: blocks) after returning from the sub. Additionally, we can set a new
: entrypoint for the sub after running the INIT code (or static
: initializer). The entrypoint would be reset for cloning closures to
: achieve perl6 FIRST block semantics.

Uh, maybe I'm pointing out something that's already blindingly obvious
to everyone else, but for "state" variables cloned closures can't
use the same static storage location. (Or is that what you're meaning
already by "keep the call frame"?)

: The draw backs are increased memory usage and it doesn't work together

: with recursive subroutines easily, albeit I don't know, if recursive
: subs with statics are really meaningful.

Unlike the situation with clones, a "state" variable *is* shared
between recursive invocations. As for whether that's meaningful,
I don't know either. But you could, say, temporize such a variable
just like a global, and that might make some kind of sense. Anyway,
the P6 model of "state" is more like a persistent lexical than like
C's static. (Though of course Parrot will probably want C's static
semantics for various other languages...)

Anyway, I thought I'd clarify a bit--we just don't want people
confusing "state" with "static", given the similarity of the names.

Larry

Leopold Toetsch

unread,
Feb 2, 2006, 1:12:08 PM2/2/06
to Larry Wall, Perl 6 Internals
Larry Wall wrote:
> On Thu, Feb 02, 2006 at 12:51:36PM +0100, Leopold Toetsch wrote:
> : Another idea:
> :
> : We keep the call frame of subs with statics (or Perl6 INIT and FIRST
> : blocks) after returning from the sub. Additionally, we can set a new
> : entrypoint for the sub after running the INIT code (or static
> : initializer). The entrypoint would be reset for cloning closures to
> : achieve perl6 FIRST block semantics.
>
> Uh, maybe I'm pointing out something that's already blindingly obvious
> to everyone else, but for "state" variables cloned closures can't
> use the same static storage location. (Or is that what you're meaning
> already by "keep the call frame"?)

Yep. With the scheme mentioned above a cloned closure would get a fresh
'state' variable as it of course needs distinct registers (aka call
frame) too.

> : The draw backs are increased memory usage and it doesn't work together
> : with recursive subroutines easily, albeit I don't know, if recursive
> : subs with statics are really meaningful.
>
> Unlike the situation with clones, a "state" variable *is* shared
> between recursive invocations. As for whether that's meaningful,
> I don't know either.

That's the same with a C static. Rescursion (not tail recursion) would
need some extra copying of state vars and book-keeping of register frames.

> ...But you could, say, temporize such a variable


> just like a global, and that might make some kind of sense.

Yep.

> ... Anyway,


> the P6 model of "state" is more like a persistent lexical than like
> C's static.

Sorry for my dumb question - what's the difference then? (Besides that C
dosn't have closures ;)

> ... (Though of course Parrot will probably want C's static


> semantics for various other languages...)

>
> Anyway, I thought I'd clarify a bit--we just don't want people
> confusing "state" with "static", given the similarity of the names.
>
> Larry

leo

Larry Wall

unread,
Feb 2, 2006, 4:56:57 PM2/2/06
to Perl 6 Internals
On Thu, Feb 02, 2006 at 07:12:08PM +0100, Leopold Toetsch wrote:
: >... Anyway,

: >the P6 model of "state" is more like a persistent lexical than like
: >C's static.
:
: Sorry for my dumb question - what's the difference then? (Besides that C
: dosn't have closures ;)

That *is* the difference. But for those of us handicapped by coming
from a C background, the extension of "static" semantics into closure
space would tend to lead one toward thinking that all clones share a
particular state variable, because a C programmer doesn't really known
when he's confusing a particular storage mechanism with a particular
semantic model. But then, all humans tend to confuse cultural truth
with universal truth--even when (some would say "especially when")
they come from a culture that aspires to learn universal truth.

Hmm, I'm not sure I've ever slammed fundamentalists and mathematicians
in the same sentence before... :-)

Larry

0 new messages