Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
June 2016
- 812 messages
Re: [Pharo-dev] atomicity of non-local returns
by Ben Coman
On Tue, Jun 7, 2016 at 2:39 AM, Clément Bera <bera.clement(a)gmail.com> wrote:
> Yeah anyway the non local return happens after the ensure: send, so nothing
> to worry about.
>
> In your analysis, you need to see that the #returnTop bytecode means NLR in
> a block but method return in a method. Even if it looks the same, in one
> case the #returnTop belongs to a block closure bytecode, hence is a NLR,
> whereas in the othercase, it belongs to the method bytecode, hence it's a
> method return.
>
> See StackInterpreter>>commonReturn, this code:
>
> "If this is a method simply return to the sender/caller."
> (self iframeIsBlockActivation: localFP) ifFalse:
> [^self commonCallerReturn].
>
Ahhh, got it. Quite a subtle semantic when the source code looks much the same.
> test if the return top is a method return or block NLR. I don't know why
> Eliot decided to share the bytecode between method return and block NLR, but
> there are 3 returns in Smalltalk, method return, block return and block NLR
> and they're all quite different.
>
> About your example, the normal closure bytecode creates the closure, pushes
> it on top of the stack, then skips over the closure bytecode (jump forward).
> About the jump instructions generated by ifTrue:ifFalse:, the jump forward
> instruction has no interrupt point, while the conditional jump have an
> interrupt point only in the case of a must be boolean. Does this make sense
> ?
Just to confirm in my own words...
the jumpFalse:
* sent to a boolean has no interrupt point
* sent to a non-boolean has an interrupt point
In Squeak there's indentation in bytecode printing to ease control flow
> understanding, that may help you. You are using a Squeak image for VM
> simulation and Pharo image to implement the primitives and experiment with
> the primitives, aren't you ?
The purpose of the primitives is for Pharo, but right this moment I'm
using Squeak for both the simulator and the image being simulated (my
changeset only needed a few changes to split Context back to its
earlier components). While learning the simulator it was the path of
least resistance using the supplied scripts to build the reader image,
and I hadn't swapped to simulating a Pharo image yet.
cheers -ben
>
> Cheers
>
> On Mon, Jun 6, 2016 at 6:34 PM, Ben Coman <btc(a)openinworld.com> wrote:
>>
>> On Mon, Jun 6, 2016 at 9:34 PM, Clément Bera <bera.clement(a)gmail.com>
>> wrote:
>> > Hi Ben,
>> >
>> > Firstly be careful because atomic usually means that the thread cannot
>> > be
>> > interrupted by a concurrent native thread, so an atomic operation has to
>> > be
>> > guaranteed at processor level.
>> >
>> > Assuming that by atomic you mean that the operation's process cannot be
>> > preempted by another green thread, yes there is big problems with non
>> > local
>> > returns.
>>
>> Yes, I meant at the image level, run by the single-thread VM.
>>
>> >
>> > Two main issues:
>> > - NLR can trigger unwind blocks, which can switch to another process.
>> > - NLR can fail, triggering the cannotReturn: call-back, which can switch
>> > to
>> > another process.
>>
>> These would presumably could only occur after the #ensure: had been
>> invoked? .
>>
>> >
>> > I understand generally that an inlined #ifTrue is atomic. For
>> > example, here after the primitive returns, no interruption can occur
>> > before the #ensure is invoked...
>> > self primitiveWaitAcquire ifTrue:
>> > [mutuallyExclusiveBlock ensure: [self release]].
>> >
>> > The exact answer is that #ifTrue: can be interrupted if self
>> > primitiveWaitAcquire is not a boolean, and can't be interrupted if it's
>> > a
>> > boolean. It's nice to mark in a comment if part of the method's code has
>> > not
>> > to be interrupted to avoid issues years later.
>>
>> Good tip.
>>
>> >
>> > But I want to know whether a non-local return could have an impact on
>> > that atomicity. For example ...
>> > self primitiveWaitAcquire ifTrue:
>> > [ ^ mutuallyExclusiveBlock ensure: [self release]]
>> >
>> > In your code there is no non local return because ifTrue: is inlined by
>> > the
>> > Bytecode compiler.
>>
>> I'm not clear on your meaning. If there were additional code
>> following those two lines, then they would not be executed, so it
>> would still be a NLR ? I took my understanding from [1]. And in the
>> bytecode below it seems #returnTop is associated with the NLRs - so
>> the NLR is still there(?), but having looked at the bytecode I can now
>> see it has no impact, I think either with or without inlining makes no
>> difference wrt NLR.
>>
>>
>> [1]
>> https://silversmalltalk.wordpress.com/2011/02/02/implementing-smalltalks-no…
>>
>> > Try to compile it and look at the bytecode you will see.
>>
>> Good idea. So I share a little analysis...
>>
>>
>> The bytecode for these two lines is identical,
>> a blah: [ [ self foo ] ensure: [ self bar ] ]
>> a blah: [ ^ [ self foo ] ensure: [ self bar ] ]
>> except for bytecode 49, respectively...
>> "49 <7D> blockReturn"
>> "49 <7C> returnTop"
>>
>> "29 <10> pushTemp: 0"
>> "30 <8F 00 00 10> closureNumCopied: 0 numArgs: 0 bytes 34 to 49"
>> "34 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 38 to 40"
>> "38 <70> self"
>> "39 <D0> send: foo"
>> "40 <7D> blockReturn"
>> "41 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 45 to 47"
>> "45 <70> self"
>> "46 <D1> send: bar"
>> "47 <7D> blockReturn"
>> "48 <E2> send: ensure:"
>> "49 <7C> returnTop"
>> "50 <E3> send: blah:"
>> "51 <87> pop"
>> "52 <78> returnSelf"
>>
>>
>> Changing #blah: to #ifTrue: these two lines
>> a ifTrue: [ [ self foo ] ensure: [ self bar ] ]
>> a ifTrue: [ ^ [ self foo ] ensure: [ self bar ] ]
>> are the same except for bytecode 49, respectively...
>> "47 <87> pop"
>> "47 <7C> returnTop"
>>
>> "29 <10> pushTemp: 0"
>> "30 <AC 10> jumpFalse: 48"
>> "32 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 36 to 38"
>> "36 <70> self"
>> "37 <D0> send: foo"
>> "38 <7D> blockReturn"
>> "39 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 43 to 45"
>> "43 <70> self"
>> "44 <D1> send: bar"
>> "45 <7D> blockReturn"
>> "46 <E2> send: ensure:"
>> "47 <87> pop"
>> "48 <78> returnSelf"
>>
>> And between #blah: and #ifTrue: the difference is
>> removal of...
>> "30 <8F 00 00 10> closureNumCopied: 0 numArgs: 0 bytes 34 to 49"
>> "49 <7D> blockReturn"
>> "50 <E3> send: blah:"
>> and replaced them with...
>> "30 <AC 10> jumpFalse: 48"
>>
>> It took me a while to guess how to follow the execution path. I had
>> assumed it would just go top to bottom, but that didn't make sense for
>> foo to be executed before blah. Can you confirm.. I guess the trick
>> (for #blah) is...
>>
>> 1. At 29, push the temp
>> 2. skip the closureNumCopied bytes 34 to 49,
>> 3. At 50, send #blah.
>> 4. next is bytecode 34 skips bytecodes 38 to 40,
>> 5. and bytecode 41 skips bytecodes 45 to 47
>> 6. At 48 send #ensure:.
>>
>> versus #ifTrue: bytecocde...
>>
>> 1. At 29, push the temp
>> 2. skip closureNumCopied bytes 36 to 38"
>> 3. skip closureNumCopied: bytes 43 to 45"
>> 4. At 46, send #ensure:
>>
>> So its clear (IIUC) that with #IfTrue: the #ensure is the first send:
>> after the push temp, but the non-inlined #blah: is an extra send
>> between which could be interrupted and prevent the #ensure from being
>> executed.
>>
>> >
>> > Else as I said at the beginning of the mail, a non local return can
>> > imply a
>> > process switch if that was your question.
>>
>> Yes, but a process switch is okay after the send of #ensure:
>> just not before.
>>
>> thx. cheers -ben
>>
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > On Mon, Jun 6, 2016 at 2:46 PM, Ben Coman <btc(a)openinworld.com> wrote:
>> >>
>> >> I understand generally that an inlined #ifTrue is atomic. For
>> >> example, here after the primitive returns, no interruption can occur
>> >> before the #ensure is invoked...
>> >> self primitiveWaitAcquire ifTrue:
>> >> [mutuallyExclusiveBlock ensure: [self release]].
>> >>
>> >> But I want to know whether a non-local return could have an impact on
>> >> that atomicity. For example ...
>> >> self primitiveWaitAcquire ifTrue:
>> >> [ ^ mutuallyExclusiveBlock ensure: [self release]]
>> >>
>> >> cheers -ben
>> >>
>> >
>>
>
June 6, 2016
Privacy sendDiagnosticsAndUsageData should be ternary, not binary
by Peter Uhnak
Hi,
Privacy>>sendDiagnosticsAndUsageData should be ternary, not binary.
Because right now if I refuse sending the data I will be asked again every single time.
So the proper behavior (imho) should be:
ask Privacy for the setting⦠if the setting is not defined, then show a popup.
If the setting is defined then respect it and do not show another popup.
Also it would be nice to know what happens with the data.
I mean my projects are open source so "sendSourceCode" shouldn't be an issue⦠but what you can possibly learn from it?
Why not just analyze the content of SmalltalkHub/GitHub?
Peter
June 6, 2016
Re: [Pharo-dev] [Ann] ObjectStatistics
by phil@highoctane.be
Nice thing!
On Mon, Jun 6, 2016 at 4:56 PM, Denis Kudriashov <dionisiydk(a)gmail.com>
wrote:
> And you can load it by
>
> Gofer it smalltalkhubUser: 'Pharo' project: 'ObjectStatistics';
> configuration; loadStable
>
> And play with examples on ObjectStatistics class side
>
> 2016-06-06 16:53 GMT+02:00 Denis Kudriashov <dionisiydk(a)gmail.com>:
>
>> Hello.
>>
>> I just publish new tool ObjectStatistics to analyze objects set.
>> I first created it to analyze network communication during remote
>> debugging. And then I realize how general it could be.
>> Now it is ready to use package. It could be good foundation to improve
>> and simplify our profiler tools.
>>
>> You can see details and examples on my blog
>> http://dionisiydk.blogspot.fr/2016/06/objectstatistics-simple-objects.html
>> .
>>
>> Here is little abstract:
>> ObjectStatistics tool to analyse set of objects by computing different
>> kind of metrics and look at them from different angles. It implements
>> simplistic OLAP Cube approach for data analysis but in objects space.
>> Imaging that we have collection of message sends and we want to know
>> number of message sends in dimension of receiver, receiver class and
>> message selector. We have different angles to look at this data: from
>> receiver class to selector and receiver or from selector to receiver class
>> and receiver or any other combination.
>> We also could analyze different kind of metrics which could be computed
>> on given objects. It could be number of unique receivers, execution time,
>> executed lines of code, etc.
>> This package implements computation of object statistics over declared
>> metrics and dimensions space.
>>
>> Best regards,
>> Denis
>>
>
>
June 6, 2016
Re: [Pharo-dev] atomicity of non-local returns
by Clément Bera
Yeah anyway the non local return happens after the ensure: send, so nothing
to worry about.
In your analysis, you need to see that the #returnTop bytecode means NLR in
a block but method return in a method. Even if it looks the same, in one
case the #returnTop belongs to a block closure bytecode, hence is a NLR,
whereas in the othercase, it belongs to the method bytecode, hence it's a
method return.
See StackInterpreter>>commonReturn, this code:
"If this is a method simply return to the sender/caller."
(self iframeIsBlockActivation: localFP) ifFalse:
[^self commonCallerReturn].
test if the return top is a method return or block NLR. I don't know why
Eliot decided to share the bytecode between method return and block NLR,
but there are 3 returns in Smalltalk, method return, block return and block
NLR and they're all quite different.
About your example, the normal closure bytecode creates the closure, pushes
it on top of the stack, then skips over the closure bytecode (jump
forward). About the jump instructions generated by ifTrue:ifFalse:, the
jump forward instruction has no interrupt point, while the conditional jump
have an interrupt point only in the case of a must be boolean. Does this
make sense ? In Squeak there's indentation in bytecode printing to ease
control flow understanding, that may help you. You are using a Squeak image
for VM simulation and Pharo image to implement the primitives and
experiment with the primitives, aren't you ?
Cheers
On Mon, Jun 6, 2016 at 6:34 PM, Ben Coman <btc(a)openinworld.com> wrote:
> On Mon, Jun 6, 2016 at 9:34 PM, Clément Bera <bera.clement(a)gmail.com>
> wrote:
> > Hi Ben,
> >
> > Firstly be careful because atomic usually means that the thread cannot be
> > interrupted by a concurrent native thread, so an atomic operation has to
> be
> > guaranteed at processor level.
> >
> > Assuming that by atomic you mean that the operation's process cannot be
> > preempted by another green thread, yes there is big problems with non
> local
> > returns.
>
> Yes, I meant at the image level, run by the single-thread VM.
>
> >
> > Two main issues:
> > - NLR can trigger unwind blocks, which can switch to another process.
> > - NLR can fail, triggering the cannotReturn: call-back, which can switch
> to
> > another process.
>
> These would presumably could only occur after the #ensure: had been
> invoked? .
>
> >
> > I understand generally that an inlined #ifTrue is atomic. For
> > example, here after the primitive returns, no interruption can occur
> > before the #ensure is invoked...
> > self primitiveWaitAcquire ifTrue:
> > [mutuallyExclusiveBlock ensure: [self release]].
> >
> > The exact answer is that #ifTrue: can be interrupted if self
> > primitiveWaitAcquire is not a boolean, and can't be interrupted if it's a
> > boolean. It's nice to mark in a comment if part of the method's code has
> not
> > to be interrupted to avoid issues years later.
>
> Good tip.
>
> >
> > But I want to know whether a non-local return could have an impact on
> > that atomicity. For example ...
> > self primitiveWaitAcquire ifTrue:
> > [ ^ mutuallyExclusiveBlock ensure: [self release]]
> >
> > In your code there is no non local return because ifTrue: is inlined by
> the
> > Bytecode compiler.
>
> I'm not clear on your meaning. If there were additional code
> following those two lines, then they would not be executed, so it
> would still be a NLR ? I took my understanding from [1]. And in the
> bytecode below it seems #returnTop is associated with the NLRs - so
> the NLR is still there(?), but having looked at the bytecode I can now
> see it has no impact, I think either with or without inlining makes no
> difference wrt NLR.
>
>
> [1]
> https://silversmalltalk.wordpress.com/2011/02/02/implementing-smalltalks-no…
>
> > Try to compile it and look at the bytecode you will see.
>
> Good idea. So I share a little analysis...
>
>
> The bytecode for these two lines is identical,
> a blah: [ [ self foo ] ensure: [ self bar ] ]
> a blah: [ ^ [ self foo ] ensure: [ self bar ] ]
> except for bytecode 49, respectively...
> "49 <7D> blockReturn"
> "49 <7C> returnTop"
>
> "29 <10> pushTemp: 0"
> "30 <8F 00 00 10> closureNumCopied: 0 numArgs: 0 bytes 34 to 49"
> "34 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 38 to 40"
> "38 <70> self"
> "39 <D0> send: foo"
> "40 <7D> blockReturn"
> "41 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 45 to 47"
> "45 <70> self"
> "46 <D1> send: bar"
> "47 <7D> blockReturn"
> "48 <E2> send: ensure:"
> "49 <7C> returnTop"
> "50 <E3> send: blah:"
> "51 <87> pop"
> "52 <78> returnSelf"
>
>
> Changing #blah: to #ifTrue: these two lines
> a ifTrue: [ [ self foo ] ensure: [ self bar ] ]
> a ifTrue: [ ^ [ self foo ] ensure: [ self bar ] ]
> are the same except for bytecode 49, respectively...
> "47 <87> pop"
> "47 <7C> returnTop"
>
> "29 <10> pushTemp: 0"
> "30 <AC 10> jumpFalse: 48"
> "32 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 36 to 38"
> "36 <70> self"
> "37 <D0> send: foo"
> "38 <7D> blockReturn"
> "39 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 43 to 45"
> "43 <70> self"
> "44 <D1> send: bar"
> "45 <7D> blockReturn"
> "46 <E2> send: ensure:"
> "47 <87> pop"
> "48 <78> returnSelf"
>
> And between #blah: and #ifTrue: the difference is
> removal of...
> "30 <8F 00 00 10> closureNumCopied: 0 numArgs: 0 bytes 34 to 49"
> "49 <7D> blockReturn"
> "50 <E3> send: blah:"
> and replaced them with...
> "30 <AC 10> jumpFalse: 48"
>
> It took me a while to guess how to follow the execution path. I had
> assumed it would just go top to bottom, but that didn't make sense for
> foo to be executed before blah. Can you confirm.. I guess the trick
> (for #blah) is...
>
> 1. At 29, push the temp
> 2. skip the closureNumCopied bytes 34 to 49,
> 3. At 50, send #blah.
> 4. next is bytecode 34 skips bytecodes 38 to 40,
> 5. and bytecode 41 skips bytecodes 45 to 47
> 6. At 48 send #ensure:.
>
> versus #ifTrue: bytecocde...
>
> 1. At 29, push the temp
> 2. skip closureNumCopied bytes 36 to 38"
> 3. skip closureNumCopied: bytes 43 to 45"
> 4. At 46, send #ensure:
>
> So its clear (IIUC) that with #IfTrue: the #ensure is the first send:
> after the push temp, but the non-inlined #blah: is an extra send
> between which could be interrupted and prevent the #ensure from being
> executed.
>
> >
> > Else as I said at the beginning of the mail, a non local return can
> imply a
> > process switch if that was your question.
>
> Yes, but a process switch is okay after the send of #ensure:
> just not before.
>
> thx. cheers -ben
>
> >
> >
> >
> >
> >
> >
> >
> > On Mon, Jun 6, 2016 at 2:46 PM, Ben Coman <btc(a)openinworld.com> wrote:
> >>
> >> I understand generally that an inlined #ifTrue is atomic. For
> >> example, here after the primitive returns, no interruption can occur
> >> before the #ensure is invoked...
> >> self primitiveWaitAcquire ifTrue:
> >> [mutuallyExclusiveBlock ensure: [self release]].
> >>
> >> But I want to know whether a non-local return could have an impact on
> >> that atomicity. For example ...
> >> self primitiveWaitAcquire ifTrue:
> >> [ ^ mutuallyExclusiveBlock ensure: [self release]]
> >>
> >> cheers -ben
> >>
> >
>
>
June 6, 2016
Re: [Pharo-dev] atomicity of non-local returns
by Ben Coman
On Mon, Jun 6, 2016 at 9:34 PM, Clément Bera <bera.clement(a)gmail.com> wrote:
> Hi Ben,
>
> Firstly be careful because atomic usually means that the thread cannot be
> interrupted by a concurrent native thread, so an atomic operation has to be
> guaranteed at processor level.
>
> Assuming that by atomic you mean that the operation's process cannot be
> preempted by another green thread, yes there is big problems with non local
> returns.
Yes, I meant at the image level, run by the single-thread VM.
>
> Two main issues:
> - NLR can trigger unwind blocks, which can switch to another process.
> - NLR can fail, triggering the cannotReturn: call-back, which can switch to
> another process.
These would presumably could only occur after the #ensure: had been invoked? .
>
> I understand generally that an inlined #ifTrue is atomic. For
> example, here after the primitive returns, no interruption can occur
> before the #ensure is invoked...
> self primitiveWaitAcquire ifTrue:
> [mutuallyExclusiveBlock ensure: [self release]].
>
> The exact answer is that #ifTrue: can be interrupted if self
> primitiveWaitAcquire is not a boolean, and can't be interrupted if it's a
> boolean. It's nice to mark in a comment if part of the method's code has not
> to be interrupted to avoid issues years later.
Good tip.
>
> But I want to know whether a non-local return could have an impact on
> that atomicity. For example ...
> self primitiveWaitAcquire ifTrue:
> [ ^ mutuallyExclusiveBlock ensure: [self release]]
>
> In your code there is no non local return because ifTrue: is inlined by the
> Bytecode compiler.
I'm not clear on your meaning. If there were additional code
following those two lines, then they would not be executed, so it
would still be a NLR ? I took my understanding from [1]. And in the
bytecode below it seems #returnTop is associated with the NLRs - so
the NLR is still there(?), but having looked at the bytecode I can now
see it has no impact, I think either with or without inlining makes no
difference wrt NLR.
[1] https://silversmalltalk.wordpress.com/2011/02/02/implementing-smalltalks-no…
> Try to compile it and look at the bytecode you will see.
Good idea. So I share a little analysis...
The bytecode for these two lines is identical,
a blah: [ [ self foo ] ensure: [ self bar ] ]
a blah: [ ^ [ self foo ] ensure: [ self bar ] ]
except for bytecode 49, respectively...
"49 <7D> blockReturn"
"49 <7C> returnTop"
"29 <10> pushTemp: 0"
"30 <8F 00 00 10> closureNumCopied: 0 numArgs: 0 bytes 34 to 49"
"34 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 38 to 40"
"38 <70> self"
"39 <D0> send: foo"
"40 <7D> blockReturn"
"41 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 45 to 47"
"45 <70> self"
"46 <D1> send: bar"
"47 <7D> blockReturn"
"48 <E2> send: ensure:"
"49 <7C> returnTop"
"50 <E3> send: blah:"
"51 <87> pop"
"52 <78> returnSelf"
Changing #blah: to #ifTrue: these two lines
a ifTrue: [ [ self foo ] ensure: [ self bar ] ]
a ifTrue: [ ^ [ self foo ] ensure: [ self bar ] ]
are the same except for bytecode 49, respectively...
"47 <87> pop"
"47 <7C> returnTop"
"29 <10> pushTemp: 0"
"30 <AC 10> jumpFalse: 48"
"32 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 36 to 38"
"36 <70> self"
"37 <D0> send: foo"
"38 <7D> blockReturn"
"39 <8F 00 00 03> closureNumCopied: 0 numArgs: 0 bytes 43 to 45"
"43 <70> self"
"44 <D1> send: bar"
"45 <7D> blockReturn"
"46 <E2> send: ensure:"
"47 <87> pop"
"48 <78> returnSelf"
And between #blah: and #ifTrue: the difference is
removal of...
"30 <8F 00 00 10> closureNumCopied: 0 numArgs: 0 bytes 34 to 49"
"49 <7D> blockReturn"
"50 <E3> send: blah:"
and replaced them with...
"30 <AC 10> jumpFalse: 48"
It took me a while to guess how to follow the execution path. I had
assumed it would just go top to bottom, but that didn't make sense for
foo to be executed before blah. Can you confirm.. I guess the trick
(for #blah) is...
1. At 29, push the temp
2. skip the closureNumCopied bytes 34 to 49,
3. At 50, send #blah.
4. next is bytecode 34 skips bytecodes 38 to 40,
5. and bytecode 41 skips bytecodes 45 to 47
6. At 48 send #ensure:.
versus #ifTrue: bytecocde...
1. At 29, push the temp
2. skip closureNumCopied bytes 36 to 38"
3. skip closureNumCopied: bytes 43 to 45"
4. At 46, send #ensure:
So its clear (IIUC) that with #IfTrue: the #ensure is the first send:
after the push temp, but the non-inlined #blah: is an extra send
between which could be interrupted and prevent the #ensure from being
executed.
>
> Else as I said at the beginning of the mail, a non local return can imply a
> process switch if that was your question.
Yes, but a process switch is okay after the send of #ensure:
just not before.
thx. cheers -ben
>
>
>
>
>
>
>
> On Mon, Jun 6, 2016 at 2:46 PM, Ben Coman <btc(a)openinworld.com> wrote:
>>
>> I understand generally that an inlined #ifTrue is atomic. For
>> example, here after the primitive returns, no interruption can occur
>> before the #ensure is invoked...
>> self primitiveWaitAcquire ifTrue:
>> [mutuallyExclusiveBlock ensure: [self release]].
>>
>> But I want to know whether a non-local return could have an impact on
>> that atomicity. For example ...
>> self primitiveWaitAcquire ifTrue:
>> [ ^ mutuallyExclusiveBlock ensure: [self release]]
>>
>> cheers -ben
>>
>
June 6, 2016
Re: [Pharo-dev] [Ann] ObjectStatistics
by Denis Kudriashov
And you can load it by
Gofer it smalltalkhubUser: 'Pharo' project: 'ObjectStatistics';
configuration; loadStable
And play with examples on ObjectStatistics class side
2016-06-06 16:53 GMT+02:00 Denis Kudriashov <dionisiydk(a)gmail.com>:
> Hello.
>
> I just publish new tool ObjectStatistics to analyze objects set.
> I first created it to analyze network communication during remote
> debugging. And then I realize how general it could be.
> Now it is ready to use package. It could be good foundation to improve and
> simplify our profiler tools.
>
> You can see details and examples on my blog
> http://dionisiydk.blogspot.fr/2016/06/objectstatistics-simple-objects.html
> .
>
> Here is little abstract:
> ObjectStatistics tool to analyse set of objects by computing different
> kind of metrics and look at them from different angles. It implements
> simplistic OLAP Cube approach for data analysis but in objects space.
> Imaging that we have collection of message sends and we want to know
> number of message sends in dimension of receiver, receiver class and
> message selector. We have different angles to look at this data: from
> receiver class to selector and receiver or from selector to receiver class
> and receiver or any other combination.
> We also could analyze different kind of metrics which could be computed on
> given objects. It could be number of unique receivers, execution time,
> executed lines of code, etc.
> This package implements computation of object statistics over declared
> metrics and dimensions space.
>
> Best regards,
> Denis
>
June 6, 2016
[Ann] ObjectStatistics
by Denis Kudriashov
Hello.
I just publish new tool ObjectStatistics to analyze objects set.
I first created it to analyze network communication during remote
debugging. And then I realize how general it could be.
Now it is ready to use package. It could be good foundation to improve and
simplify our profiler tools.
You can see details and examples on my blog
http://dionisiydk.blogspot.fr/2016/06/objectstatistics-simple-objects.html.
Here is little abstract:
ObjectStatistics tool to analyse set of objects by computing different kind
of metrics and look at them from different angles. It implements simplistic
OLAP Cube approach for data analysis but in objects space.
Imaging that we have collection of message sends and we want to know number
of message sends in dimension of receiver, receiver class and message
selector. We have different angles to look at this data: from receiver
class to selector and receiver or from selector to receiver class and
receiver or any other combination.
We also could analyze different kind of metrics which could be computed on
given objects. It could be number of unique receivers, execution time,
executed lines of code, etc.
This package implements computation of object statistics over declared
metrics and dimensions space.
Best regards,
Denis
June 6, 2016
Re: [Pharo-dev] atomicity of non-local returns
by Clément Bera
Hi Ben,
Firstly be careful because atomic usually means that the thread cannot be
interrupted by a concurrent native thread, so an atomic operation has to be
guaranteed at processor level.
Assuming that by atomic you mean that the operation's process cannot be
preempted by another green thread, yes there is big problems with non local
returns.
Two main issues:
- NLR can trigger unwind blocks, which can switch to another process.
- NLR can fail, triggering the cannotReturn: call-back, which can switch to
another process.
*I understand generally that an inlined #ifTrue is atomic. Forexample,
here after the primitive returns, no interruption can occurbefore the
#ensure is invoked... self primitiveWaitAcquire ifTrue:
[mutuallyExclusiveBlock ensure: [self release]].*
The exact answer is that #*ifTrue*: can be interrupted if *self
primitiveWaitAcquire *is not a boolean, and can't be interrupted if it's a
boolean. It's nice to mark in a comment if part of the method's code has
not to be interrupted to avoid issues years later.
*But I want to know whether a non-local return could have an impact onthat
atomicity. For example ... self primitiveWaitAcquire ifTrue: [
^ mutuallyExclusiveBlock ensure: [self release]]*
In your code there is no non local return because ifTrue: is inlined by the
Bytecode compiler. Try to compile it and look at the bytecode you will see.
Else as I said at the beginning of the mail, a non local return can imply a
process switch if that was your question.
On Mon, Jun 6, 2016 at 2:46 PM, Ben Coman <btc(a)openinworld.com> wrote:
> I understand generally that an inlined #ifTrue is atomic. For
> example, here after the primitive returns, no interruption can occur
> before the #ensure is invoked...
> self primitiveWaitAcquire ifTrue:
> [mutuallyExclusiveBlock ensure: [self release]].
>
> But I want to know whether a non-local return could have an impact on
> that atomicity. For example ...
> self primitiveWaitAcquire ifTrue:
> [ ^ mutuallyExclusiveBlock ensure: [self release]]
>
> cheers -ben
>
>
June 6, 2016
Re: [Pharo-dev] From a mooc user: method source with it' take so long in Pharo 5
by Mariano Martinez Peck
Hi Henrik,
I use the "method source with it" quite frequently (mostly when I am
renaming methods or classes and I want to be sure those are not referenced
from methods and class comments and other cases) and so I would love some
speedup. Would you mind opening an issue in the issue tracker and
submitting an issue? Or at least sharing a .st ?
>From what I can imagine is simply the code you pasted plus some #initialize
that does "queue := SharedQueue new" ?
Thanks!
On Sun, Jun 5, 2016 at 8:52 AM, Henrik Nergaard <henrik.nergaard(a)uia.no>
wrote:
> *I like this approach, but it has a fatal flaw. If one is debugging file
> access, then as the debugger causes the source of methods to be fetched as
> the debugger displays them, so the file pointer in the read-only file the
> access of which one is trying to debug will change under one's feet, and
> the results will be completely wrong.*
>
> Ah yes, and trying to do something like:
>
> SourceFiles readStreamAtFileIndex: 2 atPosition: 42 ifPresent: [ :stream |
> Halt now ] ifAbsent: [ ]
>
> Crashes the image.
>
>
>
> Here is another approach using a SharedQueue which caches any created read
> only copies up to a limit (5?). So for normal usage the queue will only
> hold 1 entry, but if there is concurrent work reading source files it might
> hold more so one do not have to always create a read only copy, if the
> first one is in use.
>
>
>
> readStreamAtFileIndex: index atPosition: position ifPresent: presentBlock
> ifAbsent: absentBlock
>
>
>
> | stream rofa result |
>
>
>
> rofa := queue nextOrNil.
>
>
>
> rofa ifNil: [
>
> [ rofa := files collect: [ :f | f
> readOnlyCopy ] ]
>
> on: FileDoesNotExistException
>
> do: [ ^ absentBlock value ]
>
> ].
>
>
>
> stream := rofa at: index.
>
>
>
> position > stream size ifTrue: [ ^ absentBlock value ].
>
> stream position: position.
>
> result := presentBlock value: stream.
>
>
>
> queue size < 5
>
> ifTrue: [ queue nextPut: rofa ]
>
> ifFalse: [ rofa do: [ :each | each close ] ].
>
>
>
> ^ result
>
>
>
>
>
> Best regards,
>
> Henrik
>
>
>
>
>
> *From:* Pharo-dev [mailto:pharo-dev-bounces@lists.pharo.org] *On Behalf
> Of *Eliot Miranda
> *Sent:* Sunday, May 22, 2016 5:27 PM
> *To:* Pharo Development List <pharo-dev(a)lists.pharo.org>
> *Cc:* squeak-dev(a)lists.squeakfoundation.org
>
> *Subject:* Re: [Pharo-dev] From a mooc user: method source with it' take
> so long in Pharo 5
>
>
>
> Hi Henrik,
>
> cc'ing squeak-dev cuz this is relevant to both communities (if and
> until Pharo takes the unwise decision to double the size of the image by
> keeping sources in the image).
>
>
> On May 22, 2016, at 5:01 AM, Henrik Nergaard <henrik.nergaard(a)uia.no>
> wrote:
>
> There is a method in SourceFileArray
> #localProcessReadStreamAtFileIndex:atPosition:ifPresent:ifAbsent: which
> uses a ProccessLocalVariable called ProccessAndSessionLocalSourcesFileArray
> (see #localProcessReadOnlyCopy). Changing the last line in
> #readStreamAt:ifPresent:ifAbsent: to use this local process one makes the
> time to run this snippet:
>
>
>
> [ 1 systemNavigation browseMethodsWithSourceString: 'Morph' matchCase:
> false ] timeProfile
>
>
>
> From ~ 10 seconds to ~ 3 seconds (Windows).
>
>
>
> However I cannot see that the file handles created by this
> processLocalVariable to ever be closed, so I suspect those are leaked? In
> that case there might be the need to implement some âclean upâ mechanism
> for ProccessLocalVariables before they are changed/nilled when a process
> changes.
>
>
>
> Another approach could be to not use a ProccessLocalVariabe at all, but
> extend the SourceFilesArray class to also hold one read only handle for
> each of its files, and use these in readStreamAtFileIndex:::⦠. I guess
> that it is also necessary then to have semaphore protecting the two last
> lines such that setting the position in the stream and reading from it
> cannot be changed by other threads.
>
>
>
> I like this approach, but it has a fatal flaw. If one is debugging file
> access, then as the debugger causes the source of methods to be fetched as
> the debugger displays them, so the file pointer in the read-only file the
> access of which one is trying to debug will change under one's feet, and
> the results will be completely wrong.
>
>
>
> An approach which uses a special copy for the debugger doesn't work; one
> can't debug access to that file for the same reason.
>
>
>
> An approach that /should/ work is for the debugger to install its own copy
> around file-access. This should be recursive. So around every file access
> in the debugger there would need to be something like
>
>
>
> SourceFiles substituteFreshReadOnlyCopiesDuring: [...file access...]
>
>
>
> which would remember the current read-only files, evaluate the block using
> ensure: and have the ensure: block reinstall the previous file.
>
>
>
> Does this make sense?
>
>
>
>
>
> readStreamAtFileIndex: index atPosition: position ifPresent: presentBlock
> ifAbsent: absentBlock
>
>
>
> | stream result|
>
> stream := self readOnlyFileAt: index.
>
> stream ifNil: [ ^ absentBlock value ]. "sources file
> not available"
>
>
>
> position > stream size ifTrue: [ ^ absentBlock value ].
>
>
>
> readSema critical: [
>
> stream position: position.
>
> result := presentBlock value: stream
>
> ].
>
>
>
> ^ result
>
>
>
>
>
> Best regards,
>
> Henrik
>
>
>
>
>
> *From:* Pharo-dev [mailto:pharo-dev-bounces@lists.pharo.org
> <pharo-dev-bounces(a)lists.pharo.org>] *On Behalf Of *Nicolai Hess
> *Sent:* Thursday, May 19, 2016 9:31 AM
> *To:* Pharo Development List <pharo-dev(a)lists.pharo.org>
> *Subject:* Re: [Pharo-dev] From a mooc user: method source with it' take
> so long in Pharo 5
>
>
>
> Squeak caches the opened readonly file(handle). It does not have to reopen
> the file on every call for reading (readonly).
>
>
>
> 2016-05-18 19:12 GMT+02:00 stepharo <stepharo(a)free.fr>:
>
> I am wondering why does the search 'method source with it' take so long in
> Pharo 5? On my PC, When I select the text 'menu' and search for all 'method
> source with it', in Squeak 5 it takes 3 seconds. In Pharo 5 it takes 21
> seconds.
>
>
>
>
>
--
Mariano
http://marianopeck.wordpress.com
June 6, 2016
atomicity of non-local returns
by Ben Coman
I understand generally that an inlined #ifTrue is atomic. For
example, here after the primitive returns, no interruption can occur
before the #ensure is invoked...
self primitiveWaitAcquire ifTrue:
[mutuallyExclusiveBlock ensure: [self release]].
But I want to know whether a non-local return could have an impact on
that atomicity. For example ...
self primitiveWaitAcquire ifTrue:
[ ^ mutuallyExclusiveBlock ensure: [self release]]
cheers -ben
June 6, 2016