[vwnc] HELP . some ideas on decompiled code wrong??

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

[vwnc] HELP . some ideas on decompiled code wrong??

giorgiof
HI, My friends,

I have a strage problem happening on an image:

I have a methid that when the change.log is present, is correct and run right. When change.log is not present, it's wrong. OIf I look at the decompiled code (due to missing source.) , the decompiled code is wrong and not equivalent to the original code.

I'm thinking to be crazy, but some other guys (and customer too, he doesn't have code, so discovered the problem...) have seen the same..

Any idea or help?

Thanks a lot, I'm really locked down

ciao
Giorgio

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

Alan Knight-2
Is it really wrong, or just different? Some constructs get compiled down in a way that the decompiler reconstructs them differently, but they still produce the same effect.  If you recompile the method, do you get the same bytecodes as if you compiled the decompiled source?

At 01:07 PM 10/28/2008, giorgio ferraris wrote:
HI, My friends,

I have a strage problem happening on an image:

I have a methid that when the change.log is present, is correct and run right. When change.log is not present, it's wrong. OIf I look at the decompiled code (due to missing source.) , the decompiled code is wrong and not equivalent to the original code.

I'm thinking to be crazy, but some other guys (and customer too, he doesn't have code, so discovered the problem...) have seen the same..

Any idea or help?

Thanks a lot, I'm really locked down

ciao
Giorgio
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

--
Alan Knight [|], Engineering Manager, Cincom Smalltalk

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

giorgiof
In reply to this post by giorgiof
hi, Alan,

you are on the right.

I got the request for help from my group of developers, and they  had a problem signaled by customer, and the decompiled code that was really different from the original.

Other than this, we had the copy of the production image running nicely (with all of the source) and with no problems at all, and the customer assured us that they just copied to production the testing image.

So, everyone (including myself) did a surely too marginal look at the decompiled code (that is really different from the original, and this is a surprise, usually is quite close )

So, after sending the mail I asked a  different test, and yes, the code is decompiled and  completely different but just ok...

There was a problem  on  a spurious data on the production DB generating the error, and this bad data was not on our testing environment.

Sorry for generating the noise, but I got this call at the end of a very bad day ... and, just going out on my car toward home, having time to think (!!) , I recognized the possible effect of a decompilation and asked by phone to do the final and clarifying test....

BTW: I'll look better at the original code just to see why the decompiled is so different, I suspect the original code has something to be cleared up, luckily it is not a long code.

Ciao and thanks again

Giorgio


Thanks a lot
On Tue, Oct 28, 2008 at 6:24 PM, Alan Knight <[hidden email]> wrote:
Is it really wrong, or just different? Some constructs get compiled down in a way that the decompiler reconstructs them differently, but they still produce the same effect.  If you recompile the method, do you get the same bytecodes as if you compiled the decompiled source?


At 01:07 PM 10/28/2008, giorgio ferraris wrote:
HI, My friends,

I have a strage problem happening on an image:

I have a methid that when the change.log is present, is correct and run right. When change.log is not present, it's wrong. OIf I look at the decompiled code (due to missing source.) , the decompiled code is wrong and not equivalent to the original code.

I'm thinking to be crazy, but some other guys (and customer too, he doesn't have code, so discovered the problem...) have seen the same..

Any idea or help?

Thanks a lot, I'm really locked down

ciao
Giorgio
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

--
Alan Knight [|], Engineering Manager, Cincom Smalltalk


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

Paul Baumann
Here is an example of how decompiled code differs.  #to:do: converts to bytecodes that decompile to show #whileTrue:.
 
example
 1 to: 10 do: [:i | i yourself ].
 
decompiles to:
 
example
 | t1 |
 t1 := 1.
 [t1 <= 10]
  whileTrue:
   [t1 yourself.
   t1 := t1 + 1].
 ^self
 
