Hi Folks,
There seems to be a problem in the validation of the number of arguments passed to #perform: (primitive 83, presumably also 84 and 100). I can reproduce the problem consistently in Cuis using OpenSmalltalk Mac x64 Cog Spur VMs. Tried releases from 2022-05 and 2022-06. Also tried build from 2022-11-21. I observe the same behavior on a fresh Squeak6.0-22104 Mac bundle from squeak.org.
To reproduce the problem, print the result of this snippet:
results := Bag new. n := 100. c := 0. n timesRepeat: [ "Smalltalk garbageCollect." b := [ 7 perform: #isDivisibleBy: ] on: Error do: [ #errorAsExpected ]. results add: b. b = #errorAsExpected ifFalse: [ c := c + 1 ]]. {c. 'failures out of'. n}
I get 98 or 99 failures out of 100. The results bag shows that the answer of #isDivisibleBy: without any argument is false (when the Error is not raised). Adding this line:
true ifTrue: [ ^ {self. aNumber} ].
to the the start of #isDivisibleBy: shows that the argument passed to the method is the #isDivisibleBy: symbol itself, i.e. the argument to #perform:.
As a last experiment, if I activate the call to garbage collection, it works as expected, the Error is always raised, and there are zero failures. So, whatever got broken, GC fixes it.
I don't know the related VM internals in enough detail to work this out. Can you please take a look?
Thanks!
Thanks Juan., Thanks Boris,
that was easy to fix. The JIT primitive simply forgot to check the the target method;'s argument count a bad oversight on my part. I think what you're seeing in your example is the JIT primitive falling back on the interpreter version the first time, because either GC has voided the method cache or the target method isn't yet jitted (cuz it's never been used). The interpreter version has always correctly checked the target method;'s argument count. I'll generate new sources soon.
On Mon, Dec 12, 2022 at 5:32 AM Juan Vuletich juan@cuis.st wrote:
Hi Folks,
There seems to be a problem in the validation of the number of arguments passed to #perform: (primitive 83, presumably also 84 and 100). I can reproduce the problem consistently in Cuis using OpenSmalltalk Mac x64 Cog Spur VMs. Tried releases from 2022-05 and 2022-06. Also tried build from 2022-11-21. I observe the same behavior on a fresh Squeak6.0-22104 Mac bundle from squeak.org.
To reproduce the problem, print the result of this snippet:
results := Bag new. n := 100. c := 0. n timesRepeat: [ "Smalltalk garbageCollect." b := [ 7 perform: #isDivisibleBy: ] on: Error do: [ #errorAsExpected ]. results add: b. b = #errorAsExpected ifFalse: [ c := c + 1 ]]. {c. 'failures out of'. n}
I get 98 or 99 failures out of 100. The results bag shows that the answer of #isDivisibleBy: without any argument is false (when the Error is not raised). Adding this line:
true ifTrue: [ ^ {self. aNumber} ].
to the the start of #isDivisibleBy: shows that the argument passed to the method is the #isDivisibleBy: symbol itself, i.e. the argument to #perform:.
As a last experiment, if I activate the call to garbage collection, it works as expected, the Error is always raised, and there are zero failures. So, whatever got broken, GC fixes it.
I don't know the related VM internals in enough detail to work this out. Can you please take a look?
Thanks!
-- Juan Vuletich cuis.st github.com/jvuletich researchgate.net/profile/Juan-Vuletich independent.academia.edu/JuanVuletich patents.justia.com/inventor/juan-manuel-vuletich linkedin.com/in/juan-vuletich-75611b3 twitter.com/JuanVuletich
Thanks a lot Eliot!
Cheers,
On 12/12/2022 2:40 PM, Eliot Miranda wrote:
Thanks Juan., Thanks Boris,
that was easy to fix. The JIT primitive simply forgot to check
the the target method;'s argument count a bad oversight on my part. I think what you're seeing in your example is the JIT primitive falling back on the interpreter version the first time, because either GC has voided the method cache or the target method isn't yet jitted (cuz it's never been used). The interpreter version has always correctly checked the target method;'s argument count. I'll generate new sources soon.
On Mon, Dec 12, 2022 at 5:32 AM Juan Vuletich <juan@cuis.st mailto:juan@cuis.st> wrote:
Hi Folks, There seems to be a problem in the validation of the number of arguments passed to #perform: (primitive 83, presumably also 84 and 100). I can reproduce the problem consistently in Cuis using OpenSmalltalk Mac x64 Cog Spur VMs. Tried releases from 2022-05 and 2022-06. Also tried build from 2022-11-21. I observe the same behavior on a fresh Squeak6.0-22104 Mac bundle from squeak.org <http://squeak.org>. To reproduce the problem, print the result of this snippet: results := Bag new. n := 100. c := 0. n timesRepeat: [ "Smalltalk garbageCollect." b := [ 7 perform: #isDivisibleBy: ] on: Error do: [ #errorAsExpected ]. results add: b. b = #errorAsExpected ifFalse: [ c := c + 1 ]]. {c. 'failures out of'. n} I get 98 or 99 failures out of 100. The results bag shows that the answer of #isDivisibleBy: without any argument is false (when the Error is not raised). Adding this line: true ifTrue: [ ^ {self. aNumber} ]. to the the start of #isDivisibleBy: shows that the argument passed to the method is the #isDivisibleBy: symbol itself, i.e. the argument to #perform:. As a last experiment, if I activate the call to garbage collection, it works as expected, the Error is always raised, and there are zero failures. So, whatever got broken, GC fixes it. I don't know the related VM internals in enough detail to work this out. Can you please take a look? Thanks! -- Juan Vuletich cuis.st <http://cuis.st> github.com/jvuletich <http://github.com/jvuletich> researchgate.net/profile/Juan-Vuletich <http://researchgate.net/profile/Juan-Vuletich> independent.academia.edu/JuanVuletich <http://independent.academia.edu/JuanVuletich> patents.justia.com/inventor/juan-manuel-vuletich <http://patents.justia.com/inventor/juan-manuel-vuletich> linkedin.com/in/juan-vuletich-75611b3 <http://linkedin.com/in/juan-vuletich-75611b3> twitter.com/JuanVuletich <http://twitter.com/JuanVuletich>
-- _,,,^..^,,,_ best, Eliot
I built the latest VM and now everything works. Thank you so much Eliot!!
*Huge sigh of relief* When I first came across this problem, for a moment I was very scared that it might be just the tip-of-the-iceberg of some much larger problem (because in my test scenario the behavior seemed to correlate with whether or not an outer context has materialized, and *that* part is insanely complex). I am really happy that it's much simpler than I feared (in fact the diff is easy to understand and makes perfectly straightforward sense). Thanks again!
On 12/12/22 12:40, Eliot Miranda wrote:
Thanks Juan., Thanks Boris,
that was easy to fix. The JIT primitive simply forgot to check the the target method;'s argument count a bad oversight on my part. I think what you're seeing in your example is the JIT primitive falling back on the interpreter version the first time, because either GC has voided the method cache or the target method isn't yet jitted (cuz it's never been used). The interpreter version has always correctly checked the target method;'s argument count. I'll generate new sources soon.
On Mon, Dec 12, 2022 at 5:32 AM Juan Vuletich juan@cuis.st wrote:
Hi Folks, There seems to be a problem in the validation of the number of arguments passed to #perform: (primitive 83, presumably also 84 and 100). I can reproduce the problem consistently in Cuis using OpenSmalltalk Mac x64 Cog Spur VMs. Tried releases from 2022-05 and 2022-06. Also tried build from 2022-11-21. I observe the same behavior on a fresh Squeak6.0-22104 Mac bundle from squeak.org <http://squeak.org>. To reproduce the problem, print the result of this snippet: results := Bag new. n := 100. c := 0. n timesRepeat: [ "Smalltalk garbageCollect." b := [ 7 perform: #isDivisibleBy: ] on: Error do: [ #errorAsExpected ]. results add: b. b = #errorAsExpected ifFalse: [ c := c + 1 ]]. {c. 'failures out of'. n} I get 98 or 99 failures out of 100. The results bag shows that the answer of #isDivisibleBy: without any argument is false (when the Error is not raised). Adding this line: true ifTrue: [ ^ {self. aNumber} ]. to the the start of #isDivisibleBy: shows that the argument passed to the method is the #isDivisibleBy: symbol itself, i.e. the argument to #perform:. As a last experiment, if I activate the call to garbage collection, it works as expected, the Error is always raised, and there are zero failures. So, whatever got broken, GC fixes it. I don't know the related VM internals in enough detail to work this out. Can you please take a look? Thanks! -- Juan Vuletich cuis.st <http://cuis.st> github.com/jvuletich <http://github.com/jvuletich> researchgate.net/profile/Juan-Vuletich <http://researchgate.net/profile/Juan-Vuletich> independent.academia.edu/JuanVuletich <http://independent.academia.edu/JuanVuletich> patents.justia.com/inventor/juan-manuel-vuletich <http://patents.justia.com/inventor/juan-manuel-vuletich> linkedin.com/in/juan-vuletich-75611b3 <http://linkedin.com/in/juan-vuletich-75611b3> twitter.com/JuanVuletich <http://twitter.com/JuanVuletich>
-- _,,,^..^,,,_ best, Eliot
vm-dev@lists.squeakfoundation.org