[Pharo-project] About condensing sources, becoming CompiledMethods and VM crashes
Hi! There is this bug open I was taking a look yesterday: http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto... The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method. CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good. However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example: (Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1 (ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1 My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing. Any idea? Guille
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else. Marcus
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it? On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker <marcus.denker@inria.fr>wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
BTW, I can reproduce the crash with latest Eliot's Cog and Pharo vm. On Wed, Feb 20, 2013 at 11:00 AM, Guillermo Polito < guillermopolito@gmail.com> wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker <marcus.denker@inria.fr>wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
On Feb 20, 2013, at 11:01 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
Not for those methods installed in classes⦠we are updating an existing pointer here. Marcus
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
I summon Eliot :). On Wed, Feb 20, 2013 at 11:03 AM, Marcus Denker <marcus.denker@inria.fr>wrote:
On Feb 20, 2013, at 11:01 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
Not for those methods installed in classes⦠we are updating an existing pointer here.
Marcus
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker <marcus.denker@inria.fr>wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
i thinking that become is unnecessary, it can be just at:put: into method dictionary, so eventually all methods will be updated (after restarting permanent processes) On 20 February 2013 11:13, Guillermo Polito <guillermopolito@gmail.com> wrote:
I summon Eliot :).
On Wed, Feb 20, 2013 at 11:03 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 11:01 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
Not for those methods installed in classes⦠we are updating an existing pointer here.
Marcus
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
-- Best regards, Igor Stasenko.
Ok, I tried the following: - changed the become in #setSourcePointer: by an #at:put: in the method dict - before exporting the sources, I run the shutdown and after, I run the startup lists. - I ran the condense sources like [ Smalltalk condenseSources ] forkAt: Processor highestPriority. Then, the export runs ok, but there is a crash in the CompiledMethod class>>cleanUp Segmentation fault Smalltalk stack dump: 0xbffbe2d0 M ByteString class(String class)>new: 528605460: a(n) ByteString class 0xbffbe2f8 M ByteString(SequenceableCollection)>copyReplaceFrom:to:with: 531139536: a(n) ByteString 0xbffbe31c M ByteString(SequenceableCollection)>, 531139536: a(n) ByteString 0xbffbe33c M CompiledMethodTrailer>encode 570089224: a(n) CompiledMethodTrailer 0xbffbe35c M CompiledMethodTrailer>createMethod:class:header: 570089224: a(n) CompiledMethodTrailer 0xbffbe39c M CompiledMethod>copyWithTrailerBytes: 530925156: a(n) CompiledMethod 0xbffbe3bc M CompiledMethod>zapSourcePointer 530925156: a(n) CompiledMethod 0xbffbe3d4 M [] in CompiledMethod class>cleanUp 528604864: a(n) CompiledMethod class On Wed, Feb 20, 2013 at 12:00 PM, Igor Stasenko <siguctua@gmail.com> wrote:
i thinking that become is unnecessary, it can be just at:put: into method dictionary, so eventually all methods will be updated (after restarting permanent processes)
On 20 February 2013 11:13, Guillermo Polito <guillermopolito@gmail.com> wrote:
I summon Eliot :).
On Wed, Feb 20, 2013 at 11:03 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 11:01 AM, Guillermo Polito <
guillermopolito@gmail.com>
wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
Not for those methods installed in classes⦠we are updating an existing pointer here.
Marcus
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker <marcus.denker@inria.fr
wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer.
In
order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
-- Best regards, Igor Stasenko.
On Feb 20, 2013, at 12:13 PM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Ok, I tried the following:
- changed the become in #setSourcePointer: by an #at:put: in the method dict - before exporting the sources, I run the shutdown and after, I run the startup lists. - I ran the condense sources like
[ Smalltalk condenseSources ] forkAt: Processor highestPriority.
Then, the export runs ok, but there is a crash in the CompiledMethod class>>cleanUp
I think the cleanup is not necessary when condensing⦠it touches only methods that are *not* installed in classes. We should remove that call from the condense method.
Segmentation fault
Smalltalk stack dump: 0xbffbe2d0 M ByteString class(String class)>new: 528605460: a(n) ByteString class 0xbffbe2f8 M ByteString(SequenceableCollection)>copyReplaceFrom:to:with: 531139536: a(n) ByteString 0xbffbe31c M ByteString(SequenceableCollection)>, 531139536: a(n) ByteString 0xbffbe33c M CompiledMethodTrailer>encode 570089224: a(n) CompiledMethodTrailer 0xbffbe35c M CompiledMethodTrailer>createMethod:class:header: 570089224: a(n) CompiledMethodTrailer 0xbffbe39c M CompiledMethod>copyWithTrailerBytes: 530925156: a(n) CompiledMethod 0xbffbe3bc M CompiledMethod>zapSourcePointer 530925156: a(n) CompiledMethod 0xbffbe3d4 M [] in CompiledMethod class>cleanUp 528604864: a(n) CompiledMethod class
On Wed, Feb 20, 2013 at 12:00 PM, Igor Stasenko <siguctua@gmail.com> wrote: i thinking that become is unnecessary, it can be just at:put: into method dictionary, so eventually all methods will be updated (after restarting permanent processes)
On 20 February 2013 11:13, Guillermo Polito <guillermopolito@gmail.com> wrote:
I summon Eliot :).
On Wed, Feb 20, 2013 at 11:03 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 11:01 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
Not for those methods installed in classes⦠we are updating an existing pointer here.
Marcus
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
-- Best regards, Igor Stasenko.
Ok, so I did that, and have this. So the condense looks finished, but when returning to the UI thread, canvas is nil? Hmm, I think we should stop the UI thread also and spawn a new one after condensing... Error: MessageNotUnderstood: receiver of "finish" is nil UndefinedObject(Object)>>error: WorldState>>displayWorldSafely: in Block: [:t2 :t3 | ... BlockClosure>>cull:cull: BlockClosure>>ifError: in Block: [:t2 | t1 cull: t2 description cull: t2 receiver] BlockClosure>>cull: MethodContext(ContextPart)>>handleSignal: in Block: [self exceptionHandlerBlock cull: exception] BlockClosure>>ensure: MethodContext(ContextPart)>>handleSignal: MessageNotUnderstood(Exception)>>signal UndefinedObject(Object)>>doesNotUnderstand: #finish WorldState>>displayWorld:submorphs: On Wed, Feb 20, 2013 at 12:15 PM, Marcus Denker <marcus.denker@inria.fr>wrote:
On Feb 20, 2013, at 12:13 PM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Ok, I tried the following:
- changed the become in #setSourcePointer: by an #at:put: in the method dict - before exporting the sources, I run the shutdown and after, I run the startup lists. - I ran the condense sources like
[ Smalltalk condenseSources ] forkAt: Processor highestPriority.
Then, the export runs ok, but there is a crash in the CompiledMethod class>>cleanUp
I think the cleanup is not necessary when condensing⦠it touches only methods that are *not* installed in classes. We should remove that call from the condense method.
Segmentation fault
Smalltalk stack dump: 0xbffbe2d0 M ByteString class(String class)>new: 528605460: a(n) ByteString class 0xbffbe2f8 M ByteString(SequenceableCollection)>copyReplaceFrom:to:with: 531139536: a(n) ByteString 0xbffbe31c M ByteString(SequenceableCollection)>, 531139536: a(n) ByteString 0xbffbe33c M CompiledMethodTrailer>encode 570089224: a(n) CompiledMethodTrailer 0xbffbe35c M CompiledMethodTrailer>createMethod:class:header: 570089224: a(n) CompiledMethodTrailer 0xbffbe39c M CompiledMethod>copyWithTrailerBytes: 530925156: a(n) CompiledMethod 0xbffbe3bc M CompiledMethod>zapSourcePointer 530925156: a(n) CompiledMethod 0xbffbe3d4 M [] in CompiledMethod class>cleanUp 528604864: a(n) CompiledMethod class
On Wed, Feb 20, 2013 at 12:00 PM, Igor Stasenko <siguctua@gmail.com>wrote:
i thinking that become is unnecessary, it can be just at:put: into method dictionary, so eventually all methods will be updated (after restarting permanent processes)
On 20 February 2013 11:13, Guillermo Polito <guillermopolito@gmail.com> wrote:
I summon Eliot :).
On Wed, Feb 20, 2013 at 11:03 AM, Marcus Denker <marcus.denker@inria.fr
wrote:
On Feb 20, 2013, at 11:01 AM, Guillermo Polito <
guillermopolito@gmail.com>
wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
Not for those methods installed in classes⦠we are updating an existing pointer here.
Marcus
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker < marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer.
In
order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
-- Best regards, Igor Stasenko.
Hi, Why do we create new methods at all? *every* existing, installed method has enough space at the end for any kind of trailer. So can't we just write the source in the file, get the offset, then put that offset in the *existing* method? Marcus On Wed, Feb 20, 2013 at 12:26 PM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Ok, so I did that, and have this. So the condense looks finished, but when returning to the UI thread, canvas is nil?
Hmm, I think we should stop the UI thread also and spawn a new one after condensing...
Error: MessageNotUnderstood: receiver of "finish" is nil UndefinedObject(Object)>>error: WorldState>>displayWorldSafely: in Block: [:t2 :t3 | ... BlockClosure>>cull:cull: BlockClosure>>ifError: in Block: [:t2 | t1 cull: t2 description cull: t2 receiver] BlockClosure>>cull: MethodContext(ContextPart)>>handleSignal: in Block: [self exceptionHandlerBlock cull: exception] BlockClosure>>ensure: MethodContext(ContextPart)>>handleSignal: MessageNotUnderstood(Exception)>>signal UndefinedObject(Object)>>doesNotUnderstand: #finish WorldState>>displayWorld:submorphs:
On Wed, Feb 20, 2013 at 12:15 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 12:13 PM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Ok, I tried the following:
- changed the become in #setSourcePointer: by an #at:put: in the method dict - before exporting the sources, I run the shutdown and after, I run the startup lists. - I ran the condense sources like
[ Smalltalk condenseSources ] forkAt: Processor highestPriority.
Then, the export runs ok, but there is a crash in the CompiledMethod class>>cleanUp
I think the cleanup is not necessary when condensing⦠it touches only methods that are *not* installed in classes. We should remove that call from the condense method.
Segmentation fault
Smalltalk stack dump: 0xbffbe2d0 M ByteString class(String class)>new: 528605460: a(n) ByteString class 0xbffbe2f8 M ByteString(SequenceableCollection)>copyReplaceFrom:to:with: 531139536: a(n) ByteString 0xbffbe31c M ByteString(SequenceableCollection)>, 531139536: a(n) ByteString 0xbffbe33c M CompiledMethodTrailer>encode 570089224: a(n) CompiledMethodTrailer 0xbffbe35c M CompiledMethodTrailer>createMethod:class:header: 570089224: a(n) CompiledMethodTrailer 0xbffbe39c M CompiledMethod>copyWithTrailerBytes: 530925156: a(n) CompiledMethod 0xbffbe3bc M CompiledMethod>zapSourcePointer 530925156: a(n) CompiledMethod 0xbffbe3d4 M [] in CompiledMethod class>cleanUp 528604864: a(n) CompiledMethod class
On Wed, Feb 20, 2013 at 12:00 PM, Igor Stasenko <siguctua@gmail.com> wrote:
i thinking that become is unnecessary, it can be just at:put: into method dictionary, so eventually all methods will be updated (after restarting permanent processes)
On 20 February 2013 11:13, Guillermo Polito <guillermopolito@gmail.com> wrote:
I summon Eliot :).
On Wed, Feb 20, 2013 at 11:03 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 11:01 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
Not for those methods installed in classes⦠we are updating an existing pointer here.
Marcus
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
-- Best regards, Igor Stasenko.
-- -- Marcus Denker -- denker@acm.org http://www.marcusdenker.de
On Wed, Feb 20, 2013 at 1:35 PM, Marcus Denker <marcus.denker@inria.fr>wrote:
Hi,
Why do we create new methods at all? *every* existing, installed method has enough space at the end for any kind of trailer.
So can't we just write the source in the file, get the offset, then put that offset in the *existing* method?
But isn't that circumstantial? I mean, today we have source pointers inside all compiled methods, but there is infrastructure to do something different in the future... Anyway, I'm in hacky mode now, so I didn't think to much, just made it work :P
Marcus
On Wed, Feb 20, 2013 at 12:26 PM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Ok, so I did that, and have this. So the condense looks finished, but when returning to the UI thread, canvas is nil?
Hmm, I think we should stop the UI thread also and spawn a new one after condensing...
Error: MessageNotUnderstood: receiver of "finish" is nil UndefinedObject(Object)>>error: WorldState>>displayWorldSafely: in Block: [:t2 :t3 | ... BlockClosure>>cull:cull: BlockClosure>>ifError: in Block: [:t2 | t1 cull: t2 description cull: t2 receiver] BlockClosure>>cull: MethodContext(ContextPart)>>handleSignal: in Block: [self exceptionHandlerBlock cull: exception] BlockClosure>>ensure: MethodContext(ContextPart)>>handleSignal: MessageNotUnderstood(Exception)>>signal UndefinedObject(Object)>>doesNotUnderstand: #finish WorldState>>displayWorld:submorphs:
On Wed, Feb 20, 2013 at 12:15 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 12:13 PM, Guillermo Polito <
guillermopolito@gmail.com>
wrote:
Ok, I tried the following:
- changed the become in #setSourcePointer: by an #at:put: in the method dict - before exporting the sources, I run the shutdown and after, I run the startup lists. - I ran the condense sources like
[ Smalltalk condenseSources ] forkAt: Processor highestPriority.
Then, the export runs ok, but there is a crash in the CompiledMethod class>>cleanUp
I think the cleanup is not necessary when condensing⦠it touches only methods that are *not* installed in classes. We should remove that call from the condense method.
Segmentation fault
Smalltalk stack dump: 0xbffbe2d0 M ByteString class(String class)>new: 528605460: a(n) ByteString class 0xbffbe2f8 M ByteString(SequenceableCollection)>copyReplaceFrom:to:with: 531139536: a(n) ByteString 0xbffbe31c M ByteString(SequenceableCollection)>, 531139536: a(n) ByteString 0xbffbe33c M CompiledMethodTrailer>encode 570089224: a(n) CompiledMethodTrailer 0xbffbe35c M CompiledMethodTrailer>createMethod:class:header: 570089224: a(n) CompiledMethodTrailer 0xbffbe39c M CompiledMethod>copyWithTrailerBytes: 530925156: a(n) CompiledMethod 0xbffbe3bc M CompiledMethod>zapSourcePointer 530925156: a(n) CompiledMethod 0xbffbe3d4 M [] in CompiledMethod class>cleanUp 528604864: a(n) CompiledMethod class
On Wed, Feb 20, 2013 at 12:00 PM, Igor Stasenko <siguctua@gmail.com> wrote:
i thinking that become is unnecessary, it can be just at:put: into method dictionary, so eventually all methods will be updated (after restarting permanent processes)
On 20 February 2013 11:13, Guillermo Polito <guillermopolito@gmail.com
wrote:
I summon Eliot :).
On Wed, Feb 20, 2013 at 11:03 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 11:01 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
Not for those methods installed in classes⦠we are updating an existing pointer here.
Marcus
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and
adds
a new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
-- Best regards, Igor Stasenko.
-- -- Marcus Denker -- denker@acm.org http://www.marcusdenker.de
On Feb 20, 2013, at 1:41 PM, Guillermo Polito <guillermopolito@gmail.com> wrote:
On Wed, Feb 20, 2013 at 1:35 PM, Marcus Denker <marcus.denker@inria.fr> wrote: Hi,
Why do we create new methods at all? *every* existing, installed method has enough space at the end for any kind of trailer.
So can't we just write the source in the file, get the offset, then put that offset in the *existing* method?
But isn't that circumstantial? I mean, today we have source pointers inside all compiled methods, but there is infrastructure to do something different in the future...
If we do anything, after we have done that, there will be no condensing necessary...
Anyway, I'm in hacky mode now, so I didn't think to much, just made it work :P
:-)
but aside of making things work, i really wonder why become on methods makes VM crash. we should have an easily reproducible case for study. -- Best regards, Igor Stasenko.
On Wed, Feb 20, 2013 at 2:23 PM, Igor Stasenko <siguctua@gmail.com> wrote:
but aside of making things work, i really wonder why become on methods makes VM crash. we should have an easily reproducible case for study.
These? (Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1 (ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
-- Best regards, Igor Stasenko.
On 20 February 2013 14:37, Guillermo Polito <guillermopolito@gmail.com> wrote:
On Wed, Feb 20, 2013 at 2:23 PM, Igor Stasenko <siguctua@gmail.com> wrote:
but aside of making things work, i really wonder why become on methods makes VM crash. we should have an easily reproducible case for study.
These?
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
this one shows "computation has terminated" its not crashing my VM.. this happens when context has no sender to return to (sender is nil)
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
this one crashing.. but still showing the same "computation has terminated" dialog before.
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
Yes, because the vm crash is caused by the lost of the active process... On Wed, Feb 20, 2013 at 2:44 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 20 February 2013 14:37, Guillermo Polito <guillermopolito@gmail.com> wrote:
On Wed, Feb 20, 2013 at 2:23 PM, Igor Stasenko <siguctua@gmail.com>
wrote:
but aside of making things work, i really wonder why become on methods makes VM crash. we should have an easily reproducible case for study.
These?
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
this one shows "computation has terminated" its not crashing my VM.. this happens when context has no sender to return to (sender is nil)
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
this one crashing.. but still showing the same "computation has terminated" dialog before.
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
BTW, the become works in StackVM, so I would blame the JIT :) On Wed, Feb 20, 2013 at 2:48 PM, Guillermo Polito <guillermopolito@gmail.com
wrote:
Yes, because the vm crash is caused by the lost of the active process...
On Wed, Feb 20, 2013 at 2:44 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 20 February 2013 14:37, Guillermo Polito <guillermopolito@gmail.com> wrote:
On Wed, Feb 20, 2013 at 2:23 PM, Igor Stasenko <siguctua@gmail.com>
wrote:
but aside of making things work, i really wonder why become on methods makes VM crash. we should have an easily reproducible case for study.
These?
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
this one shows "computation has terminated" its not crashing my VM.. this happens when context has no sender to return to (sender is nil)
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
this one crashing.. but still showing the same "computation has terminated" dialog before.
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
So, this (hacky) changeset does the trick. [ Smalltalk condenseSources ] forkAt: Processor highestPriority. works.. Resuming: - changed the becomeForward by an at:put: - a little hack/fix to serialize unicode chars in the sources file (Japanese environment) - removed the progress bar stuff from condenseChanges - before condensing process the shutdown list - after condensing process the startup list - do not cleanup methods - after processing the startuplist, kill current UIProcess and start a new one - run the condense changes in highest priority so it does not get preempted by inconsistent processes. On Wed, Feb 20, 2013 at 12:26 PM, Guillermo Polito < guillermopolito@gmail.com> wrote:
Ok, so I did that, and have this. So the condense looks finished, but when returning to the UI thread, canvas is nil?
Hmm, I think we should stop the UI thread also and spawn a new one after condensing...
Error: MessageNotUnderstood: receiver of "finish" is nil UndefinedObject(Object)>>error: WorldState>>displayWorldSafely: in Block: [:t2 :t3 | ... BlockClosure>>cull:cull: BlockClosure>>ifError: in Block: [:t2 | t1 cull: t2 description cull: t2 receiver] BlockClosure>>cull: MethodContext(ContextPart)>>handleSignal: in Block: [self exceptionHandlerBlock cull: exception] BlockClosure>>ensure: MethodContext(ContextPart)>>handleSignal: MessageNotUnderstood(Exception)>>signal UndefinedObject(Object)>>doesNotUnderstand: #finish WorldState>>displayWorld:submorphs:
On Wed, Feb 20, 2013 at 12:15 PM, Marcus Denker <marcus.denker@inria.fr>wrote:
On Feb 20, 2013, at 12:13 PM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Ok, I tried the following:
- changed the become in #setSourcePointer: by an #at:put: in the method dict - before exporting the sources, I run the shutdown and after, I run the startup lists. - I ran the condense sources like
[ Smalltalk condenseSources ] forkAt: Processor highestPriority.
Then, the export runs ok, but there is a crash in the CompiledMethod class>>cleanUp
I think the cleanup is not necessary when condensing⦠it touches only methods that are *not* installed in classes. We should remove that call from the condense method.
Segmentation fault
Smalltalk stack dump: 0xbffbe2d0 M ByteString class(String class)>new: 528605460: a(n) ByteString class 0xbffbe2f8 M ByteString(SequenceableCollection)>copyReplaceFrom:to:with: 531139536: a(n) ByteString 0xbffbe31c M ByteString(SequenceableCollection)>, 531139536: a(n) ByteString 0xbffbe33c M CompiledMethodTrailer>encode 570089224: a(n) CompiledMethodTrailer 0xbffbe35c M CompiledMethodTrailer>createMethod:class:header: 570089224: a(n) CompiledMethodTrailer 0xbffbe39c M CompiledMethod>copyWithTrailerBytes: 530925156: a(n) CompiledMethod 0xbffbe3bc M CompiledMethod>zapSourcePointer 530925156: a(n) CompiledMethod 0xbffbe3d4 M [] in CompiledMethod class>cleanUp 528604864: a(n) CompiledMethod class
On Wed, Feb 20, 2013 at 12:00 PM, Igor Stasenko <siguctua@gmail.com>wrote:
i thinking that become is unnecessary, it can be just at:put: into method dictionary, so eventually all methods will be updated (after restarting permanent processes)
On 20 February 2013 11:13, Guillermo Polito <guillermopolito@gmail.com> wrote:
I summon Eliot :).
On Wed, Feb 20, 2013 at 11:03 AM, Marcus Denker < marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 11:01 AM, Guillermo Polito <
guillermopolito@gmail.com>
wrote:
'cause you don't know if the method has trailer or not I think... There are empty trailers and trailers embedding source (directly in the image)... isn't it?
Not for those methods installed in classes⦠we are updating an existing pointer here.
Marcus
On Wed, Feb 20, 2013 at 10:52 AM, Marcus Denker < marcus.denker@inria.fr> wrote:
On Feb 20, 2013, at 10:45 AM, Guillermo Polito <guillermopolito@gmail.com> wrote:
Hi!
There is this bug open I was taking a look yesterday:
http://code.google.com/p/pharo/issues/detail?can=2&start=0&num=100&q=Milesto...
The condense sources compacts the changes and source files, and adds
a
new method trailer to a compiled method with it's new source pointer. In order to do that, it does a #becomeForward: to the method.
CompiledMethod>>setSourcePointer: srcPointer "We can't change the trailer of existing method, since it could have completely different format. Therefore we need to generate a copy with new trailer, containing an scrPointer, and then #become it" | trailer copy | trailer := CompiledMethodTrailer new sourcePointer: srcPointer. copy := self copyWithTrailerBytes: trailer.
self becomeForward: copy. ^ copy
So far, with simple methods, so good.
However, there are cases, in which becoming the compiled method, breaks processes, sometimes getting a crash in the VM. For example:
(Delay class>>#handleTimerEvent) setSourcePosition: 200 inFile: 1
(ProcessorScheduler class>>#idleProcess) setSourcePosition: 200 inFile: 1
My assumption is that the #becomeForward: of compiled methods do not get well with the stack mapping in the vm... But just guessing.
I wonder why we don't just update the pointer. That is: we keep the method the same, rewrite the pointer, and nothing else.
Marcus
-- Best regards, Igor Stasenko.
participants (3)
-
Guillermo Polito -
Igor Stasenko -
Marcus Denker