normal CompiledMethod numArgs=0 numTemps=1 frameSize=12
literals: ()
1 <4A> push 1
2 <4C> store local 0; pop
3 <67> loop head
4 <10> push local 0
5 <D8 0A> push 10
7 <A4> send <=
8 <C7> jump false 17
9 <10> push local 0
10 <F0 40> send yourself
12 <56> pop; push local 0
13 <C8> push 1; send +
14 <4C> store local 0; pop
15 <E3 F2> jump 3
17 <60> push self; return
Look at all those bytecodes from such simple code. VA is one Smalltalk dialect that that worked to reduce that cost. VA collections were iterated using #apply:from:to: which was then optimized using a primitive to bypass the cost of those bytecode operations.
 
BlockContextTemplate>>apply: aCollection from: start to: end
 "Evaluate the receiver for each variable slot of aCollection from start to end.  Answer aCollection."
 <primitive: VMprBlockContextApplyFromTo>
 start to: end do: [:i | self value: (aCollection basicAt: i)].
 ^aCollection
 
I'm wondering if a new inline #to:do: bytecode operation could be made faster than the primitive-based approach used by VA.
 
Paul Baumann 
 


From: [hidden email] [mailto:[hidden email]] On Behalf Of giorgio ferraris
Sent: Tuesday, October 28, 2008 4:52 PM
To: Alan Knight
Cc: [hidden email]
Subject: Re: [vwnc] HELP . some ideas on decompiled code wrong??

hi, Alan,

you are on the right.

I got the request for help from my group of developers, and they  had a problem signaled by customer, and the decompiled code that was really different from the original.

Other than this, we had the copy of the production image running nicely (with all of the source) and with no problems at all, and the customer assured us that they just copied to production the testing image.

So, everyone (including myself) did a surely too marginal look at the decompiled code (that is really different from the original, and this is a surprise, usually is quite close )

So, after sending the mail I asked a  different test, and yes, the code is decompiled and  completely different but just ok...

There was a problem  on  a spurious data on the production DB generating the error, and this bad data was not on our testing environment.

Sorry for generating the noise, but I got this call at the end of a very bad day ... and, just going out on my car toward home, having time to think (!!) , I recognized the possible effect of a decompilation and asked by phone to do the final and clarifying test....

BTW: I'll look better at the original code just to see why the decompiled is so different, I suspect the original code has something to be cleared up, luckily it is not a long code.

Ciao and thanks again

Giorgio


Thanks a lot
On Tue, Oct 28, 2008 at 6:24 PM, Alan Knight <[hidden email]> wrote:
Is it really wrong, or just different? Some constructs get compiled down in a way that the decompiler reconstructs them differently, but they still produce the same effect.  If you recompile the method, do you get the same bytecodes as if you compiled the decompiled source?


At 01:07 PM 10/28/2008, giorgio ferraris wrote:
HI, My friends,

I have a strage problem happening on an image:

I have a methid that when the change.log is present, is correct and run right. When change.log is not present, it's wrong. OIf I look at the decompiled code (due to missing source.) , the decompiled code is wrong and not equivalent to the original code.

I'm thinking to be crazy, but some other guys (and customer too, he doesn't have code, so discovered the problem...) have seen the same..

Any idea or help?

Thanks a lot, I'm really locked down

ciao
Giorgio
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

--
Alan Knight [|], Engineering Manager, Cincom Smalltalk



This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

Stefan Schmiedl
On Wed, 29 Oct 2008 14:42:27 -0400
Paul Baumann <[hidden email]> wrote:

> Here is an example of how decompiled code differs.  #to:do: converts
> to bytecodes that decompile to show #whileTrue:.
>
> example
>  1 to: 10 do: [:i | i yourself ].
>
> decompiles to:
>
> example
>  | t1 |
>  t1 := 1.
>  [t1 <= 10]
>   whileTrue:
>    [t1 yourself.
>    t1 := t1 + 1].
>  ^self

Note that this does not create a collection, which your VA-quote seems to do.
What does (1 to: 10) do: [:i | i yourself] decompile to?

s.
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

Paul Baumann
Stefan wrote:
> Note that this does not create a collection, which your VA-quote seems to do.
> What does (1 to: 10) do: [:i | i yourself] decompile to?

