[Cog] Problems with generating code (initialization of options)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

[Cog] Problems with generating code (initialization of options)

Igor Stasenko
 
There are a bit mess with newly introduced generation options.

Here the problem:

generateCogitFile
        "Translate the Smalltalk description of the virtual machine into C.
If 'self doInlining' is true, small method bodies are inlined to
reduce procedure call overhead.  On the PPC, this results in a factor
of three speedup with only 30% increase in code size.  Subclasses can
use specialised versions of CCodeGenerator and interpreterClass."

        | cg cogitClass |
        self interpreterClass needsCogit ifFalse: [^nil].
        self needsToRegenerateCogitFile ifFalse: [^nil].
        cg := [self buildCodeGeneratorForCogit]


The options are initialized first in
#buildCodeGeneratorForCogit

but before that, in method #needsToRegenerateCogitFile it leads to call in:

ancilliaryStructClasses
        ProcessorClass ifNil: [thisContext methodClass theNonMetaClass initialize].
        ^{ CogAbstractInstruction.
                ProcessorClass basicNew abstractInstructionCompilerClass.
    ...

here ProcessorClass class var is still nil, because its not yet initialized.
it is initialized only if you send #initializeWithOptions: to cogit class


--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Problems with generating code (initialization of options)

Igor Stasenko
 
StackToRegisterMapping class>>initializeWithOptions:

doesn't have a super send
and that's why ProcessorClass class variable is still nil durring call to
CogIt class>>ancilliaryStructClasses

--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Problems with generating code (initialization of options)

Igor Stasenko
 
i'm still fighting with initialization.

This time is with pool vars.
The problem is that some pool vars are initialized _after_ being added
to code generator (which converts them to TDefineNode)
so, in debugger i was confused (and thought it is some bug of compiler)
that variable name is
Byte3ShiftNegated
and when i print it , it shows -24
but actual TDefineNode value is nil.

So, what happens is that class pool vars values are read and converted
into TDefineNode _before_ these vars are properly initialized,
which of course leads to errors when generating code.

Eliot, could you check the initialization procedure?

Here are image with preloaded vmmaker (its fresh with just loaded packages):
https://pharo-ic.lille.inria.fr/hudson/view/Cog/job/Cog%20Git%20Tracker%20(sig-cog)/lastSuccessfulBuild/artifact/vmmaker-image.zip

in workspace do:
StackMacOSConfig generateWithSources

and you will see the error.

Or maybe i doing it wrong (using wrong entry point to vmmaker)?

--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Problems with generating code (initialization of options)

Igor Stasenko
 
On 29 June 2011 20:21, Igor Stasenko <[hidden email]> wrote:

> i'm still fighting with initialization.
>
> This time is with pool vars.
> The problem is that some pool vars are initialized _after_ being added
> to code generator (which converts them to TDefineNode)
> so, in debugger i was confused (and thought it is some bug of compiler)
> that variable name is
> Byte3ShiftNegated
> and when i print it , it shows -24
> but actual TDefineNode value is nil.
>
> So, what happens is that class pool vars values are read and converted
> into TDefineNode _before_ these vars are properly initialized,
> which of course leads to errors when generating code.
>
> Eliot, could you check the initialization procedure?
>
> Here are image with preloaded vmmaker (its fresh with just loaded packages):
> https://pharo-ic.lille.inria.fr/hudson/view/Cog/job/Cog%20Git%20Tracker%20(sig-cog)/lastSuccessfulBuild/artifact/vmmaker-image.zip
>
> in workspace do:
> StackMacOSConfig generateWithSources
>
> and you will see the error.

oh yeah, i forgot to add, that if you run the same expression second
time it will work ok (since vars are now initialized).
So, its another point of confusion, since i assumed that i fixed that
problem and commited new CMakeVMMaker version..

>
> Or maybe i doing it wrong (using wrong entry point to vmmaker)?
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>



--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Problems with generating code (initialization of options)

Eliot Miranda-2
In reply to this post by Igor Stasenko
 
Hi Igor,

On Wed, Jun 29, 2011 at 10:01 AM, Igor Stasenko <[hidden email]> wrote:

StackToRegisterMapping class>>initializeWithOptions:

doesn't have a super send
and that's why ProcessorClass class variable is still nil durring call to
CogIt class>>ancilliaryStructClasses

This is on purpose.  If you look at buildCodeGeneratorForCogit it initializes each class (Cogit, SimpleStackBasedCogit and StackToRegisterMappingCogit) individually, and that style predates my work on Cog.  I'm committing a version which moves the check for regeneration being required to after the building of the code generator and hence initialization has been done.



--
Best regards,
Igor Stasenko AKA sig.



--
best,
Eliot

Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Problems with generating code (initialization of options)

Igor Stasenko

On 29 June 2011 22:10, Eliot Miranda <[hidden email]> wrote:

>
> Hi Igor,
>
> On Wed, Jun 29, 2011 at 10:01 AM, Igor Stasenko <[hidden email]> wrote:
>>
>> StackToRegisterMapping class>>initializeWithOptions:
>>
>> doesn't have a super send
>> and that's why ProcessorClass class variable is still nil durring call to
>> CogIt class>>ancilliaryStructClasses
>
> This is on purpose.  If you look at buildCodeGeneratorForCogit it initializes each class (Cogit, SimpleStackBasedCogit and StackToRegisterMappingCogit) individually, and that style predates my work on Cog.

Well, i think that this code (logic) better to be placed into class
chain a subclass could initialize things in right order before calling
super initialize etc.
Because code which i seen in build..forCog (forgot the method) which
calls #initializeWithOptions: contains too much bells and whistles as
to me.

>  I'm committing a version which moves the check for regeneration being required to after the building of the code generator and hence initialization has been done.
>
Thanks, i will check tomorrow if issues with initialization is gone.
--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Problems with generating code (initialization of options)

Igor Stasenko
 
Eliot, i still have the same problem with code generator TDefineNode.
After merging with eem.89,
i run the
StackMacOSConfig generateWithSources

and it still barks that value in TDefineNode is nil.



--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Problems with generating code (initialization of options)

Igor Stasenko
 
I found the problem.
Its in #buildCodeGeneratorForInterpreter

i put a halt in
addPoolVarsFor: aClass
        "Add the pool variables for the given class to the code base as constants."

        (aClass sharedPools reject: [:pool| pools includes: pool]) do:
                [:pool |
                pools add: pool.
                pool bindingsDo: [:assoc | | val node |
                        self halt.
                        val := assoc value.
                        node := (useSymbolicConstants and:[self isCLiteral: val])
                                                ifTrue:[TDefineNode new setName: assoc key asString value: assoc value]
                                                ifFalse:[TConstantNode new setValue: assoc value].
                        constants at: assoc key asString put: node]].

and it triggered before the halt in:

ObjectMemory>>initializeWithOptions: optionsDictionary
        "ObjectMemory initializeWithOptions: Dictionary new"
self halt.
        self initBytesPerWord: (optionsDictionary at: #BytesPerWord ifAbsent: [4])..
    ...


The #initBytesPerWord: initializing VMBasicConstants pool vars.
But they are already added to codegenerator (with nil values) before
#initBytesPerWord: are sent.

This is because in #buildCodeGeneratorForInterpreter the
#addStructClass: adds given shared pool before it get initialized:

 ....
        (ChangeSet superclassOrder: structClasses asArray) do:
                [:structClass|
                structClass initialize.
a)>>>> cg addStructClass: structClass].

        interpreterClasses do:
                [:ic|
                (ic respondsTo: #initializeWithOptions:)
b)>>>> ifTrue: [ic initializeWithOptions: optionsDictionary]
                        ifFalse: [ic initialize]].

        interpreterClasses do: [:ic| cg addClass: ic].
        ^cg

apparently, for correct initialization (b) should precede (a) ,
because once you adding class to code generator it automatically sucks
all pools vars in, and converts them into TDefineNode before their
values are properly initialized.

Here the proposed fix (in attachment). I just split the #initialize
from adding to code generator.
So, initialization order will remain the same (first a struct classes
are initialized , and then interpreterClasses),
because i don't know if its important to initialize struct classes
before initializing interpreter class(es).



--
Best regards,
Igor Stasenko AKA sig.

VMMaker-buildCodeGeneratorForInterpreter.st (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Problems with generating code (initialization of options)

Igor Stasenko
 
Another solution to that problem is to change TDefineNode to keep a
reference to pool var association, instead of capturing name and value
at the moment it created.
Then initialization can be performed after adding classes to code
generator , because it is no longer important.
Same could be done for TConstantNode.

--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: [Cog] Problems with generating code (initialization of options)

Eliot Miranda-2
In reply to this post by Igor Stasenko
 
Hi Igor,

    which shared pool and which constant(s)?  I suspect the problem is in initializing the shared pools constants, and should not be hacked around in VMMaker.

On Thu, Jun 30, 2011 at 7:30 AM, Igor Stasenko <[hidden email]> wrote:
 
I found the problem.
Its in #buildCodeGeneratorForInterpreter

i put a halt in
addPoolVarsFor: aClass
       "Add the pool variables for the given class to the code base as constants."

       (aClass sharedPools reject: [:pool| pools includes: pool]) do:
               [:pool |
               pools add: pool.
               pool bindingsDo: [:assoc | | val node |
                       self halt.
                       val := assoc value.
                       node := (useSymbolicConstants and:[self isCLiteral: val])
                                               ifTrue:[TDefineNode new setName: assoc key asString value: assoc value]
                                               ifFalse:[TConstantNode new setValue: assoc value].
                       constants at: assoc key asString put: node]].

and it triggered before the halt in:

ObjectMemory>>initializeWithOptions: optionsDictionary
       "ObjectMemory initializeWithOptions: Dictionary new"
self halt.
       self initBytesPerWord: (optionsDictionary at: #BytesPerWord ifAbsent: [4])..
   ...


The #initBytesPerWord: initializing VMBasicConstants pool vars.
But they are already added to codegenerator (with nil values) before
#initBytesPerWord: are sent.

This is because in #buildCodeGeneratorForInterpreter the
#addStructClass: adds given shared pool before it get initialized:

 ....
       (ChangeSet superclassOrder: structClasses asArray) do:
               [:structClass|
               structClass initialize.
a)>>>>          cg addStructClass: structClass].

       interpreterClasses do:
               [:ic|
               (ic respondsTo: #initializeWithOptions:)
b)>>>>                  ifTrue: [ic initializeWithOptions: optionsDictionary]
                       ifFalse: [ic initialize]].

       interpreterClasses do: [:ic| cg addClass: ic].
       ^cg

apparently, for correct initialization (b) should precede (a) ,
because once you adding class to code generator it automatically sucks
all pools vars in, and converts them into TDefineNode before their
values are properly initialized.

Here the proposed fix (in attachment). I just split the #initialize
from adding to code generator.
So, initialization order will remain the same (first a struct classes
are initialized , and then interpreterClasses),
because i don't know if its important to initialize struct classes
before initializing interpreter class(es).



--
Best regards,
Igor Stasenko AKA sig.




--
best,
Eliot