While trying to speed up hash lookups [1] I came (again) to the problem that we are missing true PMC constants. We just have a special Sub PMC for storing subroutine entries but no general way to represent a constant PMC item. E.g.:
.const pmc s = "value" .const pmc i = 1 ... add $P0, i setprop $P0, "xxx", s
This would AFAIK not need a lot more opcode variants, because where we now have C<add_p_ic> and C<add_p_nc>, we would then just have C<add_p_pc>[2]. Only some ops that take PMCs only would need additional variants like setprop_p_sc?_pc. I'm currently thinking of constant scalar PMCs only, but this could get generalized to constant aggregates too.
Comments? leo
[1] constant _S("string") gets a precomputed hash value [2] Compiling "add P0, 1" imcc would look for add_p_ic and if this isn't there then for add_p_pc *and* convert the constant.
>While trying to speed up hash lookups [1] I came (again) to the >problem that we are missing true PMC constants. We just have a >special Sub PMC for storing subroutine entries but no general way to >represent a constant PMC item. E.g.:
> .const pmc s = "value" > .const pmc i = 1 > ... > add $P0, i > setprop $P0, "xxx", s
>This would AFAIK not need a lot more opcode variants, because where >we now have C<add_p_ic> and C<add_p_nc>, we would then just have >C<add_p_pc>[2]. Only some ops that take PMCs only would need >additional variants like setprop_p_sc?_pc. >I'm currently thinking of constant scalar PMCs only, but this could >get generalized to constant aggregates too.
I'm all for constant PMCs--they've been in the base design since the beginning, and I'd love to get them in and running.
The interpreter stuff's simple enough--we teach the ops preprocessor to handle them the same way that it does string constants, and index into the PMC constant table. We'll want to put them in a separate part of the bytecode file, so we probably ought to nail down metadata so we can fully expose bytecode files to running code. And we need to finish that fight over freeze/thaw methodologies, as constant PMCs would end up being frozen in the bytecode.
As for the actual declaration of the constants... That's going to be somewhat interesting. I can see one of two ways of doing it:
1) we execute the initialization code at compiletime and freeze the result 2) We compile the initialization code and execute it at runtime to create the PMC
Both have their drawbacks when it comes to more complex PMCs. For simple stuff it's not a big deal one way or the other, and for the base PMC types we can even cheat and teach imcc how to create the freeze format directly, but that's not tenable as a full solution. -- Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai d...@sidhe.org have teddy bears and even teddy bears get drunk
Dan Sugalski <d...@sidhe.org> wrote: > The interpreter stuff's simple enough--we teach the ops preprocessor > to handle them the same way that it does string constants, and index > into the PMC constant table. We'll want to put them in a separate > part of the bytecode file,
Why I second table? This just adds duplicate code paths and complexity. One constant table ought to be enough.
> so we can fully expose bytecode files to running code. And we need to > finish that fight over freeze/thaw methodologies, as constant PMCs > would end up being frozen in the bytecode.
The freeze/thaw internals can change. We only have to invalidate existing PBCs, if the frozen image format differs.
> As for the actual declaration of the constants... That's going to be > somewhat interesting. I can see one of two ways of doing it: > 1) we execute the initialization code at compiletime and freeze the result > 2) We compile the initialization code and execute it at runtime to > create the PMC
It probably depends on the PMC. *If* there are any side effects, initialization has to be done at run time.
>> The interpreter stuff's simple enough--we teach the ops preprocessor >> to handle them the same way that it does string constants, and index >> into the PMC constant table. We'll want to put them in a separate >> part of the bytecode file,
>Why I second table? This just adds duplicate code paths and complexity. >One constant table ought to be enough.
Mainly because I was assuming that we were going to separate the float, pmc, and string constants into separate tables for locality-of-reference reasons and ease of doing reflective access. (Or something line that...)
> > so we can fully expose bytecode files to running code. And we need to >> finish that fight over freeze/thaw methodologies, as constant PMCs >> would end up being frozen in the bytecode.
>The freeze/thaw internals can change. We only have to invalidate >existing PBCs, if the frozen image format differs.
Yep. I thought there was still some outstanding stuff, but it might just be dodgy memory on my part.
> > As for the actual declaration of the constants... That's going to be >> somewhat interesting. I can see one of two ways of doing it:
>> 1) we execute the initialization code at compiletime and freeze the result >> 2) We compile the initialization code and execute it at runtime to >> create the PMC
>It probably depends on the PMC. *If* there are any side effects, >initialization has to be done at run time.
Yeah, but we have to pick one. :( -- Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai d...@sidhe.org have teddy bears and even teddy bears get drunk
Dan Sugalski <d...@sidhe.org> wrote: > At 8:30 AM +0200 4/20/04, Leopold Toetsch wrote:
>>Why I second table? This just adds duplicate code paths and complexity. >>One constant table ought to be enough. > Mainly because I was assuming that we were going to separate the > float, pmc, and string constants into separate tables for > locality-of-reference reasons and ease of doing reflective access.
The constants are currrently a typed union, so there is some wasted space. OTOH constants compiled at the same time tend to stick together (modulo constant folding of course). Three distinct tables could have worse locality then one. Dunno.
>>The freeze/thaw internals can change. We only have to invalidate >>existing PBCs, if the frozen image format differs. > Yep. I thought there was still some outstanding stuff, but it might > just be dodgy memory on my part.
$ parrot parrot-config.imc VERSION 0.1.0
is accessing the frozen image of the config hash. Most of the basic types are working.
>> > As for the actual declaration of the constants... That's going to be >>> somewhat interesting. I can see one of two ways of doing it:
>>> 1) we execute the initialization code at compiletime and freeze the result >>> 2) We compile the initialization code and execute it at runtime to >>> create the PMC
>>It probably depends on the PMC. *If* there are any side effects, >>initialization has to be done at run time. > Yeah, but we have to pick one. :(
For
.const PerlInt i = 5
or some such, the compiler knows the type and can freeze the compiled result. It's of course the question, what is all allowed to create a PMC constant.