#to:do: is faster than #to: and then #do: in all dialects. #to:do: involves more but less costly bytecodes than the separate #to: and then #do: message sends. Interval iteration misses the point though. VA had implemented their collections to take advantage of #to:do: performance and then optimized that using a primitive. VA doesn't have a decompiler, but I remember the meaning of some of their bytecodes and can see they are similar to what VW is doing with #to:do:.

Paul Baumann

This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

Mark Plas
In reply to this post by Paul Baumann

There’s even a bug(?) in the to:do: optimization. We’ve implemented + on Date such that it adds a number of days to the date. By accident I’ve sent to:do: with Dates as arguments and it works just fine even though to:do: is only implemented on Number.

 

I’ve always wondered why to:do: isn’t implemented by using a special bytecode as Paul suggests. If the arguments of to:do: are both SmallIntegers a lot of type checking and checking for possible conversion to LargeIntegers could be avoided which I guess has to be done the way it is done now for every iteration in the loop. The same goes for the collection iteration primitive/bytecode Paul mentions. If you have that, the #at: doesn’t need to check its arguments for type correctness or being in range either. You could do all the checking just once and not for every iteration in the loop.

 

These may be simple extensions to the VM that could make things measurably faster.

 

Mark

 


From: [hidden email] [mailto:[hidden email]] On Behalf Of Paul Baumann
Sent: woensdag 29 oktober 2008 19:42
To: 'giorgio ferraris'; Alan Knight
Cc: [hidden email]
Subject: Re: [vwnc] HELP . some ideas on decompiled code wrong??

 

Here is an example of how decompiled code differs.  #to:do: converts to bytecodes that decompile to show #whileTrue:.

 

example
 1 to: 10 do: [:i | i yourself ].

 

decompiles to:

 

example
 | t1 |
 t1 := 1.
 [t1 <= 10]
  whileTrue:
   [t1 yourself.
   t1 := t1 + 1].
 ^self

 

normal CompiledMethod numArgs=0 numTemps=1 frameSize=12

literals: ()

1 <4A> push 1
2 <4C> store local 0; pop
3 <67> loop head
4 <10> push local 0
5 <D8 0A> push 10
7 <A4> send <=
8 <C7> jump false 17
9 <10> push local 0
10 <F0 40> send yourself
12 <56> pop; push local 0
13 <C8> push 1; send +
14 <4C> store local 0; pop
15 <E3 F2> jump 3
17 <60> push self; return

Look at all those bytecodes from such simple code. VA is one Smalltalk dialect that that worked to reduce that cost. VA collections were iterated using #apply:from:to: which was then optimized using a primitive to bypass the cost of those bytecode operations.

 

BlockContextTemplate>>apply: aCollection from: start to: end
 "Evaluate the receiver for each variable slot of aCollection from start to end.  Answer aCollection."

 <primitive: VMprBlockContextApplyFromTo>
 start to: end do: [:i | self value: (aCollection basicAt: i)].
 ^aCollection

 

I'm wondering if a new inline #to:do: bytecode operation could be made faster than the primitive-based approach used by VA.

 

Paul Baumann 

 

 


From: [hidden email] [mailto:[hidden email]] On Behalf Of giorgio ferraris
Sent: Tuesday, October 28, 2008 4:52 PM
To: Alan Knight
Cc: [hidden email]
Subject: Re: [vwnc] HELP . some ideas on decompiled code wrong??

hi, Alan,

you are on the right.

I got the request for help from my group of developers, and they  had a problem signaled by customer, and the decompiled code that was really different from the original.

Other than this, we had the copy of the production image running nicely (with all of the source) and with no problems at all, and the customer assured us that they just copied to production the testing image.

So, everyone (including myself) did a surely too marginal look at the decompiled code (that is really different from the original, and this is a surprise, usually is quite close )

So, after sending the mail I asked a  different test, and yes, the code is decompiled and  completely different but just ok...

There was a problem  on  a spurious data on the production DB generating the error, and this bad data was not on our testing environment.

Sorry for generating the noise, but I got this call at the end of a very bad day ... and, just going out on my car toward home, having time to think (!!) , I recognized the possible effect of a decompilation and asked by phone to do the final and clarifying test....

