[Pharo-project] Problem with CompiledMethodTrailer

Igor Stasenko siguctua at gmail.com
Mon May 9 21:55:53 CEST 2011


On 9 May 2011 17:20, Mariano Martinez Peck <marianopeck at gmail.com> wrote:
>
>
> On Mon, May 9, 2011 at 5:06 PM, Igor Stasenko <siguctua at gmail.com> wrote:
>>
>> On 9 May 2011 16:01, Mariano Martinez Peck <marianopeck at gmail.com> wrote:
>> > Another that....all those incorrect compiled method has the same:  they
>> > miss
>> > the bytecode 120 (self return), and they ALL have the same last byte:
>> > 32.
>> > what that 32 can be?  I don't know...
>> >
>> This is indicating a trailer kind:
>>
>> ((CompiledMethod allInstances select:  [:each | each trailer kind =
>> #VarLengthSourcePointer] ) ) first trailer kindAsByte
>>  32
>>
>> 32 stands for #VarLengthSourcePointer trailer.
>
> ahaaaa!!  I didn't know that ;)
>
>
>>
>> And i have plenty of methods with #VarLengthSourcePointer in my image
>>
>> ((CompiledMethod allInstances select:  [:each | each trailer kind =
>> #VarLengthSourcePointer] ) ) size 4387
>>
>> because my .changes file go over 32Mb "limit".
>
> So...when the .changes file is over 32 bits, the default trailer is
> #VarLengthSourcePointer ?
>
> BTW, do you know how can I create a CompiledMethod for testing with this
> kind of trailer ?
>
>
>>
>> Now to check what is going on, we should run a following:
>>
>>
>> methods := ((CompiledMethod allInstances select:  [:each | each
>> trailer kind = #VarLengthSourcePointer] ) ).
>>
>> methods := methods select: [:m | m isInstalled ]. "we don't care about
>> not-installed ones"
>>
>
> No, non of the methods is installed.  So that script answers an empty array.
>
>
>>
>> and for installed we should verify that after compilation it from source
>> code,
>> it ends up with same bytecode as in currently installed method.
>>
>>
>> | methods |
>>
>> methods := ((CompiledMethod allInstances select:  [:each | each
>> trailer kind = #VarLengthSourcePointer] ) ).
>> methods := methods select: [:m |
>>        | cls |
>>        cls := m methodClass.
>>        cls isObsolete not and: [ (cls compiledMethodAt: m selector) == m ]
>> ].
>>
>> methods select: [:m |
>>        | m2 |
>>        m2 := m methodNode generate.
>>
>>        ((m initialPC = m2 initialPC and: [m endPC = m2 endPC ]) and: [
>>                (m initialPC to: m endPC) allSatisfy: [:i | (m at: i) = (m2
>> at: i)]     ]) not
>> ].
>>
>>
>> In my image the result of doit is empty array.
>> Note that endPC is calculating based on trailer data. So if trailer is
>> not correct, it would affect the comparison.
>> So, it could fail if source code pointer is not valid or endPC
>> calculation is wrong.
>> But for all methods it is correct.
>
>
> Thanks for the help. In fact, since non of them is installed, I also have
> that array empty.
>
> The problem is the code (like mine) that does  CompiledMethod allInstances
> directly...without filtering by #isInstalled. Depending on what they do it
> can even be a crash (as it happened to me).
>
> So I would like to still know:
> 1) while those fucking CMs are not GCed
> 2) how they can be generated.
>
> I have spent the whole day and I couldn't :(    I am more interested in 1)
> Notice that I didn't do anything weird. I just took the default Pharo1.3
> image.
>
you could take any method and just do
#copyWithTrailerBytes:
with any trailer you would like to test.

You can also look at CompiledMethodTrailerTest for examples (see #testEncoding).

As for finding pointers.. have you tried to use pointer finder? :)
(it means i can't help with it more than you already know).


> Thanks Igor for your help.
>
>
> --
> Mariano
> http://marianopeck.wordpress.com
>
>



-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Pharo-project mailing list