Hi Henry, On Wed, Aug 16, 2017 at 9:04 PM, henry <henry@callistohouse.club> wrote:
To let you know what I tried, trying to learn about this system as I dig into it, I added isInteger to the #blockedSelectors of NearERef. This crashed the squeak vm when I ran the test, and as I look into how blockedSelectors is used it smashes the resolver. What seems to be needed is a list of immediateSelectors, though that may grow to be a sizeable list. This causes me to think there must be a different approach between async and sync code.
Please wait until mustBeBooleanMagic: is fixed before you write this off. In Squeak what happens if you implement mustBeBoolean to resolve the promise?
- HH
-------- Original Message -------- Subject: Re: [Vm-dev] [Pharo-dev] eventual crashes pharo vm Local Time: August 16, 2017 11:46 PM UTC Time: August 17, 2017 3:46 AM From: henry@callistohouse.club To: Eliot Miranda <eliot.miranda@gmail.com> Squeak Virtual Machine Development Discussion <vm-dev@lists. squeakfoundation.org>, Pharo Development List <pharo-dev@lists.pharo.org>, Marcus Denker <marcus.denker@inria.fr>
Hi Eliot,
I have disabled that test for the time being. It will require some deeper thought regarding immediate selectors, I think, and I am deep into another area right now. As mustBeBoolean is from inside the VM, a different approach may be the right solution. A part of me thinks autocoercion between msg sending (async) and msg calling (sync) is what is needed, but I want continuation-based VatSemaphores to prevent a liveness lock on the event loop to support. Again, I have not thought deep enough in this area.
Thanks again for your help,
- HH
-------- Original Message -------- Subject: Re: [Pharo-dev] eventual crashes pharo vm Local Time: August 16, 2017 10:32 PM UTC Time: August 17, 2017 2:32 AM From: eliot.miranda@gmail.com To: henry <henry@callistohouse.club> Marcus Denker <marcus.denker@inria.fr>, Pharo Development List < pharo-dev@lists.pharo.org>, Squeak Virtual Machine Development Discussion <vm-dev@lists.squeakfoundation.org>
Hi Henry,
On Wed, Aug 16, 2017 at 6:33 PM, henry <henry@callistohouse.club> wrote:
That is good news, that it is due to this code doing funniness than a VM issue. This code trying to bring asynchrony within a synchronous environment brings new issues.
What do you think that right solution is to the issue of a call expected to be immediate, change out to go eventual until the arguments resolve?
I'm not informed enough to know. One could implement mustBeBoolean in the ERef hierarchy and resolve the promise before going on. One could rely on the mustBeBooleanMagic: if one wanted a fully lazy system. I don't know the trade-offs between the two. I do know that while the miustBeBooleanMagic: solution is cool and fun it is extremely slow. So if performance is an issue use the first approach.
How can it be structured correctly on the stack without generic functions? I think with the double dispatch of an eventual but I have not spend much time in this particular area.
Yes that's an issue There is already a problem with #==. It needs to be symmetric for correctness.
Preventing the vm from crashing would be a good interim step but even here I am not sure how to go about crafting a solution.
Well, the issue is simply that the wrong pc is chosen for the continuation after the mustBeBoolean. I'm sure the right answer is straight-forward to obtain.
Thank you for investigating this.
You're welcome.
- HH
On Wed, Aug 16, 2017 at 20:46, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Hi Henry, Hi Marcus,
On Sun, Aug 13, 2017 at 5:08 AM, henry <henry@callistohouse.club> wrote:
Hi all. I was testing with this eventual_test package and it blows up the
pharo 6.1 vm. I'd welcome pointers
http://www.squeaksource.com/TurquoiseTesting.html
- HH
I took a look at this and I think you've found a bug in the mustBeBooleanMagic: code. What's happening is a mustBeBoolean in Integer>>* due to evaluating 10 * 42 eventual in RefsTest>>testFailureArithmeticPrimitivesWithPromiseArgument
Since 42 eventual is a NearERef the SmallInteger>>* primitive fails and does ^super * anInteger (where anInteger is the NearERef). So that evaluates Integer>>*
Integer>>* aNumber "Refer to the comment in Number * " aNumber isInteger ifTrue: [^ self digitMultiply: aNumber neg: self negative ~~ aNumber negative]. ^ aNumber adaptToInteger: self andSend: #*
aNumber, being a NearERef, answers a PromiseERef for the isInteger send, and this provokes a mustBeBoolean for the isInteger ifTrue: [...
After the mustBeBooleanMagic: the stack looks wrong. The activation of Integer>>*, which is about to do ^ aNumber adaptToInteger: self andSend: #* does not have enough items on the stack. Instead of containing a NearERef (for 42) 10 #* it contains a PromiseERef (for 42 eventual isInteger)
and the send of #adaptToInteger:andSend: ends up taking more form the stack than the VM can handle and it crashes. The bug appears to be with the use of sendNode irInstruction nextBytecodeOffsetAfterJump in Object>>mustBeBooleanMagic: since execution should resume at bytecode 55 below, but does so at bytecode 57
41 <10> pushTemp: 0 42 <D0> send: isInteger 43 <AC 09> jumpFalse: 54 45 <70> self 46 <10> pushTemp: 0 47 <70> self 48 <D1> send: negative 49 <10> pushTemp: 0 50 <D1> send: negative 51 <E2> send: ~~ 52 <F3> send: digitMultiply:neg: 53 <7C> returnTop 54 <10> pushTemp: 0 55 <70> self 56 <24> pushConstant: #* 57 <F5> send: adaptToInteger:andSend: 58 <7C> returnTop
So the positioning of the context's pc must be before any argument marshaling for the next send, not simply the send itself.
Put a breakpoint at the end of Object>>mustBeBooleanMagic: and add initlaPC and resumePC temporaries at the beginning and capture them via initialPC := context pc. at the beginning and then context pc: (resumePC := sendNode irInstruction nextBytecodeOffsetAfterJump) to see what I'm seeing.
Phew. Glad it's not a VM bug :-)
HTH _,,,^..^,,,_ best, Eliot
-- _,,,^..^,,,_ best, Eliot
-- _,,,^..^,,,_ best, Eliot