BTW: I'll look better at the original code just to see why the decompiled is so different, I suspect the original code has something to be cleared up, luckily it is not a long code.

Ciao and thanks again

Giorgio


Thanks a lot

On Tue, Oct 28, 2008 at 6:24 PM, Alan Knight <[hidden email]> wrote:

Is it really wrong, or just different? Some constructs get compiled down in a way that the decompiler reconstructs them differently, but they still produce the same effect.  If you recompile the method, do you get the same bytecodes as if you compiled the decompiled source?



At 01:07 PM 10/28/2008, giorgio ferraris wrote:

HI, My friends,

I have a strage problem happening on an image:

I have a methid that when the change.log is present, is correct and run right. When change.log is not present, it's wrong. OIf I look at the decompiled code (due to missing source.) , the decompiled code is wrong and not equivalent to the original code.

I'm thinking to be crazy, but some other guys (and customer too, he doesn't have code, so discovered the problem...) have seen the same..

Any idea or help?

Thanks a lot, I'm really locked down

ciao
Giorgio

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

 

--

Alan Knight [|], Engineering Manager, Cincom Smalltalk

 


This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

Travis Griggs-3

On Oct 30, 2008, at 1:15 AM, Mark Plas wrote:

> There’s even a bug(?) in the to:do: optimization. We’ve implemented  
> + on Date such that it adds a number of days to the date. By  
> accident I’ve sent to:do: with Dates as arguments and it works just  
> fine even though to:do: is only implemented on Number.
>
> I’ve always wondered why to:do: isn’t implemented by using a special  
> bytecode as Paul suggests. If the arguments of to:do: are both  
> SmallIntegers a lot of type checking and checking for possible  
> conversion to LargeIntegers could be avoided which I guess has to be  
> done the way it is done now for every iteration in the loop. The  
> same goes for the collection iteration primitive/bytecode Paul  
> mentions. If you have that, the #at: doesn’t need to check its  
> arguments for type correctness or being in range either. You could  
> do all the checking just once and not for every iteration in the loop.
>
> These may be simple extensions to the VM that could make things  
> measurably faster.
>  different? Some constructs get compiled down in a way that the  
> decompiler reconstructs them differently, but they still produce the  
> same effect.  If you recompile the method, do you get the same  
> bytecodes as if you compiled the decompiled source?

collection := Object comment asString runsFailing: #isSeparator.
1 to: collection size do: [:n | collection removeFirst. collection at:  
n].

How does one prematurely range check that?

--
Travis Griggs
[hidden email]
"The dissenter is every human being at those moments of his life when  
he resigns momentarily from the herd and thinks for himself." -
Archibald MacLeish, poet and librarian




_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

Mark Plas
"How does one prematurely range check that?"

Good example: changing the collection while looping over it. But your example is a bit misleading. It wouldn't be the #at: in your example that gets optimized, it would be the #basicAt: used in the #apply:from:to: method that Paul mentions.

But let's look a bit closer at your example. If you would slightly change it to this:

        |collection|
        collection := Object comment asString
                runsFailing: [:c | c isSeparator].
        1 to: collection size do: [:n |
                collection removeFirst.
                collection basicAt: n].

then it doesn't crash anymore. I used a #basicAt: instead of #at:

it's interesting to know that OrderedCollection>>do: wouldn't crash either if you did:

        | collection idx |
        collection := #(1 2 3 4 5) asOrderedCollection.
        idx := 0.
        collection do: [:each | collection removeLast.
                idx := idx + 1].
        idx

it will print '5'. This could be seen as a bug in the implementation.

It would however crash in this case:

        | collection |
        collection := #(1 2 3 4 5) asOrderedCollection.
        collection do: [:each | collection become: (OrderedCollection basicNew: 0)]

...because I used #become: to reduce the number of indexed vars. So range checking is necessary.

This is what OrderedCollection>>do: looks like:

OrderedCollection>>do: aBlock
        firstIndex to: lastIndex do:
                [:index | aBlock value: (self basicAt: index)]

It's the #basicAt: in this method that can be optimized I believe. If you know that firstIndex and lastIndex are in range before you start looping, then I think there's only one way that the #basicAt: could fail, and that would be because the collection got replaced via a #become: as shown above. (I don't know if there is another way to reduce the number of indexed vars other than using #become?).

It's unfortunate that this become would be the only reason while range checking is needed during the loop, because it happens rather exceptional (does it happen in 'normal' code?).

So here's a possible solution:

Suppose that, when using the 'optimizedDo:' method, a collection wouldn't be allowed to #become: something else. If it isn't allowed to swap to another object, then you can completely optimize the inner workings of #optimizedDo:.

#optimizedDo: would be implemented like this:

OrderedCollection>>optimizedDo: aBlock
        self dontAllowBecome.
        ...do the optimized loop...
        self allowBecome.

If you would send #become: during the loop you'd get an exception: 'become not allowed while iterating over the object'.

Could this work?

Mark

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Travis Griggs
Sent: donderdag 30 oktober 2008 15:37
To: [hidden email] NC
Subject: Re: [vwnc] HELP . some ideas on decompiled code wrong??


On Oct 30, 2008, at 1:15 AM, Mark Plas wrote:

> There's even a bug(?) in the to:do: optimization. We've implemented
> + on Date such that it adds a number of days to the date. By
> accident I've sent to:do: with Dates as arguments and it works just
> fine even though to:do: is only implemented on Number.
>
> I've always wondered why to:do: isn't implemented by using a special
> bytecode as Paul suggests. If the arguments of to:do: are both
> SmallIntegers a lot of type checking and checking for possible
> conversion to LargeIntegers could be avoided which I guess has to be
> done the way it is done now for every iteration in the loop. The
> same goes for the collection iteration primitive/bytecode Paul
> mentions. If you have that, the #at: doesn't need to check its
> arguments for type correctness or being in range either. You could
> do all the checking just once and not for every iteration in the loop.
>
> These may be simple extensions to the VM that could make things
> measurably faster.
>  different? Some constructs get compiled down in a way that the
> decompiler reconstructs them differently, but they still produce the
> same effect.  If you recompile the method, do you get the same
> bytecodes as if you compiled the decompiled source?

collection := Object comment asString runsFailing: #isSeparator.
1 to: collection size do: [:n | collection removeFirst. collection at:
n].

How does one prematurely range check that?

--
Travis Griggs
[hidden email]
"The dissenter is every human being at those moments of his life when
he resigns momentarily from the herd and thinks for himself." -
Archibald MacLeish, poet and librarian




_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

Alan Knight-2
become: happens a lot in collection operations in VW - usually, but not exclusively, to increase size

At 12:28 PM 10/30/2008, Mark Plas wrote:
"How does one prematurely range check that?"

Good example: changing the collection while looping over it. But your example is a bit misleading. It wouldn't be the #at: in your example that gets optimized, it would be the #basicAt: used in the #apply:from:to: method that Paul mentions.

But let's look a bit closer at your example. If you would slightly change it to this:

        |collection|
        collection := Object comment asString
                runsFailing: [:c | c isSeparator].
        1 to: collection size do: [:n |
                collection removeFirst.
                collection basicAt: n].

then it doesn't crash anymore. I used a #basicAt: instead of #at:

it's interesting to know that OrderedCollection>>do: wouldn't crash either if you did:

        | collection idx |
        collection := #(1 2 3 4 5) asOrderedCollection.
        idx := 0.
        collection do: [:each | collection removeLast.
                idx := idx + 1].
        idx

it will print '5'. This could be seen as a bug in the implementation.

It would however crash in this case:

        | collection |
        collection := #(1 2 3 4 5) asOrderedCollection.
        collection do: [:each | collection become: (OrderedCollection basicNew: 0)]

...because I used #become: to reduce the number of indexed vars. So range checking is necessary.

This is what OrderedCollection>>do: looks like:

OrderedCollection>>do: aBlock
        firstIndex to: lastIndex do:
                [:index | aBlock value: (self basicAt: index)]

It's the #basicAt: in this method that can be optimized I believe. If you know that firstIndex and lastIndex are in range before you start looping, then I think there's only one way that the #basicAt: could fail, and that would be because the collection got replaced via a #become: as shown above. (I don't know if there is another way to reduce the number of indexed vars other than using #become?).

It's unfortunate that this become would be the only reason while range checking is needed during the loop, because it happens rather exceptional (does it happen in 'normal' code?).

So here's a possible solution:

Suppose that, when using the 'optimizedDo:' method, a collection wouldn't be allowed to #become: something else. If it isn't allowed to swap to another object, then you can completely optimize the inner workings of #optimizedDo:.

#optimizedDo: would be implemented like this:

OrderedCollection>>optimizedDo: aBlock
        self dontAllowBecome.
        ...do the optimized loop...
        self allowBecome.

If you would send #become: during the loop you'd get an exception: 'become not allowed while iterating over the object'.

Could this work?

Mark

-----Original Message-----
From: [hidden email] [[hidden email]] On Behalf Of Travis Griggs
Sent: donderdag 30 oktober 2008 15:37
To: [hidden email] NC
Subject: Re: [vwnc] HELP . some ideas on decompiled code wrong??


On Oct 30, 2008, at 1:15 AM, Mark Plas wrote:

> There's even a bug(?) in the to:do: optimization. We've implemented
> + on Date such that it adds a number of days to the date. By
> accident I've sent to:do: with Dates as arguments and it works just
> fine even though to:do: is only implemented on Number.
>
> I've always wondered why to:do: isn't implemented by using a special
> bytecode as Paul suggests. If the arguments of to:do: are both
> SmallIntegers a lot of type checking and checking for possible
> conversion to LargeIntegers could be avoided which I guess has to be
> done the way it is done now for every iteration in the loop. The
> same goes for the collection iteration primitive/bytecode Paul
> mentions. If you have that, the #at: doesn't need to check its
> arguments for type correctness or being in range either. You could
> do all the checking just once and not for every iteration in the loop.
>
> These may be simple extensions to the VM that could make things
> measurably faster.
>  different? Some constructs get compiled down in a way that the
> decompiler reconstructs them differently, but they still produce the
> same effect.  If you recompile the method, do you get the same
> bytecodes as if you compiled the decompiled source?

collection := Object comment asString runsFailing: #isSeparator.
1 to: collection size do: [:n | collection removeFirst. collection at:
n].

How does one prematurely range check that?

--
Travis Griggs
[hidden email]
"The dissenter is every human being at those moments of his life when
he resigns momentarily from the herd and thinks for himself." -
Archibald MacLeish, poet and librarian




_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

--
Alan Knight [|], Engineering Manager, Cincom Smalltalk

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] HELP . some ideas on decompiled code wrong??

Mark Plas
In reply to this post by Mark Plas

Hi Alan,

 

Yes, it’s used a lot when adding items to a collection, but I think it’s hardly used when using do:, select:, reject:, collect:, detect:, contains:,... You normally don’t add or remove items from a collection while using one of the previous methods.

 

If you’d want to modify a collection while looping over it, you probably don’t use do: anyway, so I think it would be no problem at all to disallow the use of #become: on a collection while you’re performing one of the messages above. You could make a bytecode (just like you could do for #to:do:) called #from:to:do: that loops over all indexed vars of an object between from: and to: and that disallows a become: with the receiver while it’s looping.

 

Summarized you can have a performance gain on:

-        #to:do: à no integer type checking and overflow checking during the loop

-        #to:by:do: à same as above

-        Collection>>from:to:do: à no integer type checking, overflow checking, range checking, method lookup for #at: during the loop

 

 

Is there a way to predict what the performance gain would be if you would have these changes?

 

For instance:

 

Time millisecondsToRun: [1 to: 100000000 do: [:i |]]

 

takes 550 millisecs on my PC. What would the result be if you’d do it without the checking?

 

Mark

 


From: Alan Knight [mailto:[hidden email]]
Sent: donderdag 30 oktober 2008 18:55
To: Mark Plas; Travis Griggs; [hidden email]
Subject: Re: [vwnc] HELP . some ideas on decompiled code wrong??

 

become: happens a lot in collection operations in VW - usually, but not exclusively, to increase size

At 12:28 PM 10/30/2008, Mark Plas wrote:

"How does one prematurely range check that?"

Good example: changing the collection while looping over it. But your example is a bit misleading. It wouldn't be the #at: in your example that gets optimized, it would be the #basicAt: used in the #apply:from:to: method that Paul mentions.

But let's look a bit closer at your example. If you would slightly change it to this:

        |collection|
        collection := Object comment asString
                runsFailing: [:c | c isSeparator].
        1 to: collection size do: [:n |
                collection removeFirst.
                collection basicAt: n].

then it doesn't crash anymore. I used a #basicAt: instead of #at:

it's interesting to know that OrderedCollection>>do: wouldn't crash either if you did:

        | collection idx |
        collection := #(1 2 3 4 5) asOrderedCollection.
        idx := 0.
        collection do: [:each | collection removeLast.
                idx := idx + 1].
        idx

it will print '5'. This could be seen as a bug in the implementation.

It would however crash in this case:

        | collection |
        collection := #(1 2 3 4 5) asOrderedCollection.
        collection do: [:each | collection become: (OrderedCollection basicNew: 0)]

...because I used #become: to reduce the number of indexed vars. So range checking is necessary.

This is what OrderedCollection>>do: looks like:

OrderedCollection>>do: aBlock
        firstIndex to: lastIndex do:
                [:index | aBlock value: (self basicAt: index)]

It's the #basicAt: in this method that can be optimized I believe. If you know that firstIndex and lastIndex are in range before you start looping, then I think there's only one way that the #basicAt: could fail, and that would be because the collection got replaced via a #become: as shown above. (I don't know if there is another way to reduce the number of indexed vars other than using #become?).

It's unfortunate that this become would be the only reason while range checking is needed during the loop, because it happens rather exceptional (does it happen in 'normal' code?).

So here's a possible solution:

Suppose that, when using the 'optimizedDo:' method, a collection wouldn't be allowed to #become: something else. If it isn't allowed to swap to another object, then you can completely optimize the inner workings of #optimizedDo:.

#optimizedDo: would be implemented like this:

OrderedCollection>>optimizedDo: aBlock
        self dontAllowBecome.
        ...do the optimized loop...
        self allowBecome.

If you would send #become: during the loop you'd get an exception: 'become not allowed while iterating over the object'.

Could this work?

Mark

-----Original Message-----
From: [hidden email] [[hidden email]] On Behalf Of Travis Griggs
Sent: donderdag 30 oktober 2008 15:37
To: [hidden email] NC
Subject: Re: [vwnc] HELP . some ideas on decompiled code wrong??


On Oct 30, 2008, at 1:15 AM, Mark Plas wrote:

> There's even a bug(?) in the to:do: optimization. We've implemented
> + on Date such that it adds a number of days to the date. By
> accident I've sent to:do: with Dates as arguments and it works just
> fine even though to:do: is only implemented on Number.
>
> I've always wondered why to:do: isn't implemented by using a special
> bytecode as Paul suggests. If the arguments of to:do: are both
> SmallIntegers a lot of type checking and checking for possible
> conversion to LargeIntegers could be avoided which I guess has to be
> done the way it is done now for every iteration in the loop. The
> same goes for the collection iteration primitive/bytecode Paul
> mentions. If you have that, the #at: doesn't need to check its
> arguments for type correctness or being in range either. You could
> do all the checking just once and not for every iteration in the loop.
>
> These may be simple extensions to the VM that could make things
> measurably faster.
>  different? Some constructs get compiled down in a way that the
> decompiler reconstructs them differently, but they still produce the
> same effect.  If you recompile the method, do you get the same
> bytecodes as if you compiled the decompiled source?

collection := Object comment asString runsFailing: #isSeparator.
1 to: collection size do: [:n | collection removeFirst. collection at:
n].

How does one prematurely range check that?

--
Travis Griggs
[hidden email]
"The dissenter is every human being at those moments of his life when
he resigns momentarily from the herd and thinks for himself." -
Archibald MacLeish, poet and librarian




_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc


--
Alan Knight [|], Engineering Manager, Cincom Smalltalk

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc