From eliot.miranda at gmail.com Fri Jan 2 04:28:31 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 2 04:28:39 2015 Subject: [squeak-dev] New Cog VMs available Message-ID: ...at http://www.mirandabanda.org/files/Cog/VM/VM.r3205/. Happy New Year! CogVM source as per VMMaker.oscog-eem.1008/r3205 Send cannotReturn for sideways return attemps when there's an unwind-protect. Old code would erroneously answer unwind-protect even if home could'nt be found. e.g. This should raise cannot return: | b | b := [ ^ 42 ]. [ [b value] ensure: [1] ] fork. Processor yield just as this does: | b | b := [ ^ 42 ]. [ b value ] fork. Processor yield Speed up non-local return processing by using the fact that 98% of the time returns are within the same page. The search for the home context following finding an unwind is unnecessary iff the home is married and on the same page. Refactor commonReturn to eiminate CoInterpreter's version, moving the divergence into maybeReturnToMachineCodeFrame. Ensure search for home through the block's closure uses followField:ofObject:. (related) Revisit the Sista bug fix for followed contexts during scavenging in VMMaker.oscog-eem.913 of 24 October 2014. Split isWidowedContext: into a more careful version, isWidowedContextDuringGC: for use only during scavenging. Win32: Nuke obsolete RCS vrsion info Spur: Fix argument count slips in three primitives. Check for sufficient memory in two-way become. All: Fix checking of boolean arg in primitiveArrayBecomeOneWayCopyHash. Make primitiveSlotAt[Put] cope with non-pointer objects. Change the pixel-touch-pixel prim to allow LPI arguments for the color values Update the ScratchPlugin bilinear scaling prim to include the correct alpha channel value for non-transparent output pixels. No longer build or upload the Newspeak V3 VMs, now superseded by Spur. Use the gcc/clang built-ins for CAS and atomic increment if available. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150101/cf714ce5/attachment.htm From brasspen at gmail.com Fri Jan 2 05:23:15 2015 From: brasspen at gmail.com (Chris Cunnington) Date: Fri Jan 2 05:23:24 2015 Subject: [squeak-dev] New Cog VMs available In-Reply-To: References: Message-ID: <19E30DC3-5E83-4005-8BAB-9B058D8E0EC5@gmail.com> Happy New Year, Eliot, I?m wondering if I can ask you a question? Owing to my ignorance, it may seem odd. Here it is: How long has it been since you re-compiled the socket plugin sources? I figure it?s been more than six months. The confusion I have is that netstyle.ch asked you to make a change to the Cog sources, which you did. [1] Now, to me, this suggests to me that every subsequent Linux Cog vm in mirandaband would have the systemd capability they asked for. But that?s not my experience. See, the SVN sources have what I want, but I have the impression that your binaries do not. The reason I can infer anything about your compilation process is that I added the netstyle.ch diff file [2] and compiled my own interpreter vm. And it works on my Ubuntu laptop. Just like the netstyle.ch video. So i thought to myself: ?How could it be that there?s a difference between the Cog sources and the vm binaries at mirandabanda?? And I figured it was that you don't recompile everything every time you make a change. You probably have an army of foo.o object files sitting unchanged for long periods of time. And netstyle.ch being netstyle.ch they can compile their own Cog vm, which they probably have done. So, again, how long has it been since you re-compiled the plugin sources? Any answer you could give to this question will no doubt prove extremely illuminating to me. Thanks in advance, Chris [1] ProvidedTCPSocketType http://squeakvm.org/cgi-bin/viewvc.cgi/squeak/branches/Cog/platforms/unix/plugins/SocketPlugin/sqUnixSocket.c?revision=3040&view=markup [2] http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-July/179015.html > On Jan 1, 2015, at 11:28 PM, Eliot Miranda wrote: > > ...at http://www.mirandabanda.org/files/Cog/VM/VM.r3205/ . > > Happy New Year! > > CogVM source as per VMMaker.oscog-eem.1008/r3205 > > Send cannotReturn for sideways return attemps when there's an unwind-protect. > Old code would erroneously answer unwind-protect even if home could'nt be found. > > e.g. This should raise cannot return: > > | b | > b := [ ^ 42 ]. > [ [b value] ensure: [1] ] fork. > Processor yield > > just as this does: > > | b | > b := [ ^ 42 ]. > [ b value ] fork. > Processor yield > > Speed up non-local return processing by using the fact that 98% of the time > returns are within the same page. The search for the home context following > finding an unwind is unnecessary iff the home is married and on the same page. > > Refactor commonReturn to eiminate CoInterpreter's version, moving the > divergence into maybeReturnToMachineCodeFrame. > > Ensure search for home through the block's closure uses followField:ofObject:. > > (related) Revisit the Sista bug fix for followed contexts during scavenging in > VMMaker.oscog-eem.913 of 24 October 2014. Split isWidowedContext: into a more > careful version, isWidowedContextDuringGC: for use only during scavenging. > > Win32: > Nuke obsolete RCS vrsion info > > Spur: > Fix argument count slips in three primitives. > Check for sufficient memory in two-way become. > > All: > Fix checking of boolean arg in primitiveArrayBecomeOneWayCopyHash. > > Make primitiveSlotAt[Put] cope with non-pointer objects. > > Change the pixel-touch-pixel prim to allow LPI arguments for the color values > > Update the ScratchPlugin bilinear scaling prim to include the correct alpha channel value for non-transparent output pixels. > > No longer build or upload the Newspeak V3 VMs, now superseded by Spur. > > Use the gcc/clang built-ins for CAS and atomic increment if available. > > -- > best, > Eliot > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150102/910ae4cb/attachment.htm From trygver at ifi.uio.no Fri Jan 2 11:01:24 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Fri Jan 2 11:01:32 2015 Subject: [squeak-dev] A puzzle for the New Year Message-ID: <54A67A84.9080903@ifi.uio.no> Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: Collaboration-[1224] BB5aMoneyTransferContext # BB5aMoneyTransferContext class.1.gif Type: image/gif Size: 20429 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150102/23036290/Collaboration-1224BB5aMoneyTransferContextBB5aMoneyTransferContextclass.1.gif From Lou at Keystone-Software.com Wed Jan 7 14:39:15 2015 From: Lou at Keystone-Software.com (Louis LaBrunda) Date: Wed Jan 7 16:14:16 2015 Subject: [squeak-dev] test Message-ID: Hi Everyone, Happy New Year! Sorry for the noise of this test but I haven't seen any posts to this news group since 1/2/2015. In fact I haven't seen any posts since then for any of the seven Smalltalk news groups that I follow. That is odd. Because there aren't any posts for any of the news groups it would seem that the problem is on my end but I don't see any errors when I try retrieve new post headers. It just says there is nothing new. I'm using the latest version of Forte Agent (a combination news group reader and email client). Hopefully this post will show up. If anyone sees it and has any idea what is going on, please let me know. Thanks for your time. Lou ----------------------------------------------------------- Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon mailto:Lou@Keystone-Software.com http://www.Keystone-Software.com From Das.Linux at gmx.de Wed Jan 7 14:12:13 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 7 16:14:18 2015 Subject: [squeak-dev] Test Message-ID: Please regard this mail :D Best -Tobias From lewis at mail.msen.com Fri Jan 2 16:07:22 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed Jan 7 16:14:24 2015 Subject: [squeak-dev] A puzzle for the New Year In-Reply-To: <54A67A84.9080903@ifi.uio.no> References: <54A67A84.9080903@ifi.uio.no> Message-ID: <20150102160722.GA33093@shell.msen.com> On Fri, Jan 02, 2015 at 12:01:24PM +0100, Trygve Reenskaug wrote: > Hi, > I had to dive into the deeper regions of Smalltalk when I was preparing > BabyIDE for Monticello. I needed to specialize a class /fileOut /method: > > BB5aMoneyTransferContext>>fileOutOn: aFileStream moveSource: > moveSource toFile: fileIndex initializing: aBool > super fileOutOn: aFileStream moveSource: moveSource toFile: > fileIndex initializing: aBool. > > > This works, but the /fileOutOn:moveSource:toFile:initializing:/-method > is defined in class /Class/ which is not a superclass of > /BB5aMoneyTransferContext/. So /super /does not refer to the superclass! > What's going on? > -------------------------------------------------- > There are two essential object structures in Smalltalk: The > instantiation tree and the class inheritance tree. They are independent > but intertwined as described in chapter 16 of the Blue Book. It's pretty > complicated in the general but fairly obvious in this concrete example. > > Smalltalk is all about objects, not classes. I used my /Smalltalk > Reverse Engineering (SRE)/ tool and produced the attached object > diagram. The notation in the diagram is > > * a rectangle represents an object > * the object's name is [] : > * a line represents a link. An 'instanceOf' relationship is marked > //self class/; an inheritance relationship is marked /superclass/. > > The diagram shows that the answer to the puzzle is one 'instaceOf' > relationship followed by four 'superclass' relationships. The departure > from the usual is that while most class objects are instances of their > own Metaclass. ProtoObject is an exception. It has no superclass, but > its metaclass has. It is class Class. Add to this that when an object > receives a message, it goes to its class to find the corresponding > method. [1224]:MoneyTransferContext receives the super fileout message. > The VM goes to the superclass of its class, [3253]:Metaclass and looks > for the required method in its methodDict. It doesn't find it and > continues up the superclass chain until it finds it in [1254]:Class > class . Straight forward, isn't it. > > I hope you enjoy this dive into the innards of Smalltalk and wish you > all A Happy New Year! > --Trygve Very nice illustration. It's interesting that you were able to generate the diagram automatically and produce a very clear diagram to show the relationships. Dave From Das.Linux at gmx.de Wed Jan 7 14:36:30 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 7 16:14:26 2015 Subject: [squeak-dev] Test 1536 Message-ID: Please regard this mail :D Best -Tobias From Das.Linux at gmx.de Wed Jan 7 14:33:04 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 7 16:17:57 2015 Subject: [squeak-dev] Test Message-ID: <8BA159BD-CE84-4749-85D1-47F600CA421C@gmx.de> Please regard this mail :D Best -Tobias From Das.Linux at gmx.de Wed Jan 7 14:34:11 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 7 16:18:56 2015 Subject: [squeak-dev] Test 1534 Message-ID: Please regard this mail :D Best -Tobias From Das.Linux at gmx.de Wed Jan 7 16:28:12 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 7 16:28:14 2015 Subject: [squeak-dev] Test 1728 Message-ID: <3AF64A61-B2A8-4DEE-A6A8-80AD58EB978B@gmx.de> Please regard this mail :D Best -Tobias From edgardec2005 at gmail.com Wed Jan 7 16:30:19 2015 From: edgardec2005 at gmail.com (Edgar De Cleene) Date: Wed Jan 7 16:30:24 2015 Subject: [squeak-dev] JavaScript y archivos externos Message-ID: Esta ma?ana con @garduino en Slack estuvimos hablando de esto. Este tutorial es muy bueno http://www.html5rocks.com/es/tutorials/file/dndfiles/ Todavia no pude crear archivos desde JavaScript. Supongo que el Adelantado Lopez sabe... -- Edgar De Cleene @morplenauta en twitter Sent with Sparrow (http://www.sparrowmailapp.com/?sig) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/06ee78ae/attachment.html From Das.Linux at gmx.de Wed Jan 7 16:38:24 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 7 16:38:27 2015 Subject: [squeak-dev] Test 1738 Message-ID: Please regard this mail :D Best -Tobias From Das.Linux at gmx.de Wed Jan 7 16:39:54 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 7 16:39:57 2015 Subject: [squeak-dev] Test 1739 Message-ID: Please regard this mail :D Best -Tobias From brasspen at gmail.com Wed Jan 7 16:42:59 2015 From: brasspen at gmail.com (Chris Cunnington) Date: Wed Jan 7 16:43:00 2015 Subject: [squeak-dev] Test 1728 In-Reply-To: <3AF64A61-B2A8-4DEE-A6A8-80AD58EB978B@gmx.de> References: <3AF64A61-B2A8-4DEE-A6A8-80AD58EB978B@gmx.de> Message-ID: I for one welcome the arrival of our robot overlords. Chris On Wed, Jan 7, 2015 at 11:28 AM, Tobias Pape wrote: > Please regard this mail :D > Best > -Tobias > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/ff67eb89/attachment.html From brasspen at gmail.com Wed Jan 7 16:43:40 2015 From: brasspen at gmail.com (Chris Cunnington) Date: Wed Jan 7 16:43:43 2015 Subject: [squeak-dev] Test 1536 In-Reply-To: References: Message-ID: I for one welcome the arrival of our robot overlords. Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/3130a258/attachment.htm From edgardec2005 at gmail.com Wed Jan 7 07:55:24 2015 From: edgardec2005 at gmail.com (Edgar De Cleene) Date: Wed Jan 7 17:00:37 2015 Subject: [squeak-dev] http://source.squeak.org/ is down? Message-ID: <19879CE2680640978F80D18D73C4B237@gmail.com> Folks: Seems 2015 do not start well. Can?t conect to http://source.squeak.org -- Edgar De Cleene @morplenauta en twitter -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/25c87629/attachment.htm From trygver at ifi.uio.no Wed Jan 7 09:51:40 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Wed Jan 7 17:02:36 2015 Subject: [squeak-dev] SqueakMap master servers down. Message-ID: <54AD01AC.8060203@ifi.uio.no> MCConfigurationBrowser>>Update gives error: 'Error occurred when updating map: All SqueakMap master servers are down: ''map.squeak.org'' ''map1.squeakfoundation.org'' ''map2.squeakfoundation.org'' ''127.0.0.1:8080'' Can not update SqueakMap... Would you like to open a debugger?' -- Trygve Reenskaug mailto: trygver@ifi.uio.no Morgedalsvn. 5A http://folk.uio.no/trygver/ N-0378 Oslo http://fullOO.info Norway Tel: (+47) 22 49 57 27 Save our in-boxes!/http://emailcharter.org// -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/856c7bd1/attachment.htm From leves at elte.hu Wed Jan 7 17:05:05 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed Jan 7 17:05:14 2015 Subject: [squeak-dev] http://source.squeak.org/ is down? In-Reply-To: <19879CE2680640978F80D18D73C4B237@gmail.com> References: <19879CE2680640978F80D18D73C4B237@gmail.com> Message-ID: It's because it hasn't been restored yet. http://squeakboard.wordpress.com/2015/01/05/squeak-org-server-outage/ Levente On Wed, 7 Jan 2015, Edgar De Cleene wrote: > Folks: > Seems 2015 do not?start well. > Can?t conect to?http://source.squeak.org > --? > Edgar De Cleene > @morplenauta en twitter > > > > From edgardec2005 at gmail.com Wed Jan 7 17:11:41 2015 From: edgardec2005 at gmail.com (Edgar De Cleene) Date: Wed Jan 7 17:11:47 2015 Subject: [squeak-dev] http://source.squeak.org/ is down? In-Reply-To: References: <19879CE2680640978F80D18D73C4B237@gmail.com> Message-ID: <120E870D67334CCBB5782E1E2DF28AE7@gmail.com> On Wednesday, January 7, 2015 at 2:05 PM, Levente Uzonyi wrote: > It's because it hasn't been restored yet. > http://squeakboard.wordpress.com/2015/01/05/squeak-org-server-outage/ > > Levente Ok. I hope all squeak works again ASAP -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/372aa895/attachment.htm From nicolas.cellier.aka.nice at gmail.com Wed Jan 7 17:25:12 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 7 17:25:15 2015 Subject: Fwd: [squeak-dev] A puzzle for the New Year In-Reply-To: References: <54A67A84.9080903@ifi.uio.no> Message-ID: ---------- Forwarded message ---------- From: Nicolas Cellier Date: 2015-01-04 11:30 GMT+01:00 Subject: Re: [squeak-dev] A puzzle for the New Year To: The general-purpose Squeak developers list < squeak-dev@lists.squeakfoundation.org> Ah, you mean like http://stackoverflow.com/questions/27386061/overriding-compile-method-in-squeak/27413079#27413079 A picture is worth a few dozen of words indeed. I'm pretty sure I saw a browser showing the whole metaclass hierarchy in the past which also might be helpfull to better understand these corners, but I just don't remember where exactly (st-80 v2.3?). 2015-01-02 12:01 GMT+01:00 Trygve Reenskaug : > Hi, > I had to dive into the deeper regions of Smalltalk when I was preparing > BabyIDE for Monticello. I needed to specialize a class *fileOut *method: > > BB5aMoneyTransferContext>>fileOutOn: aFileStream moveSource: moveSource > toFile: fileIndex initializing: aBool > super fileOutOn: aFileStream moveSource: moveSource toFile: fileIndex > initializing: aBool. > > > This works, but the *fileOutOn:moveSource:toFile:initializing:*-method is > defined in class *Class* which is not a superclass of > *BB5aMoneyTransferContext*. So *super *does not refer to the superclass! > What's going on? > -------------------------------------------------- > There are two essential object structures in Smalltalk: The instantiation > tree and the class inheritance tree. They are independent but intertwined > as described in chapter 16 of the Blue Book. It's pretty complicated in the > general but fairly obvious in this concrete example. > > Smalltalk is all about objects, not classes. I used my *Smalltalk > Reverse Engineering (SRE)* tool and produced the attached object diagram. > The notation in the diagram is > > - a rectangle represents an object > - the object's name is [] : > - a line represents a link. An 'instanceOf' relationship is marked */self > class*; an inheritance relationship is marked *superclass*. > > The diagram shows that the answer to the puzzle is one 'instaceOf' > relationship followed by four 'superclass' relationships. The departure > from the usual is that while most class objects are instances of their own > Metaclass. ProtoObject is an exception. It has no superclass, but its > metaclass has. It is class Class. Add to this that when an object receives > a message, it goes to its class to find the corresponding method. > [1224]:MoneyTransferContext receives the super fileout message. The VM > goes to the superclass of its class, [3253]:Metaclass and looks for the > required method in its methodDict. It doesn't find it and continues up the > superclass chain until it finds it in [1254]:Class class . Straight > forward, isn't it. > > I hope you enjoy this dive into the innards of Smalltalk and wish you all > A Happy New Year! > --Trygve > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/9281518e/attachment.htm From Das.Linux at gmx.de Wed Jan 7 17:27:17 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 7 17:27:20 2015 Subject: [squeak-dev] Test 1728 In-Reply-To: References: <3AF64A61-B2A8-4DEE-A6A8-80AD58EB978B@gmx.de> Message-ID: <6D2D5864-5173-4A6F-BB3A-7BC2E63385DD@gmx.de> On 07.01.2015, at 17:42, Chris Cunnington wrote: > I for one welcome the arrival of our robot overlords. > :( I failed the turing test? > Chris > > On Wed, Jan 7, 2015 at 11:28 AM, Tobias Pape wrote: > Please regard this mail :D > Best > -Tobias From nicolas.cellier.aka.nice at gmail.com Wed Jan 7 17:27:29 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 7 17:27:32 2015 Subject: [squeak-dev] A puzzle for the New Year In-Reply-To: References: <54A67A84.9080903@ifi.uio.no> Message-ID: 2015-01-07 18:25 GMT+01:00 Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com>: > > ---------- Forwarded message ---------- > From: Nicolas Cellier > Date: 2015-01-04 11:30 GMT+01:00 > Subject: Re: [squeak-dev] A puzzle for the New Year > To: The general-purpose Squeak developers list < > squeak-dev@lists.squeakfoundation.org> > > > Ah, you mean like > http://stackoverflow.com/questions/27386061/overriding-compile-method-in-squeak/27413079#27413079 > > A picture is worth a few dozen of words indeed. > > I'm pretty sure I saw a browser showing the whole metaclass hierarchy in > the past which also might be helpfull to better understand these corners, > but I just don't remember where exactly (st-80 v2.3?). > Oh I just see it now, still there in Squeak trunk after all these years!!! Select a class, select the class side button, and operate the pop up menu 'show hierarchy'. It's not as powerfull as a Hierarchybrowser, but is already someting. > > 2015-01-02 12:01 GMT+01:00 Trygve Reenskaug : > >> Hi, >> I had to dive into the deeper regions of Smalltalk when I was preparing >> BabyIDE for Monticello. I needed to specialize a class *fileOut *method: >> >> BB5aMoneyTransferContext>>fileOutOn: aFileStream moveSource: moveSource >> toFile: fileIndex initializing: aBool >> super fileOutOn: aFileStream moveSource: moveSource toFile: fileIndex >> initializing: aBool. >> >> >> This works, but the *fileOutOn:moveSource:toFile:initializing:*-method >> is defined in class *Class* which is not a superclass of >> *BB5aMoneyTransferContext*. So *super *does not refer to the superclass! >> What's going on? >> -------------------------------------------------- >> There are two essential object structures in Smalltalk: The instantiation >> tree and the class inheritance tree. They are independent but intertwined >> as described in chapter 16 of the Blue Book. It's pretty complicated in the >> general but fairly obvious in this concrete example. >> >> Smalltalk is all about objects, not classes. I used my *Smalltalk >> Reverse Engineering (SRE)* tool and produced the attached object >> diagram. The notation in the diagram is >> >> - a rectangle represents an object >> - the object's name is [] : >> - a line represents a link. An 'instanceOf' relationship is marked */self >> class*; an inheritance relationship is marked *superclass*. >> >> The diagram shows that the answer to the puzzle is one 'instaceOf' >> relationship followed by four 'superclass' relationships. The departure >> from the usual is that while most class objects are instances of their own >> Metaclass. ProtoObject is an exception. It has no superclass, but its >> metaclass has. It is class Class. Add to this that when an object receives >> a message, it goes to its class to find the corresponding method. >> [1224]:MoneyTransferContext receives the super fileout message. The VM >> goes to the superclass of its class, [3253]:Metaclass and looks for the >> required method in its methodDict. It doesn't find it and continues up the >> superclass chain until it finds it in [1254]:Class class . Straight >> forward, isn't it. >> >> I hope you enjoy this dive into the innards of Smalltalk and wish you all >> A Happy New Year! >> --Trygve >> >> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/ea226758/attachment.htm From nicolas.cellier.aka.nice at gmail.com Wed Jan 7 17:28:33 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 7 17:28:35 2015 Subject: [squeak-dev] Fwd: Process scheduling question In-Reply-To: References: Message-ID: ---------- Forwarded message ---------- From: Nicolas Cellier Date: 2015-01-02 21:16 GMT+01:00 Subject: Process scheduling question To: The general-purpose Squeak developers list < squeak-dev@lists.squeakfoundation.org> Interestingly, using Transcript in Processes in Squeak/Pharo make them behave as if the scheduler was preemptive, which it is not. http://stackoverflow.com/questions/27731274/smalltalk-visual-works-concurrency So there must be some sort of wait on a busy Semaphore, but where? I failed to find it... -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/dd00b7d6/attachment.htm From brasspen at gmail.com Wed Jan 7 18:00:30 2015 From: brasspen at gmail.com (Chris Cunnington) Date: Wed Jan 7 18:00:39 2015 Subject: [squeak-dev] Test 1728 In-Reply-To: <6D2D5864-5173-4A6F-BB3A-7BC2E63385DD@gmx.de> References: <3AF64A61-B2A8-4DEE-A6A8-80AD58EB978B@gmx.de> <6D2D5864-5173-4A6F-BB3A-7BC2E63385DD@gmx.de> Message-ID: <4C719050-E056-45B9-9D96-A5E275484367@gmail.com> You passed flying colours. qmail on box4 looks great. I?m sure our robot overlords will be impressed. Chris > On Jan 7, 2015, at 12:27 PM, Tobias Pape wrote: > > > On 07.01.2015, at 17:42, Chris Cunnington wrote: > >> I for one welcome the arrival of our robot overlords. >> > > :( I failed the turing test? > >> Chris >> >> On Wed, Jan 7, 2015 at 11:28 AM, Tobias Pape wrote: >> Please regard this mail :D >> Best >> -Tobias > > > From leves at elte.hu Wed Jan 7 18:33:54 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed Jan 7 18:33:58 2015 Subject: [squeak-dev] Fwd: Process scheduling question In-Reply-To: References: Message-ID: Transcript >> #endEntry uses the AccessSema semaphore. That method is sent from #show:. Levente On Wed, 7 Jan 2015, Nicolas Cellier wrote: > > ---------- Forwarded message ---------- > From: Nicolas Cellier > Date: 2015-01-02 21:16 GMT+01:00 > Subject: Process scheduling question > To: The general-purpose Squeak developers list > > > Interestingly, using Transcript in Processes in Squeak/Pharo make them behave as if the scheduler was preemptive, which it is not. > > http://stackoverflow.com/questions/27731274/smalltalk-visual-works-concurrency > > So there must be some sort of wait on a busy Semaphore, but where? > I failed to find it... > > > > > From javier_diaz_r at mac.com Tue Jan 6 20:31:26 2015 From: javier_diaz_r at mac.com (Javier Diaz-Reinoso) Date: Wed Jan 7 21:32:05 2015 Subject: [squeak-dev] New year mac cog VM bug? Message-ID: I try open an image (4.4) today, when I try to browse Collection, for example, fails with the error 'RemoteString past end of file', this error is because the VM (Cog 4.0.3205 but also older versions) is not recognizing an (mac) alias to the file SqueakV41.sources, if I change the alias for the file or a unix soft link then all works OK. The strange thing is that I'm sure this worked on December 31, maybe this fail because the change from year? From nicolas.cellier.aka.nice at gmail.com Wed Jan 7 21:37:51 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 7 21:37:53 2015 Subject: [squeak-dev] Fwd: Process scheduling question In-Reply-To: References: Message-ID: Right, but is there a concurrent use of this semaphore? I mean the active process will acquire AccessSema again and again until it give up control. A process of same priority cannot take control and concurrently preempt AccessSema until then. The active process will give up control if 1) it explicitely yield (not that many senders) 2) or if a higher priority process take possession of AccessSema. AccessSema is only used by endEntry, so it would mean a higher priority proess is transcripting. 3) or if the acquisition of another semaphore is blocked... I failed to find occurences of 1) and 2) so I was tempted by explanation 3) but also failed to find it... Case of blindness? 2015-01-07 19:33 GMT+01:00 Levente Uzonyi : > Transcript >> #endEntry uses the AccessSema semaphore. That method is sent > from #show:. > > Levente > > > On Wed, 7 Jan 2015, Nicolas Cellier wrote: > > >> ---------- Forwarded message ---------- >> From: Nicolas Cellier >> Date: 2015-01-02 21:16 GMT+01:00 >> Subject: Process scheduling question >> To: The general-purpose Squeak developers list > squeakfoundation.org> >> >> >> Interestingly, using Transcript in Processes in Squeak/Pharo make them >> behave as if the scheduler was preemptive, which it is not. >> >> http://stackoverflow.com/questions/27731274/smalltalk- >> visual-works-concurrency >> >> So there must be some sort of wait on a busy Semaphore, but where? >> I failed to find it... >> >> >> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/ed567e63/attachment.htm From eliot.miranda at gmail.com Wed Jan 7 21:43:59 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed Jan 7 21:44:02 2015 Subject: [squeak-dev] New year mac cog VM bug? In-Reply-To: References: Message-ID: On Tue, Jan 6, 2015 at 12:31 PM, Javier Diaz-Reinoso wrote: > I try open an image (4.4) today, when I try to browse Collection, for > example, fails with the error 'RemoteString past end of file', this error > is because the VM (Cog 4.0.3205 but also older versions) is not recognizing > an (mac) alias to the file SqueakV41.sources, if I change the alias for the > file or a unix soft link then all works OK. > > The strange thing is that I'm sure this worked on December 31, maybe this > fail because the change from year? > Thanks, Javier. I must have broken this in my recent changes. I'll fix it asap. Thanks for the report! -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150107/9762e9cf/attachment.htm From nicolas.cellier.aka.nice at gmail.com Wed Jan 7 23:23:42 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 7 23:23:44 2015 Subject: [squeak-dev] Fwd: Process scheduling question In-Reply-To: References: Message-ID: And if you perform endEntry job outside of AccessSema critical:section, then there is still a concurrent write of AA and BB, until some process will bug with an inconsistent state mutation and a hardly recoverable error... So, there is an inversion : AccessSema does not cause concurrency. AccessSema is there to protect from concurrency that happens elsewhere and would cause unconsistent state mutations... 2015-01-07 22:37 GMT+01:00 Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com>: > Right, but is there a concurrent use of this semaphore? > I mean the active process will acquire AccessSema again and again until it > give up control. > A process of same priority cannot take control and concurrently preempt > AccessSema until then. > The active process will give up control if > 1) it explicitely yield (not that many senders) > 2) or if a higher priority process take possession of AccessSema. > AccessSema is only used by endEntry, so it would mean a higher priority > proess is transcripting. > 3) or if the acquisition of another semaphore is blocked... > > I failed to find occurences of 1) and 2) so I was tempted by explanation > 3) but also failed to find it... > Case of blindness? > > 2015-01-07 19:33 GMT+01:00 Levente Uzonyi : > >> Transcript >> #endEntry uses the AccessSema semaphore. That method is >> sent from #show:. >> >> Levente >> >> >> On Wed, 7 Jan 2015, Nicolas Cellier wrote: >> >> >>> ---------- Forwarded message ---------- >>> From: Nicolas Cellier >>> Date: 2015-01-02 21:16 GMT+01:00 >>> Subject: Process scheduling question >>> To: The general-purpose Squeak developers list >> squeakfoundation.org> >>> >>> >>> Interestingly, using Transcript in Processes in Squeak/Pharo make them >>> behave as if the scheduler was preemptive, which it is not. >>> >>> http://stackoverflow.com/questions/27731274/smalltalk- >>> visual-works-concurrency >>> >>> So there must be some sort of wait on a busy Semaphore, but where? >>> I failed to find it... >>> >>> >>> >>> >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150108/9cd834a2/attachment.htm From maxleske at gmail.com Thu Jan 8 10:37:48 2015 From: maxleske at gmail.com (Max Leske) Date: Thu Jan 8 10:37:52 2015 Subject: [squeak-dev] [OSProcess] forking and file descriptors Message-ID: <62E9815B-9B3B-4909-A728-B0032ABDB7BE@gmail.com> Hi We currently use ImageSegment to create snapshots of our object graphs. To ensure consistency (and for performance reasons) we create a fork of the image and then run the segment creation in the fork. We?ve always had minor issues with TCP sockets but they are pretty rare and have never corrupted any data (we close the TCP connections in the child). Recently however, we created a new application which also makes heavy use of a database and now it seems that forking creates a real problem. In anticipation of possible problems I opted to destroy all sockets (with Socket>>destroy) in the fork, thinking that, since all file descriptors are copies of the ones in the parent process, the sockets in the parent process should be unaffected [1], [2]. With that mechanism in place however, we are seeing very weird things, such as multiples sockets in the parent (!) having the same file handle (which leads to the wrong data being read from the database and, in turn, corrupt objects). AFAICT, the OSProcess plugin doesn?t offer any way of dealing with such problems so I was wondering if anybody has had any experience with these kinds of issues and whether there is some kind of best practice. I am aware that the most simple option is to close the sockets in the parent before forking, but that will mean that we would have to wait for all database connections to finish executing, then blocking them to prevent new connections to the database. Depending on the time a query takes (which may well be a couple of seconds in our case) clients would need to wait for quite a long time before their request can be answered (and this scenario of course assumes that we only close the database sockets and leave the TCP sockets open?). So under the condition that I need to fork that image, what is the best way to deal with open file descriptors? Thanks for your time. Max [1] http://man7.org/linux/man-pages/man2/fork.2.html [2] http://man7.org/linux/man-pages/man2/clone.2.html From lewis at mail.msen.com Thu Jan 8 12:54:57 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Thu Jan 8 12:55:00 2015 Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <62E9815B-9B3B-4909-A728-B0032ABDB7BE@gmail.com> References: <62E9815B-9B3B-4909-A728-B0032ABDB7BE@gmail.com> Message-ID: <20150108125457.GA94358@shell.msen.com> On Thu, Jan 08, 2015 at 11:37:48AM +0100, Max Leske wrote: > > Hi > > We currently use ImageSegment to create snapshots of our object graphs. To ensure consistency (and for performance reasons) we create a fork of the image and then run the segment creation in the fork. We???ve always had minor issues with TCP sockets but they are pretty rare and have never corrupted any data (we close the TCP connections in the child). > > Recently however, we created a new application which also makes heavy use of a database and now it seems that forking creates a real problem. In anticipation of possible problems I opted to destroy all sockets (with Socket>>destroy) in the fork, thinking that, since all file descriptors are copies of the ones in the parent process, the sockets in the parent process should be unaffected [1], [2]. > With that mechanism in place however, we are seeing very weird things, such as multiples sockets in the parent (!) having the same file handle (which leads to the wrong data being read from the database and, in turn, corrupt objects). > > AFAICT, the OSProcess plugin doesn???t offer any way of dealing with such problems so I was wondering if anybody has had any experience with these kinds of issues and whether there is some kind of best practice. > > I am aware that the most simple option is to close the sockets in the parent before forking, but that will mean that we would have to wait for all database connections to finish executing, then blocking them to prevent new connections to the database. Depending on the time a query takes (which may well be a couple of seconds in our case) clients would need to wait for quite a long time before their request can be answered (and this scenario of course assumes that we only close the database sockets and leave the TCP sockets open???). > > So under the condition that I need to fork that image, what is the best way to deal with open file descriptors? > > > Thanks for your time. > Max > > [1] http://man7.org/linux/man-pages/man2/fork.2.html > [2] http://man7.org/linux/man-pages/man2/clone.2.html The only file descriptor (socket or file) that is directly controlled by forkSqueak is the socket connection to the X11 display. That is done via the XDisplayControlPlugin. Everything else needs to be handled by the image (including the changes file BTW). For connections such as those to a database, I think that you would want to maintain complete control of this in your image, such that you would ensure that you have one and only one of the images interacting with any given socket. You can probably do this either before or after forking, whichever might make more sense to you. If you handle it after the forkSqueak, use the result of the forkSqueak to determine which image is the child and which is the parent. I don't know if this helps, if not please keep askng questions. Dave From henrik.s.johansen at veloxit.no Thu Jan 8 15:56:30 2015 From: henrik.s.johansen at veloxit.no (Henrik Johansen) Date: Thu Jan 8 15:56:37 2015 Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <62E9815B-9B3B-4909-A728-B0032ABDB7BE@gmail.com> References: <62E9815B-9B3B-4909-A728-B0032ABDB7BE@gmail.com> Message-ID: <9813A3DC-BE04-490E-8217-AF10ABD63ECA@veloxit.no> > On 08 Jan 2015, at 11:37 , Max Leske wrote: > > > Hi > > We currently use ImageSegment to create snapshots of our object graphs. To ensure consistency (and for performance reasons) we create a fork of the image and then run the segment creation in the fork. We?ve always had minor issues with TCP sockets but they are pretty rare and have never corrupted any data (we close the TCP connections in the child). > > Recently however, we created a new application which also makes heavy use of a database and now it seems that forking creates a real problem. In anticipation of possible problems I opted to destroy all sockets (with Socket>>destroy) in the fork, thinking that, since all file descriptors are copies of the ones in the parent process, the sockets in the parent process should be unaffected [1], [2]. > With that mechanism in place however, we are seeing very weird things, such as multiples sockets in the parent (!) having the same file handle (which leads to the wrong data being read from the database and, in turn, corrupt objects). > > AFAICT, the OSProcess plugin doesn?t offer any way of dealing with such problems so I was wondering if anybody has had any experience with these kinds of issues and whether there is some kind of best practice. > > I am aware that the most simple option is to close the sockets in the parent before forking, but that will mean that we would have to wait for all database connections to finish executing, then blocking them to prevent new connections to the database. Depending on the time a query takes (which may well be a couple of seconds in our case) clients would need to wait for quite a long time before their request can be answered (and this scenario of course assumes that we only close the database sockets and leave the TCP sockets open?). > > So under the condition that I need to fork that image, what is the best way to deal with open file descriptors? > > > Thanks for your time. > Max > > [1] http://man7.org/linux/man-pages/man2/fork.2.html > [2] http://man7.org/linux/man-pages/man2/clone.2.html Well... If I understand the source correctly (at least on Unix, https://github.com/pharo-project/pharo-vm/blob/master/platforms/unix/plugins/SocketPlugin/sqUnixSocket.c ) The socketHandle in a Socket instance is a pointer to a private (platform-specific) struct. That struct again has a handle to the native socket, which I assume is what gets copied when you fork a process? Socket >> primDestroySocket frees the memory pointed to by socketHandle. So, are you using clone or fork to create a fork of the image? If their memory is shared (clone) instead of copied (fork), you might be kicking the feet out from under the parent image as well, so to speak... Cheers, Henry -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150108/831a4d28/attachment.htm From eliot.miranda at gmail.com Thu Jan 8 18:01:34 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu Jan 8 18:01:37 2015 Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <9813A3DC-BE04-490E-8217-AF10ABD63ECA@veloxit.no> References: <62E9815B-9B3B-4909-A728-B0032ABDB7BE@gmail.com> <9813A3DC-BE04-490E-8217-AF10ABD63ECA@veloxit.no> Message-ID: On Thu, Jan 8, 2015 at 7:56 AM, Henrik Johansen < henrik.s.johansen@veloxit.no> wrote: > > On 08 Jan 2015, at 11:37 , Max Leske wrote: > > > Hi > > We currently use ImageSegment to create snapshots of our object graphs. To > ensure consistency (and for performance reasons) we create a fork of the > image and then run the segment creation in the fork. We?ve always had minor > issues with TCP sockets but they are pretty rare and have never corrupted > any data (we close the TCP connections in the child). > > Recently however, we created a new application which also makes heavy use > of a database and now it seems that forking creates a real problem. In > anticipation of possible problems I opted to destroy all sockets (with > Socket>>destroy) in the fork, thinking that, since all file descriptors are > copies of the ones in the parent process, the sockets in the parent process > should be unaffected [1], [2]. > With that mechanism in place however, we are seeing very weird things, > such as multiples sockets in the parent (!) having the same file handle > (which leads to the wrong data being read from the database and, in turn, > corrupt objects). > > AFAICT, the OSProcess plugin doesn?t offer any way of dealing with such > problems so I was wondering if anybody has had any experience with these > kinds of issues and whether there is some kind of best practice. > > I am aware that the most simple option is to close the sockets in the > parent before forking, but that will mean that we would have to wait for > all database connections to finish executing, then blocking them to prevent > new connections to the database. Depending on the time a query takes (which > may well be a couple of seconds in our case) clients would need to wait for > quite a long time before their request can be answered (and this scenario > of course assumes that we only close the database sockets and leave the TCP > sockets open?). > > So under the condition that I need to fork that image, what is the best > way to deal with open file descriptors? > > > Thanks for your time. > Max > > [1] http://man7.org/linux/man-pages/man2/fork.2.html > [2] http://man7.org/linux/man-pages/man2/clone.2.html > > > Well... > If I understand the source correctly (at least on Unix, > https://github.com/pharo-project/pharo-vm/blob/master/platforms/unix/plugins/SocketPlugin/sqUnixSocket.c > ) > The socketHandle in a Socket instance is a pointer to a private > (platform-specific) struct. > That struct again has a handle to the native socket, which I assume is > what gets copied when you fork a process? > > Socket >> primDestroySocket frees the memory pointed to by socketHandle. > So, are you using clone or fork to create a fork of the image? > If their memory is shared (clone) instead of copied (fork), you might be > kicking the feet out from under the parent image as well, so to speak... > Hmmm, that reminds me that in Spur we can perhaps move some of these structs up into the image if we keep them in pinned objects. I just wanted to note that for my own memory. Cheers, > Henry > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150108/d9bfe44e/attachment.htm From javier_diaz_r at mac.com Thu Jan 8 19:48:25 2015 From: javier_diaz_r at mac.com (Javier Diaz-Reinoso) Date: Thu Jan 8 19:48:35 2015 Subject: [squeak-dev] New year mac cog VM bug? In-Reply-To: References: Message-ID: <0E27D452-94BD-4E4B-90F9-D28927254096@mac.com> > On Jan 7, 2015, at 16:43, Eliot Miranda wrote: > > > > On Tue, Jan 6, 2015 at 12:31 PM, Javier Diaz-Reinoso > wrote: > I try open an image (4.4) today, when I try to browse Collection, for example, fails with the error 'RemoteString past end of file', this error is because the VM (Cog 4.0.3205 but also older versions) is not recognizing an (mac) alias to the file SqueakV41.sources, if I change the alias for the file or a unix soft link then all works OK. > > The strange thing is that I'm sure this worked on December 31, maybe this fail because the change from year? > > Thanks, Javier. I must have broken this in my recent changes. I'll fix it asap. Thanks for the report! > > -- > best, > Eliot > I think this error is because Apple finally remove the Alias manager API, this API was marked ?Deprecated' in 10.8 but continue to work, I think in the update to 10.10.1 the API was removed. The editor TextWrangler also fail with the error: 'An unexpected end-of-file was encountered (MacOS Error code: -39)? when try to open the SqueakV41.sources; notice that the alias files remain working, is the calls to this specific API who don?t work. I am worry that the (Cog) mac VM have a few of this APIs deprecated, perhaps is time to migrate to Cocoa. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150108/c35621cd/attachment-0001.htm From trygver at ifi.uio.no Thu Jan 8 19:50:46 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Thu Jan 8 19:50:50 2015 Subject: [squeak-dev] [BUG] http://www.squeak.org/Development>> 'Squeak Map - release deployment' is a dead reference.(map.squeak.org) Message-ID: <54AEDF96.2050600@ifi.uio.no> /[BUG] http://www.squeak.org/Development>> 'Squeak Map - release deployment' is a dead reference. (map.squeak.org does not exist)/ -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150108/33a47080/attachment.htm From leves at elte.hu Thu Jan 8 19:58:06 2015 From: leves at elte.hu (Levente Uzonyi) Date: Thu Jan 8 19:58:12 2015 Subject: [squeak-dev] [BUG] http://www.squeak.org/Development>> 'Squeak Map - release deployment' is a dead reference.(map.squeak.org) In-Reply-To: <54AEDF96.2050600@ifi.uio.no> References: <54AEDF96.2050600@ifi.uio.no> Message-ID: It works for me: NetNameResolver addressForName: 'map.squeak.org'. "==> #[173 246 104 42]" HTTPSocket httpShowPage: 'map.squeak.org' "==> 'SqueakMap...'" Levente On Thu, 8 Jan 2015, Trygve Reenskaug wrote: > [BUG] http://www.squeak.org/Development>> 'Squeak Map - release deployment' is a dead reference. > (map.squeak.org does not exist) > > From eliot.miranda at gmail.com Thu Jan 8 20:20:21 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu Jan 8 20:20:24 2015 Subject: [squeak-dev] New year mac cog VM bug? In-Reply-To: <0E27D452-94BD-4E4B-90F9-D28927254096@mac.com> References: <0E27D452-94BD-4E4B-90F9-D28927254096@mac.com> Message-ID: Hi Javier, On Thu, Jan 8, 2015 at 11:48 AM, Javier Diaz-Reinoso wrote: > > On Jan 7, 2015, at 16:43, Eliot Miranda wrote: > > > > On Tue, Jan 6, 2015 at 12:31 PM, Javier Diaz-Reinoso < > javier_diaz_r@mac.com> wrote: > >> I try open an image (4.4) today, when I try to browse Collection, for >> example, fails with the error 'RemoteString past end of file', this error >> is because the VM (Cog 4.0.3205 but also older versions) is not recognizing >> an (mac) alias to the file SqueakV41.sources, if I change the alias for the >> file or a unix soft link then all works OK. >> >> The strange thing is that I'm sure this worked on December 31, maybe this >> fail because the change from year? >> > > Thanks, Javier. I must have broken this in my recent changes. I'll fix > it asap. Thanks for the report! > > -- > best, > Eliot > > > I think this error is because Apple finally remove the Alias manager API, > this API was marked ?Deprecated' in 10.8 but continue to work, I think in > the update to 10.10.1 the API was removed. > > The editor TextWrangler also fail with the error: 'An unexpected > end-of-file was encountered (MacOS Error code: -39)? when try to open the > SqueakV41.sources; notice that the alias files remain working, is the calls > to this specific API who don?t work. > > I am worry that the (Cog) mac VM have a few of this APIs deprecated, > perhaps is time to migrate to Cocoa. > Luckily I've started doing that, with help from John McIntosh. I can't build a 64-bit VM on Carbon, hence I need to move. I'm curious though. Have you upgraded your operating sytsem or is it the VM that's changed? If you use an older VM does the alias get dererferenced or not? If the older VM works I wonder if you could do the following for me: 1. tell me what the last good version of the VM is 2. Copy both the current VM's .app bundle and the last good VM's .app bundle. Swap the executable (CogSpur.app/Contents/MacOS/Squeak) between the two. Repeat the experiment. Tel me which fails. This will tell me whether something in the Info.plist has changed or whether something in the executable changed. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150108/a4ca2a1c/attachment.htm From trygver at ifi.uio.no Thu Jan 8 20:21:39 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Thu Jan 8 20:21:41 2015 Subject: [squeak-dev] [BUG] http://www.squeak.org/Development>> 'Squeak Map - release deployment' is a dead reference.(map.squeak.org) In-Reply-To: References: <54AEDF96.2050600@ifi.uio.no> Message-ID: <54AEE6D3.4040802@ifi.uio.no> For me also. It didn't this morning. Something has been repaired during the day. :-) Same applies to SqueakMap Packasge Loader:-) On 08.01.2015 20:58, Levente Uzonyi wrote: > It works for me: > > NetNameResolver addressForName: 'map.squeak.org'. > "==> #[173 246 104 42]" > > HTTPSocket httpShowPage: 'map.squeak.org' > "==> 'SqueakMap...'" > > Levente > > On Thu, 8 Jan 2015, Trygve Reenskaug wrote: > >> [BUG] http://www.squeak.org/Development>> 'Squeak Map - release >> deployment' is a dead reference. >> (map.squeak.org does not exist) >> >> > > > From javier_diaz_r at mac.com Thu Jan 8 23:28:33 2015 From: javier_diaz_r at mac.com (Javier Diaz-Reinoso) Date: Thu Jan 8 23:28:40 2015 Subject: [squeak-dev] New year mac cog VM bug? In-Reply-To: References: <0E27D452-94BD-4E4B-90F9-D28927254096@mac.com> Message-ID: <9EC8C418-2361-4F2E-9396-58DA280D8C69@mac.com> > On Jan 8, 2015, at 15:20, Eliot Miranda wrote: > > Hi Javier, > > On Thu, Jan 8, 2015 at 11:48 AM, Javier Diaz-Reinoso > wrote: > >> On Jan 7, 2015, at 16:43, Eliot Miranda > wrote: >> >> >> >> On Tue, Jan 6, 2015 at 12:31 PM, Javier Diaz-Reinoso > wrote: >> I try open an image (4.4) today, when I try to browse Collection, for example, fails with the error 'RemoteString past end of file', this error is because the VM (Cog 4.0.3205 but also older versions) is not recognizing an (mac) alias to the file SqueakV41.sources, if I change the alias for the file or a unix soft link then all works OK. >> >> The strange thing is that I'm sure this worked on December 31, maybe this fail because the change from year? >> >> Thanks, Javier. I must have broken this in my recent changes. I'll fix it asap. Thanks for the report! >> >> -- >> best, >> Eliot >> > > I think this error is because Apple finally remove the Alias manager API, this API was marked ?Deprecated' in 10.8 but continue to work, I think in the update to 10.10.1 the API was removed. > > The editor TextWrangler also fail with the error: 'An unexpected end-of-file was encountered (MacOS Error code: -39)? when try to open the SqueakV41.sources; notice that the alias files remain working, is the calls to this specific API who don?t work. > > I am worry that the (Cog) mac VM have a few of this APIs deprecated, perhaps is time to migrate to Cocoa. > > Luckily I've started doing that, with help from John McIntosh. I can't build a 64-bit VM on Carbon, hence I need to move. > > I'm curious though. Have you upgraded your operating sytsem or is it the VM that's changed? If you use an older VM does the alias get dererferenced or not? If the older VM works I wonder if you could do the following for me: I upgrade OS X to 10.10.1, all the older VMs also fail including the original Carbon VM Squeak 4.2.5beta1U, as I said I think is the OS upgrade. > > 1. tell me what the last good version of the VM is > 2. Copy both the current VM's .app bundle and the last good VM's .app bundle. Swap the executable (CogSpur.app/Contents/MacOS/Squeak) between the two. Repeat the experiment. Tel me which fails. This will tell me whether something in the Info.plist has changed or whether something in the executable changed. > > -- > best, > Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150108/406cedcd/attachment.htm From eliot.miranda at gmail.com Fri Jan 9 01:04:48 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 9 01:04:53 2015 Subject: [squeak-dev] Cannot commit VMMaker to source.squeak.org Message-ID: Hi Levente, not sure if this is due to the replacement of box2 (I suspect it is) but in trying to upload the VMMaker.oscog versions I've been keeping back while box2 is repaired/replaced I get the following error: HTTP/1.1 413 Request Entity Too Large Server: nginx Date: Fri, 09 Jan 2015 01:00:40 GMT Content-Type: text/html Content-Length: 192 Connection: closeHTTP/1.1 413 Request Entity Too Large Server: nginx Date: Fri, 09 Jan 2015 01:00:40 GMT Content-Type: text/html Content-Length: 192 Connection: close 413 Request Entity Too Large

413 Request Entity Too Large


nginx
The sizes of the packages are currently McStalker.Cog$ ls -lh package-cache/VMMaker.oscog-eem.101* -rw-r--r--@ 1 eliot staff 3.5M Jan 6 10:52 package-cache/VMMaker.oscog-eem.1010.mcz -rw-r--r--@ 1 eliot staff 3.5M Jan 8 13:01 package-cache/VMMaker.oscog-eem.1011.mcz -rw-r--r--@ 1 eliot staff 3.5M Jan 8 17:00 package-cache/VMMaker.oscog-eem.1012.mcz I think we should allow at least 5m. Is this possible or will I have to split up VMMaker?? (oh no, Mr Billllll!) -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150108/3499a8f6/attachment.htm From lewis at mail.msen.com Fri Jan 9 02:56:15 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri Jan 9 03:35:44 2015 Subject: [squeak-dev] Cannot commit VMMaker to source.squeak.org In-Reply-To: References: Message-ID: <20150109025615.GA30762@shell.msen.com> Hi Eliot, On Thu, Jan 08, 2015 at 05:04:48PM -0800, Eliot Miranda wrote: > Hi Levente, > > not sure if this is due to the replacement of box2 (I suspect it is) > but in trying to upload the VMMaker.oscog versions I've been keeping back > while box2 is repaired/replaced I get the following error: > > HTTP/1.1 413 Request Entity Too Large > Server: nginx > Date: Fri, 09 Jan 2015 01:00:40 GMT > Content-Type: text/html > Content-Length: 192 > Connection: closeHTTP/1.1 413 Request Entity Too Large > Server: nginx > Date: Fri, 09 Jan 2015 01:00:40 GMT > Content-Type: text/html > Content-Length: 192 > Connection: close > 413 Request Entity Too Large > >

413 Request Entity Too Large

>
nginx
> > The last successful uploads into source.squeak.org were these: davidlewis@squeak-box4:/srv/box2/home/squeaksource/ss$ tr '\r' '\n' < ss.log | tail 2014-12-31T22:22:54.955+00:00 PUT /VMMaker/VMMaker.oscog-eem.1004.mcz (eem) 2014-12-31T22:23:05.575+00:00 STORED VMMaker/VMMaker.oscog-eem.1004.mcz 2015-01-01T21:18:05.364+00:00 PUT /VMMaker/VMMaker.oscog-eem.1005.mcz (eem) 2015-01-01T21:18:16.333+00:00 STORED VMMaker/VMMaker.oscog-eem.1005.mcz 2015-01-01T21:28:02.069+00:00 PUT /VMMaker/VMMaker.oscog-eem.1006.mcz (eem) 2015-01-01T21:28:12.61+00:00 STORED VMMaker/VMMaker.oscog-eem.1006.mcz 2015-01-01T21:39:15.692+00:00 PUT /VMMaker/VMMaker.oscog-eem.1007.mcz (eem) 2015-01-01T21:39:26.056+00:00 STORED VMMaker/VMMaker.oscog-eem.1007.mcz 2015-01-01T22:03:30.81+00:00 PUT /VMMaker/VMMaker.oscog-eem.1008.mcz (eem) 2015-01-01T22:03:41.23+00:00 STORED VMMaker/VMMaker.oscog-eem.1008.mcz That was before the box2 crash. It looks like the response is due to this: http://www.daveperrett.com/articles/2009/11/18/nginx-error-413-request-entity-too-large/ So it is not a limit related to source.squeak.org, it is just a limit on size of uploads imposed by the nginx reverse proxy server. My guess is that adding a local configuration file in /etc/nginx/conf.d/ would be a reasonable way to bump the limit up to 5M. I do not have any experience with nginx, so I will wait for Levente or one of the other box-admins to respond (but I have access to make the change if someone tells me what to do). > > The sizes of the packages are currently > McStalker.Cog$ ls -lh package-cache/VMMaker.oscog-eem.101* > -rw-r--r--@ 1 eliot staff 3.5M Jan 6 10:52 > package-cache/VMMaker.oscog-eem.1010.mcz > -rw-r--r--@ 1 eliot staff 3.5M Jan 8 13:01 > package-cache/VMMaker.oscog-eem.1011.mcz > -rw-r--r--@ 1 eliot staff 3.5M Jan 8 17:00 > package-cache/VMMaker.oscog-eem.1012.mcz > > > I think we should allow at least 5m. Is this possible or will I have to > split up VMMaker?? (oh no, Mr Billllll!) What a rediculous notion. How could you possibly suggest that three and a half megabytes of compressed source code would be too large for a single package? ;-) Dave From leves at elte.hu Fri Jan 9 05:59:00 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri Jan 9 05:59:05 2015 Subject: [squeak-dev] Re: Cannot commit VMMaker to source.squeak.org In-Reply-To: References: Message-ID: Hi Eliot, Yes, this is related to the migration of the service. I've increased the upload size limit. Sorry for the inconvenience. Levente On Thu, 8 Jan 2015, Eliot Miranda wrote: > Hi Levente, > ? ? ?not sure if this is due to the replacement of box2 (I suspect it is) but in trying to upload the VMMaker.oscog versions I've been keeping back while box2 is repaired/replaced I get the following error: > > HTTP/1.1 413 Request Entity Too Large > Server: nginx > Date: Fri, 09 Jan 2015 01:00:40 GMT > Content-Type: text/html > Content-Length: 192 > Connection: closeHTTP/1.1 413 Request Entity Too Large > Server: nginx > Date: Fri, 09 Jan 2015 01:00:40 GMT > Content-Type: text/html > Content-Length: 192 > Connection: close > 413 Request Entity Too Large > >

413 Request Entity Too Large

>
nginx
> > > > The sizes of the packages are currently > McStalker.Cog$ ls -lh package-cache/VMMaker.oscog-eem.101* > -rw-r--r--@ 1 eliot ?staff ? 3.5M Jan ?6 10:52 package-cache/VMMaker.oscog-eem.1010.mcz > -rw-r--r--@ 1 eliot ?staff ? 3.5M Jan ?8 13:01 package-cache/VMMaker.oscog-eem.1011.mcz > -rw-r--r--@ 1 eliot ?staff ? 3.5M Jan ?8 17:00 package-cache/VMMaker.oscog-eem.1012.mcz > > > I think we should allow at least 5m.? Is this possible or will I have to split up VMMaker?? ?(oh no, Mr Billllll!) > -- > best,Eliot > > From maxleske at gmail.com Fri Jan 9 08:12:39 2015 From: maxleske at gmail.com (Max Leske) Date: Fri Jan 9 08:12:46 2015 Subject: [squeak-dev] Re: Squeak-dev Digest, Vol 145, Issue 3 In-Reply-To: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> References: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <9F20C01C-034F-46B6-AB4F-D0D91220BCEB@gmail.com> > On 08 Jan 2015, at 20:48, squeak-dev-request@lists.squeakfoundation.org wrote: > > From: "David T. Lewis" > > Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file > descriptors > > On Thu, Jan 08, 2015 at 11:37:48AM +0100, Max Leske wrote: >> >> Hi >> >> We currently use ImageSegment to create snapshots of our object graphs. To ensure consistency (and for performance reasons) we create a fork of the image and then run the segment creation in the fork. We???ve always had minor issues with TCP sockets but they are pretty rare and have never corrupted any data (we close the TCP connections in the child). >> >> Recently however, we created a new application which also makes heavy use of a database and now it seems that forking creates a real problem. In anticipation of possible problems I opted to destroy all sockets (with Socket>>destroy) in the fork, thinking that, since all file descriptors are copies of the ones in the parent process, the sockets in the parent process should be unaffected [1], [2]. >> With that mechanism in place however, we are seeing very weird things, such as multiples sockets in the parent (!) having the same file handle (which leads to the wrong data being read from the database and, in turn, corrupt objects). >> >> AFAICT, the OSProcess plugin doesn???t offer any way of dealing with such problems so I was wondering if anybody has had any experience with these kinds of issues and whether there is some kind of best practice. >> >> I am aware that the most simple option is to close the sockets in the parent before forking, but that will mean that we would have to wait for all database connections to finish executing, then blocking them to prevent new connections to the database. Depending on the time a query takes (which may well be a couple of seconds in our case) clients would need to wait for quite a long time before their request can be answered (and this scenario of course assumes that we only close the database sockets and leave the TCP sockets open???). >> >> So under the condition that I need to fork that image, what is the best way to deal with open file descriptors? >> >> >> Thanks for your time. >> Max >> >> [1] http://man7.org/linux/man-pages/man2/fork.2.html >> [2] http://man7.org/linux/man-pages/man2/clone.2.html > > The only file descriptor (socket or file) that is directly controlled by > forkSqueak is the socket connection to the X11 display. That is done via > the XDisplayControlPlugin. Everything else needs to be handled by the > image (including the changes file BTW). True, I?d never thought of that? > > For connections such as those to a database, I think that you would want to > maintain complete control of this in your image, such that you would ensure > that you have one and only one of the images interacting with any given socket. > > You can probably do this either before or after forking, whichever might > make more sense to you. If you handle it after the forkSqueak, use the > result of the forkSqueak to determine which image is the child and which > is the parent. That?s what I?m trying to do. The problem I face is that the database queries run in a separate process (Smalltalk process in the VM). Once I?m in the child process, there?s always a small window in which the scheduler might run that process before I can terminate it or do something else. My understanding from the C code (from reading man fork(2) and man clone(2)) is that sending Socket>>destroy (which does a close()) shouldn?t have any effect on the socket in the parent. My guess is that things get hairy when the process with the database queries gets processor time before I can destroy the sockets. When that happens, I suddenly have two processes reading from AND writing to the same socket (which can?t be good?). I just realized, there are BlockClosure>>valueUnpreemptively and BlockClosure>>valueUninterruptably. Maybe a can wrap the the code in the fork into such a block somehow to prevent the other processes from running? Thanks Dave. > > I don't know if this helps, if not please keep askng questions. > > Dave -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/bb95c852/attachment.htm From maxleske at gmail.com Fri Jan 9 08:32:07 2015 From: maxleske at gmail.com (Max Leske) Date: Fri Jan 9 08:32:12 2015 Subject: [squeak-dev] Re: Squeak-dev Digest, Vol 145, Issue 3 In-Reply-To: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> References: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <9F6F0306-91C4-48DF-B57F-031245C89DAD@gmail.com> > On 08 Jan 2015, at 20:48, squeak-dev-request@lists.squeakfoundation.org wrote: > > Date: Thu, 8 Jan 2015 16:56:30 +0100 > From: Henrik Johansen > > Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file > descriptors > > >> On 08 Jan 2015, at 11:37 , Max Leske > wrote: >> >> >> Hi >> >> We currently use ImageSegment to create snapshots of our object graphs. To ensure consistency (and for performance reasons) we create a fork of the image and then run the segment creation in the fork. We?ve always had minor issues with TCP sockets but they are pretty rare and have never corrupted any data (we close the TCP connections in the child). >> >> Recently however, we created a new application which also makes heavy use of a database and now it seems that forking creates a real problem. In anticipation of possible problems I opted to destroy all sockets (with Socket>>destroy) in the fork, thinking that, since all file descriptors are copies of the ones in the parent process, the sockets in the parent process should be unaffected [1], [2]. >> With that mechanism in place however, we are seeing very weird things, such as multiples sockets in the parent (!) having the same file handle (which leads to the wrong data being read from the database and, in turn, corrupt objects). >> >> AFAICT, the OSProcess plugin doesn?t offer any way of dealing with such problems so I was wondering if anybody has had any experience with these kinds of issues and whether there is some kind of best practice. >> >> I am aware that the most simple option is to close the sockets in the parent before forking, but that will mean that we would have to wait for all database connections to finish executing, then blocking them to prevent new connections to the database. Depending on the time a query takes (which may well be a couple of seconds in our case) clients would need to wait for quite a long time before their request can be answered (and this scenario of course assumes that we only close the database sockets and leave the TCP sockets open?). >> >> So under the condition that I need to fork that image, what is the best way to deal with open file descriptors? >> >> >> Thanks for your time. >> Max >> >> [1] http://man7.org/linux/man-pages/man2/fork.2.html >> [2] http://man7.org/linux/man-pages/man2/clone.2.html > > Well... > If I understand the source correctly (at least on Unix, https://github.com/pharo-project/pharo-vm/blob/master/platforms/unix/plugins/SocketPlugin/sqUnixSocket.c >) > The socketHandle in a Socket instance is a pointer to a private (platform-specific) struct. > That struct again has a handle to the native socket, which I assume is what gets copied when you fork a process? > > Socket >> primDestroySocket frees the memory pointed to by socketHandle. Hm? that gives me an idea: assume that everything works as advertised and that the child process gets copies of the socket descriptors (which can be closed safely without intefering with the parent). If I?m right, the Socket instances in the image hold on to the address of the *parent* handle (in an inst var). So now, when I close a socket with #primSocketDestroy:, the handle passed to the plugin will be the handle of the parent socket (although it sounds strange that the child should be able to close a file descriptor of its parent?). That would mean that I must not close any sockets in the child. One option, it seems to me, is to suspend all processes that use sockets. Terminating them might pose another problem, if socket destruction is part of an unwind block in one of the processes (e.g. TCP connections in Seaside) then sockets will be destroyed during termination. Another option: set all the socket handles to nil, then terminate the processes (yes ugly, but it might just work?). > So, are you using clone or fork to create a fork of the image? OSProcess uses plain fork() (in forkSqueak()). That?s what I use from the image. > If their memory is shared (clone) instead of copied (fork), you might be kicking the feet out from under the parent image as well, so to speak? From my understanding the file descriptors should be copied (fork). So that shouldn?t happen (but see above?). Thanks Henry. > > Cheers, > Henry -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/bbe37c15/attachment-0001.htm From maxleske at gmail.com Fri Jan 9 08:32:53 2015 From: maxleske at gmail.com (Max Leske) Date: Fri Jan 9 08:32:59 2015 Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> References: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <4C2212B6-626F-4ECF-9D17-52C096B86A82@gmail.com> (Resending with proper subject?) > On 08 Jan 2015, at 20:48, squeak-dev-request@lists.squeakfoundation.org wrote: > > Date: Thu, 8 Jan 2015 16:56:30 +0100 > From: Henrik Johansen > > Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file > descriptors > > >> On 08 Jan 2015, at 11:37 , Max Leske > wrote: >> >> >> Hi >> >> We currently use ImageSegment to create snapshots of our object graphs. To ensure consistency (and for performance reasons) we create a fork of the image and then run the segment creation in the fork. We?ve always had minor issues with TCP sockets but they are pretty rare and have never corrupted any data (we close the TCP connections in the child). >> >> Recently however, we created a new application which also makes heavy use of a database and now it seems that forking creates a real problem. In anticipation of possible problems I opted to destroy all sockets (with Socket>>destroy) in the fork, thinking that, since all file descriptors are copies of the ones in the parent process, the sockets in the parent process should be unaffected [1], [2]. >> With that mechanism in place however, we are seeing very weird things, such as multiples sockets in the parent (!) having the same file handle (which leads to the wrong data being read from the database and, in turn, corrupt objects). >> >> AFAICT, the OSProcess plugin doesn?t offer any way of dealing with such problems so I was wondering if anybody has had any experience with these kinds of issues and whether there is some kind of best practice. >> >> I am aware that the most simple option is to close the sockets in the parent before forking, but that will mean that we would have to wait for all database connections to finish executing, then blocking them to prevent new connections to the database. Depending on the time a query takes (which may well be a couple of seconds in our case) clients would need to wait for quite a long time before their request can be answered (and this scenario of course assumes that we only close the database sockets and leave the TCP sockets open?). >> >> So under the condition that I need to fork that image, what is the best way to deal with open file descriptors? >> >> >> Thanks for your time. >> Max >> >> [1] http://man7.org/linux/man-pages/man2/fork.2.html >> [2] http://man7.org/linux/man-pages/man2/clone.2.html > > Well... > If I understand the source correctly (at least on Unix, https://github.com/pharo-project/pharo-vm/blob/master/platforms/unix/plugins/SocketPlugin/sqUnixSocket.c >) > The socketHandle in a Socket instance is a pointer to a private (platform-specific) struct. > That struct again has a handle to the native socket, which I assume is what gets copied when you fork a process? > > Socket >> primDestroySocket frees the memory pointed to by socketHandle. Hm? that gives me an idea: assume that everything works as advertised and that the child process gets copies of the socket descriptors (which can be closed safely without intefering with the parent). If I?m right, the Socket instances in the image hold on to the address of the *parent* handle (in an inst var). So now, when I close a socket with #primSocketDestroy:, the handle passed to the plugin will be the handle of the parent socket (although it sounds strange that the child should be able to close a file descriptor of its parent?). That would mean that I must not close any sockets in the child. One option, it seems to me, is to suspend all processes that use sockets. Terminating them might pose another problem, if socket destruction is part of an unwind block in one of the processes (e.g. TCP connections in Seaside) then sockets will be destroyed during termination. Another option: set all the socket handles to nil, then terminate the processes (yes ugly, but it might just work?). > So, are you using clone or fork to create a fork of the image? OSProcess uses plain fork() (in forkSqueak()). That?s what I use from the image. > If their memory is shared (clone) instead of copied (fork), you might be kicking the feet out from under the parent image as well, so to speak? From my understanding the file descriptors should be copied (fork). So that shouldn?t happen (but see above?). Thanks Henry. > > Cheers, > Henry -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/2fa336a2/attachment.htm From maxleske at gmail.com Fri Jan 9 08:33:28 2015 From: maxleske at gmail.com (Max Leske) Date: Fri Jan 9 08:33:33 2015 Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> References: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <42993292-DA91-4291-95E3-90D7205540AF@gmail.com> (Resending with proper subject?) > On 08 Jan 2015, at 20:48, squeak-dev-request@lists.squeakfoundation.org wrote: > > From: "David T. Lewis" > > Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file > descriptors > > On Thu, Jan 08, 2015 at 11:37:48AM +0100, Max Leske wrote: >> >> Hi >> >> We currently use ImageSegment to create snapshots of our object graphs. To ensure consistency (and for performance reasons) we create a fork of the image and then run the segment creation in the fork. We???ve always had minor issues with TCP sockets but they are pretty rare and have never corrupted any data (we close the TCP connections in the child). >> >> Recently however, we created a new application which also makes heavy use of a database and now it seems that forking creates a real problem. In anticipation of possible problems I opted to destroy all sockets (with Socket>>destroy) in the fork, thinking that, since all file descriptors are copies of the ones in the parent process, the sockets in the parent process should be unaffected [1], [2]. >> With that mechanism in place however, we are seeing very weird things, such as multiples sockets in the parent (!) having the same file handle (which leads to the wrong data being read from the database and, in turn, corrupt objects). >> >> AFAICT, the OSProcess plugin doesn???t offer any way of dealing with such problems so I was wondering if anybody has had any experience with these kinds of issues and whether there is some kind of best practice. >> >> I am aware that the most simple option is to close the sockets in the parent before forking, but that will mean that we would have to wait for all database connections to finish executing, then blocking them to prevent new connections to the database. Depending on the time a query takes (which may well be a couple of seconds in our case) clients would need to wait for quite a long time before their request can be answered (and this scenario of course assumes that we only close the database sockets and leave the TCP sockets open???). >> >> So under the condition that I need to fork that image, what is the best way to deal with open file descriptors? >> >> >> Thanks for your time. >> Max >> >> [1] http://man7.org/linux/man-pages/man2/fork.2.html >> [2] http://man7.org/linux/man-pages/man2/clone.2.html > > The only file descriptor (socket or file) that is directly controlled by > forkSqueak is the socket connection to the X11 display. That is done via > the XDisplayControlPlugin. Everything else needs to be handled by the > image (including the changes file BTW). True, I?d never thought of that? > > For connections such as those to a database, I think that you would want to > maintain complete control of this in your image, such that you would ensure > that you have one and only one of the images interacting with any given socket. > > You can probably do this either before or after forking, whichever might > make more sense to you. If you handle it after the forkSqueak, use the > result of the forkSqueak to determine which image is the child and which > is the parent. That?s what I?m trying to do. The problem I face is that the database queries run in a separate process (Smalltalk process in the VM). Once I?m in the child process, there?s always a small window in which the scheduler might run that process before I can terminate it or do something else. My understanding from the C code (from reading man fork(2) and man clone(2)) is that sending Socket>>destroy (which does a close()) shouldn?t have any effect on the socket in the parent. My guess is that things get hairy when the process with the database queries gets processor time before I can destroy the sockets. When that happens, I suddenly have two processes reading from AND writing to the same socket (which can?t be good?). I just realized, there are BlockClosure>>valueUnpreemptively and BlockClosure>>valueUninterruptably. Maybe a can wrap the the code in the fork into such a block somehow to prevent the other processes from running? Thanks Dave. > > I don't know if this helps, if not please keep askng questions. > > Dave -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/920e8a77/attachment.htm From henrik.s.johansen at veloxit.no Fri Jan 9 09:24:42 2015 From: henrik.s.johansen at veloxit.no (Henrik Johansen) Date: Fri Jan 9 09:24:47 2015 Subject: [squeak-dev] [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <4C2212B6-626F-4ECF-9D17-52C096B86A82@gmail.com> References: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> <4C2212B6-626F-4ECF-9D17-52C096B86A82@gmail.com> Message-ID: <60858782-93A0-421F-9E49-118FBBC5C13E@veloxit.no> > On 09 Jan 2015, at 9:32 , Max Leske wrote: > > > That would mean that I must not close any sockets in the child. One option, it seems to me, is to suspend all processes that use sockets. Terminating them might pose another problem, if socket destruction is part of an unwind block in one of the processes (e.g. TCP connections in Seaside) then sockets will be destroyed during termination. > > Another option: set all the socket handles to nil, then terminate the processes (yes ugly, but it might just work?). Just beware you might run into the issue that resuming a processes waiting for a semaphore will proceed as if the semaphore were signalled, Can't tell offhand if that would actually be a problem in this case, or if the affected processes would promptly resume waiting after socket read/writes may initiate with no data. Another (probably non-portable, which would be painful if not consistent across platforms) option: Forget about image-side handling, and alter the SocketPlugin to set FD_CLOEXEC if available when opening sockets. (It's in http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fcntl.h.html , but that's rather new) On newer Linuxen, you also have SOCK_CLOEXEC for socket(), which opens/sets in an atomic operation, but the race condition avoided by that is hardly relevant in our case. Cheers, Henry From maxleske at gmail.com Fri Jan 9 09:44:46 2015 From: maxleske at gmail.com (Max Leske) Date: Fri Jan 9 09:44:51 2015 Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <54af9e6c.28518c0a.6eb4.ffff929bSMTPIN_ADDED_MISSING@mx.google.com> References: <54af9e6c.28518c0a.6eb4.ffff929bSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <1F9E011A-5782-4577-81E7-8094B4A3D8D3@gmail.com> > On 09 Jan 2015, at 10:25, vm-dev-request@lists.squeakfoundation.org wrote: > > Date: Fri, 9 Jan 2015 10:24:42 +0100 > From: Henrik Johansen > > Subject: Re: [squeak-dev] [Vm-dev] [OSProcess] forking and file > descriptors > > >> On 09 Jan 2015, at 9:32 , Max Leske > wrote: >> >> > >> That would mean that I must not close any sockets in the child. One option, it seems to me, is to suspend all processes that use sockets. Terminating them might pose another problem, if socket destruction is part of an unwind block in one of the processes (e.g. TCP connections in Seaside) then sockets will be destroyed during termination. >> >> Another option: set all the socket handles to nil, then terminate the processes (yes ugly, but it might just work?). > > Just beware you might run into the issue that resuming a processes waiting for a semaphore will proceed as if the semaphore were signalled, > Can't tell offhand if that would actually be a problem in this case, or if the affected processes would promptly resume waiting after socket read/writes may initiate with no data. I wouldn?t resume any of those processes if I can help it. After creating the segment the child kills itself. Thanks for pointing that out though. > > Another (probably non-portable, which would be painful if not consistent across platforms) option: > Forget about image-side handling, and alter the SocketPlugin to set FD_CLOEXEC if available when opening sockets. (It's in http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fcntl.h.html , but that's rather new) > On newer Linuxen, you also have SOCK_CLOEXEC for socket(), which opens/sets in an atomic operation, but the race condition avoided by that is hardly relevant in our case. True. But I really don?t want to maintain a branch of OSProcess :) > > Cheers, > Henry -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/ba3a3a88/attachment.htm From henrik.s.johansen at veloxit.no Fri Jan 9 09:55:22 2015 From: henrik.s.johansen at veloxit.no (Henrik Johansen) Date: Fri Jan 9 09:55:27 2015 Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <1F9E011A-5782-4577-81E7-8094B4A3D8D3@gmail.com> References: <54af9e6c.28518c0a.6eb4.ffff929bSMTPIN_ADDED_MISSING@mx.google.com> <1F9E011A-5782-4577-81E7-8094B4A3D8D3@gmail.com> Message-ID: > On 09 Jan 2015, at 10:44 , Max Leske wrote: > > >> On 09 Jan 2015, at 10:25, vm-dev-request@lists.squeakfoundation.org wrote: >> >> Date: Fri, 9 Jan 2015 10:24:42 +0100 >> From: Henrik Johansen > >> Subject: Re: [squeak-dev] [Vm-dev] [OSProcess] forking and file >> descriptors >> >> >>> On 09 Jan 2015, at 9:32 , Max Leske > wrote: >>> >>> >> >>> That would mean that I must not close any sockets in the child. One option, it seems to me, is to suspend all processes that use sockets. Terminating them might pose another problem, if socket destruction is part of an unwind block in one of the processes (e.g. TCP connections in Seaside) then sockets will be destroyed during termination. >>> >>> Another option: set all the socket handles to nil, then terminate the processes (yes ugly, but it might just work?). >> >> Just beware you might run into the issue that resuming a processes waiting for a semaphore will proceed as if the semaphore were signalled, >> Can't tell offhand if that would actually be a problem in this case, or if the affected processes would promptly resume waiting after socket read/writes may initiate with no data. > > I wouldn?t resume any of those processes if I can help it. After creating the segment the child kills itself. Thanks for pointing that out though. I was thinking you'd need to suspend the processes in the parent, before forking off a child, (to ensure there will be no possibility of a process running before it's suspended in the child) then resume after forking? > >> >> Another (probably non-portable, which would be painful if not consistent across platforms) option: >> Forget about image-side handling, and alter the SocketPlugin to set FD_CLOEXEC if available when opening sockets. (It's in http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fcntl.h.html , but that's rather new) >> On newer Linuxen, you also have SOCK_CLOEXEC for socket(), which opens/sets in an atomic operation, but the race condition avoided by that is hardly relevant in our case. > > True. But I really don?t want to maintain a branch of OSProcess :) It wouldn't be a branch of OSProcess, but an update to the platform SocketPlugin sources. I was probably wrong and it's not so new (wouldn't it be nice if all API's had the same structure as Postgres, where checking previous versions is *really* easy?), the 2004 version of the standard also includes it. A cursory check indicates at least OSX/*BSD/*Solaris would support it as well. Doing the equivalent on Windows seems to have certain caveats though... http://stackoverflow.com/questions/12058911/can-tcp-socket-handles-be-set-not-inheritable Cheers, Henry -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/1df4f4d6/attachment-0001.htm From maxleske at gmail.com Fri Jan 9 10:28:21 2015 From: maxleske at gmail.com (Max Leske) Date: Fri Jan 9 10:28:25 2015 Subject: [squeak-dev] [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <54afa5a1.ae628c0a.126e.ffff810cSMTPIN_ADDED_MISSING@mx.google.com> References: <54afa5a1.ae628c0a.126e.ffff810cSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: > On 09 Jan 2015, at 10:55, squeak-dev-request@lists.squeakfoundation.org wrote: > > Date: Fri, 9 Jan 2015 10:55:22 +0100 > From: Henrik Johansen > > Subject: Re: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file > descriptors > >> On 09 Jan 2015, at 10:44 , Max Leske > wrote: >> >> >>> On 09 Jan 2015, at 10:25, vm-dev-request@lists.squeakfoundation.org > wrote: >>> >>> Date: Fri, 9 Jan 2015 10:24:42 +0100 >>> From: Henrik Johansen >> >>> Subject: Re: [squeak-dev] [Vm-dev] [OSProcess] forking and file >>> descriptors >>> >>> >>>> On 09 Jan 2015, at 9:32 , Max Leske >> wrote: >>>> >>>> >>> >>>> That would mean that I must not close any sockets in the child. One option, it seems to me, is to suspend all processes that use sockets. Terminating them might pose another problem, if socket destruction is part of an unwind block in one of the processes (e.g. TCP connections in Seaside) then sockets will be destroyed during termination. >>>> >>>> Another option: set all the socket handles to nil, then terminate the processes (yes ugly, but it might just work?). >>> >>> Just beware you might run into the issue that resuming a processes waiting for a semaphore will proceed as if the semaphore were signalled, >>> Can't tell offhand if that would actually be a problem in this case, or if the affected processes would promptly resume waiting after socket read/writes may initiate with no data. >> >> I wouldn?t resume any of those processes if I can help it. After creating the segment the child kills itself. Thanks for pointing that out though. > > I was thinking you'd need to suspend the processes in the parent, before forking off a child, (to ensure there will be no possibility of a process running before it's suspended in the child) then resume after forking? I?m hoping that I can get around that by using #valueUninterruptibly (or similar). It would be much nicer to leave the parent as it is and do everything related to the snapshot in the child. But maybe I?ll have to suspend the processes in the parent in the end. > >> >>> >>> Another (probably non-portable, which would be painful if not consistent across platforms) option: >>> Forget about image-side handling, and alter the SocketPlugin to set FD_CLOEXEC if available when opening sockets. (It's in http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fcntl.h.html > , but that's rather new) >>> On newer Linuxen, you also have SOCK_CLOEXEC for socket(), which opens/sets in an atomic operation, but the race condition avoided by that is hardly relevant in our case. >> >> True. But I really don?t want to maintain a branch of OSProcess :) > It wouldn't be a branch of OSProcess, but an update to the platform SocketPlugin sources. > > I was probably wrong and it's not so new (wouldn't it be nice if all API's had the same structure as Postgres, where checking previous versions is *really* easy?), the 2004 version of the standard also includes it. A cursory check indicates at least OSX/*BSD/*Solaris would support it as well. > Doing the equivalent on Windows seems to have certain caveats though... > http://stackoverflow.com/questions/12058911/can-tcp-socket-handles-be-set-not-inheritable I?m not entirely sure that what you are suggesting will work, at least not with FD_CLOEXEC. man fcntl says: File descriptor flags The following commands manipulate the flags associated with a file descriptor. Currently, only one such flag is defined: FD_CLOEXEC , the close-on-exec flag. If the FD_CLOEXEC bit is 0, the file descriptor will remain open across an execve(2) , otherwise it will be closed. IIRC fork doesn?t use exec, so this flag doesn?t change anything for my scenario. [1] seems to confirm this. Cheers, Max [1] http://stackoverflow.com/questions/5713242/linux-fork-prevent-file-descriptors-inheritance > > Cheers, > Henry -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/9855f80a/attachment.htm From commits at source.squeak.org Fri Jan 9 12:34:59 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 9 12:35:00 2015 Subject: [squeak-dev] The Trunk: Graphics-kfr.304.mcz Message-ID: Karl Ramberg uploaded a new version of Graphics to project The Trunk: http://source.squeak.org/trunk/Graphics-kfr.304.mcz ==================== Summary ==================== Name: Graphics-kfr.304 Author: kfr Time: 9 January 2015, 1:34:19.648 pm UUID: 5d91df23-754f-2943-a152-9111ccf644e0 Ancestors: Graphics-bf.303 GIFReadWriter>>close caused error since change to read only file stream reading =============== Diff against Graphics-bf.303 =============== Item was removed: - ----- Method: GIFReadWriter>>close (in category 'stream access') ----- - close - "Write terminator" - self nextPut: Terminator. - ^super close! From marcel.taeumel at student.hpi.uni-potsdam.de Fri Jan 9 12:45:12 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri Jan 9 12:47:14 2015 Subject: [squeak-dev] Re: The Trunk: Graphics-kfr.304.mcz In-Reply-To: References: Message-ID: <1420807512845-4798555.post@n4.nabble.com> Is that terminator written in the write-case? Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Graphics-kfr-304-mcz-tp4798553p4798555.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From lewis at mail.msen.com Fri Jan 9 12:51:43 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri Jan 9 12:51:46 2015 Subject: [squeak-dev] Re: [Vm-dev] [OSProcess] forking and file descriptors In-Reply-To: <4C2212B6-626F-4ECF-9D17-52C096B86A82@gmail.com> References: <54aedf21.115de00a.4286.1398SMTPIN_ADDED_MISSING@mx.google.com> <4C2212B6-626F-4ECF-9D17-52C096B86A82@gmail.com> Message-ID: <20150109125143.GA21591@shell.msen.com> On Fri, Jan 09, 2015 at 09:32:53AM +0100, Max Leske wrote: > > OSProcess uses plain fork() (in forkSqueak()). That???s what I use from the image. > > > If their memory is shared (clone) instead of copied (fork), you might be kicking the feet out from under the parent image as well, so to speak??? > > From my understanding the file descriptors should be copied (fork). So that shouldn???t happen (but see above???). > The method comment in UnixOSProcessPlugin>>forkSqueak may be helpful, so I will copy it here: forkSqueak "Fork a child process, and continue running squeak in the child process. Answer the result of the fork() call, either the child pid or zero. After calling fork(), two OS processes exist, one of which is the child of the other. On systems which implement copy-on-write memory management, and which support the fork() system call, both processes will be running Smalltalk images, and will be sharing the same memory space. In the original OS process, the resulting value of pid is the process id of the child process (a non-zero integer). In the child process, the value of pid is zero. The child recreates sufficient external resources to continue running. This is done by attaching to a new X session. The child is otherwise a copy of the parent process, and will continue executing the Smalltalk image at the same point as its parent. The return value of this primitive may be used by the two running Smalltalk images to determine which is the parent and which is the child. The child should not depend on using existing connections to external resources. For example, the child may lose its connections to stdin, stdout, and stderr after its parent exits. The new child image does not start itself from the image in the file system; rather it is a clone of the parent image as it existed at the time of primitiveForkSqueak. For this reason, the parent and child should agree in advance as to whom is allowed to save the image to the file system, otherwise one Smalltalk may overwrite the image of the other. This is a simple call to fork(), rather than the more common idiom of vfork() followed by exec(). The vfork() call cannot be used here because it is designed to be followed by an exec(), and its semantics require the parent process to wait for the child to exit. See the BSD programmers documentation for details." | pid intervalTimer saveIntervalTimer | "Turn off the interval timer. If this is not done, then the program which we exec in the child process will receive a timer interrupt, and will not know how to handle it." self cCode: 'intervalTimer.it_interval.tv_sec = 0'. self cCode: 'intervalTimer.it_interval.tv_usec = 0'. self cCode: 'intervalTimer.it_value.tv_sec = 0'. self cCode: 'intervalTimer.it_value.tv_usec = 0'. self cCode: 'setitimer (ITIMER_REAL, &intervalTimer, &saveIntervalTimer)'. pid := self fork. "Enable the timer again before resuming Smalltalk." self cCode: 'setitimer (ITIMER_REAL, &saveIntervalTimer, 0L)'. ^ pid From commits at source.squeak.org Fri Jan 9 12:58:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 9 12:58:28 2015 Subject: [squeak-dev] The Trunk: System-kfr.693.mcz Message-ID: Karl Ramberg uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-kfr.693.mcz ==================== Summary ==================== Name: System-kfr.693 Author: kfr Time: 2 January 2015, 8:41:05.888 pm UUID: 760e94c5-2386-f642-a545-55a1fe293351 Ancestors: System-bf.692 empty log message =============== Diff against System-bf.692 =============== Item was changed: ----- Method: Preferences class>>loadPreferencesFrom: (in category 'personalization') ----- + loadPreferencesFrom: aFile - loadPreferencesFrom: aFileName | stream params dict desktopColor | + stream := ReferenceStream on: aFile. - stream := ReferenceStream fileNamed: aFileName. params := stream next. self assert: (params isKindOf: IdentityDictionary). params removeKey: #PersonalDictionaryOfPreferences. dict := stream next. self assert: (dict isKindOf: IdentityDictionary). desktopColor := stream next. stream close. dict keysAndValuesDo: [:key :value | (self preferenceAt: key ifAbsent: [nil]) ifNotNil: [:pref | pref preferenceValue: value preferenceValue]]. params keysAndValuesDo: [ :key :value | self setParameter: key to: value ]. Smalltalk isMorphic ifTrue: [ World fillStyle: desktopColor ] ifFalse: [ self desktopColor: desktopColor. ScheduledControllers updateGray ]. ! Item was changed: ----- Method: Preferences class>>restorePreferencesFromDisk (in category 'personalization') ----- restorePreferencesFromDisk + | result | + result := (FileList2 modalFileSelectorForSuffixes: #('prefs')) . + result ifNil: [^ self]. + self restorePreferencesFromDisk: result + - (FileDirectory default fileExists: 'my.prefs') - ifTrue: [ Cursor wait showWhile: [ - [ self loadPreferencesFrom: 'my.prefs' ] on: Error do: [ :ex | self inform: 'there was an error restoring the preferences' ] - ] ] - ifFalse: [ self inform: 'you haven''t saved your preferences yet!!' ]. ! Item was added: + ----- Method: Preferences class>>restorePreferencesFromDisk: (in category 'personalization') ----- + restorePreferencesFromDisk: aFile + Cursor wait + showWhile: [[self loadPreferencesFrom: aFile] + on: Error + do: [:ex | self halt.self inform: 'there was an error restoring the preferences' translated]]! Item was changed: ----- Method: Preferences class>>storePreferencesToDisk (in category 'personalization') ----- storePreferencesToDisk + | newName | + newName := UIManager default request: 'Please confirm name for save...' initialAnswer: 'myPreferences'. + newName isEmpty + ifTrue: [^ self]. + Cursor wait + showWhile: [[self storePreferencesIn: newName , '.prefs'] + on: Error + do: [:ex | self inform: 'there was an error storing your preferences to disk. you probably already have stored your preferences' translated]]! - Cursor wait showWhile: [ - [ self storePreferencesIn: 'my.prefs' ] on: Error do: [ :ex | self inform: 'there was an error storing your preferences to disk' ]]! From commits at source.squeak.org Fri Jan 9 12:58:56 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 9 12:58:56 2015 Subject: [squeak-dev] The Trunk: System-kfr.694.mcz Message-ID: Karl Ramberg uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-kfr.694.mcz ==================== Summary ==================== Name: System-kfr.694 Author: kfr Time: 9 January 2015, 1:54:05.175 pm UUID: 0c27d195-86eb-ab4e-ba53-b35c502fb375 Ancestors: System-kfr.693 empty log message =============== Diff against System-kfr.693 =============== Item was changed: ----- Method: Preferences class>>giveHelpWithPreferences (in category 'misc') ----- giveHelpWithPreferences "Open up a workspace with explanatory info in it about Preferences" | aString | aString := String streamContents: [:aStream | aStream nextPutAll: 'Many aspects of the system are governed by the settings of various "Preferences". Click on any of brown tabs at the top of the panel to see all the preferences in that category. Or type in to the box above the Search button, then hit Search, and all Preferences matching whatever you typed in will appear in the "search results" category. A preference is considered to match your search if either its name matches the characters *or* if anything in the balloon help provided for the preferences matches the search text. To find out more about any particular Preference, hold the mouse over it for a moment and balloon help will appear. Also, a complete list of all the Preferences, with documentation for each, is included below. Preferences whose names are in shown in bold in the Preferences Panel are designated as being allowed to vary from project to project; those whose name are not in bold are "global", which is to say, they apply equally whatever project you are in. Click on the name of any preference to get a menu which allows you to *change* whether the preference should vary from project to project or should be global, and also allows you to browse all the senders of the preference, and to discover all the categories under which the preference has been classified, and to be handed a button that you can drop wherever you please that will control the preference. If you like all your current Preferences settings, you may wish to hit the "Save Current Settings as my Personal Preferences" button. Once you have done that, you can at any point in the future hit "Restore my Personal Preferences" and all your saved settings will get restored immediately. Also, you can use "themes" to set multiple preferences all at once; click on the "change theme..." button in the Squeak flap or in the Preferences panel, or seek out the themes item in the Appearance menu.' translated. aStream cr; cr; nextPutAll: '-----------------------------------------------------------------'; cr; cr; nextPutAll: 'Alphabetical listing of all Preferences' translated; cr; cr. (Preferences allPreferenceObjects asSortedCollection: [:a :b | a name < b name]) do: [:pref | | aHelpString | aStream nextPutAll: pref name; cr. aHelpString := pref helpString translated. (aHelpString beginsWith: pref name) ifTrue: + [aHelpString := aHelpString copyFrom: (pref name size ) to: aHelpString size]. - [aHelpString := aHelpString copyFrom: (pref name size + 3) to: aHelpString size]. aHelpString := (aHelpString copyReplaceAll: String cr with: ' ') copyWithout: Character tab. aStream nextPutAll: aHelpString capitalized. (aHelpString isEmpty or: [aHelpString last == $.]) ifFalse: [aStream nextPut: $.]. aStream cr; cr]]. UIManager default edit: aString label: 'About Preferences' translated "Preferences giveHelpWithPreferences"! Item was added: + ----- Method: Preferences class>>parameters (in category 'parameters') ----- + parameters + + "Preferences parameters explore" + ^Parameters! Item was changed: ----- Method: Preferences class>>restorePreferencesFromDisk: (in category 'personalization') ----- restorePreferencesFromDisk: aFile Cursor wait showWhile: [[self loadPreferencesFrom: aFile] on: Error + do: [:ex | self inform: 'there was an error restoring the preferences' translated]]! - do: [:ex | self halt.self inform: 'there was an error restoring the preferences' translated]]! Item was changed: ----- Method: Preferences class>>togglePreference: (in category 'get/set') ----- togglePreference: prefSymbol "Toggle the given preference. prefSymbol must be of a boolean preference" + (self preferenceAt: prefSymbol ifAbsent: [self inform: 'unknown preference: ', prefSymbol]) togglePreferenceValue! - (self preferenceAt: prefSymbol ifAbsent: [self error: 'unknown preference: ', prefSymbol]) togglePreferenceValue! From karlramberg at gmail.com Fri Jan 9 13:02:32 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri Jan 9 13:02:34 2015 Subject: [squeak-dev] Re: The Trunk: Graphics-kfr.304.mcz In-Reply-To: <1420807512845-4798555.post@n4.nabble.com> References: <1420807512845-4798555.post@n4.nabble.com> Message-ID: Yes it is. Unfortunatly Karl On Fri, Jan 9, 2015 at 1:45 PM, Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > Is that terminator written in the write-case? > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Trunk-Graphics-kfr-304-mcz-tp4798553p4798555.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/04a2a9a2/attachment.htm From karlramberg at gmail.com Fri Jan 9 13:09:29 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri Jan 9 13:09:31 2015 Subject: [squeak-dev] The Trunk: System-kfr.694.mcz In-Reply-To: <54afd096.c887e00a.20c1.49e1SMTPIN_ADDED_MISSING@mx.google.com> References: <54afd096.c887e00a.20c1.49e1SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Sorry for empty log message. This change opens the file list so it's easier to locate a saved preference file on the disk Karl On Fri, Jan 9, 2015 at 1:58 PM, wrote: > Karl Ramberg uploaded a new version of System to project The Trunk: > http://source.squeak.org/trunk/System-kfr.694.mcz > > ==================== Summary ==================== > > Name: System-kfr.694 > Author: kfr > Time: 9 January 2015, 1:54:05.175 pm > UUID: 0c27d195-86eb-ab4e-ba53-b35c502fb375 > Ancestors: System-kfr.693 > > empty log message > > =============== Diff against System-kfr.693 =============== > > Item was changed: > ----- Method: Preferences class>>giveHelpWithPreferences (in category > 'misc') ----- > giveHelpWithPreferences > "Open up a workspace with explanatory info in it about Preferences" > > | aString | > aString := String streamContents: [:aStream | > aStream nextPutAll: > > 'Many aspects of the system are governed by the settings of various > "Preferences". > > Click on any of brown tabs at the top of the panel to see all the > preferences in that category. > Or type in to the box above the Search button, then hit Search, and all > Preferences matching whatever you typed in will appear in the "search > results" category. A preference is considered to match your search if > either its name matches the characters *or* if anything in the balloon help > provided for the preferences matches the search text. > > To find out more about any particular Preference, hold the mouse over it > for a moment and balloon help will appear. Also, a complete list of all > the Preferences, with documentation for each, is included below. > > Preferences whose names are in shown in bold in the Preferences Panel > are designated as being allowed to vary from project to project; those > whose name are not in bold are "global", which is to say, they apply > equally whatever project you are in. > > Click on the name of any preference to get a menu which allows you to > *change* whether the preference should vary from project to project or > should be global, and also allows you to browse all the senders of the > preference, and to discover all the categories under which the preference > has been classified, and to be handed a button that you can drop wherever > you please that will control the preference. > > If you like all your current Preferences settings, you may wish to hit > the "Save Current Settings as my Personal Preferences" button. Once you > have done that, you can at any point in the future hit "Restore my Personal > Preferences" and all your saved settings will get restored immediately. > > Also, you can use "themes" to set multiple preferences all at once; > click on the "change theme..." button in the Squeak flap or in the > Preferences panel, or seek out the themes item in the Appearance menu.' > translated. > > aStream cr; cr; nextPutAll: > '-----------------------------------------------------------------'; > cr; cr; nextPutAll: 'Alphabetical listing of all > Preferences' translated; cr; cr. > (Preferences allPreferenceObjects asSortedCollection: [:a :b | a name > < b name]) do: > [:pref | | aHelpString | > aStream nextPutAll: pref name; cr. > aHelpString := pref helpString translated. > (aHelpString beginsWith: pref name) ifTrue: > + [aHelpString := aHelpString copyFrom: (pref name > size ) to: aHelpString size]. > - [aHelpString := aHelpString copyFrom: (pref name > size + 3) to: aHelpString size]. > aHelpString := (aHelpString copyReplaceAll: String cr > with: ' ') copyWithout: Character tab. > aStream nextPutAll: aHelpString capitalized. > (aHelpString isEmpty or: [aHelpString last == $.]) > ifFalse: [aStream nextPut: $.]. > aStream cr; cr]]. > > UIManager default edit: aString label: 'About Preferences' > translated > > "Preferences giveHelpWithPreferences"! > > Item was added: > + ----- Method: Preferences class>>parameters (in category 'parameters') > ----- > + parameters > + > + "Preferences parameters explore" > + ^Parameters! > > Item was changed: > ----- Method: Preferences class>>restorePreferencesFromDisk: (in > category 'personalization') ----- > restorePreferencesFromDisk: aFile > Cursor wait > showWhile: [[self loadPreferencesFrom: aFile] > on: Error > + do: [:ex | self inform: 'there was an > error restoring the preferences' translated]]! > - do: [:ex | self halt.self inform: 'there > was an error restoring the preferences' translated]]! > > Item was changed: > ----- Method: Preferences class>>togglePreference: (in category > 'get/set') ----- > togglePreference: prefSymbol > "Toggle the given preference. prefSymbol must be of a boolean > preference" > + (self preferenceAt: prefSymbol ifAbsent: [self inform: 'unknown > preference: ', prefSymbol]) togglePreferenceValue! > - (self preferenceAt: prefSymbol ifAbsent: [self error: 'unknown > preference: ', prefSymbol]) togglePreferenceValue! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/fb81e6e8/attachment.htm From karlramberg at gmail.com Fri Jan 9 13:22:57 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri Jan 9 13:23:00 2015 Subject: [squeak-dev] Problem with image lock up with self error: Message-ID: Hi, Image lock up doing Preferences togglePreference: #justATest If I change error: to inform: in the method I do not get a image lock up. This is in a trunk image and tested with several Cog VM on Windows. Preferences>>togglePreference: prefSymbol "Toggle the given preference. prefSymbol must be of a boolean preference" (self preferenceAt: prefSymbol ifAbsent: [self error: 'unknown preference: ', prefSymbol]) togglePreferenceValue Karl -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/fe1792f3/attachment.htm From lewis at mail.msen.com Fri Jan 9 14:08:24 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri Jan 9 14:08:26 2015 Subject: [squeak-dev] Problem with image lock up with self error: In-Reply-To: References: Message-ID: <20150109140824.GA34777@shell.msen.com> On Fri, Jan 09, 2015 at 02:22:57PM +0100, karl ramberg wrote: > Hi, > > Image lock up doing > Preferences togglePreference: #justATest > > If I change error: to inform: in the method I do not get a image lock up. > > This is in a trunk image and tested with several Cog VM on Windows. > > Preferences>>togglePreference: prefSymbol > "Toggle the given preference. prefSymbol must be of a boolean preference" > (self preferenceAt: prefSymbol ifAbsent: [self error: 'unknown preference: > ', prefSymbol]) togglePreferenceValue > > Karl Confirmed. I get the same result on Linux with an interpreter VM. Dave From leves at elte.hu Fri Jan 9 15:01:50 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri Jan 9 15:01:57 2015 Subject: [squeak-dev] Problem with image lock up with self error: In-Reply-To: References: Message-ID: It's because the error occurs in the critical section of AccessLock, so it'll stay locked during error handling. This probably locks up the debugger, because it can't access the preferences. Here's a fix: preferenceAt: aSymbol ifAbsent: aBlock "Answer the Preference object at the given symbol, or the value of aBlock if not present" self accessDictionaryOfPreferencesIn: [ :dictionaryOfPreferences | dictionaryOfPreferences at: aSymbol ifPresent: [ :preference | ^preference ] ]. ^aBlock value Levente On Fri, 9 Jan 2015, karl ramberg wrote: > Hi, > Image lock up doing > Preferences togglePreference: #justATest > > If I change error: ?to inform: in the method I do not get a image lock up. > > This is in a trunk image and tested with several Cog VM on Windows. > > Preferences>>togglePreference: prefSymbol > "Toggle the given preference. prefSymbol must be of a boolean preference" > (self preferenceAt: prefSymbol ifAbsent: [self error: 'unknown preference: ', prefSymbol]) togglePreferenceValue? > > Karl > > From jeff.gonis at gmail.com Fri Jan 9 16:32:46 2015 From: jeff.gonis at gmail.com (Jeff Gonis) Date: Fri Jan 9 16:32:48 2015 Subject: [squeak-dev] Squeak Bug Tracker Message-ID: Hi Folks, The box admins may already be on the case, but I thought that I would just ping the list and say that the squeak bug tracker page is reporting that it can't access the db and thus can't load. Thanks to the box admins for their hard work resolving all of these issues! Jeff -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/4f8d61c1/attachment.htm From eliot.miranda at gmail.com Fri Jan 9 18:17:32 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 9 18:17:35 2015 Subject: [squeak-dev] Re: Cannot commit VMMaker to source.squeak.org In-Reply-To: References: Message-ID: On Thu, Jan 8, 2015 at 9:59 PM, Levente Uzonyi wrote: > Hi Eliot, > > Yes, this is related to the migration of the service. I've increased the > upload size limit. Sorry for the inconvenience. No need to apologize. Thank you /so much/ for your efforts in getting the system back up. I'm sure we're all really thankful! > > > Levente > > > On Thu, 8 Jan 2015, Eliot Miranda wrote: > > Hi Levente, >> not sure if this is due to the replacement of box2 (I suspect it is) >> but in trying to upload the VMMaker.oscog versions I've been keeping back >> while box2 is repaired/replaced I get the following error: >> >> HTTP/1.1 413 Request Entity Too Large >> Server: nginx >> Date: Fri, 09 Jan 2015 01:00:40 GMT >> Content-Type: text/html >> Content-Length: 192 >> Connection: closeHTTP/1.1 413 Request Entity Too Large >> Server: nginx >> Date: Fri, 09 Jan 2015 01:00:40 GMT >> Content-Type: text/html >> Content-Length: 192 >> Connection: close >> 413 Request Entity Too Large >> >>

413 Request Entity Too Large

>>
nginx
>> >> >> >> The sizes of the packages are currently >> McStalker.Cog$ ls -lh package-cache/VMMaker.oscog-eem.101* >> -rw-r--r--@ 1 eliot staff 3.5M Jan 6 10:52 >> package-cache/VMMaker.oscog-eem.1010.mcz >> -rw-r--r--@ 1 eliot staff 3.5M Jan 8 13:01 >> package-cache/VMMaker.oscog-eem.1011.mcz >> -rw-r--r--@ 1 eliot staff 3.5M Jan 8 17:00 >> package-cache/VMMaker.oscog-eem.1012.mcz >> >> >> I think we should allow at least 5m. Is this possible or will I have to >> split up VMMaker?? (oh no, Mr Billllll!) >> -- >> best,Eliot >> >> -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/0c524b27/attachment.htm From commits at source.squeak.org Fri Jan 9 22:30:20 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 9 22:30:23 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.693.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.693.mcz ==================== Summary ==================== Name: System.spur-kfr.693 Author: eem Time: 9 January 2015, 2:29:43.674 pm UUID: a8dceb19-9180-4687-bc7b-8aa54c6e6fda Ancestors: System-kfr.693, System.spur-bf.692 System-kfr.693 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.234 empty log message =============== Diff against System-kfr.693 =============== Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Fri Jan 9 22:30:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 9 22:30:44 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.694.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.694.mcz ==================== Summary ==================== Name: System.spur-kfr.694 Author: eem Time: 9 January 2015, 2:29:46.084 pm UUID: d734d333-36b9-45a0-b316-e0ae1b7d4a40 Ancestors: System-kfr.694, System.spur-kfr.693 System-kfr.694 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.234 empty log message =============== Diff against System-kfr.694 =============== Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Fri Jan 9 22:32:34 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 9 22:32:35 2015 Subject: [squeak-dev] The Trunk: System-kfr.695.mcz Message-ID: Karl Ramberg uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-kfr.695.mcz ==================== Summary ==================== Name: System-kfr.695 Author: kfr Time: 9 January 2015, 11:31:58.576 pm UUID: 808d324c-59a1-0e42-b83c-c70a7491f7b7 Ancestors: System-kfr.694 Fix a image lock up with preference look up =============== Diff against System-kfr.694 =============== Item was changed: ----- Method: Preferences class>>preferenceAt:ifAbsent: (in category 'preference-object access') ----- preferenceAt: aSymbol ifAbsent: aBlock "Answer the Preference object at the given symbol, or the value of aBlock if not present" + self accessDictionaryOfPreferencesIn: [ :dictionaryOfPreferences | + dictionaryOfPreferences + at: aSymbol + ifPresent: [ :preference | ^preference ] ]. + ^aBlock value! - ^self accessDictionaryOfPreferencesIn: [ :dictionaryOfPreferences | - dictionaryOfPreferences at: aSymbol ifAbsent: aBlock ]! Item was changed: ----- Method: Preferences class>>togglePreference: (in category 'get/set') ----- togglePreference: prefSymbol "Toggle the given preference. prefSymbol must be of a boolean preference" + (self preferenceAt: prefSymbol ifAbsent: [self error: 'unknown preference: ', prefSymbol]) togglePreferenceValue! - (self preferenceAt: prefSymbol ifAbsent: [self inform: 'unknown preference: ', prefSymbol]) togglePreferenceValue! From karlramberg at gmail.com Fri Jan 9 22:33:15 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri Jan 9 22:33:18 2015 Subject: [squeak-dev] Problem with image lock up with self error: In-Reply-To: References: Message-ID: Hi, That fixes the image lock up. I have commited the fix to trunk Karl On Fri, Jan 9, 2015 at 4:01 PM, Levente Uzonyi wrote: > It's because the error occurs in the critical section of AccessLock, so > it'll stay locked during error handling. This probably locks up the > debugger, because it can't access the preferences. > Here's a fix: > > preferenceAt: aSymbol ifAbsent: aBlock > "Answer the Preference object at the given symbol, or the value of > aBlock if not present" > > self accessDictionaryOfPreferencesIn: [ :dictionaryOfPreferences | > dictionaryOfPreferences > at: aSymbol > ifPresent: [ :preference | ^preference ] ]. > ^aBlock value > > Levente > > > On Fri, 9 Jan 2015, karl ramberg wrote: > > Hi, >> Image lock up doing >> Preferences togglePreference: #justATest >> >> If I change error: to inform: in the method I do not get a image lock up. >> >> This is in a trunk image and tested with several Cog VM on Windows. >> >> Preferences>>togglePreference: prefSymbol >> "Toggle the given preference. prefSymbol must be of a boolean preference" >> (self preferenceAt: prefSymbol ifAbsent: [self error: 'unknown >> preference: ', prefSymbol]) togglePreferenceValue >> >> Karl >> >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150109/79aeca86/attachment.htm From lewis at mail.msen.com Fri Jan 9 23:33:01 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri Jan 9 23:33:03 2015 Subject: [squeak-dev] Problem with image lock up with self error: In-Reply-To: References: Message-ID: <20150109233301.GA21418@shell.msen.com> That fixed it. Thanks Karl and Levente! Dave On Fri, Jan 09, 2015 at 11:33:15PM +0100, karl ramberg wrote: > Hi, > That fixes the image lock up. > I have commited the fix to trunk > > Karl > > On Fri, Jan 9, 2015 at 4:01 PM, Levente Uzonyi wrote: > > > It's because the error occurs in the critical section of AccessLock, so > > it'll stay locked during error handling. This probably locks up the > > debugger, because it can't access the preferences. > > Here's a fix: > > > > preferenceAt: aSymbol ifAbsent: aBlock > > "Answer the Preference object at the given symbol, or the value of > > aBlock if not present" > > > > self accessDictionaryOfPreferencesIn: [ :dictionaryOfPreferences | > > dictionaryOfPreferences > > at: aSymbol > > ifPresent: [ :preference | ^preference ] ]. > > ^aBlock value > > > > Levente > > > > > > On Fri, 9 Jan 2015, karl ramberg wrote: > > > > Hi, > >> Image lock up doing > >> Preferences togglePreference: #justATest > >> > >> If I change error: to inform: in the method I do not get a image lock up. > >> > >> This is in a trunk image and tested with several Cog VM on Windows. > >> > >> Preferences>>togglePreference: prefSymbol > >> "Toggle the given preference. prefSymbol must be of a boolean preference" > >> (self preferenceAt: prefSymbol ifAbsent: [self error: 'unknown > >> preference: ', prefSymbol]) togglePreferenceValue > >> > >> Karl > >> > From commits at source.squeak.org Fri Jan 9 23:54:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 9 23:54:44 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.695.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.695.mcz ==================== Summary ==================== Name: System.spur-kfr.695 Author: eem Time: 9 January 2015, 3:54:20.541 pm UUID: 47193e8a-3670-4d50-9f56-086ecac0c7d4 Ancestors: System-kfr.695, System.spur-kfr.694 System-kfr.695 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.234 Fix a image lock up with preference look up =============== Diff against System-kfr.695 =============== Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Sat Jan 10 14:10:15 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 10 14:10:16 2015 Subject: [squeak-dev] The Inbox: Graphics-kfr.304.mcz Message-ID: A new version of Graphics was added to project The Inbox: http://source.squeak.org/inbox/Graphics-kfr.304.mcz ==================== Summary ==================== Name: Graphics-kfr.304 Author: kfr Time: 9 January 2015, 1:34:19.648 pm UUID: 5d91df23-754f-2943-a152-9111ccf644e0 Ancestors: Graphics-bf.303 GIFReadWriter>>close caused error since change to read only file stream reading =============== Diff against Graphics-bf.303 =============== Item was removed: - ----- Method: GIFReadWriter>>close (in category 'stream access') ----- - close - "Write terminator" - self nextPut: Terminator. - ^super close! From Das.Linux at gmx.de Sat Jan 10 18:27:20 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Sat Jan 10 18:27:20 2015 Subject: [squeak-dev] The Inbox: Graphics-kfr.304.mcz Message-ID: <79D63895-D6B2-46A0-8B82-F50FE44D301C@gmx.de> Isn't that already in trunk? On 10.01.2015, at 14:10, commits@source.squeak.org wrote: > A new version of Graphics was added to project The Inbox: > http://source.squeak.org/inbox/Graphics-kfr.304.mcz > > ==================== Summary ==================== > > Name: Graphics-kfr.304 > Author: kfr > Time: 9 January 2015, 1:34:19.648 pm > UUID: 5d91df23-754f-2943-a152-9111ccf644e0 > Ancestors: Graphics-bf.303 > > GIFReadWriter>>close caused error since change to read only file stream reading > > =============== Diff against Graphics-bf.303 =============== > > Item was removed: From astares at gmx.de Sat Jan 10 20:21:08 2015 From: astares at gmx.de (Torsten Bergmann) Date: Sat Jan 10 20:21:11 2015 Subject: [squeak-dev] [OT] Things people built with Smalltalk on Twitter: #thingsPeopleBuiltWithSmalltalk Message-ID: If you know something built in Smalltalk then twitter it: https://twitter.com/hashtag/thingsPeopleBuiltWithSmalltalk?src=hash Lets make 2015 the "Anybody knows about Smalltalk" year ;) From asqueaker at gmail.com Sat Jan 10 21:31:09 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sat Jan 10 21:31:12 2015 Subject: [squeak-dev] The Trunk: System-kfr.693.mcz In-Reply-To: <54afd078.4908e00a.20da.0ad5SMTPIN_ADDED_MISSING@mx.google.com> References: <54afd078.4908e00a.20da.0ad5SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: I strongly object to this change! I use this feature everytime I start a base image, but now you've introduced an unnecessary and horribly-hard-to-use modal UI interaction to something that, previously, could be done in one-click or non-interactively via script. I'm sorry, but this is utterly *awful* and, wrong-headed in the first place. There is now no quick and easy way to transfer of personal preferences from one image to another -- I have to click 57 times instead of 1. No way. Please put it back the way it was and let's talk about what you want to do and work out an amicable way of doing it before slamming such a thing into trunk. My guess is you want to have multiple .prefs files. Maybe we need a new button for that. Or, how about holding the Shift key when clicking "load from disk" as a way to tell it to pop up your file-selection dialog? PS -- Plus, you forgot to put a log message in the version and now its part of trunk. Please always include a log message explaining "why" (not "what") the change is being made. On Fri, Jan 9, 2015 at 6:58 AM, wrote: > Karl Ramberg uploaded a new version of System to project The Trunk: > http://source.squeak.org/trunk/System-kfr.693.mcz > > ==================== Summary ==================== > > Name: System-kfr.693 > Author: kfr > Time: 2 January 2015, 8:41:05.888 pm > UUID: 760e94c5-2386-f642-a545-55a1fe293351 > Ancestors: System-bf.692 > > empty log message > > =============== Diff against System-bf.692 =============== > > Item was changed: > ----- Method: Preferences class>>loadPreferencesFrom: (in category 'personalization') ----- > + loadPreferencesFrom: aFile > - loadPreferencesFrom: aFileName > | stream params dict desktopColor | > + stream := ReferenceStream on: aFile. > - stream := ReferenceStream fileNamed: aFileName. > params := stream next. > self assert: (params isKindOf: IdentityDictionary). > params removeKey: #PersonalDictionaryOfPreferences. > dict := stream next. > self assert: (dict isKindOf: IdentityDictionary). > desktopColor := stream next. > stream close. > dict keysAndValuesDo: > [:key :value | (self preferenceAt: key ifAbsent: [nil]) ifNotNil: > [:pref | pref preferenceValue: value preferenceValue]]. > > params keysAndValuesDo: [ :key :value | self setParameter: key to: value ]. > > Smalltalk isMorphic > ifTrue: [ World fillStyle: desktopColor ] > ifFalse: [ self desktopColor: desktopColor. ScheduledControllers updateGray ]. > ! > > Item was changed: > ----- Method: Preferences class>>restorePreferencesFromDisk (in category 'personalization') ----- > restorePreferencesFromDisk > + | result | > + result := (FileList2 modalFileSelectorForSuffixes: #('prefs')) . > + result ifNil: [^ self]. > + self restorePreferencesFromDisk: result > + > - (FileDirectory default fileExists: 'my.prefs') > - ifTrue: [ Cursor wait showWhile: [ > - [ self loadPreferencesFrom: 'my.prefs' ] on: Error do: [ :ex | self inform: 'there was an error restoring the preferences' ] > - ] ] > - ifFalse: [ self inform: 'you haven''t saved your preferences yet!!' ]. > ! > > Item was added: > + ----- Method: Preferences class>>restorePreferencesFromDisk: (in category 'personalization') ----- > + restorePreferencesFromDisk: aFile > + Cursor wait > + showWhile: [[self loadPreferencesFrom: aFile] > + on: Error > + do: [:ex | self halt.self inform: 'there was an error restoring the preferences' translated]]! > > Item was changed: > ----- Method: Preferences class>>storePreferencesToDisk (in category 'personalization') ----- > storePreferencesToDisk > + | newName | > + newName := UIManager default request: 'Please confirm name for save...' initialAnswer: 'myPreferences'. > + newName isEmpty > + ifTrue: [^ self]. > + Cursor wait > + showWhile: [[self storePreferencesIn: newName , '.prefs'] > + on: Error > + do: [:ex | self inform: 'there was an error storing your preferences to disk. you probably already have stored your preferences' translated]]! > - Cursor wait showWhile: [ > - [ self storePreferencesIn: 'my.prefs' ] on: Error do: [ :ex | self inform: 'there was an error storing your preferences to disk' ]]! > > From asqueaker at gmail.com Sat Jan 10 21:38:39 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sat Jan 10 21:38:42 2015 Subject: [squeak-dev] The Trunk: System-kfr.694.mcz In-Reply-To: References: <54afd096.c887e00a.20c1.49e1SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: It's much harder, not easier. Before it was one-click, now it's multiple and I have to name my prefs file? Please tell us what your real requirement is. It's to support multiple .prefs files isn't it? My requirement is one-click transfer of preferences from one image to another. On Fri, Jan 9, 2015 at 7:09 AM, karl ramberg wrote: > Sorry for empty log message. > This change opens the file list so it's easier to locate a saved preference > file on the disk > > Karl > > On Fri, Jan 9, 2015 at 1:58 PM, wrote: >> >> Karl Ramberg uploaded a new version of System to project The Trunk: >> http://source.squeak.org/trunk/System-kfr.694.mcz >> >> ==================== Summary ==================== >> >> Name: System-kfr.694 >> Author: kfr >> Time: 9 January 2015, 1:54:05.175 pm >> UUID: 0c27d195-86eb-ab4e-ba53-b35c502fb375 >> Ancestors: System-kfr.693 >> >> empty log message >> >> =============== Diff against System-kfr.693 =============== >> >> Item was changed: >> ----- Method: Preferences class>>giveHelpWithPreferences (in category >> 'misc') ----- >> giveHelpWithPreferences >> "Open up a workspace with explanatory info in it about >> Preferences" >> >> | aString | >> aString := String streamContents: [:aStream | >> aStream nextPutAll: >> >> 'Many aspects of the system are governed by the settings of various >> "Preferences". >> >> Click on any of brown tabs at the top of the panel to see all the >> preferences in that category. >> Or type in to the box above the Search button, then hit Search, and all >> Preferences matching whatever you typed in will appear in the "search >> results" category. A preference is considered to match your search if >> either its name matches the characters *or* if anything in the balloon help >> provided for the preferences matches the search text. >> >> To find out more about any particular Preference, hold the mouse over it >> for a moment and balloon help will appear. Also, a complete list of all the >> Preferences, with documentation for each, is included below. >> >> Preferences whose names are in shown in bold in the Preferences Panel >> are designated as being allowed to vary from project to project; those whose >> name are not in bold are "global", which is to say, they apply equally >> whatever project you are in. >> >> Click on the name of any preference to get a menu which allows you to >> *change* whether the preference should vary from project to project or >> should be global, and also allows you to browse all the senders of the >> preference, and to discover all the categories under which the preference >> has been classified, and to be handed a button that you can drop wherever >> you please that will control the preference. >> >> If you like all your current Preferences settings, you may wish to hit >> the "Save Current Settings as my Personal Preferences" button. Once you >> have done that, you can at any point in the future hit "Restore my Personal >> Preferences" and all your saved settings will get restored immediately. >> >> Also, you can use "themes" to set multiple preferences all at once; >> click on the "change theme..." button in the Squeak flap or in the >> Preferences panel, or seek out the themes item in the Appearance menu.' >> translated. >> >> aStream cr; cr; nextPutAll: >> '-----------------------------------------------------------------'; >> cr; cr; nextPutAll: 'Alphabetical listing of all >> Preferences' translated; cr; cr. >> (Preferences allPreferenceObjects asSortedCollection: [:a :b | a name >> < b name]) do: >> [:pref | | aHelpString | >> aStream nextPutAll: pref name; cr. >> aHelpString := pref helpString translated. >> (aHelpString beginsWith: pref name) ifTrue: >> + [aHelpString := aHelpString copyFrom: (pref name >> size ) to: aHelpString size]. >> - [aHelpString := aHelpString copyFrom: (pref name >> size + 3) to: aHelpString size]. >> aHelpString := (aHelpString copyReplaceAll: String cr >> with: ' ') copyWithout: Character tab. >> aStream nextPutAll: aHelpString capitalized. >> (aHelpString isEmpty or: [aHelpString last == $.]) >> ifFalse: [aStream nextPut: $.]. >> aStream cr; cr]]. >> >> UIManager default edit: aString label: 'About Preferences' >> translated >> >> "Preferences giveHelpWithPreferences"! >> >> Item was added: >> + ----- Method: Preferences class>>parameters (in category 'parameters') >> ----- >> + parameters >> + >> + "Preferences parameters explore" >> + ^Parameters! >> >> Item was changed: >> ----- Method: Preferences class>>restorePreferencesFromDisk: (in >> category 'personalization') ----- >> restorePreferencesFromDisk: aFile >> Cursor wait >> showWhile: [[self loadPreferencesFrom: aFile] >> on: Error >> + do: [:ex | self inform: 'there was an >> error restoring the preferences' translated]]! >> - do: [:ex | self halt.self inform: 'there >> was an error restoring the preferences' translated]]! >> >> Item was changed: >> ----- Method: Preferences class>>togglePreference: (in category >> 'get/set') ----- >> togglePreference: prefSymbol >> "Toggle the given preference. prefSymbol must be of a boolean >> preference" >> + (self preferenceAt: prefSymbol ifAbsent: [self inform: 'unknown >> preference: ', prefSymbol]) togglePreferenceValue! >> - (self preferenceAt: prefSymbol ifAbsent: [self error: 'unknown >> preference: ', prefSymbol]) togglePreferenceValue! >> >> > > > > From karlramberg at gmail.com Sat Jan 10 23:17:30 2015 From: karlramberg at gmail.com (karl ramberg) Date: Sat Jan 10 23:17:33 2015 Subject: [squeak-dev] The Inbox: Graphics-kfr.304.mcz In-Reply-To: <79D63895-D6B2-46A0-8B82-F50FE44D301C@gmx.de> References: <79D63895-D6B2-46A0-8B82-F50FE44D301C@gmx.de> Message-ID: yes On Sat, Jan 10, 2015 at 7:27 PM, Tobias Pape wrote: > Isn't that already in trunk? > > > On 10.01.2015, at 14:10, commits@source.squeak.org wrote: > > > A new version of Graphics was added to project The Inbox: > > http://source.squeak.org/inbox/Graphics-kfr.304.mcz > > > > ==================== Summary ==================== > > > > Name: Graphics-kfr.304 > > Author: kfr > > Time: 9 January 2015, 1:34:19.648 pm > > UUID: 5d91df23-754f-2943-a152-9111ccf644e0 > > Ancestors: Graphics-bf.303 > > > > GIFReadWriter>>close caused error since change to read only file stream > reading > > > > =============== Diff against Graphics-bf.303 =============== > > > > Item was removed: > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150111/5cf76dfa/attachment.htm From commits at source.squeak.org Sat Jan 10 23:21:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 10 23:21:01 2015 Subject: [squeak-dev] The Trunk: Graphics-kfr.305.mcz Message-ID: Karl Ramberg uploaded a new version of Graphics to project The Trunk: http://source.squeak.org/trunk/Graphics-kfr.305.mcz ==================== Summary ==================== Name: Graphics-kfr.305 Author: kfr Time: 11 January 2015, 12:19:12.738 am UUID: ad7be66f-dd0c-8443-b773-b96836359b05 Ancestors: Graphics-kfr.304 Nil return if stream atEnd true =============== Diff against Graphics-kfr.304 =============== Item was changed: ----- Method: GIFReadWriter>>readBody (in category 'private-decoding') ----- readBody "Read the GIF blocks. Modified to return a form. " | form extype block blocksize packedFields delay1 | form := nil. [stream atEnd] whileFalse: [ block := self next. block = Terminator ifTrue: [^ form]. block = ImageSeparator ifTrue: [ form isNil ifTrue: [form := self readBitData] ifFalse: [self skipBitData]. ] ifFalse: [ block = Extension ifFalse: [^ form "^ self error: 'Unknown block type'"]. "Extension block" extype := self next. "extension type" extype = 16rF9 ifTrue: [ "graphics control" self next = 4 ifFalse: [^ form "^ self error: 'corrupt GIF file'"]. "==== Reserved 3 Bits Disposal Method 3 Bits User Input Flag 1 Bit Transparent Color Flag 1 Bit ===" packedFields := self next. delay1 := self next. "delay time 1" delay := (self next*256 + delay1) *10. "delay time 2" transparentIndex := self next. (packedFields bitAnd: 1) = 0 ifTrue: [transparentIndex := nil]. self next = 0 ifFalse: [^ form "^ self error: 'corrupt GIF file'"]. ] ifFalse: [ "Skip blocks" [(blocksize := self next) > 0] whileTrue: [ "Read the block and ignore it and eat the block terminator" + self next: blocksize]]]]. + ^nil! - self next: blocksize]]]]! From karlramberg at gmail.com Sat Jan 10 23:23:21 2015 From: karlramberg at gmail.com (karl ramberg) Date: Sat Jan 10 23:23:23 2015 Subject: [squeak-dev] The Trunk: System-kfr.693.mcz In-Reply-To: References: <54afd078.4908e00a.20da.0ad5SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Now I remember why I quit comitting to Squeak, Bye On Sat, Jan 10, 2015 at 10:31 PM, Chris Muller wrote: > I strongly object to this change! I use this feature everytime I > start a base image, but now you've introduced an unnecessary and > horribly-hard-to-use modal UI interaction to something that, > previously, could be done in one-click or non-interactively via > script. I'm sorry, but this is utterly *awful* and, wrong-headed in > the first place. There is now no quick and easy way to transfer of > personal preferences from one image to another -- I have to click 57 > times instead of 1. No way. > > Please put it back the way it was and let's talk about what you want > to do and work out an amicable way of doing it before slamming such a > thing into trunk. > > My guess is you want to have multiple .prefs files. Maybe we need a > new button for that. Or, how about holding the Shift key when > clicking "load from disk" as a way to tell it to pop up your > file-selection dialog? > > PS -- Plus, you forgot to put a log message in the version and now its > part of trunk. Please always include a log message explaining "why" > (not "what") the change is being made. > > On Fri, Jan 9, 2015 at 6:58 AM, wrote: > > Karl Ramberg uploaded a new version of System to project The Trunk: > > http://source.squeak.org/trunk/System-kfr.693.mcz > > > > ==================== Summary ==================== > > > > Name: System-kfr.693 > > Author: kfr > > Time: 2 January 2015, 8:41:05.888 pm > > UUID: 760e94c5-2386-f642-a545-55a1fe293351 > > Ancestors: System-bf.692 > > > > empty log message > > > > =============== Diff against System-bf.692 =============== > > > > Item was changed: > > ----- Method: Preferences class>>loadPreferencesFrom: (in category > 'personalization') ----- > > + loadPreferencesFrom: aFile > > - loadPreferencesFrom: aFileName > > | stream params dict desktopColor | > > + stream := ReferenceStream on: aFile. > > - stream := ReferenceStream fileNamed: aFileName. > > params := stream next. > > self assert: (params isKindOf: IdentityDictionary). > > params removeKey: #PersonalDictionaryOfPreferences. > > dict := stream next. > > self assert: (dict isKindOf: IdentityDictionary). > > desktopColor := stream next. > > stream close. > > dict keysAndValuesDo: > > [:key :value | (self preferenceAt: key ifAbsent: [nil]) > ifNotNil: > > [:pref | pref preferenceValue: value > preferenceValue]]. > > > > params keysAndValuesDo: [ :key :value | self setParameter: key > to: value ]. > > > > Smalltalk isMorphic > > ifTrue: [ World fillStyle: desktopColor ] > > ifFalse: [ self desktopColor: desktopColor. > ScheduledControllers updateGray ]. > > ! > > > > Item was changed: > > ----- Method: Preferences class>>restorePreferencesFromDisk (in > category 'personalization') ----- > > restorePreferencesFromDisk > > + | result | > > + result := (FileList2 modalFileSelectorForSuffixes: #('prefs')) . > > + result ifNil: [^ self]. > > + self restorePreferencesFromDisk: result > > + > > - (FileDirectory default fileExists: 'my.prefs') > > - ifTrue: [ Cursor wait showWhile: [ > > - [ self loadPreferencesFrom: 'my.prefs' ] on: > Error do: [ :ex | self inform: 'there was an error restoring the > preferences' ] > > - ] ] > > - ifFalse: [ self inform: 'you haven''t saved your > preferences yet!!' ]. > > ! > > > > Item was added: > > + ----- Method: Preferences class>>restorePreferencesFromDisk: (in > category 'personalization') ----- > > + restorePreferencesFromDisk: aFile > > + Cursor wait > > + showWhile: [[self loadPreferencesFrom: aFile] > > + on: Error > > + do: [:ex | self halt.self inform: 'there > was an error restoring the preferences' translated]]! > > > > Item was changed: > > ----- Method: Preferences class>>storePreferencesToDisk (in category > 'personalization') ----- > > storePreferencesToDisk > > + | newName | > > + newName := UIManager default request: 'Please confirm name for > save...' initialAnswer: 'myPreferences'. > > + newName isEmpty > > + ifTrue: [^ self]. > > + Cursor wait > > + showWhile: [[self storePreferencesIn: newName , '.prefs'] > > + on: Error > > + do: [:ex | self inform: 'there was an > error storing your preferences to disk. you probably already have stored > your preferences' translated]]! > > - Cursor wait showWhile: [ > > - [ self storePreferencesIn: 'my.prefs' ] on: Error do: [ > :ex | self inform: 'there was an error storing your preferences to disk' ]]! > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150111/607e83d7/attachment.htm From lewis at mail.msen.com Sat Jan 10 23:47:36 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat Jan 10 23:47:40 2015 Subject: [squeak-dev] The Trunk: System-kfr.693.mcz In-Reply-To: References: <54afd078.4908e00a.20da.0ad5SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <20150110234736.GA42865@shell.msen.com> On Sun, Jan 11, 2015 at 12:23:21AM +0100, karl ramberg wrote: > Now I remember why I quit comitting to Squeak, > Karl, Please keep committing. Your contributions are appreciated. I appreciate them very much. I especially appreciate that you contribute in areas that matter to real Squeak users, not just the guru types. I have yet not even looked this particular change, but from my point of view, mistakes and wrong steps can be a good thing when done for the right reasons. After all this is trunk, and if we make a change that we do not like, we can always change it back tomorrow. I am quite serious - I really look forward to any change with the kfr stamp, and I don't care at all if a few of those changes do not work out. Chris, Lighten up. Dave > > Bye > > On Sat, Jan 10, 2015 at 10:31 PM, Chris Muller wrote: > > > I strongly object to this change! I use this feature everytime I > > start a base image, but now you've introduced an unnecessary and > > horribly-hard-to-use modal UI interaction to something that, > > previously, could be done in one-click or non-interactively via > > script. I'm sorry, but this is utterly *awful* and, wrong-headed in > > the first place. There is now no quick and easy way to transfer of > > personal preferences from one image to another -- I have to click 57 > > times instead of 1. No way. > > > > Please put it back the way it was and let's talk about what you want > > to do and work out an amicable way of doing it before slamming such a > > thing into trunk. > > > > My guess is you want to have multiple .prefs files. Maybe we need a > > new button for that. Or, how about holding the Shift key when > > clicking "load from disk" as a way to tell it to pop up your > > file-selection dialog? > > > > PS -- Plus, you forgot to put a log message in the version and now its > > part of trunk. Please always include a log message explaining "why" > > (not "what") the change is being made. > > > > On Fri, Jan 9, 2015 at 6:58 AM, wrote: > > > Karl Ramberg uploaded a new version of System to project The Trunk: > > > http://source.squeak.org/trunk/System-kfr.693.mcz > > > > > > ==================== Summary ==================== > > > > > > Name: System-kfr.693 > > > Author: kfr > > > Time: 2 January 2015, 8:41:05.888 pm > > > UUID: 760e94c5-2386-f642-a545-55a1fe293351 > > > Ancestors: System-bf.692 > > > > > > empty log message > > > > > > =============== Diff against System-bf.692 =============== > > > > > > Item was changed: > > > ----- Method: Preferences class>>loadPreferencesFrom: (in category > > 'personalization') ----- > > > + loadPreferencesFrom: aFile > > > - loadPreferencesFrom: aFileName > > > | stream params dict desktopColor | > > > + stream := ReferenceStream on: aFile. > > > - stream := ReferenceStream fileNamed: aFileName. > > > params := stream next. > > > self assert: (params isKindOf: IdentityDictionary). > > > params removeKey: #PersonalDictionaryOfPreferences. > > > dict := stream next. > > > self assert: (dict isKindOf: IdentityDictionary). > > > desktopColor := stream next. > > > stream close. > > > dict keysAndValuesDo: > > > [:key :value | (self preferenceAt: key ifAbsent: [nil]) > > ifNotNil: > > > [:pref | pref preferenceValue: value > > preferenceValue]]. > > > > > > params keysAndValuesDo: [ :key :value | self setParameter: key > > to: value ]. > > > > > > Smalltalk isMorphic > > > ifTrue: [ World fillStyle: desktopColor ] > > > ifFalse: [ self desktopColor: desktopColor. > > ScheduledControllers updateGray ]. > > > ! > > > > > > Item was changed: > > > ----- Method: Preferences class>>restorePreferencesFromDisk (in > > category 'personalization') ----- > > > restorePreferencesFromDisk > > > + | result | > > > + result := (FileList2 modalFileSelectorForSuffixes: #('prefs')) . > > > + result ifNil: [^ self]. > > > + self restorePreferencesFromDisk: result > > > + > > > - (FileDirectory default fileExists: 'my.prefs') > > > - ifTrue: [ Cursor wait showWhile: [ > > > - [ self loadPreferencesFrom: 'my.prefs' ] on: > > Error do: [ :ex | self inform: 'there was an error restoring the > > preferences' ] > > > - ] ] > > > - ifFalse: [ self inform: 'you haven''t saved your > > preferences yet!!' ]. > > > ! > > > > > > Item was added: > > > + ----- Method: Preferences class>>restorePreferencesFromDisk: (in > > category 'personalization') ----- > > > + restorePreferencesFromDisk: aFile > > > + Cursor wait > > > + showWhile: [[self loadPreferencesFrom: aFile] > > > + on: Error > > > + do: [:ex | self halt.self inform: 'there > > was an error restoring the preferences' translated]]! > > > > > > Item was changed: > > > ----- Method: Preferences class>>storePreferencesToDisk (in category > > 'personalization') ----- > > > storePreferencesToDisk > > > + | newName | > > > + newName := UIManager default request: 'Please confirm name for > > save...' initialAnswer: 'myPreferences'. > > > + newName isEmpty > > > + ifTrue: [^ self]. > > > + Cursor wait > > > + showWhile: [[self storePreferencesIn: newName , '.prefs'] > > > + on: Error > > > + do: [:ex | self inform: 'there was an > > error storing your preferences to disk. you probably already have stored > > your preferences' translated]]! > > > - Cursor wait showWhile: [ > > > - [ self storePreferencesIn: 'my.prefs' ] on: Error do: [ > > :ex | self inform: 'there was an error storing your preferences to disk' ]]! > > > > > > > > > > > From btc at openInWorld.com Sun Jan 11 04:36:14 2015 From: btc at openInWorld.com (Ben Coman) Date: Sun Jan 11 04:36:17 2015 Subject: [squeak-dev] OSProcess stdErr issue on Windows Message-ID: On Windows 7, trying to execute a non-existent program as follows... OSProcess command: 'notepadXX.exe' ...causes an MNU in ExternalWindowsOSProcess>>value. This is due to writing to stderr where "self initialStdErr" returns nil, seemingly due to ExternalWindowsOSProcess missing the #initialize and #setDefaults of E xternalUnixOSProcess. Now I understand that stderr is problematic in general on Windows. The following statements... OSProcess thisOSProcess stdErr nextPutAll: 'test'. FileStream stderr nextPutAll: 'test'. ...both work fine on OSX, but fail on Windows with the error "FileWriteError: File stderr is closed" The result is the same on both Pharo 4 and Squeak 4.5. (Squeak also brings up a bottom message bar saying... "# To disable: F2 -> 'debug options' -> 'show console on errors' WARNING: Manufactured file handle detected!") Pharo has a workaround for the general issue by creating a disk file named 'stderr' as follows... FileStream class >> standardIOStreamNamed: moniker forWrite: forWrite self flag: #todo. "This is an ugly hack, while waiting for a real fix for windows. There several problems with this approach, but it allow us to run tests, etc." Smalltalk os isWin32 ifTrue: [ [ ^ MultiByteFileStream forceNewFileNamed: moniker asString ] on: CannotDeleteFileException do: [ "HACK: if the image is opened a second time windows barks about the already opened locked file" ^ MultiByteFileStream forceNewFileNamed: moniker asString, '_', (Random new nextInt: SmallInteger maxVal) asString ]]. So to address the MNU for OSProcess? 1. wrap the "self initialStdErr" with an #ifNil: check 2. Squeak adopt the Pharo workaround, then lean on that to define #initialize and #setDefaults for ExternalWindowsOSProcess 3. real fix for stderr (outside of OSProcess?) 4. wont fix 5. other? Note that this is not a burning issue for me. I am just cleaning out old issues that I logged in the Pharo bug tracker. If the answer if (4.) I'll just close the issue [1]. For both Squeak and Pharo, I loaded ConfigurationOfOSProcess-ThierryGoubier.33 from... MCHttpRepository location: 'http://smalltalkhub.com/mc/Pharo/MetaRepoForPharo40/main' (Perhaps someone with access can copy that to the main repo) cheers -ben [1] https://pharo.fogbugz.com/default.asp?11615 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150111/3df726bc/attachment.htm From bert at freudenbergs.de Sun Jan 11 14:22:49 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Sun Jan 11 14:22:53 2015 Subject: [squeak-dev] The Trunk: System-kfr.693.mcz In-Reply-To: <20150110234736.GA42865@shell.msen.com> References: <54afd078.4908e00a.20da.0ad5SMTPIN_ADDED_MISSING@mx.google.com> <20150110234736.GA42865@shell.msen.com> Message-ID: <251BE332-A3A7-48F0-A217-A76D6C2071F1@freudenbergs.de> > On 11.01.2015, at 00:47, David T. Lewis wrote: > > On Sun, Jan 11, 2015 at 12:23:21AM +0100, karl ramberg wrote: >> Now I remember why I quit comitting to Squeak, >> > > Karl, > > Please keep committing. Your contributions are appreciated. I appreciate > them very much. I especially appreciate that you contribute in areas that > matter to real Squeak users, not just the guru types. > > I have yet not even looked this particular change, but from my point of view, > mistakes and wrong steps can be a good thing when done for the right reasons. > After all this is trunk, and if we make a change that we do not like, we > can always change it back tomorrow. > > I am quite serious - I really look forward to any change with the kfr stamp, > and I don't care at all if a few of those changes do not work out. +1 - Bert - > > Chris, > > Lighten up. > > Dave > > >> >> Bye >> >> On Sat, Jan 10, 2015 at 10:31 PM, Chris Muller wrote: >> >>> I strongly object to this change! I use this feature everytime I >>> start a base image, but now you've introduced an unnecessary and >>> horribly-hard-to-use modal UI interaction to something that, >>> previously, could be done in one-click or non-interactively via >>> script. I'm sorry, but this is utterly *awful* and, wrong-headed in >>> the first place. There is now no quick and easy way to transfer of >>> personal preferences from one image to another -- I have to click 57 >>> times instead of 1. No way. >>> >>> Please put it back the way it was and let's talk about what you want >>> to do and work out an amicable way of doing it before slamming such a >>> thing into trunk. >>> >>> My guess is you want to have multiple .prefs files. Maybe we need a >>> new button for that. Or, how about holding the Shift key when >>> clicking "load from disk" as a way to tell it to pop up your >>> file-selection dialog? >>> >>> PS -- Plus, you forgot to put a log message in the version and now its >>> part of trunk. Please always include a log message explaining "why" >>> (not "what") the change is being made. >>> >>> On Fri, Jan 9, 2015 at 6:58 AM, wrote: >>>> Karl Ramberg uploaded a new version of System to project The Trunk: >>>> http://source.squeak.org/trunk/System-kfr.693.mcz >>>> >>>> ==================== Summary ==================== >>>> >>>> Name: System-kfr.693 >>>> Author: kfr >>>> Time: 2 January 2015, 8:41:05.888 pm >>>> UUID: 760e94c5-2386-f642-a545-55a1fe293351 >>>> Ancestors: System-bf.692 >>>> >>>> empty log message >>>> >>>> =============== Diff against System-bf.692 =============== >>>> >>>> Item was changed: >>>> ----- Method: Preferences class>>loadPreferencesFrom: (in category >>> 'personalization') ----- >>>> + loadPreferencesFrom: aFile >>>> - loadPreferencesFrom: aFileName >>>> | stream params dict desktopColor | >>>> + stream := ReferenceStream on: aFile. >>>> - stream := ReferenceStream fileNamed: aFileName. >>>> params := stream next. >>>> self assert: (params isKindOf: IdentityDictionary). >>>> params removeKey: #PersonalDictionaryOfPreferences. >>>> dict := stream next. >>>> self assert: (dict isKindOf: IdentityDictionary). >>>> desktopColor := stream next. >>>> stream close. >>>> dict keysAndValuesDo: >>>> [:key :value | (self preferenceAt: key ifAbsent: [nil]) >>> ifNotNil: >>>> [:pref | pref preferenceValue: value >>> preferenceValue]]. >>>> >>>> params keysAndValuesDo: [ :key :value | self setParameter: key >>> to: value ]. >>>> >>>> Smalltalk isMorphic >>>> ifTrue: [ World fillStyle: desktopColor ] >>>> ifFalse: [ self desktopColor: desktopColor. >>> ScheduledControllers updateGray ]. >>>> ! >>>> >>>> Item was changed: >>>> ----- Method: Preferences class>>restorePreferencesFromDisk (in >>> category 'personalization') ----- >>>> restorePreferencesFromDisk >>>> + | result | >>>> + result := (FileList2 modalFileSelectorForSuffixes: #('prefs')) . >>>> + result ifNil: [^ self]. >>>> + self restorePreferencesFromDisk: result >>>> + >>>> - (FileDirectory default fileExists: 'my.prefs') >>>> - ifTrue: [ Cursor wait showWhile: [ >>>> - [ self loadPreferencesFrom: 'my.prefs' ] on: >>> Error do: [ :ex | self inform: 'there was an error restoring the >>> preferences' ] >>>> - ] ] >>>> - ifFalse: [ self inform: 'you haven''t saved your >>> preferences yet!!' ]. >>>> ! >>>> >>>> Item was added: >>>> + ----- Method: Preferences class>>restorePreferencesFromDisk: (in >>> category 'personalization') ----- >>>> + restorePreferencesFromDisk: aFile >>>> + Cursor wait >>>> + showWhile: [[self loadPreferencesFrom: aFile] >>>> + on: Error >>>> + do: [:ex | self halt.self inform: 'there >>> was an error restoring the preferences' translated]]! >>>> >>>> Item was changed: >>>> ----- Method: Preferences class>>storePreferencesToDisk (in category >>> 'personalization') ----- >>>> storePreferencesToDisk >>>> + | newName | >>>> + newName := UIManager default request: 'Please confirm name for >>> save...' initialAnswer: 'myPreferences'. >>>> + newName isEmpty >>>> + ifTrue: [^ self]. >>>> + Cursor wait >>>> + showWhile: [[self storePreferencesIn: newName , '.prefs'] >>>> + on: Error >>>> + do: [:ex | self inform: 'there was an >>> error storing your preferences to disk. you probably already have stored >>> your preferences' translated]]! >>>> - Cursor wait showWhile: [ >>>> - [ self storePreferencesIn: 'my.prefs' ] on: Error do: [ >>> :ex | self inform: 'there was an error storing your preferences to disk' ]]! >>>> >>>> >>> >>> > >> > > -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150111/23a40168/smime.bin From asqueaker at gmail.com Sun Jan 11 19:29:00 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sun Jan 11 19:29:03 2015 Subject: [squeak-dev] The Trunk: System-kfr.693.mcz In-Reply-To: <20150110234736.GA42865@shell.msen.com> References: <54afd078.4908e00a.20da.0ad5SMTPIN_ADDED_MISSING@mx.google.com> <20150110234736.GA42865@shell.msen.com> Message-ID: On Sat, Jan 10, 2015 at 5:47 PM, David T. Lewis wrote: > On Sun, Jan 11, 2015 at 12:23:21AM +0100, karl ramberg wrote: >> Now I remember why I quit comitting to Squeak, >> > > Karl, > > Please keep committing. Your contributions are appreciated. I appreciate > them very much. I especially appreciate that you contribute in areas that > matter to real Squeak users, not just the guru types. > > I have yet not even looked this particular change, but from my point of view, > mistakes and wrong steps can be a good thing when done for the right reasons. > After all this is trunk, and if we make a change that we do not like, we > can always change it back tomorrow. Experimentation is what Inbox is for. Trunk is for changes we already know we like. > I am quite serious - I really look forward to any change with the kfr stamp, > and I don't care at all if a few of those changes do not work out. I see no reason to make it personal about Karl. I didn't. I /never/ evaluate changes based on who did them, only the content and how they affect the system. When you have criticized my past contributions, I did not take it personally. I know that is important if I want Squeak to be the best it can be. > Chris, > > Lighten up. I apologize for the sentence with "wrong-headed" in it, that was overly critical. But the rest is pretty much straight facts. This change is not ready for trunk. It loses functionality and FileList2 is something we're trying to deprecate so we should not be introducing new dependencies on it, should we? From lewis at mail.msen.com Sun Jan 11 19:42:01 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sun Jan 11 19:42:09 2015 Subject: [squeak-dev] OSProcess stdErr issue on Windows In-Reply-To: References: Message-ID: <20150111194201.GA45270@shell.msen.com> Thanks Ben, On Sun, Jan 11, 2015 at 12:36:14PM +0800, Ben Coman wrote: > On Windows 7, trying to execute a non-existent program as follows... > OSProcess command: 'notepadXX.exe' > > ...causes an MNU in ExternalWindowsOSProcess>>value. This is due to writing > to stderr where "self initialStdErr" returns nil, seemingly due to > ExternalWindowsOSProcess missing the #initialize and #setDefaults of E > xternalUnixOSProcess. I made the change to prevent this error, and committed it to the OSProcess repository. > > Now I understand that stderr is problematic in general on Windows. > The following statements... > OSProcess thisOSProcess stdErr nextPutAll: 'test'. > FileStream stderr nextPutAll: 'test'. > > ...both work fine on OSX, but fail on Windows with the error > "FileWriteError: File stderr is closed" > The result is the same on both Pharo 4 and Squeak 4.5. > (Squeak also brings up a bottom message bar saying... "# To disable: F2 -> > 'debug options' -> 'show console on errors' WARNING: Manufactured file > handle detected!") A word of explanation is in order here. There is a handle registry in the Windows support code for FilePlugin that was added specifically to prevent use of "manufactured" file handles. I think that the idea was enhance security, although in practice the only effect is to prevent OSProcess from attaching to pipes and stdio streams. A workaround would be to provide an external FilePlugin dll with the handle registry disabled. > > Pharo has a workaround for the general issue by creating a disk file > named 'stderr' > as follows... > FileStream class >> standardIOStreamNamed: moniker forWrite: forWrite > self flag: #todo. "This is an ugly hack, while waiting for a real fix for > windows. There several problems with this approach, but it allow us to run > tests, etc." > Smalltalk os isWin32 > ifTrue: [ > [ ^ MultiByteFileStream forceNewFileNamed: moniker asString ] > on: CannotDeleteFileException do: [ > "HACK: if the image is opened a second time windows barks about the already > opened locked file" > ^ MultiByteFileStream forceNewFileNamed: moniker asString, '_', (Random new > nextInt: SmallInteger maxVal) asString ]]. > > So to address the MNU for OSProcess? > 1. wrap the "self initialStdErr" with an #ifNil: check > 2. Squeak adopt the Pharo workaround, then lean on that to define > #initialize and #setDefaults for ExternalWindowsOSProcess > 3. real fix for stderr (outside of OSProcess?) > 4. wont fix > 5. other? > > > Note that this is not a burning issue for me. I am just cleaning out old > issues that I logged in the Pharo bug tracker. If the answer if (4.) I'll > just close the issue [1]. I did #1, and hopefully that will take care of the issue. > > > For both Squeak and Pharo, I > loaded ConfigurationOfOSProcess-ThierryGoubier.33 from... > MCHttpRepository > location: 'http://smalltalkhub.com/mc/Pharo/MetaRepoForPharo40/main' > (Perhaps someone with access can copy that to the main repo) > I copied ConfigurationOfOSProcess-ThierryGoubier.33 to the OSProcess repository. An update to ConfigurationOfOSProcess will be needed to get the latest version (Thierry, can you do this?). For Squeak, no ConfigurationOfOSProcess is needed, just use the latest version (with SqueakMap, or currently it OSProcess-dtl.93 in the repo). Pharo should also use the latest version if possible, although the Metacello configurations are needed to make things work on various older Pharo versions. The versions for a current spec would be: OSProcess-Base-dtl.46 OSProcess-Unix-dtl.20 OSProcess-Win32-dtl.12 OSProcess-Mac-dtl.2 OSProcess-OS2-dtl.2 OSProcess-RiscOS-dtl.2 OSProcess-AIO-dtl.8 Tests-OSProcess-dtl.21 > > cheers -ben > > [1] https://pharo.fogbugz.com/default.asp?11615 Thanks a lot for reporting this! Dave From lewis at mail.msen.com Sun Jan 11 20:07:59 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sun Jan 11 20:08:02 2015 Subject: [Pharo-dev] [squeak-dev] OSProcess stdErr issue on Windows In-Reply-To: <20150111194201.GA45270@shell.msen.com> References: <20150111194201.GA45270@shell.msen.com> Message-ID: <20150111200759.GA53877@shell.msen.com> On Sun, Jan 11, 2015 at 02:42:01PM -0500, David T. Lewis wrote: > > I copied ConfigurationOfOSProcess-ThierryGoubier.33 to the OSProcess > repository. An update to ConfigurationOfOSProcess will be needed to > get the latest version (Thierry, can you do this?). > > For Squeak, no ConfigurationOfOSProcess is needed, just use the latest > version (with SqueakMap, or currently it OSProcess-dtl.93 in the repo). > > Pharo should also use the latest version if possible, although the > Metacello configurations are needed to make things work on various older > Pharo versions. The versions for a current spec would be: > > OSProcess-Base-dtl.46 > OSProcess-Unix-dtl.20 > OSProcess-Win32-dtl.12 > OSProcess-Mac-dtl.2 > OSProcess-OS2-dtl.2 > OSProcess-RiscOS-dtl.2 > OSProcess-AIO-dtl.8 > Tests-OSProcess-dtl.21 > Oops, sorry. That should be OSProcess-Tests-dtl.12, not Tests-OSProcess-dtl.21. Dave From lewis at mail.msen.com Sun Jan 11 20:21:28 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sun Jan 11 20:21:31 2015 Subject: [Pharo-dev] [squeak-dev] OSProcess stdErr issue on Windows In-Reply-To: <20150111200759.GA53877@shell.msen.com> References: <20150111194201.GA45270@shell.msen.com> <20150111200759.GA53877@shell.msen.com> Message-ID: <20150111202128.GA54570@shell.msen.com> On Sun, Jan 11, 2015 at 03:07:59PM -0500, David T. Lewis wrote: > On Sun, Jan 11, 2015 at 02:42:01PM -0500, David T. Lewis wrote: > > > > I copied ConfigurationOfOSProcess-ThierryGoubier.33 to the OSProcess > > repository. An update to ConfigurationOfOSProcess will be needed to > > get the latest version (Thierry, can you do this?). > > > > For Squeak, no ConfigurationOfOSProcess is needed, just use the latest > > version (with SqueakMap, or currently it OSProcess-dtl.93 in the repo). > > > > Pharo should also use the latest version if possible, although the > > Metacello configurations are needed to make things work on various older > > Pharo versions. The versions for a current spec would be: > > > > OSProcess-Base-dtl.46 > > OSProcess-Unix-dtl.20 > > OSProcess-Win32-dtl.12 > > OSProcess-Mac-dtl.2 > > OSProcess-OS2-dtl.2 > > OSProcess-RiscOS-dtl.2 > > OSProcess-AIO-dtl.8 > > Tests-OSProcess-dtl.21 > > > > Oops, sorry. That should be OSProcess-Tests-dtl.12, not Tests-OSProcess-dtl.21. Sorry to keep replying to myself, but I noticed some missing test updates from the main OSProcess package, so now it is OSProcess-Tests-dtl.13. Dave From btc at openInWorld.com Sun Jan 11 22:01:18 2015 From: btc at openInWorld.com (Ben Coman) Date: Sun Jan 11 22:01:21 2015 Subject: [Pharo-dev] [squeak-dev] OSProcess stdErr issue on Windows In-Reply-To: <20150111202128.GA54570@shell.msen.com> References: <20150111194201.GA45270@shell.msen.com> <20150111200759.GA53877@shell.msen.com> <20150111202128.GA54570@shell.msen.com> Message-ID: Thanks Dave. I'll try it out this evening. cheers -ben On Mon, Jan 12, 2015 at 4:21 AM, David T. Lewis wrote: > On Sun, Jan 11, 2015 at 03:07:59PM -0500, David T. Lewis wrote: > > On Sun, Jan 11, 2015 at 02:42:01PM -0500, David T. Lewis wrote: > > > > > > I copied ConfigurationOfOSProcess-ThierryGoubier.33 to the OSProcess > > > repository. An update to ConfigurationOfOSProcess will be needed to > > > get the latest version (Thierry, can you do this?). > > > > > > For Squeak, no ConfigurationOfOSProcess is needed, just use the latest > > > version (with SqueakMap, or currently it OSProcess-dtl.93 in the repo). > > > > > > Pharo should also use the latest version if possible, although the > > > Metacello configurations are needed to make things work on various > older > > > Pharo versions. The versions for a current spec would be: > > > > > > OSProcess-Base-dtl.46 > > > OSProcess-Unix-dtl.20 > > > OSProcess-Win32-dtl.12 > > > OSProcess-Mac-dtl.2 > > > OSProcess-OS2-dtl.2 > > > OSProcess-RiscOS-dtl.2 > > > OSProcess-AIO-dtl.8 > > > Tests-OSProcess-dtl.21 > > > > > > > Oops, sorry. That should be OSProcess-Tests-dtl.12, not > Tests-OSProcess-dtl.21. > > Sorry to keep replying to myself, but I noticed some missing test updates > from > the main OSProcess package, so now it is OSProcess-Tests-dtl.13. > > Dave > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150112/7caf8f06/attachment.htm From lewis at mail.msen.com Mon Jan 12 00:47:14 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Mon Jan 12 00:47:17 2015 Subject: [squeak-dev] A update to SystemTracer for getting back to 32 bits Message-ID: <20150112004714.GA94167@shell.msen.com> I have been using a 64-bit (format 68002) image as my working Squeak image for a few months now, so I became interested in the question of whether that image could be converted back to a 32-bit image that could be run again on Cog and on future Spur VMs. To my surprise, this turned out to be quite easy to do. >From the class comment from the original SystemTracer: The SystemTracer was invented by Ted Kaehler. It has gone through many variations. I have simplified it and adapted it to work with Squeak's limited Object hashing. It has written runnable Mac images on a Mac. Some changes may be needed for it to produce runnable images on a bigEndian machine. -- Dan I. 9/29/97 The current archive is at http://www.squeaksource.com/SystemTracing One variation of this is SystemTracer64, which is used for converting ("tracing") a standard 32-bit image into a 64-bit image format (identified as image format 68002). An up to date trace of the Squeak image is maintained at http://build.squeak.org/job/Squeak%2064-bit%20image/, and a Linux VM is at http://squeakvm.org/unix/release/Squeak-4.10.2.2614_64bit-linux_x86_64.tar.gzl This 64-bit image (format 68002) is a straightforward extension of the standard 32-bit image formats currently used for Squeak and Pharo (image format 6504 or 6505). Details are in the class comment for ObjectMemory, which now resides in package VMMaker on source.squeak.org. It provides essentially unlimited object memory space, with minimal change to the internal representation of the objects in that object memory. This is not to be confused with the 64-bit Spur object memory, which provides substantial performance improvements based on an improved (and different) object memory design. I made a minor update to the SystemTracer that allows it to convert a 64-bit image back to 32-bit format, and it worked perfectly with my working Squeak image that has been in 64-bit format for several months now. >From the update comment: Name: SystemTracing-dtl.26 Author: dtl Time: 2 January 2015, 1:21:45.031 pm Update SystemTracer2 to support tracing a 64-bit image format 68002 image back to 32-bit image format 6504. This makes conversion to 64-bit format a reversible process. To trace an existing 32-bit (format 6504 or 6505) image to 64-bit format: SystemTracer64 writeImage: 'clone64.image' To trace an 64-bit (format 68002) image to 32-bit format: SystemTracer2 writeImage: 'clone32.image' The resulting 32-bit image must be opened first using an interpreter VM, after which it can be run normally with a Cog VM. Tracing should be done using an interpreter VM. Dave From mbaehr at email.archlab.tuwien.ac.at Mon Jan 12 03:01:59 2015 From: mbaehr at email.archlab.tuwien.ac.at (=?utf-8?q?Martin_B=C3=A4hr?=) Date: Mon Jan 12 03:02:15 2015 Subject: [squeak-dev] VALS semester of code Message-ID: <1421031478-sup-3887@email.archlab.tuwien.ac.at> hi, i am a mentor for FOSSASIA, which is signing up for VALS semester of code: http://www.semesterofcode.com/ http://vps2.semesterofcode.com/ VALS semester of code is similar to Google summer of code, except that students work for class credit instead of money. while discussing potential projects on irc, the suggestion came up that since squeak and pharo have been participating in the Google summer of code before through ESUG, you might be interested in the VALS semester of code too. the only issue is, the signup deadline is on the 13th of january. that is tomorrow! instructions to join are here: https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1501&L=VALS-SOC&F=&S=&P=1719 in short, an email needs to be sent to scott wilson. his email address can be found on this page: https://blogs.it.ox.ac.uk/acit-rs-team/team/ (scroll down. sorry for the inconvenience, i don't want to republish personal email addresses without permission) for FOSSASIA i'll be mentoring a few projects that involve the use of pharo, and i think it would be nice to see squeak and pharo involved directly with your own projects as well. greetings, martin. -- eKita - the online platform for your entire academic life -- chief engineer eKita.co pike programmer pike.lysator.liu.se caudium.net societyserver.org BLUG secretary beijinglug.org foresight developer foresightlinux.org realss.com unix sysadmin Martin B?hr working in china http://societyserver.org/mbaehr/ From trygver at ifi.uio.no Mon Jan 12 10:09:04 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Mon Jan 12 10:09:08 2015 Subject: [squeak-dev] [BUG?]SMSimpleInstaller>>fileIntoChangeSetNamed:fromStream: Message-ID: <54B39D40.5010302@ifi.uio.no> SMSimpleInstaller>>fileIntoChangeSetNamed: aString fromStream: stream "We let the user confirm filing into an existing ChangeSet or specify another ChangeSet name if the name derived from the filename already exists." | changeSet newName oldChanges global | newName := aString. changeSet := SMInstaller changeSetNamed: newName. changeSet ifNotNil: [ newName := self silent ifNil: [UIManager default request: 'ChangeSet already present, just confirm to overwrite or enter a new name:' initialAnswer: newName] ifNotNil: [newName]. ++++++ AFAICS, 'self silent' cannot return nil, it always returns a boolan. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150112/ee81a427/attachment.htm From Das.Linux at gmx.de Mon Jan 12 10:39:57 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 12 10:40:00 2015 Subject: [squeak-dev] [BUG?]SMSimpleInstaller>>fileIntoChangeSetNamed:fromStream: In-Reply-To: <54B39D40.5010302@ifi.uio.no> References: <54B39D40.5010302@ifi.uio.no> Message-ID: <4F715307-38F1-48BF-8245-C9A13ACBE84C@gmx.de> Hi On 12.01.2015, at 11:09, Trygve Reenskaug wrote: > SMSimpleInstaller>>fileIntoChangeSetNamed: aString fromStream: stream > "We let the user confirm filing into an existing ChangeSet > or specify another ChangeSet name if > the name derived from the filename already exists." > | changeSet newName oldChanges global | > newName := aString. > changeSet := SMInstaller changeSetNamed: newName. > changeSet ifNotNil: [ > newName := self silent ifNil: [UIManager default > request: 'ChangeSet already present, just confirm to overwrite or enter a new name:' > initialAnswer: newName] > ifNotNil: [newName]. > ++++++ > > AFAICS, 'self silent' cannot return nil, it always returns a boolan. you're right :) Care to put a fixed version into the inbox? http://source.squeak.org/inbox.html Best -Tobia From Das.Linux at gmx.de Mon Jan 12 15:02:16 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 12 15:02:21 2015 Subject: [squeak-dev] Squeak does not react Message-ID: <8C396FCD-337A-41B5-AD61-67E726ED3A54@gmx.de> Hi all I just tried the 4.5 All-In-One (using Cog 2776) and just after the start, I seem to have a lockup. The image/vm does not react to any input, neither keyboard nor mouse. Resizing the window results in a scrambled window. I tested on a Linux Wheezy 7.4, x86_64 with 32bit libraries (hosted on a VirtualBox). The last output I get from strace is a very high number of getitimer calls followed by reads wich result in EAGAIN. Interestingly, the Squeak-vm shipped with Debian, a (probably interpreter) 4.4.7-2357[2] works but is missing the SqueakSSL plugin. I cannot use the one distributed with our All-In-One[3], alas. Anybody has a clue? Best -Tobias PS: This is sadly also true for the vm that is used by builderCI[1] [1]: https://github.com/dalehenrich/builderCI and vm: https://github.com/dalehenrich/builderCI/blob/master/oneclick/Contents/Linux/squeak aparently a Cog 2693 [2]: Interestingly, this is a 64bit binary that is able to run 32bit Squeak images. [3]: The AIO SqueakSSL plugin is 32bit and cannot be loaded with the Debian 64bit Squeak From bert at freudenbergs.de Mon Jan 12 15:52:32 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Mon Jan 12 15:52:35 2015 Subject: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: <20150112004714.GA94167@shell.msen.com> References: <20150112004714.GA94167@shell.msen.com> Message-ID: On 12.01.2015, at 01:47, David T. Lewis wrote: > > I made a minor update to the SystemTracer that allows it to convert a 64-bit > image back to 32-bit format, and it worked perfectly with my working Squeak > image that has been in 64-bit format for several months now. Nice! > The resulting 32-bit image must be opened first using an interpreter VM, > after which it can be run normally with a Cog VM. Tracing should be done > using an interpreter VM. Why is that? - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150112/09ec57d5/smime.bin From bert at freudenbergs.de Mon Jan 12 16:03:26 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Mon Jan 12 16:03:30 2015 Subject: [squeak-dev] #thingsPeopleBuiltWithSmalltalk Message-ID: <65ACF5DB-3E85-4609-A75F-16E4D2167C47@freudenbergs.de> https://twitter.com/hashtag/thingsPeopleBuiltWithSmalltalk - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150112/ab803883/smime.bin From mbaehr at email.archlab.tuwien.ac.at Mon Jan 12 16:42:26 2015 From: mbaehr at email.archlab.tuwien.ac.at (=?utf-8?q?Martin_B=C3=A4hr?=) Date: Mon Jan 12 16:42:48 2015 Subject: [squeak-dev] Re: VALS semester of code In-Reply-To: <1421031478-sup-3887@email.archlab.tuwien.ac.at> References: <1421031478-sup-3887@email.archlab.tuwien.ac.at> Message-ID: <1421080235-sup-187@email.archlab.tuwien.ac.at> Excerpts from Martin B?hr's message of 2015-01-12 04:01:59 +0100: > i am a mentor for FOSSASIA, which is signing up for VALS semester of code: > http://www.semesterofcode.com/ > http://vps2.semesterofcode.com/ > > while discussing potential projects on irc, the suggestion came up that since > squeak and pharo have been participating in the Google summer of code before > through ESUG, you might be interested in the VALS semester of code too. I don't know if anyone from ESUG, squeak and pharo orgs have tried to sign up, but in case they haven't, in the meantime FOSSASIA has been accepted, and since i am mentoring a few smalltalk projects, i would like to invite squeak and pharo developers to join me as mentors, and also offer you to mentor your own projects. my smalltalk projects are here: http://labs.fossasia.org/2015/01/10/smalltalk-search-app.html http://labs.fossasia.org/2015/01/10/smalltalk-file-editor.html Registration for mentors is by invitation, so if you are able to mentor projects please send me an email with details about projects you would like to mentor. We only have a short time to register mentors and list projects, so please reply as soon as you can. The name of the project Describe the project At a minimum, please include the expected outcome of the project, a potential mentor, the skills and/or languages required to complete the project, and a general "difficulty" level. The project should take about 3 months to complete. Please bear in mind that it's better to start with a smaller project that can be extended if your student proves to be capable rather than have an over-ambitious idea which can't be completed in time. The url of this project This could be for example a link to a bug tracker issue or google doc that describes the project idea. Some tags to facilitate searching (Delimited by comma i.e. php, javascript, html) greetings, martin. -- eKita - the online platform for your entire academic life -- chief engineer eKita.co pike programmer pike.lysator.liu.se caudium.net societyserver.org secretary beijinglug.org mentor fossasia.org foresight developer foresightlinux.org realss.com unix sysadmin Martin B?hr working in china http://societyserver.org/mbaehr/ From lewis at mail.msen.com Mon Jan 12 18:20:27 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Mon Jan 12 18:20:30 2015 Subject: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: References: <20150112004714.GA94167@shell.msen.com> Message-ID: <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> > On 12.01.2015, at 01:47, David T. Lewis wrote: >> >> I made a minor update to the SystemTracer that allows it to convert a >> 64-bit >> image back to 32-bit format, and it worked perfectly with my working >> Squeak >> image that has been in 64-bit format for several months now. > > Nice! > >> The resulting 32-bit image must be opened first using an interpreter >> VM, >> after which it can be run normally with a Cog VM. Tracing should be >> done >> using an interpreter VM. > > Why is that? > I have not yet figured out why it did not work with Cog. One possibility is that the system is running a jitted method at the time of the trace, and when the new 64-bit image wakes up in the interpreter VM, it is still in the middle of that method and the VM does not know what to do with it. That said, I also tried tracing 64 back to 32 and then running the traced 32-bit image immediately in Cog. That also did not work, so it may be that there is some other issue involved. I am guessing that it might be related to the saved start of memory location in the image header, but this is just a guess. Dave From eliot.miranda at gmail.com Mon Jan 12 19:02:27 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon Jan 12 19:02:35 2015 Subject: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> References: <20150112004714.GA94167@shell.msen.com> <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> Message-ID: Hi Dave, give me detailed instructions on what to load (or preferably an image ready to go) and I'll fix this. Eliot (phone) On Jan 12, 2015, at 10:20 AM, "David T. Lewis" wrote: >> On 12.01.2015, at 01:47, David T. Lewis wrote: >>> >>> I made a minor update to the SystemTracer that allows it to convert a >>> 64-bit >>> image back to 32-bit format, and it worked perfectly with my working >>> Squeak >>> image that has been in 64-bit format for several months now. >> >> Nice! >> >>> The resulting 32-bit image must be opened first using an interpreter >>> VM, >>> after which it can be run normally with a Cog VM. Tracing should be >>> done >>> using an interpreter VM. >> >> Why is that? > > I have not yet figured out why it did not work with Cog. One possibility > is that the system is running a jitted method at the time of the trace, > and when the new 64-bit image wakes up in the interpreter VM, it is still > in the middle of that method and the VM does not know what to do with it. > > That said, I also tried tracing 64 back to 32 and then running the traced > 32-bit image immediately in Cog. That also did not work, so it may be that > there is some other issue involved. I am guessing that it might be related > to the saved start of memory location in the image header, but this is > just a guess. > > Dave > > > From asqueaker at gmail.com Mon Jan 12 20:00:13 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon Jan 12 20:00:15 2015 Subject: [squeak-dev] Squeak does not react In-Reply-To: <8C396FCD-337A-41B5-AD61-67E726ED3A54@gmx.de> References: <8C396FCD-337A-41B5-AD61-67E726ED3A54@gmx.de> Message-ID: Just downloaded it from squeak.org and had no problems in Ubuntu 14.04. Maybe could be your 32-bit libs? Did you try using that same VM to launch another image, as well as the latest Cog VM on that 13680 image? On Mon, Jan 12, 2015 at 9:02 AM, Tobias Pape wrote: > Hi all > > I just tried the 4.5 All-In-One (using Cog 2776) > and just after the start, I seem to have a lockup. > The image/vm does not react to any input, neither > keyboard nor mouse. Resizing the window results > in a scrambled window. > I tested on a Linux Wheezy 7.4, x86_64 with 32bit > libraries (hosted on a VirtualBox). > > The last output I get from strace is a very high number of > getitimer calls followed by reads wich result in EAGAIN. > > > Interestingly, the Squeak-vm shipped with Debian, > a (probably interpreter) 4.4.7-2357[2] works but is missing > the SqueakSSL plugin. I cannot use the one distributed with > our All-In-One[3], alas. > > Anybody has a clue? > > > Best > -Tobias > > PS: This is sadly also true for the vm that is used by > builderCI[1] > > > [1]: https://github.com/dalehenrich/builderCI > and vm: https://github.com/dalehenrich/builderCI/blob/master/oneclick/Contents/Linux/squeak > aparently a Cog 2693 > [2]: Interestingly, this is a 64bit binary that is able to > run 32bit Squeak images. > [3]: The AIO SqueakSSL plugin is 32bit and cannot be loaded with the > Debian 64bit Squeak From Das.Linux at gmx.de Mon Jan 12 20:56:48 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 12 20:56:52 2015 Subject: [squeak-dev] Squeak does not react In-Reply-To: References: <8C396FCD-337A-41B5-AD61-67E726ED3A54@gmx.de> Message-ID: <7A4BF447-E775-436D-A678-154FFCE0DD06@gmx.de> On 12.01.2015, at 21:00, Chris Muller wrote: > Just downloaded it from squeak.org and had no problems in Ubuntu 14.04. > > Maybe could be your 32-bit libs? Did you try using that same VM to > launch another image, as well as the latest Cog VM on that 13680 > image? I first tried a current trunk image[1] with a) the 2693 CogVM - No reaction b) the Debian-shipped InterpreterVM - Normal behavior but no SqueakSSL c) the 3205 CogVM - No reaction d) the 2776 CogVM from the 4.5 AIO - No reaction in that order. There is no indication that the 32bit libs are missing or faulty (except for the right openssl libs, see other thread on vm-dev). Any Idea? Best -Tobias From lewis at mail.msen.com Mon Jan 12 21:01:56 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Mon Jan 12 21:01:58 2015 Subject: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: References: <20150112004714.GA94167@shell.msen.com> <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> Message-ID: <40308.136.2.1.102.1421096516.squirrel@webmail.msen.com> Hi Eliot, You can use any 6504/6505 image. Just load the tracer from http://www.squeaksource.com/SystemTracing or from SqueakMap. To trace an existing 32-bit (format 6504 or 6505) image to 64-bit format: SystemTracer64 writeImage: 'clone64.image' To trace an 64-bit (format 68002) image to 32-bit format: SystemTracer2 writeImage: 'clone32.image' For a VM to run the 68002 image, you can use http://www.squeakvm.org/unix/release/Squeak-4.10.2.2614_64bit-linux_x86_64.tar.gz (although it would be better to compile a new one, because I've fixed a couple things since then). I did not think to try it earlier, but you might get the same symptoms if you trace a 32-bit image into 32-bit format. I'm away and can't check it now, but that might be an easier way to figure out what is going on. Dave > Hi Dave, give me detailed instructions on what to load (or preferably an > image ready to go) and I'll fix this. > > Eliot (phone) > > On Jan 12, 2015, at 10:20 AM, "David T. Lewis" > wrote: > >>> On 12.01.2015, at 01:47, David T. Lewis wrote: >>>> >>>> I made a minor update to the SystemTracer that allows it to convert a >>>> 64-bit >>>> image back to 32-bit format, and it worked perfectly with my working >>>> Squeak >>>> image that has been in 64-bit format for several months now. >>> >>> Nice! >>> >>>> The resulting 32-bit image must be opened first using an interpreter >>>> VM, >>>> after which it can be run normally with a Cog VM. Tracing should be >>>> done >>>> using an interpreter VM. >>> >>> Why is that? >> >> I have not yet figured out why it did not work with Cog. One possibility >> is that the system is running a jitted method at the time of the trace, >> and when the new 64-bit image wakes up in the interpreter VM, it is >> still >> in the middle of that method and the VM does not know what to do with >> it. >> >> That said, I also tried tracing 64 back to 32 and then running the >> traced >> 32-bit image immediately in Cog. That also did not work, so it may be >> that >> there is some other issue involved. I am guessing that it might be >> related >> to the saved start of memory location in the image header, but this is >> just a guess. >> >> Dave >> >> >> > From lewis at mail.msen.com Tue Jan 13 02:29:52 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue Jan 13 02:29:54 2015 Subject: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> References: <20150112004714.GA94167@shell.msen.com> <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> Message-ID: <20150113022952.GC25328@shell.msen.com> On Mon, Jan 12, 2015 at 01:20:27PM -0500, David T. Lewis wrote: > > On 12.01.2015, at 01:47, David T. Lewis wrote: > >> > >> I made a minor update to the SystemTracer that allows it to convert a 64-bit > >> image back to 32-bit format, and it worked perfectly with my working Squeak > >> image that has been in 64-bit format for several months now. > > > > Nice! > > > >> The resulting 32-bit image must be opened first using an interpreter VM, > >> after which it can be run normally with a Cog VM. Tracing should be done > >> using an interpreter VM. > > > > Why is that? > > > > I have not yet figured out why it did not work with Cog. One possibility > is that the system is running a jitted method at the time of the trace, > and when the new 64-bit image wakes up in the interpreter VM, it is still > in the middle of that method and the VM does not know what to do with it. > > That said, I also tried tracing 64 back to 32 and then running the traced > 32-bit image immediately in Cog. That also did not work, so it may be that > there is some other issue involved. I am guessing that it might be related > to the saved start of memory location in the image header, but this is > just a guess. Well D'oh! I was driving home this afternoon and it popped into my head. I am quite sure the the problem is due to the change in floating point word ordering in the Cog image format (6505). If you trace an image that is running under a Cog VM on a little endian host, the Float objects will require special handling to put them back into the original canonical format (which is not the native machine order on a little endian machine). That is the reason that it does not work. Dave From bert at freudenbergs.de Tue Jan 13 16:12:39 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue Jan 13 16:12:44 2015 Subject: [Vm-dev] Re: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: <20150113022952.GC25328@shell.msen.com> References: <20150112004714.GA94167@shell.msen.com> <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> <20150113022952.GC25328@shell.msen.com> Message-ID: <72C913C8-F9C2-49A4-8599-6E1D8EBD30A2@freudenbergs.de> On 13.01.2015, at 03:29, David T. Lewis wrote: > > I was driving home this afternoon and it popped into my head. I am quite > sure the the problem is due to the change in floating point word ordering > in the Cog image format (6505). If you trace an image that is running under > a Cog VM on a little endian host, the Float objects will require special > handling to put them back into the original canonical format (which is not > the native machine order on a little endian machine). But the word accessors in Float handle that I thought? Or don't they, in 64 bits? - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150113/6bee144a/smime.bin From lewis at mail.msen.com Tue Jan 13 16:30:49 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue Jan 13 16:30:51 2015 Subject: [Vm-dev] Re: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: <72C913C8-F9C2-49A4-8599-6E1D8EBD30A2@freudenbergs.de> References: <20150112004714.GA94167@shell.msen.com> <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> <20150113022952.GC25328@shell.msen.com> <72C913C8-F9C2-49A4-8599-6E1D8EBD30A2@freudenbergs.de> Message-ID: <28726.136.2.1.104.1421166649.squirrel@webmail.msen.com> > On 13.01.2015, at 03:29, David T. Lewis wrote: >> >> I was driving home this afternoon and it popped into my head. I am quite >> sure the the problem is due to the change in floating point word >> ordering >> in the Cog image format (6505). If you trace an image that is running >> under >> a Cog VM on a little endian host, the Float objects will require special >> handling to put them back into the original canonical format (which is >> not >> the native machine order on a little endian machine). > > But the word accessors in Float handle that I thought? Or don't they, in > 64 bits? > > - Bert - > This issue would be that the in-memory representation of the float objects (which contain two 4-byte words of data) have the words reversed (i.e. put into machine word order) when running on Cog on a little endian machine. That in-memory representation is the thing being written out to disk during the trace. The tracer thinks that it is writing objects with fields in the original (format 6504, non-Cog) format, and it does not know when it encounters a Float object that it needs to swap the data words. The reason that it does not know this is that nobody has implemented it yet :-) Dave From bert at freudenbergs.de Tue Jan 13 16:59:17 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue Jan 13 16:59:22 2015 Subject: [Vm-dev] Re: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: <28726.136.2.1.104.1421166649.squirrel@webmail.msen.com> References: <20150112004714.GA94167@shell.msen.com> <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> <20150113022952.GC25328@shell.msen.com> <72C913C8-F9C2-49A4-8599-6E1D8EBD30A2@freudenbergs.de> <28726.136.2.1.104.1421166649.squirrel@webmail.msen.com> Message-ID: > On 13.01.2015, at 17:30, David T. Lewis wrote: > >> On 13.01.2015, at 03:29, David T. Lewis wrote: >>> >>> I was driving home this afternoon and it popped into my head. I am quite >>> sure the the problem is due to the change in floating point word >>> ordering >>> in the Cog image format (6505). If you trace an image that is running >>> under >>> a Cog VM on a little endian host, the Float objects will require special >>> handling to put them back into the original canonical format (which is >>> not >>> the native machine order on a little endian machine). >> >> But the word accessors in Float handle that I thought? Or don't they, in >> 64 bits? >> >> - Bert - >> > > This issue would be that the in-memory representation of the float objects > (which contain two 4-byte words of data) have the words reversed (i.e. put > into machine word order) when running on Cog on a little endian machine. > That in-memory representation is the thing being written out to disk > during the trace. The tracer thinks that it is writing objects with fields > in the original (format 6504, non-Cog) format, and it does not know when > it encounters a Float object that it needs to swap the data words. The > reason that it does not know this is that nobody has implemented it yet > :-) > > Dave I know that. I also know that Float>>basicAt: uses primitive 38 which is designed to always answer the words of a Float as if they were stored in big-endian order, no matter what the actual memory order is. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150113/31aa734b/smime.bin From trygver at ifi.uio.no Tue Jan 13 17:08:52 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Tue Jan 13 17:08:56 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? Message-ID: <54B55124.2000903@ifi.uio.no> I want to configure BabyIDE with a number of examples into a package that interested Squeakers can install with a minimum of fuss. I chose MonticelloConfigurations because it looked much simpler than Metacello. Being utterly confused after reading code, the documentation I could find. Also trying what I could guess at. The configuration is at http://www.squeaksource.com/DCI/BBAllInOne-TRee.1.mcz and at http://www.squeaksource.com/DCI/BBAllInOne-TRee.18.mcm I have defined a SqueakMap package 'BabyIdeAllInOne' with 3 versions for loading the configuration. None of them work: I open a fresh image and use the SqueakMap Package Loader to load BabyIdeAllInOne 1.2. I get an error 'No package release found with version TRee.1' ----- The question appears to be: Where did SMSqueakMap look when it didn't find a release? I have tried these scripts (among many): SMSqueakMap default installPackageNamed: 'BBallInOne' version: 'TRee.1' and SMSqueakMap default installPackageNamed: 'BBallInOne' version: 'TRee.18' May be I shouldn't have used a script at all, but relied on some unknown convention? I'm completely lost and badly need help. --Trygve From asqueaker at gmail.com Tue Jan 13 17:36:00 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue Jan 13 17:36:02 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? In-Reply-To: <54B55124.2000903@ifi.uio.no> References: <54B55124.2000903@ifi.uio.no> Message-ID: The desirable properties of a SqueakMap-based configuration are: - Load the application if it isn't already loaded, including any required dependencies first, as necessary. - Update the package to the latest version if older version(s) are already loaded in the image. - Don't lose any local changes I may have made when updating the package. - Load exact versions for production released versions of Squeak - Load the latest code for the current trunk version of Squeak Take a look at a working example; say, the "Ma client server" package, which meets all of the above requirements with a simple script. It depends on OSProcess but loads that automatically if you don't already have it. The "1.6" version is designated for Squeak 4.4 while "head" version loads the currently latest code using McmUpdater, the same process we use for trunk. Here is some documentation: http://wiki.squeak.org/squeak/779 http://wiki.squeak.org/squeak/6181 http://wiki.squeak.org/squeak/2726 HTH On Tue, Jan 13, 2015 at 11:08 AM, Trygve Reenskaug wrote: > I want to configure BabyIDE with a number of examples into a package that > interested Squeakers can install with a minimum of fuss. I chose > MonticelloConfigurations because it looked much simpler than Metacello. > Being utterly confused after reading code, the documentation I could find. > Also trying what I could guess at. > > The configuration is at > http://www.squeaksource.com/DCI/BBAllInOne-TRee.1.mcz > and at > http://www.squeaksource.com/DCI/BBAllInOne-TRee.18.mcm > > I have defined a SqueakMap package 'BabyIdeAllInOne' with 3 versions for > loading the configuration. None of them work: > I open a fresh image and use the SqueakMap Package Loader to load > BabyIdeAllInOne 1.2. I get an error > 'No package release found with version TRee.1' > ----- > The question appears to be: > Where did SMSqueakMap look when it didn't find a release? > I have tried these scripts (among many): > SMSqueakMap default installPackageNamed: 'BBallInOne' version: 'TRee.1' > and > SMSqueakMap default installPackageNamed: 'BBallInOne' version: > 'TRee.18' > > May be I shouldn't have used a script at all, but relied on some unknown > convention? > > I'm completely lost and badly need help. > --Trygve > From eliot.miranda at gmail.com Tue Jan 13 18:16:51 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 13 18:16:54 2015 Subject: [Vm-dev] Re: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: References: <20150112004714.GA94167@shell.msen.com> <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> <20150113022952.GC25328@shell.msen.com> <72C913C8-F9C2-49A4-8599-6E1D8EBD30A2@freudenbergs.de> <28726.136.2.1.104.1421166649.squirrel@webmail.msen.com> Message-ID: On Tue, Jan 13, 2015 at 8:59 AM, Bert Freudenberg wrote: > > > > On 13.01.2015, at 17:30, David T. Lewis wrote: > > > >> On 13.01.2015, at 03:29, David T. Lewis wrote: > >>> > >>> I was driving home this afternoon and it popped into my head. I am > quite > >>> sure the the problem is due to the change in floating point word > >>> ordering > >>> in the Cog image format (6505). If you trace an image that is running > >>> under > >>> a Cog VM on a little endian host, the Float objects will require > special > >>> handling to put them back into the original canonical format (which is > >>> not > >>> the native machine order on a little endian machine). > >> > >> But the word accessors in Float handle that I thought? Or don't they, in > >> 64 bits? > >> > >> - Bert - > >> > > > > This issue would be that the in-memory representation of the float > objects > > (which contain two 4-byte words of data) have the words reversed (i.e. > put > > into machine word order) when running on Cog on a little endian machine. > > That in-memory representation is the thing being written out to disk > > during the trace. The tracer thinks that it is writing objects with > fields > > in the original (format 6504, non-Cog) format, and it does not know when > > it encounters a Float object that it needs to swap the data words. The > > reason that it does not know this is that nobody has implemented it yet > > :-) > > > > Dave > > I know that. I also know that Float>>basicAt: uses primitive 38 which is > designed to always answer the words of a Float as if they were stored in > big-endian order, no matter what the actual memory order is. > And Float>>basicAt:put: uses primitive 39. I had to add these to Cog so that the VM was free for the underlying platform to choose the most efficient representation. It is a shame that we're saddled with a bug-endian order since large integers are little endian. But don't sweat the petty stuff, pet the sweaty stuff... -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150113/ca62d70d/attachment.htm From lewis at mail.msen.com Tue Jan 13 21:05:05 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue Jan 13 21:05:09 2015 Subject: [Vm-dev] Re: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: References: <20150112004714.GA94167@shell.msen.com> <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> <20150113022952.GC25328@shell.msen.com> <72C913C8-F9C2-49A4-8599-6E1D8EBD30A2@freudenbergs.de> <28726.136.2.1.104.1421166649.squirrel@webmail.msen.com> Message-ID: <15855.136.2.1.104.1421183105.squirrel@webmail.msen.com> > >> On 13.01.2015, at 17:30, David T. Lewis wrote: >> >>> On 13.01.2015, at 03:29, David T. Lewis wrote: >>>> >>>> I was driving home this afternoon and it popped into my head. I am >>>> quite >>>> sure the the problem is due to the change in floating point word >>>> ordering >>>> in the Cog image format (6505). If you trace an image that is running >>>> under >>>> a Cog VM on a little endian host, the Float objects will require >>>> special >>>> handling to put them back into the original canonical format (which is >>>> not >>>> the native machine order on a little endian machine). >>> >>> But the word accessors in Float handle that I thought? Or don't they, >>> in >>> 64 bits? >>> >>> - Bert - >>> >> >> This issue would be that the in-memory representation of the float objects >> (which contain two 4-byte words of data) have the words reversed (i.e. put >> into machine word order) when running on Cog on a little endian machine. >> That in-memory representation is the thing being written out to disk >> during the trace. The tracer thinks that it is writing objects with >> fields >> in the original (format 6504, non-Cog) format, and it does not know when >> it encounters a Float object that it needs to swap the data words. The >> reason that it does not know this is that nobody has implemented it yet >> :-) >> >> Dave > > I know that. I also know that Float>>basicAt: uses primitive 38 which is > designed to always answer the words of a Float as if they were stored in > big-endian order, no matter what the actual memory order is. > I think the primitive handles processor word ordering, but does not know about the float word ordering convention in Cog. In the interpreter VM, we check the "cog bit" in the image format number at image load time, and undo the float word ordering if the bit is set and if we are on a little endian machine. Come to think of it, I'll bet that just setting the cog bit in the traced image header would be sufficient to address this. The 64-bit image would be waking up in an interpreter VM, so it should hopefully notice the cog bit and do the necessary Float word reordering. I'll have to give that a try when I get home. Dave From lewis at mail.msen.com Wed Jan 14 04:45:05 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed Jan 14 04:45:06 2015 Subject: [Vm-dev] Re: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: <15855.136.2.1.104.1421183105.squirrel@webmail.msen.com> References: <20150112004714.GA94167@shell.msen.com> <19735.136.2.1.102.1421086827.squirrel@webmail.msen.com> <20150113022952.GC25328@shell.msen.com> <72C913C8-F9C2-49A4-8599-6E1D8EBD30A2@freudenbergs.de> <28726.136.2.1.104.1421166649.squirrel@webmail.msen.com> <15855.136.2.1.104.1421183105.squirrel@webmail.msen.com> Message-ID: <20150114044505.GA72434@shell.msen.com> On Tue, Jan 13, 2015 at 04:05:05PM -0500, David T. Lewis wrote: > > > >> On 13.01.2015, at 17:30, David T. Lewis wrote: > >> > >>> On 13.01.2015, at 03:29, David T. Lewis wrote: > >>>> > >>>> I was driving home this afternoon and it popped into my head. I am quite > >>>> sure the the problem is due to the change in floating point word ordering > >>>> in the Cog image format (6505). If you trace an image that is running under > >>>> a Cog VM on a little endian host, the Float objects will require special > >>>> handling to put them back into the original canonical format (which is not > >>>> the native machine order on a little endian machine). > >>> > >>> But the word accessors in Float handle that I thought? Or don't they, in > >>> 64 bits? > >>> > >>> - Bert - > >> > >> This issue would be that the in-memory representation of the float objects > >> (which contain two 4-byte words of data) have the words reversed (i.e. put > >> into machine word order) when running on Cog on a little endian machine. > >> That in-memory representation is the thing being written out to disk > >> during the trace. The tracer thinks that it is writing objects with > >> fields > >> in the original (format 6504, non-Cog) format, and it does not know when > >> it encounters a Float object that it needs to swap the data words. The > >> reason that it does not know this is that nobody has implemented it yet > >> :-) > >> > >> Dave > > > > I know that. I also know that Float>>basicAt: uses primitive 38 which is > > designed to always answer the words of a Float as if they were stored in > > big-endian order, no matter what the actual memory order is. > > > > I think the primitive handles processor word ordering, but does not know > about the float word ordering convention in Cog. In the interpreter VM, we > check the "cog bit" in the image format number at image load time, and > undo the float word ordering if the bit is set and if we are on a little > endian machine. > > Come to think of it, I'll bet that just setting the cog bit in the traced > image header would be sufficient to address this. The 64-bit image would > be waking up in an interpreter VM, so it should hopefully notice the cog > bit and do the necessary Float word reordering. I'll have to give that a > try when I get home. Confirmed. If I trace a 32-bit image that is running on Cog and set the image format number of the traced 64-bit image to 68003 rather than 68002, then the resulting 64-bit image can be opened by a squeak64 interpreter VM. And BTW the image trace runs much faster using Cog. Tracing that 64-bit image back to 32-bits still requires that the traced 32-bit image be opened first with an interpreter VM, after which it can be saved and run from a Cog VM. I do not know the reason for this, but I expect that it is a different issue than the Float word ordering issue discussed here. Dave From maxleske at gmail.com Wed Jan 14 09:53:02 2015 From: maxleske at gmail.com (Max Leske) Date: Wed Jan 14 09:53:04 2015 Subject: [squeak-dev] Implementing lazy loading for expandable collections (part 2) Message-ID: <52E10EA6-602F-4653-9FCC-8834A82ED099@gmail.com> Hi Alex I thought the following little experiment might interest you. I was trying to find out (as per your suggestion) how big the difference would be between: - setting the array in OrderedCollection to nil and initializing it to size 10 on first access - initializing the array in OrderedCollection to size 0. Expectation: #grow will take time, ergo, using an empty array should be slower than using a preallocated array. Experiment (Pharo 1.3 on SqueakVM): [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 100000. 1 to: 10000 do: [ :i | c add: i ] ] ] timeToRun 17566 [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 10000. 1 to: 10000 do: [ :i | c add: i ] ] ] timeToRun 19717 [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 0. 1 to: 10000 do: [ :i | c add: i ] ] ] timeToRun 17598 [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 1000. 1 to: 10000 do: [ :i | c add: i ] ] ] timeToRun 18084 Result: growing a collection is always faster (or at least nearly equally fast)! Explanation: What makes preinitialized collections so slow is the fact the the firstIndex variable will be set to the first third of the array (3333 in this case). When the last position in the array is reached, all elements are copied to the beginning of the array (2n operations). This copy operation is really slow (which can be seen from the first example with an oversized collection that does not require copying because the last position of the array is never reached). Experiment (Pharo 4 on PharoVM): (I?m using bigger numbers here to compensate for the faster VM :) ) [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 1000000. 1 to: 100000 do: [ :i | c add: i ] ] ] timeToRun "0:00:01:09.225" [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 100000. 1 to: 100000 do: [ :i | c add: i ] ] ] timeToRun "0:00:00:37.653" [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 0. 1 to: 100000 do: [ :i | c add: i ] ] ] timeToRun "0:00:00:40.152" [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 10000. 1 to: 100000 do: [ :i | c add: i ] ] ] timeToRun "0:00:00:42.121? Result: growing a collection is easily fast enough, although minute performance gains are possible with preinitialized collections. Explanation: #makeRoomAtLast has been improved. Also: firstIndex is now set to the beginning of the array, preventing the copy operation that made the former measurements so slow. The run with the oversized collection is only so slow because it apparently takes a lot of time to assign the large array (?). Consequence of my little experiment: My initial implementation of the idea in you paper set the array in OrderedCollection to nil under the assumption that grow operations are very costly. That choice leads to many changes in methods of OrderedCollection where it is necessary to check if the array has been initialized yet. This introduces overhead and makes the code more error prone. I see now that it makes much more sense to use an empty array, the performance lost by growing ist neglectable. It is also interesting to note that there almost never seems to be a good reason to initialize an OrderedCollection with a large array. Cheers, Max From commits at source.squeak.org Wed Jan 14 10:41:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 14 10:41:28 2015 Subject: [squeak-dev] The Trunk: Collections-mt.589.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.589.mcz ==================== Summary ==================== Name: Collections-mt.589 Author: mt Time: 14 January 2015, 11:41:12.144 am UUID: 0bf76b20-9b1a-2b43-ae6c-57507ce3176d Ancestors: Collections-bf.588 comment added to #concatenation =============== Diff against Collections-bf.588 =============== Item was changed: ----- Method: SequenceableCollection>>concatenation (in category 'converting') ----- concatenation + "Flattens the collection by one level into an Array. Avoids using #gather: and #streamContents: for performance reasons." - |result index| + | result index | result := Array new: (self inject: 0 into: [:sum :each | sum + each size]). index := 0. self do: [:each | each do: [:item | result at: (index := index+1) put: item]]. + ^ result! - ^result! From commits at source.squeak.org Wed Jan 14 10:52:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 14 10:52:45 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.226.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.226.mcz ==================== Summary ==================== Name: CollectionsTests-mt.226 Author: mt Time: 14 January 2015, 11:52:35.587 am UUID: 93b0d9a1-aa09-2d47-bd85-624298acbdbf Ancestors: CollectionsTests-bf.225 Tests added for #concatenation =============== Diff against CollectionsTests-bf.225 =============== Item was added: + ----- Method: SequenceableCollectionTest>>testConcatenation (in category 'tests - converting') ----- + testConcatenation + + self assert: #( (1 2) (3 4) ) concatenation = #(1 2 3 4). + self assert: #( (1 2) ( (3 4) ) ) concatenation = #(1 2 (3 4)). + self should: [#(1 2 3 4) concatenation] raise: Error. + + self assert: #() concatenation = #(). + self assert: #( (1 2) () (3) ()) concatenation = #(1 2 3).! From commits at source.squeak.org Wed Jan 14 11:47:21 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 14 11:47:22 2015 Subject: [squeak-dev] The Trunk: Collections-mt.590.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.590.mcz ==================== Summary ==================== Name: Collections-mt.590 Author: mt Time: 14 January 2015, 12:47:06.604 pm UUID: 5165dd57-c3e5-5d45-9c61-bc820f2fab02 Ancestors: Collections-mt.589 Methods added to easily join split strings. =============== Diff against Collections-mt.589 =============== Item was added: + ----- Method: SequenceableCollection>>join (in category 'converting') ----- + join + "Example: #(H e l l o W o r l d) join = 'HelloWorld'. " + + ^ self joinSeparatedBy: ''! Item was added: + ----- Method: SequenceableCollection>>joinSeparatedBy: (in category 'converting') ----- + joinSeparatedBy: aSeparator + "Returns a string, which is a concatenation of each element's string representation separated by another string." + + ^ String streamContents: [:stream | + self + do: [:ea | stream nextPutAll: ea asString] + separatedBy: [stream nextPutAll: aSeparator asString]]! From commits at source.squeak.org Wed Jan 14 11:48:38 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 14 11:48:38 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.227.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.227.mcz ==================== Summary ==================== Name: CollectionsTests-mt.227 Author: mt Time: 14 January 2015, 12:48:32.028 pm UUID: ba80ec03-2785-4642-9a8c-09ad419fe738 Ancestors: CollectionsTests-mt.226 Tests added for #join =============== Diff against CollectionsTests-mt.226 =============== Item was added: + ----- Method: SequenceableCollectionTest>>testJoin (in category 'tests - converting') ----- + testJoin + + self assert: #(a b c d e) join = 'abcde'. + self assert: (#(a b c) joinSeparatedBy: '|') = 'a|b|c'.! Item was added: + ----- Method: SequenceableCollectionTest>>testSplitAndJoin (in category 'tests - converting') ----- + testSplitAndJoin + + self assert: (('a|b|c' splitBy: '|') joinSeparatedBy: '|') = 'a|b|c'.! From frank.shearar at gmail.com Wed Jan 14 12:11:18 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Wed Jan 14 12:11:21 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.227.mcz In-Reply-To: <54b6579a.07cce50a.5556.ffff84f2SMTPIN_ADDED_MISSING@mx.google.com> References: <54b6579a.07cce50a.5556.ffff84f2SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 14 January 2015 at 11:48, wrote: > Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: > http://source.squeak.org/trunk/CollectionsTests-mt.227.mcz > > ==================== Summary ==================== > > Name: CollectionsTests-mt.227 > Author: mt > Time: 14 January 2015, 12:48:32.028 pm > UUID: ba80ec03-2785-4642-9a8c-09ad419fe738 > Ancestors: CollectionsTests-mt.226 > > Tests added for #join > > =============== Diff against CollectionsTests-mt.226 =============== > > Item was added: > + ----- Method: SequenceableCollectionTest>>testJoin (in category 'tests - converting') ----- > + testJoin > + > + self assert: #(a b c d e) join = 'abcde'. > + self assert: (#(a b c) joinSeparatedBy: '|') = 'a|b|c'.! > > Item was added: > + ----- Method: SequenceableCollectionTest>>testSplitAndJoin (in category 'tests - converting') ----- > + testSplitAndJoin > + > + self assert: (('a|b|c' splitBy: '|') joinSeparatedBy: '|') = 'a|b|c'.! +1 to the feature! I'd just add that using #assert:equals: gives better error messages: self assert: 'a|b|c' equals: (#(a b c) joinSeparatedBy: '|') and so on. frank From commits at source.squeak.org Wed Jan 14 12:13:23 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 14 12:13:23 2015 Subject: [squeak-dev] The Trunk: Collections-mt.591.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.591.mcz ==================== Summary ==================== Name: Collections-mt.591 Author: mt Time: 14 January 2015, 1:13:09.966 pm UUID: 8d73a22f-0d76-1f4a-82b7-53900b5f3be1 Ancestors: Collections-mt.590 Added #flatten as special case for #concatenation to remove any nesting except for strings. Very simple implementation with streams and recursion but not as efficient as #concatenation. =============== Diff against Collections-mt.590 =============== Item was added: + ----- Method: SequenceableCollection>>flatten (in category 'converting') ----- + flatten + "Similar to #concatenation but removes all nesting except for strings. + Example: {3 .4 .{2 .4 .{'hi'} .'ho'}} flatten = {3 .4 .2 .4 .'hi' .'ho'}" + + ^ Array streamContents: [:stream | + self do: [:each | + (each isCollection and: [each isString not]) + ifFalse: [stream nextPut: each] + ifTrue: [stream nextPutAll: each flatten]]]! From commits at source.squeak.org Wed Jan 14 12:14:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 14 12:14:04 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.228.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.228.mcz ==================== Summary ==================== Name: CollectionsTests-mt.228 Author: mt Time: 14 January 2015, 1:13:55.846 pm UUID: 77ab6cc7-31f8-ef4c-aa52-ac8efc726b82 Ancestors: CollectionsTests-mt.227 Tests added for #flatten. =============== Diff against CollectionsTests-mt.227 =============== Item was added: + ----- Method: SequenceableCollectionTest>>testFlatten (in category 'tests - converting') ----- + testFlatten + + self assert: {3 .4 .{2 .4 .{'hi'} .'ho'}} flatten = {3 .4 .2 .4 .'hi' .'ho'}. + self assert: #( (1 2) (3 4) ) flatten = #( (1 2) (3 4) ) concatenation.! From marcel.taeumel at student.hpi.uni-potsdam.de Wed Jan 14 12:18:35 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Wed Jan 14 12:21:12 2015 Subject: [squeak-dev] Re: The Trunk: CollectionsTests-mt.227.mcz In-Reply-To: References: Message-ID: <1421237915621-4799482.post@n4.nabble.com> Ah, thanks. :) All those basic tests should be fast to debug during release time. ;) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-CollectionsTests-mt-227-mcz-tp4799475p4799482.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Wed Jan 14 12:20:23 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Wed Jan 14 12:22:59 2015 Subject: [squeak-dev] Re: The Trunk: CollectionsTests-mt.227.mcz In-Reply-To: <1421237915621-4799482.post@n4.nabble.com> References: <1421237915621-4799482.post@n4.nabble.com> Message-ID: <1421238023318-4799483.post@n4.nabble.com> ... however, we should to a batch conversion? There are many such tests that would benefit from #assert:equals:. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-CollectionsTests-mt-227-mcz-tp4799475p4799483.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From bert at freudenbergs.de Wed Jan 14 12:27:35 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Wed Jan 14 12:27:40 2015 Subject: [squeak-dev] The Trunk: Collections-mt.590.mcz In-Reply-To: References: Message-ID: On 14.01.2015, at 11:47, commits@source.squeak.org wrote: > > Marcel Taeumel uploaded a new version of Collections to project The Trunk: > http://source.squeak.org/trunk/Collections-mt.590.mcz > > ==================== Summary ==================== > > Name: Collections-mt.590 > Author: mt > Time: 14 January 2015, 12:47:06.604 pm > UUID: 5165dd57-c3e5-5d45-9c61-bc820f2fab02 > Ancestors: Collections-mt.589 > > Methods added to easily join split strings. Nice :) > =============== Diff against Collections-mt.589 =============== > > Item was added: > + ----- Method: SequenceableCollection>>join (in category 'converting') ----- > + join > + "Example: #(H e l l o W o r l d) join = 'HelloWorld'. " > + > + ^ self joinSeparatedBy: ''! > > Item was added: > + ----- Method: SequenceableCollection>>joinSeparatedBy: (in category 'converting') ----- > + joinSeparatedBy: aSeparator > + "Returns a string, which is a concatenation of each element's string representation separated by another string." > + > + ^ String streamContents: [:stream | > + self > + do: [:ea | stream nextPutAll: ea asString] > + separatedBy: [stream nextPutAll: aSeparator asString]]! Any reason against calling the non-parametrized method just "join:"? Is there precedent in other dialects? - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150114/928e0150/smime-0001.bin From Das.Linux at gmx.de Wed Jan 14 12:36:10 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 14 12:36:13 2015 Subject: [squeak-dev] The Trunk: Collections-mt.591.mcz Message-ID: Heym On 14.01.2015, at 12:13, commits@source.squeak.org wrote: > Marcel Taeumel uploaded a new version of Collections to project The Trunk: > http://source.squeak.org/trunk/Collections-mt.591.mcz > > ==================== Summary ==================== > > Name: Collections-mt.591 > Author: mt > Time: 14 January 2015, 1:13:09.966 pm > UUID: 8d73a22f-0d76-1f4a-82b7-53900b5f3be1 > Ancestors: Collections-mt.590 > > Added #flatten as special case for #concatenation to remove any nesting except for strings. Very simple implementation with streams and recursion but not as efficient as #concatenation. > > =============== Diff against Collections-mt.590 =============== > > Item was added: > + ----- Method: SequenceableCollection>>flatten (in category 'converting') ----- > + flatten I know that flatten is a name for this in other languages but IMHO `flattened` would be a better fit :) (see #sorted, #negated, #rounded, ...) I would expect in-place, destructive operation when reading `flatten`, eg as with #sort Best -Tobias > + "Similar to #concatenation but removes all nesting except for strings. > + Example: {3 .4 .{2 .4 .{'hi'} .'ho'}} flatten = {3 .4 .2 .4 .'hi' .'ho'}" > + > + ^ Array streamContents: [:stream | > + self do: [:each | > + (each isCollection and: [each isString not]) > + ifFalse: [stream nextPut: each] > + ifTrue: [stream nextPutAll: each flatten]]]! > > From bert at freudenbergs.de Wed Jan 14 12:43:34 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Wed Jan 14 12:43:37 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? In-Reply-To: <54B55124.2000903@ifi.uio.no> References: <54B55124.2000903@ifi.uio.no> Message-ID: <7D59CBBC-7463-4A2E-BA11-44EEDC54DC63@freudenbergs.de> > On 13.01.2015, at 18:08, Trygve Reenskaug wrote: > > I want to configure BabyIDE with a number of examples into a package that interested Squeakers can install with a minimum of fuss. I chose MonticelloConfigurations because it looked much simpler than Metacello. > Being utterly confused after reading code, the documentation I could find. Also trying what I could guess at. > > The configuration is at > http://www.squeaksource.com/DCI/BBAllInOne-TRee.1.mcz > and at > http://www.squeaksource.com/DCI/BBAllInOne-TRee.18.mcm > > I have defined a SqueakMap package 'BabyIdeAllInOne' with 3 versions for loading the configuration. None of them work: > I open a fresh image and use the SqueakMap Package Loader to load BabyIdeAllInOne 1.2. I get an error > 'No package release found with version TRee.1' > ----- > The question appears to be: > Where did SMSqueakMap look when it didn't find a release? > I have tried these scripts (among many): > SMSqueakMap default installPackageNamed: 'BBallInOne' version: 'TRee.1' > and > SMSqueakMap default installPackageNamed: 'BBallInOne' version: 'TRee.18' > > May be I shouldn't have used a script at all, but relied on some unknown convention? > > I'm completely lost and badly need help. Did you try without a typo? 'BBAllInOne' ~= 'BBallInOne'. I have not tried with SqueakMap but this appears to work: (Installer squeaksource project: 'DCI') install: 'BBAllInOne' - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150114/aa481f65/smime.bin From trygver at ifi.uio.no Wed Jan 14 13:34:36 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Wed Jan 14 13:34:41 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? In-Reply-To: References: <54B55124.2000903@ifi.uio.no> Message-ID: <54B6706C.5090208@ifi.uio.no> Chris, Many, many thanks. I finally got it right and BBAllInOne now loads correctly. The working script reads SMSqueakMap default loadUpdates. (Installer repository: 'http://www.squeaksource.com/DCI') install: 'BBAllInOne-TRee.18' . Is there a simpler way? Most SqueakMap packages do not have a script; they only have a "Download URL". AwesomAtom is one example. BabyIDE-1.2.9 is another. I made it 6 years ago. It still works. I cannot remember how I specified the URL at the time and cannot find any user interface to edit it. Has it been removed? Again, many thanks for your help. --Trygve On 13.01.2015 18:36, Chris Muller wrote: > The desirable properties of a SqueakMap-based configuration are: > > - Load the application if it isn't already loaded, including any > required dependencies first, as necessary. > - Update the package to the latest version if older version(s) are > already loaded in the image. > - Don't lose any local changes I may have made when updating the package. > - Load exact versions for production released versions of Squeak > - Load the latest code for the current trunk version of Squeak > > Take a look at a working example; say, the "Ma client server" package, > which meets all of the above requirements with a simple script. It > depends on OSProcess but loads that automatically if you don't already > have it. The "1.6" version is designated for Squeak 4.4 while "head" > version loads the currently latest code using McmUpdater, the same > process we use for trunk. > > Here is some documentation: > > http://wiki.squeak.org/squeak/779 > http://wiki.squeak.org/squeak/6181 > http://wiki.squeak.org/squeak/2726 > > HTH > > On Tue, Jan 13, 2015 at 11:08 AM, Trygve Reenskaug wrote: >> I want to configure BabyIDE with a number of examples into a package that >> interested Squeakers can install with a minimum of fuss. I chose >> MonticelloConfigurations because it looked much simpler than Metacello. >> Being utterly confused after reading code, the documentation I could find. >> Also trying what I could guess at. >> >> The configuration is at >> http://www.squeaksource.com/DCI/BBAllInOne-TRee.1.mcz >> and at >> http://www.squeaksource.com/DCI/BBAllInOne-TRee.18.mcm >> >> I have defined a SqueakMap package 'BabyIdeAllInOne' with 3 versions for >> loading the configuration. None of them work: >> I open a fresh image and use the SqueakMap Package Loader to load >> BabyIdeAllInOne 1.2. I get an error >> 'No package release found with version TRee.1' >> ----- >> The question appears to be: >> Where did SMSqueakMap look when it didn't find a release? >> I have tried these scripts (among many): >> SMSqueakMap default installPackageNamed: 'BBallInOne' version: 'TRee.1' >> and >> SMSqueakMap default installPackageNamed: 'BBallInOne' version: >> 'TRee.18' >> >> May be I shouldn't have used a script at all, but relied on some unknown >> convention? >> >> I'm completely lost and badly need help. >> --Trygve >> > > -- Trygve Reenskaug mailto: trygver@ifi.uio.no Morgedalsvn. 5A http://folk.uio.no/trygver/ N-0378 Oslo http://fullOO.info Norway Tel: (+47) 22 49 57 27 Save our in-boxes!/http://emailcharter.org// -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150114/fde37be2/attachment.htm From trygver at ifi.uio.no Wed Jan 14 14:54:07 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Wed Jan 14 14:54:27 2015 Subject: [squeak-dev] BabyIDE now works in Squeak 4.5 Message-ID: <54B6830F.5080009@ifi.uio.no> Hi all, DCI is a programming paradigm with strong separation of concerns * Classes are used for coding system state - what the system *is*. * DCI Contexts are used for coding system behavior - what the system *does*. The DCI separation of concerns enhances code readability, supports testing, and simplifies system extension. BabyIDE is an IDE that supports the DCI separation of concerns by viewing the code in practically independent projections. BabyIDE with a number of examples is now ready for downloading into a Squeak 4.5 image: 1. WorldMenu > open... > SqueakMap Categories. 2. Select "Development tools" > BBAllInOne > (1.4) 3. Click "Install" Example programs can be run from WorldMenu > open... > BB5bBank etc. The sources for an example can be edited in BabyIDE, e.g.: WorldMenu > open... > BB1: IDE>BB5bBank BabyIDE with its DCI infrastructure is a non-intrusive addition to Squeak; everything works as before and programming can be done in the usual manner (if desired). DCI home page: http://fulloo.info/. Description of the examples: http://fulloo.info/Examples/SqueakExamples DCI mailing list: object-composition@googlegroups.com Enjoy --Trygve -- Trygve Reenskaug mailto: trygver@ifi.uio.no Morgedalsvn. 5A http://folk.uio.no/trygver/ N-0378 Oslo http://fullOO.info Norway Tel: (+47) 22 49 57 27 Save our in-boxes!/http://emailcharter.org// -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150114/35555b71/attachment.htm From cunningham.cb at gmail.com Wed Jan 14 16:04:57 2015 From: cunningham.cb at gmail.com (Chris Cunningham) Date: Wed Jan 14 16:05:00 2015 Subject: [squeak-dev] Re: [Pharo-dev] Implementing lazy loading for expandable collections (part 2) In-Reply-To: <889BA4BD-E29A-49F0-9C2D-DE5401EA1D1C@stack.nl> References: <889BA4BD-E29A-49F0-9C2D-DE5401EA1D1C@stack.nl> Message-ID: Hmm. Looking at the results in a relatively up to date Squeak 4.5: [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 100000. 1 to: 10000 do: [ :i | c add: i ] ] ] timeToRun 3624 [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 10000. 1 to: 10000 do: [ :i | c add: i ] ] ] timeToRun 2540 [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 0. 1 to: 10000 do: [ :i | c add: i ] ] ] timeToRun 2879 [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 1000. 1 to: 10000 do: [ :i | c add: i ] ] ] timeToRun 2784 Apparently Squeak takes more time to allocate the large array than Pharo? That would explain why the first run is so much slower than the other 3 - the exact opposite of Max's results (for Pharo 1.3 - but inline with Pharo4 - although not as extreme as Pharo4). Then, what about an array that only adds at the beginning (instead of end)? I would expect worse performance - especially if I removed the space at the beginning. WIthout any of those changes, though: [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 100000. 1 to: 10000 do: [ :i | c addFirst: i ] ] ] timeToRun 2782 [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 10000. 1 to: 10000 do: [ :i | c addFirst: i ] ] ] timeToRun 1845 [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 0. 1 to: 10000 do: [ :i | c addFirst: i ] ] ] timeToRun 2052 [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 1000. 1 to: 10000 do: [ :i | c addFirst: i ] ] ] timeToRun 1962 Weird that it turned out faster. Maybe it has to do with the first time it runs out of room, it move data (and doesn't allocate a new array?). Stephan's code (in the same image): [ 10000 timesRepeat: [ | c | c := OrderedCollection new: 100000. c add: 1. 2 to: 10000 do: [ :i | c add: i beforeIndex: (i atRandom) ] ] ] timeToRun 200434 This last is much slower - every time it adds an value, it forces a copy of the data. It will not be as fast as the others. -cbc On Wed, Jan 14, 2015 at 6:05 AM, Stephan Eggermont wrote: > I'm more worried about this part. > > [ 10000 timesRepeat: [ | c | > c := OrderedCollection new. > c add: 1. > 2 to: 10000 do: [ :i | > c add: i beforeIndex: (c atRandom) ] ] ] timeToRun > "5 min. 30 s." > > Stephan > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150114/4d37d60d/attachment.htm From ma.chris.m at gmail.com Wed Jan 14 20:32:37 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Wed Jan 14 20:32:38 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? In-Reply-To: <54B6706C.5090208@ifi.uio.no> References: <54B55124.2000903@ifi.uio.no> <54B6706C.5090208@ifi.uio.no> Message-ID: On Wed, Jan 14, 2015 at 7:34 AM, Trygve Reenskaug wrote: > Chris, > Many, many thanks. I finally got it right and BBAllInOne now loads > correctly. The working script reads > SMSqueakMap default loadUpdates. > (Installer repository: 'http://www.squeaksource.com/DCI') install: > 'BBAllInOne-TRee.18' . > > Is there a simpler way? Well, as in the above, you only had to give the bare minimum information the system would absolutely require to fulfill the requirement: 1) The repository and 2) MCVersion to #install. It's hard for me to imagine what could possibly be simpler than that.. > Most SqueakMap packages do not have a script; they > only have a "Download URL". They /all/ have a Download URL. What varies is what type of file is found at that url. When you entered the script above and clicked "Save" in the Release Editor browser, it saved it as a ".st" file on the SM server, with the "Download URL" field pointing to it. SqueakMap will still interpret .mcz, .sar, as well as .st files and "do the right thing" for each type. So you actually are using Download URL, just with the .st file which loading it from SS. But, yes, you could log into your SM account on the web and manually upload a copy of single .mcz file and be done that way. But since you have the script now done once, now for future versions it might be easier simply to select "Edit Release", update the version #, and click "Save". Done. That's easier than a manual upload and the code itself resides only in one place, SqueakSource. > AwesomAtom is one example. BabyIDE-1.2.9 is > another. I made it 6 years ago. It still works. I cannot remember how I > specified the URL at the time and cannot find any user interface to edit it. Plus, the coolest thing about SqueakMap is that it is an on-line resource which let's us "borrow" each other's /Smalltalk compiler/ in order to show each other how to run our software. It's a on-line catalog of Smalltalk code-snippets. This is very powerful. Maybe you would like BabyIDE to open up some sort of Welcome panel when installed from SqueakMap. That's easy with the .st script or .sar file. Not with just an uploaded .mcz. Cheers. > Has it been removed? > > Again, many thanks for your help. > --Trygve > > > > On 13.01.2015 18:36, Chris Muller wrote: > > The desirable properties of a SqueakMap-based configuration are: > > - Load the application if it isn't already loaded, including any > required dependencies first, as necessary. > - Update the package to the latest version if older version(s) are > already loaded in the image. > - Don't lose any local changes I may have made when updating the package. > - Load exact versions for production released versions of Squeak > - Load the latest code for the current trunk version of Squeak > > Take a look at a working example; say, the "Ma client server" package, > which meets all of the above requirements with a simple script. It > depends on OSProcess but loads that automatically if you don't already > have it. The "1.6" version is designated for Squeak 4.4 while "head" > version loads the currently latest code using McmUpdater, the same > process we use for trunk. > > Here is some documentation: > > http://wiki.squeak.org/squeak/779 > http://wiki.squeak.org/squeak/6181 > http://wiki.squeak.org/squeak/2726 > > HTH > > On Tue, Jan 13, 2015 at 11:08 AM, Trygve Reenskaug > wrote: > > I want to configure BabyIDE with a number of examples into a package that > interested Squeakers can install with a minimum of fuss. I chose > MonticelloConfigurations because it looked much simpler than Metacello. > Being utterly confused after reading code, the documentation I could find. > Also trying what I could guess at. > > The configuration is at > http://www.squeaksource.com/DCI/BBAllInOne-TRee.1.mcz > and at > http://www.squeaksource.com/DCI/BBAllInOne-TRee.18.mcm > > I have defined a SqueakMap package 'BabyIdeAllInOne' with 3 versions for > loading the configuration. None of them work: > I open a fresh image and use the SqueakMap Package Loader to load > BabyIdeAllInOne 1.2. I get an error > 'No package release found with version TRee.1' > ----- > The question appears to be: > Where did SMSqueakMap look when it didn't find a release? > I have tried these scripts (among many): > SMSqueakMap default installPackageNamed: 'BBallInOne' version: 'TRee.1' > and > SMSqueakMap default installPackageNamed: 'BBallInOne' version: > 'TRee.18' > > May be I shouldn't have used a script at all, but relied on some unknown > convention? > > I'm completely lost and badly need help. > --Trygve > > > > > -- > > Trygve Reenskaug mailto: trygver@ifi.uio.no > Morgedalsvn. 5A http://folk.uio.no/trygver/ > N-0378 Oslo http://fullOO.info > Norway Tel: (+47) 22 49 57 27 > > Save our in-boxes! http://emailcharter.org/ > From commits at source.squeak.org Thu Jan 15 01:47:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 15 01:48:00 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.589.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.589.mcz ==================== Summary ==================== Name: Collections.spur-mt.589 Author: eem Time: 14 January 2015, 5:47:16.223 pm UUID: f1416049-1113-4d86-99de-85b544fcc30c Ancestors: Collections-mt.589, Collections.spur-bf.588 Collections-mt.589 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.235 comment added to #concatenation =============== Diff against Collections-mt.589 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 15 January 2015 1:47:56.394 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu Jan 15 01:48:14 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 15 01:48:16 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.590.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.590.mcz ==================== Summary ==================== Name: Collections.spur-mt.590 Author: eem Time: 14 January 2015, 5:47:19.159 pm UUID: 2b6a0c25-3403-4417-91db-fab506fcb54b Ancestors: Collections-mt.590, Collections.spur-mt.589 Collections-mt.590 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.235 Methods added to easily join split strings. =============== Diff against Collections-mt.590 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 15 January 2015 1:48:12.988 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu Jan 15 01:48:18 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 15 01:48:21 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.591.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.591.mcz ==================== Summary ==================== Name: Collections.spur-mt.591 Author: eem Time: 14 January 2015, 5:47:22.024 pm UUID: dd41c76b-9063-421b-87bc-4229ac3f5243 Ancestors: Collections-mt.591, Collections.spur-mt.590 Collections-mt.591 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.235 Added #flatten as special case for #concatenation to remove any nesting except for strings. Very simple implementation with streams and recursion but not as efficient as #concatenation. =============== Diff against Collections-mt.591 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 15 January 2015 1:48:16.307 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From frank.shearar at gmail.com Thu Jan 15 09:59:44 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Thu Jan 15 09:59:46 2015 Subject: [squeak-dev] Re: The Trunk: CollectionsTests-mt.227.mcz In-Reply-To: <1421238023318-4799483.post@n4.nabble.com> References: <1421237915621-4799482.post@n4.nabble.com> <1421238023318-4799483.post@n4.nabble.com> Message-ID: They should, but if you're running the tests in some headless fashion - like in CI - those error messages let you zero in on problems much faster than just seeing "this test failed". I don't doubt that many tests would benefit from such a conversion: I just haven't done such a thing because of a lack of time, so I try get people to rewrite their new tests as they go in :) frank On 14 January 2015 at 12:20, Marcel Taeumel wrote: > ... however, we should to a batch conversion? There are many such tests that > would benefit from #assert:equals:. > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-CollectionsTests-mt-227-mcz-tp4799475p4799483.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From trygver at ifi.uio.no Thu Jan 15 10:00:03 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Thu Jan 15 10:00:08 2015 Subject: [squeak-dev] Re: BabyIDE now works in Squeak 4.5 In-Reply-To: <4BEF8437-19F8-4A4E-AF9A-C5B3FD394F31@unom.ro> References: <54B681FF.9060806@ifi.uio.no> <4BEF8437-19F8-4A4E-AF9A-C5B3FD394F31@unom.ro> Message-ID: <54B78FA3.7060508@ifi.uio.no> You are right. BBAllInOne was an unsuccessful experiment. It is now deleted. The working installer is BabyIdeAllInOne version 1.4 Thanks --Trygve On 14.01.2015 22:09, Mircea S. wrote: > Mine crashes when installing BBAllInOne > 1.4 with "No package release > found with version TRee.1 8" Maybe there's a typo in the script? > > BabyIdeAllInOne works just like Quang. > > > > > Pe 14 ian. 2015, la 16:49, Trygve Reenskaug > a scris: > >> Hi all, >> BabyIDE with a number of examples is now ready for downloading into a >> Squeak 4.5 image: >> 1. WorldMenu > open... > SqueakMap Categories. >> 2. Select "Development tools" > BBAllInOne > (1.4) >> 3. Click "Install" >> Example programs can be run from >> WorldMenu > open... > BB5bBank etc. >> The sources for an example can be edited in BabyIDE, e.g.: >> WorldMenu > open... > BB1: IDE>BB5bBank >> >> BabyIDE with its DCI infrastructure is a non-intrusive addition to >> Squeak; everything works as before and programming can be done in the >> usual manner (if desired). >> >> DCI home page with documentation etc.: http://fulloo.info/. >> DCI mailing list: object-composition@googlegroups.com >> >> Enjoy >> --Trygve >> -- -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150115/549709fa/attachment.htm From bert at freudenbergs.de Thu Jan 15 10:02:11 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Thu Jan 15 10:02:12 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? In-Reply-To: References: <54B55124.2000903@ifi.uio.no> <54B6706C.5090208@ifi.uio.no> Message-ID: <9B75BDE1-CFCA-47DF-9C2E-6D6EC507EF03@freudenbergs.de> On 14.01.2015, at 21:32, Chris Muller wrote: > >> Most SqueakMap packages do not have a script; they >> only have a "Download URL". > > They /all/ have a Download URL. What varies is what type of file is > found at that url. When you entered the script above and clicked > "Save" in the Release Editor browser, it saved it as a ".st" file on > the SM server, with the "Download URL" field pointing to it. > SqueakMap will still interpret .mcz, .sar, as well as .st files and > "do the right thing" for each type. Curious, does it handle .mcm directly nowadays? - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150115/1829f13f/smime.bin From Das.Linux at gmx.de Thu Jan 15 11:05:33 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu Jan 15 11:05:35 2015 Subject: [squeak-dev] Re: The Trunk: CollectionsTests-mt.227.mcz In-Reply-To: References: <1421237915621-4799482.post@n4.nabble.com> <1421238023318-4799483.post@n4.nabble.com> Message-ID: On 15.01.2015, at 10:59, Frank Shearar wrote: > They should, but if you're running the tests in some headless fashion > - like in CI - those error messages let you zero in on problems much > faster than just seeing "this test failed". > > I don't doubt that many tests would benefit from such a conversion: I > just haven't done such a thing because of a lack of time, so I try get > people to rewrite their new tests as they go in :) If we batch-convert, can we please also change self assert: expected equals: actual to self assert: actual equals: given ? This is IMHO more readable. If this is a naming problem, what about self expect: actual toBe: given Best -Tobias From frank.shearar at gmail.com Thu Jan 15 11:11:28 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Thu Jan 15 11:11:31 2015 Subject: [squeak-dev] Re: The Trunk: CollectionsTests-mt.227.mcz In-Reply-To: References: <1421237915621-4799482.post@n4.nabble.com> <1421238023318-4799483.post@n4.nabble.com> Message-ID: On 15 January 2015 at 11:05, Tobias Pape wrote: > > On 15.01.2015, at 10:59, Frank Shearar wrote: > >> They should, but if you're running the tests in some headless fashion >> - like in CI - those error messages let you zero in on problems much >> faster than just seeing "this test failed". >> >> I don't doubt that many tests would benefit from such a conversion: I >> just haven't done such a thing because of a lack of time, so I try get >> people to rewrite their new tests as they go in :) > > If we batch-convert, can we please also change > > self assert: expected equals: actual > > to > > self assert: actual equals: given > > ? This is IMHO more readable. > If this is a naming problem, what about > > self expect: actual toBe: given I'd rather take the latter option then. #assert:equals: does take the expected value first, and swapping the values reads better but then gives a deeply misleading message... and adjusting the message means there's a huge disconnect between our SUnit and the standard cross-platform SUnit. frank > Best > -Tobias > From Das.Linux at gmx.de Thu Jan 15 12:26:49 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu Jan 15 12:26:51 2015 Subject: [squeak-dev] Re: The Trunk: CollectionsTests-mt.227.mcz In-Reply-To: References: <1421237915621-4799482.post@n4.nabble.com> <1421238023318-4799483.post@n4.nabble.com> Message-ID: <8C12E546-6DA4-47CB-91A6-2E1564FDF501@gmx.de> On 15.01.2015, at 12:11, Frank Shearar wrote: > On 15 January 2015 at 11:05, Tobias Pape wrote: >> >> On 15.01.2015, at 10:59, Frank Shearar wrote: >> >>> They should, but if you're running the tests in some headless fashion >>> - like in CI - those error messages let you zero in on problems much >>> faster than just seeing "this test failed". >>> >>> I don't doubt that many tests would benefit from such a conversion: I >>> just haven't done such a thing because of a lack of time, so I try get >>> people to rewrite their new tests as they go in :) >> >> If we batch-convert, can we please also change >> >> self assert: expected equals: actual >> >> to >> >> self assert: actual equals: given >> >> ? This is IMHO more readable. >> If this is a naming problem, what about >> >> self expect: actual toBe: given > > I'd rather take the latter option then. #assert:equals: does take the > expected value first, and swapping the values reads better but then > gives a deeply misleading message... and adjusting the message means > there's a huge disconnect between our SUnit and the standard > cross-platform SUnit. yeah, you're right. But using something like #expect:toBe: is then not portable either :( Guess we'll stick with it until there's a new Framework ;) Best -Tobias From commits at source.squeak.org Thu Jan 15 13:38:36 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 15 13:38:38 2015 Subject: [squeak-dev] The Trunk: Collections-mt.592.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.592.mcz ==================== Summary ==================== Name: Collections-mt.592 Author: mt Time: 15 January 2015, 2:38:22.051 pm UUID: 1514e0fd-0cb5-6642-b335-98ed754dad41 Ancestors: Collections-mt.591 Some nil checks replaced with #notNil because ProtoObject knows it and it is faster (about 15%) =============== Diff against Collections-mt.591 =============== Item was changed: ----- Method: Dictionary>>includesKey: (in category 'testing') ----- includesKey: key "Answer whether the receiver has a key equal to the argument, key." + ^(array at: (self scanFor: key)) notNil! - ^(array at: (self scanFor: key)) ~~ nil "We could use #notNil here, but ProtoObject doesn't understand it."! Item was changed: ----- Method: KeyedSet>>includesKey: (in category 'testing') ----- includesKey: key + ^ (array at: (self scanFor: key)) notNil! - ^ (array at: (self scanFor: key)) ~~ nil! From commits at source.squeak.org Thu Jan 15 16:14:59 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 15 16:15:01 2015 Subject: [squeak-dev] The Trunk: Collections-mt.593.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.593.mcz ==================== Summary ==================== Name: Collections-mt.593 Author: mt Time: 15 January 2015, 5:14:16.888 pm UUID: 0316ee3c-b9ec-f845-9474-8df35a929d8b Ancestors: Collections-mt.592 New ordered dictionary added, which keeps track of the insertion order. =============== Diff against Collections-mt.592 =============== Item was added: + Dictionary subclass: #OrderedDictionary + instanceVariableNames: 'order lastIndex' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Sequenceable'! + + !OrderedDictionary commentStamp: '' prior: 0! + I am an ordered dictionary. I have an additional index (called 'order') to keep track of the insertion order of my associations. + + The read access is not affected by the additional index. + + Storing new data updates the index in O(1) for new keys. Keys that are already present involve actions in O(n) to update the insertion order. + + The growth operation compacts the index and takes O(n) additional time.! Item was added: + ----- Method: OrderedDictionary>>add: (in category 'adding') ----- + add: anAssociation + + | oldLastIndex oldCapacity | + oldLastIndex := lastIndex. + oldCapacity := self capacity. + + super add: anAssociation. + + (lastIndex = oldLastIndex or: [self capacity > oldCapacity]) ifTrue: [ + | index | + "The association was already present or we grew. We need to update the order." + index := self scanOrderFor: anAssociation key. + index = lastIndex ifFalse: [ + lastIndex := lastIndex + 1. + index := self scanOrderFor: anAssociation key. + order at: lastIndex put: (order at: index). + order at: index put: nil. + lastIndex = order size ifTrue: [self fixEmptySlots]]]. + + ^ anAssociation! Item was added: + ----- Method: OrderedDictionary>>associationsDo: (in category 'enumerating') ----- + associationsDo: aBlock + "Iterate over the order instead of the internal array." + + lastIndex = 0 ifTrue: [^ self]. + 1 to: lastIndex do: [:index | + (order at: index) ifNotNil: [:element | + aBlock value: element]].! Item was added: + ----- Method: OrderedDictionary>>at:put: (in category 'accessing') ----- + at: key put: anObject + + | oldLastIndex oldCapacity | + oldLastIndex := lastIndex. + oldCapacity := self capacity. + + super at: key put: anObject. + + (lastIndex = oldLastIndex or: [self capacity > oldCapacity]) ifTrue: [ + | index | + "The association was already present or we grew. We need to update the order." + index := self scanOrderFor: key. + index = lastIndex ifFalse: [ + lastIndex := lastIndex + 1. + order at: lastIndex put: (order at: index). + order at: index put: nil. + lastIndex = order size ifTrue: [self fixEmptySlots]]]. + + ^ anObject! Item was added: + ----- Method: OrderedDictionary>>atNewIndex:put: (in category 'private') ----- + atNewIndex: index put: anObject + + lastIndex := lastIndex + 1. + order at: lastIndex put: anObject. + + super atNewIndex: index put: anObject.! Item was added: + ----- Method: OrderedDictionary>>fillOrderFrom: (in category 'private') ----- + fillOrderFrom: anArray + + | arraySize | + arraySize := lastIndex. + lastIndex := 0. + 1 to: arraySize do: [:index | + (anArray at: index) ifNotNil: [:object | + lastIndex := lastIndex + 1. + order at: lastIndex put: object]].! Item was added: + ----- Method: OrderedDictionary>>fixEmptySlots (in category 'private') ----- + fixEmptySlots + "Remove all nil slots in the order index to avoid overflow." + + self fillOrderFrom: order.! Item was added: + ----- Method: OrderedDictionary>>growTo: (in category 'private') ----- + growTo: anInteger + + | oldOrder | + super growTo: anInteger. + oldOrder := order. + order := self class arrayType new: anInteger. + self fillOrderFrom: oldOrder.! Item was added: + ----- Method: OrderedDictionary>>initialize: (in category 'private') ----- + initialize: n + + super initialize: n. + order := self class arrayType new: n. + lastIndex := 0.! Item was added: + ----- Method: OrderedDictionary>>removeKey:ifAbsent: (in category 'removing') ----- + removeKey: key ifAbsent: aBlock + + order at: (self scanOrderFor: key) put: nil. + ^ super removeKey: key ifAbsent: aBlock! Item was added: + ----- Method: OrderedDictionary>>scanOrderFor: (in category 'private') ----- + scanOrderFor: anObject + + 1 to: lastIndex do: [:index | + | element | + ((element := order at: index) notNil and: [anObject = element key]) + ifTrue: [^ index]]. + + lastIndex = order size + ifTrue: [self errorNoFreeSpace] + ifFalse: [^ self order at: lastIndex + 1 "nil"].! From commits at source.squeak.org Thu Jan 15 16:15:41 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 15 16:15:42 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.229.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.229.mcz ==================== Summary ==================== Name: CollectionsTests-mt.229 Author: mt Time: 15 January 2015, 5:15:23.643 pm UUID: 5ed2aee8-4067-2945-8655-f1b218b95bfb Ancestors: CollectionsTests-mt.228 tests for ordered dictionary added =============== Diff against CollectionsTests-mt.228 =============== Item was added: + ClassTestCase subclass: #OrderedDictionaryTest + instanceVariableNames: 'sut' + classVariableNames: '' + poolDictionaries: '' + category: 'CollectionsTests-Sequenceable'! Item was added: + ----- Method: OrderedDictionaryTest>>setUp (in category 'running') ----- + setUp + + super setUp. + sut := OrderedDictionary new: 7.! Item was added: + ----- Method: OrderedDictionaryTest>>testCompact (in category 'tests') ----- + testCompact + + | oldCapacity | + 1 to: 3 do: [:ea | + sut at: ea put: nil]. + self assert: sut size equals: (sut instVarNamed: #lastIndex). + + sut removeKey: 2. + self assert: sut size equals: (sut instVarNamed: #lastIndex) - 1. + + oldCapacity := sut capacity. + 4 to: 20 do: [:ea | + sut at: ea put: nil]. + self + assert: sut capacity > oldCapacity; + assert: sut size equals: (sut instVarNamed: #lastIndex). + ! Item was added: + ----- Method: OrderedDictionaryTest>>testGrow (in category 'tests') ----- + testGrow + + self + assert: 11 equals: sut capacity; "next prime number to 7; see #setUp" + assert: sut capacity equals: (sut instVarNamed: #order) size. + + 1 to: sut capacity do: [:ea | + sut at: ea put: nil]. + + self + assert: sut capacity > 11; + assert: sut capacity equals: (sut instVarNamed: #order) size.! Item was added: + ----- Method: OrderedDictionaryTest>>testOrder (in category 'tests') ----- + testOrder + "We use integers as keys to match hash values." + + | dict | + dict := Dictionary new. + + 1 to: 10 do: [:ea | + dict at: ea put: nil. + sut at: ea put: nil]. + + self assert: dict keys = sut keys. + + dict removeKey: 5. + sut removeKey: 5. + + self assert: dict keys = sut keys. + + dict at: 5 put: nil. + sut at: 5 put: nil. + + self + assert: dict keys ~= sut keys; + assert: #(1 2 3 4 6 7 8 9 10 5) equals: sut keys; + assert: #(1 2 3 4 5 6 7 8 9 10) equals: dict keys.! Item was added: + ----- Method: OrderedDictionaryTest>>testOverflow (in category 'tests') ----- + testOverflow + "Check whether repeated additions of the same alternating keys causes an error." + + self + shouldnt: [20 timesRepeat: [sut at: 1 put: nil. sut at: 2 put: nil]] + raise: Error. ! Item was added: + ----- Method: OrderedDictionaryTest>>testOverwriteValue (in category 'tests') ----- + testOverwriteValue + + 1 to: 5 do: [:ea | + sut at: ea put: nil]. + + sut at: 3 put: nil. + + self assert: #(1 2 4 5 3) equals: sut keys.! From marcel.taeumel at student.hpi.uni-potsdam.de Thu Jan 15 16:15:34 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Thu Jan 15 16:18:20 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz In-Reply-To: References: Message-ID: <1421338534267-4799754.post@n4.nabble.com> Well, it was just a little programming exercise for me. Let's discuss whether you like it or not. ;) I did need such a container several times in the past. Maybe there is a reason why Squeak did not have it? :) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799754.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From frank.shearar at gmail.com Thu Jan 15 17:19:29 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Thu Jan 15 17:19:32 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.229.mcz In-Reply-To: <54b7e7b1.43318c0a.8f14.5321SMTPIN_ADDED_MISSING@mx.google.com> References: <54b7e7b1.43318c0a.8f14.5321SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 15 January 2015 at 16:15, wrote: > Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: > http://source.squeak.org/trunk/CollectionsTests-mt.229.mcz > > ==================== Summary ==================== > > Name: CollectionsTests-mt.229 > Author: mt > Time: 15 January 2015, 5:15:23.643 pm > UUID: 5ed2aee8-4067-2945-8655-f1b218b95bfb > Ancestors: CollectionsTests-mt.228 > > tests for ordered dictionary added > > =============== Diff against CollectionsTests-mt.228 =============== > > + self assert: sut size equals: (sut instVarNamed: #lastIndex). Nice! :) frank From leves at elte.hu Thu Jan 15 19:22:19 2015 From: leves at elte.hu (Levente Uzonyi) Date: Thu Jan 15 19:22:25 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <1421338534267-4799754.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> Message-ID: I find the OrderedDictionary implementation similar to the one in Pharo, and therefore sub-optimal. The order variable is only used to iterate over the associations in insertion/update order. Such behavior can achieved with a LinkedDictionary implementation, which provides O(1) average time for all lookup-based operations, and can also support different behaviors (order by last access instead of order by insertion/update) within the same time constraints. When I implement such linked dictionaries (see LRUCache, or OCompletition for examples), I usually link the values, because that way I can use any dictionary. For a general purpose linked dictionary, the links can be added to the associations to hide the details from the user. Other than this, I found the following issues with the code after a quick look: - #scanOrderFor: sends #order, which is not implemented. - #add: evaluates [index := self scanOrderFor: anAssociation key.] twice. The second evaluation seems to be unnecessary. - The class comment doesn't state it everywhere that the big O notation applies to time, not space. Can you give me some examples when/where you needed an ordered dictionary? Levente On Thu, 15 Jan 2015, Marcel Taeumel wrote: > Well, it was just a little programming exercise for me. Let's discuss whether > you like it or not. ;) I did need such a container several times in the > past. Maybe there is a reason why Squeak did not have it? :) > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799754.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From asqueaker at gmail.com Thu Jan 15 19:52:13 2015 From: asqueaker at gmail.com (Chris Muller) Date: Thu Jan 15 19:52:15 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? In-Reply-To: <9B75BDE1-CFCA-47DF-9C2E-6D6EC507EF03@freudenbergs.de> References: <54B55124.2000903@ifi.uio.no> <54B6706C.5090208@ifi.uio.no> <9B75BDE1-CFCA-47DF-9C2E-6D6EC507EF03@freudenbergs.de> Message-ID: On Thu, Jan 15, 2015 at 4:02 AM, Bert Freudenberg wrote: > On 14.01.2015, at 21:32, Chris Muller wrote: >> >>> Most SqueakMap packages do not have a script; they >>> only have a "Download URL". >> >> They /all/ have a Download URL. What varies is what type of file is >> found at that url. When you entered the script above and clicked >> "Save" in the Release Editor browser, it saved it as a ".st" file on >> the SM server, with the "Download URL" field pointing to it. >> SqueakMap will still interpret .mcz, .sar, as well as .st files and >> "do the right thing" for each type. > > Curious, does it handle .mcm directly nowadays? It appears not but could be done by adding new subclass of SMSimpleInstaller. From ma.chris.m at gmail.com Thu Jan 15 22:48:21 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Thu Jan 15 22:48:23 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! Message-ID: I did a minor class-hierarchy refactoring today which resulted in a an invalid super pointer, resulting in a confusing image lock up due to tight recursion. The script, below, demonstrates the issue in trunk: Object compile: 'test ^''Hello from Object'''. (Object subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test') compile: 'test ^ super halt test, ''my super call lands on myself!'''. (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test'). (Smalltalk classNamed: #MyNewAbstraction) new test But an existing method in the original MyClass had a call to super which now lands in itself, resulting in a tight recursion. The same script without creating the new subclass results in an instant VM crash (both interpreter 2357 and cog 3205): Object compile: 'test ^''Hello from Object'''. (Object subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test') compile: 'test ^ super halt test, ''my super call lands on itself!'''. (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. (Smalltalk classNamed: #MyNewAbstraction) new test I even tried recompiling my entire class hierarchy which was renamed, but it didn't help. How can this be? I _KNOW_ I've used rename class many times in the past... A regression? I went all the way back to 4.2. The above script doesn't crash the VM in 4.2 or 4.3. Squeak 4.4 and 4.5 and trunk all crash by the above script. All of those images (4.2 -- trunk) had the problem with the super pointer back to itself.. From Das.Linux at gmx.de Thu Jan 15 23:11:06 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu Jan 15 23:11:09 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: <94B66B30-ADDF-48C6-9806-C74A211E9F79@gmx.de> Hi, On 15.01.2015, at 23:48, Chris Muller wrote: > I did a minor class-hierarchy refactoring today which resulted in a an > invalid super pointer, resulting in a confusing image lock up due to > tight recursion. The script, below, demonstrates the issue in trunk: > > Object compile: 'test ^''Hello from Object'''. > (Object subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > 'test ^ super halt test, ''my super call lands on myself!'''. > (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass > instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' > category: 'Test'). > (Smalltalk classNamed: #MyNewAbstraction) new test > > But an existing method in the original MyClass had a call to super > which now lands in itself, resulting in a tight recursion. > > The same script without creating the new subclass results in an > instant VM crash (both interpreter 2357 and cog 3205): > > Object compile: 'test ^''Hello from Object'''. > (Object subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > 'test ^ super halt test, ''my super call lands on itself!'''. > (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > (Smalltalk classNamed: #MyNewAbstraction) new test > > I even tried recompiling my entire class hierarchy which was renamed, > but it didn't help. > > How can this be? I _KNOW_ I've used rename class many times in the > past... A regression? > > I went all the way back to 4.2. The above script doesn't crash the VM > in 4.2 or 4.3. Squeak 4.4 and 4.5 and trunk all crash by the above > script. > > All of those images (4.2 -- trunk) had the problem with the super > pointer back to itself.. I experienced this very problem in these minutes also. Best -Tobias From tim at rowledge.org Fri Jan 16 03:13:35 2015 From: tim at rowledge.org (tim Rowledge) Date: Fri Jan 16 03:13:42 2015 Subject: [squeak-dev] testing... Message-ID: <50919CFD-B3B8-4370-BB7C-A06AAD6280C7@rowledge.org> my mail server seems to be spam-canning almost everything today. will this get to me? tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: CEQ: Corrupt and Erase Queue From lewis at mail.msen.com Fri Jan 16 03:43:09 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri Jan 16 03:43:12 2015 Subject: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: References: <20150112004714.GA94167@shell.msen.com> Message-ID: <20150116034309.GA27266@shell.msen.com> On Mon, Jan 12, 2015 at 04:52:32PM +0100, Bert Freudenberg wrote: > On 12.01.2015, at 01:47, David T. Lewis wrote: > > > > I made a minor update to the SystemTracer that allows it to convert a 64-bit > > image back to 32-bit format, and it worked perfectly with my working Squeak > > image that has been in 64-bit format for several months now. > > Nice! > > > The resulting 32-bit image must be opened first using an interpreter VM, > > after which it can be run normally with a Cog VM. Tracing should be done > > using an interpreter VM. > > Why is that? > > - Bert - > The issue was Float word ordering differences in Cog/StackInterpreter. I made an update to SystemTracer that mostly handles this, the main benefit being that Cog can now be used to execute a much faster system trace from 32-bit image to 64-bit 68002 (or the mythical 68003) image, non-Spur: Name: SystemTracing-dtl.27 Time: 15 January 2015, 10:20:22.019 pm Allow 32-bit images to be traced to 64-bit using 32-bit Cog VM. Handle float word ordering differences between StackInterpreter and Interpreter. Produces a runnable 68003 image, 64-bit object format, closures, and Cog float word ordering. Requires package ImageFormat from VMMaker repository, else error is raised indicating how to hard code a workaround. This seems a reasonable dependency given the increasing number of image formats in circulation. Trace from 64-bit image to 32-bit still requires an initial load and save using an interpreter VM prior to running with Cog, reason unknown. Dave From eliot.miranda at gmail.com Fri Jan 16 05:01:13 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 05:01:16 2015 Subject: [Vm-dev] Re: [squeak-dev] A update to SystemTracer for getting back to 32 bits In-Reply-To: <20150116034309.GA27266@shell.msen.com> References: <20150112004714.GA94167@shell.msen.com> <20150116034309.GA27266@shell.msen.com> Message-ID: Hi David, On Thu, Jan 15, 2015 at 7:43 PM, David T. Lewis wrote: > > On Mon, Jan 12, 2015 at 04:52:32PM +0100, Bert Freudenberg wrote: > > On 12.01.2015, at 01:47, David T. Lewis wrote: > > > > > > I made a minor update to the SystemTracer that allows it to convert a > 64-bit > > > image back to 32-bit format, and it worked perfectly with my working > Squeak > > > image that has been in 64-bit format for several months now. > > > > Nice! > > > > > The resulting 32-bit image must be opened first using an interpreter > VM, > > > after which it can be run normally with a Cog VM. Tracing should be > done > > > using an interpreter VM. > > > > Why is that? > > > > - Bert - > > > > The issue was Float word ordering differences in Cog/StackInterpreter. I > made > an update to SystemTracer that mostly handles this, the main benefit being > that Cog can now be used to execute a much faster system trace from 32-bit > image to 64-bit 68002 (or the mythical 68003) image, non-Spur: > > Name: SystemTracing-dtl.27 > Time: 15 January 2015, 10:20:22.019 pm > > Allow 32-bit images to be traced to 64-bit using 32-bit Cog VM. Handle > float > word ordering differences between StackInterpreter and Interpreter. > Produces > a runnable 68003 image, 64-bit object format, closures, and Cog float > word > ordering. Requires package ImageFormat from VMMaker repository, else > error > is raised indicating how to hard code a workaround. This seems a > reasonable > dependency given the increasing number of image formats in circulation. > > Trace from 64-bit image to 32-bit still requires an initial load and save > using an interpreter VM prior to running with Cog, reason unknown. > > Dave > Great! -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150115/0bb21c83/attachment.htm From commits at source.squeak.org Fri Jan 16 07:49:01 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 07:49:04 2015 Subject: [squeak-dev] The Trunk: Collections-topa.594.mcz Message-ID: Tobias Pape uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-topa.594.mcz ==================== Summary ==================== Name: Collections-topa.594 Author: topa Time: 16 January 2015, 8:48:38.154 am UUID: ad0a6bee-b97d-47a5-bd6b-5c32211e8fd4 Ancestors: Collections-mt.593 Add #flattened as alias for #flatten. The former makes it more clear a copy will be returned (cf. #reversed), the latter is more in line with ANSI names (cf. #reverse) and other languages. =============== Diff against Collections-mt.593 =============== Item was added: + ----- Method: SequenceableCollection>>flattened (in category 'converting') ----- + flattened + "An alias for #flatten + This message's name is in line with messages like #sorted or #reversed + while #flatten's is in line with #reverse (as per ANSI, see comment there)" + + ^ self flatten! From commits at source.squeak.org Fri Jan 16 07:49:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 07:49:05 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-topa.230.mcz Message-ID: Tobias Pape uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-topa.230.mcz ==================== Summary ==================== Name: CollectionsTests-topa.230 Author: topa Time: 16 January 2015, 8:48:49.694 am UUID: b39de6a2-93e5-4c2b-b2d5-6f0b5cf26e8e Ancestors: CollectionsTests-mt.229 Add description to #flatten test. Add #flattened test (Collections-topa.594) =============== Diff against CollectionsTests-mt.229 =============== Item was changed: ----- Method: SequenceableCollectionTest>>testFlatten (in category 'tests - converting') ----- testFlatten + self + assert: {3 .4 .2 .4 .'hi' .'ho'} + equals: {3 .4 .{2 .4 .{'hi'} .'ho'}} flatten + description: '#flatten should deeply inline all collection-like elements'. + self + assert: #( (1 2) (3 4) ) concatenation + equals: #( (1 2) (3 4) ) flatten + description: '#flatten of one-level collection-nesting should be the same as its concatenation'. + ! - self assert: {3 .4 .{2 .4 .{'hi'} .'ho'}} flatten = {3 .4 .2 .4 .'hi' .'ho'}. - self assert: #( (1 2) (3 4) ) flatten = #( (1 2) (3 4) ) concatenation.! Item was added: + ----- Method: SequenceableCollectionTest>>testFlattened (in category 'tests - converting') ----- + testFlattened + + | randomCollection | + self + assert: {3 .4 .2 .4 .'hi' .'ho'} + equals: {3 .4 .{2 .4 .{'hi'} .'ho'}} flattened + description: '#flattened should deeply inline all collection-like elements'. + self + assert: #( (1 2) (3 4) ) concatenation + equals: #( (1 2) (3 4) ) flattened + description: '#flattened of one-level collection-nesting should be the same as its concatenation'. + + " ensure that #flatten and #flattened are compatible " + randomCollection := OrderedCollection new: 10. + 10 timesRepeat: [randomCollection add: 50 atRandom]. + + self + assert: randomCollection flatten + equals: randomCollection flattened + description: '#flatten and #flattened should be exchangeable' + ! From commits at source.squeak.org Fri Jan 16 08:10:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 08:10:06 2015 Subject: [squeak-dev] The Trunk: Collections-mt.595.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.595.mcz ==================== Summary ==================== Name: Collections-mt.595 Author: mt Time: 16 January 2015, 9:09:51.827 am UUID: 6cc6dbdd-293b-1747-a983-1cdd512bb383 Ancestors: Collections-topa.594 Some fixes to the OrderedDictionary implementation and its class comment was updated. =============== Diff against Collections-topa.594 =============== Item was changed: Dictionary subclass: #OrderedDictionary instanceVariableNames: 'order lastIndex' classVariableNames: '' poolDictionaries: '' category: 'Collections-Sequenceable'! + !OrderedDictionary commentStamp: 'mt 1/16/2015 09:08' prior: 0! - !OrderedDictionary commentStamp: '' prior: 0! I am an ordered dictionary. I have an additional index (called 'order') to keep track of the insertion order of my associations. The read access is not affected by the additional index. + The index is updated in O(1) [time] when inserting new keys. For present keys, that insertion involves actions in O(n) to move the respective element to the end of the order. - Storing new data updates the index in O(1) for new keys. Keys that are already present involve actions in O(n) to update the insertion order. The growth operation compacts the index and takes O(n) additional time.! Item was changed: ----- Method: OrderedDictionary>>add: (in category 'adding') ----- add: anAssociation | oldLastIndex oldCapacity | oldLastIndex := lastIndex. oldCapacity := self capacity. super add: anAssociation. (lastIndex = oldLastIndex or: [self capacity > oldCapacity]) ifTrue: [ | index | "The association was already present or we grew. We need to update the order." index := self scanOrderFor: anAssociation key. index = lastIndex ifFalse: [ lastIndex := lastIndex + 1. - index := self scanOrderFor: anAssociation key. order at: lastIndex put: (order at: index). order at: index put: nil. lastIndex = order size ifTrue: [self fixEmptySlots]]]. ^ anAssociation! Item was changed: ----- Method: OrderedDictionary>>scanOrderFor: (in category 'private') ----- scanOrderFor: anObject 1 to: lastIndex do: [:index | | element | ((element := order at: index) notNil and: [anObject = element key]) ifTrue: [^ index]]. lastIndex = order size ifTrue: [self errorNoFreeSpace] + ifFalse: [^ order at: lastIndex + 1 "nil"].! - ifFalse: [^ self order at: lastIndex + 1 "nil"].! From marcel.taeumel at student.hpi.uni-potsdam.de Fri Jan 16 08:39:55 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri Jan 16 08:42:45 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> Message-ID: <1421397595217-4799843.post@n4.nabble.com> Hi Levente, thank you for the quick code review. I did some fixes. :) For the LinkedDictionary: When do you establish the desired order (insertion, lexical, ... someBlock) for the associations? Use cases are similar to OrderedCollection. But instead of accessing items via index (someItems at: 5), you can access it with a more descriptive key (e.g., someItems at: #foobar). I will look for a more concrete one. To be better comparable with OrderedCollection, there might be an additional protocol to support #atFirst and others... Hmmm... Here are more references to the concept itself: https://www.python.org/dev/peps/pep-0372/ https://docs.python.org/3/library/collections.html#collections.OrderedDict Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799843.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Fri Jan 16 09:55:22 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 09:55:24 2015 Subject: [squeak-dev] The Trunk: Collections-mt.596.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.596.mcz ==================== Summary ==================== Name: Collections-mt.596 Author: mt Time: 16 January 2015, 10:55:07.303 am UUID: ca58af47-b4d1-6046-810d-27726f7a19e2 Ancestors: Collections-mt.595 some fixes to OrderedDictionary including copy; small part of the protocol of OrderedCollection adopted (#sort, #first, ...). =============== Diff against Collections-mt.595 =============== Item was changed: Dictionary subclass: #OrderedDictionary instanceVariableNames: 'order lastIndex' classVariableNames: '' poolDictionaries: '' category: 'Collections-Sequenceable'! + !OrderedDictionary commentStamp: 'mt 1/16/2015 10:42' prior: 0! - !OrderedDictionary commentStamp: 'mt 1/16/2015 09:08' prior: 0! I am an ordered dictionary. I have an additional index (called 'order') to keep track of the insertion order of my associations. The read access is not affected by the additional index. The index is updated in O(1) [time] when inserting new keys. For present keys, that insertion involves actions in O(n) to move the respective element to the end of the order. + The growth operation compacts the index and takes O(n) additional time. + + NOTE: This is still no instance of SequenceableCollection. Having this, some protocols are missing and may require working on #associations, which is an Array and thus sequenceable.! - The growth operation compacts the index and takes O(n) additional time.! Item was added: + ----- Method: OrderedDictionary>>atIndex: (in category 'accessing') ----- + atIndex: integer + + ^ self atIndex: integer ifAbsent: [self errorOutOfBounds]! Item was added: + ----- Method: OrderedDictionary>>atIndex:ifAbsent: (in category 'accessing') ----- + atIndex: integer ifAbsent: exceptionBlock + "As we are sequenceable, provide index-based access." + + | found | + found := 0. + self associationsDo: [:element | + (found := found + 1) = integer ifTrue: [ + ^ element]]. + + ^ exceptionBlock value! Item was added: + ----- Method: OrderedDictionary>>eighth (in category 'accessing') ----- + eighth + "Answer the eighth element of the receiver. + Raise an error if there are not enough elements." + + ^ self atIndex: 8! Item was added: + ----- Method: OrderedDictionary>>fifth (in category 'accessing') ----- + fifth + "Answer the fifth element of the receiver. + Raise an error if there are not enough elements." + + ^ self atIndex: 5! Item was added: + ----- Method: OrderedDictionary>>first (in category 'accessing') ----- + first + "Answer the first element of the receiver" + + ^ self atIndex: 1! Item was added: + ----- Method: OrderedDictionary>>first: (in category 'accessing') ----- + first: n + + "Answer the first n elements of the receiver. + Raise an error if there are not enough elements." + + ^ self copyFrom: 1 to: n! Item was added: + ----- Method: OrderedDictionary>>fourth (in category 'accessing') ----- + fourth + "Answer the fourth element of the receiver. + Raise an error if there are not enough elements." + + ^ self atIndex: 4! Item was added: + ----- Method: OrderedDictionary>>isSorted (in category 'sorting') ----- + isSorted + "Return true if the receiver is sorted by #<=." + + self fixEmptySlots. + ^ order + isSortedBetween: 1 + and: lastIndex! Item was added: + ----- Method: OrderedDictionary>>ninth (in category 'accessing') ----- + ninth + "Answer the ninth element of the receiver. + Raise an error if there are not enough elements." + + ^ self atIndex: 9! Item was added: + ----- Method: OrderedDictionary>>postCopy (in category 'copying') ----- + postCopy + "We must not copy associations again but retrieve them from the array, which is already a copy. See super." + + super postCopy. + order := order collect: [:association | + association ifNotNil: [array at: (self scanFor: association key)]].! Item was added: + ----- Method: OrderedDictionary>>second (in category 'accessing') ----- + second + "Answer the second element of the receiver. + Raise an error if there are not enough elements." + + ^ self atIndex: 2! Item was added: + ----- Method: OrderedDictionary>>seventh (in category 'accessing') ----- + seventh + "Answer the seventh element of the receiver. + Raise an error if there are not enough elements." + + ^ self atIndex: 7! Item was added: + ----- Method: OrderedDictionary>>sixth (in category 'accessing') ----- + sixth + "Answer the sixth element of the receiver. + Raise an error if there are not enough elements." + + ^ self atIndex: 6! Item was added: + ----- Method: OrderedDictionary>>sort (in category 'sorting') ----- + sort + + self sort: [:a1 :a2| a1 key <= a2 key].! Item was added: + ----- Method: OrderedDictionary>>sort: (in category 'sorting') ----- + sort: aSortBlock + "Like in OrderedCollection, sort the associations according to the sort block." + + self ifNotEmpty: [ + self fixEmptySlots. + order + mergeSortFrom: 1 + to: lastIndex + by: aSortBlock].! Item was added: + ----- Method: OrderedDictionary>>sorted: (in category 'sorting') ----- + sorted: aSortBlockOrNil + + ^ self copy sort: aSortBlockOrNil! Item was added: + ----- Method: OrderedDictionary>>third (in category 'accessing') ----- + third + "Answer the third element of the receiver. + Raise an error if there are not enough elements." + + ^ self atIndex: 3! From commits at source.squeak.org Fri Jan 16 09:57:08 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 09:57:10 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.231.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.231.mcz ==================== Summary ==================== Name: CollectionsTests-mt.231 Author: mt Time: 16 January 2015, 10:57:00.276 am UUID: 92893f87-f9a7-be46-874a-7353a3f29614 Ancestors: CollectionsTests-topa.230 More tests for OrderedDictionary =============== Diff against CollectionsTests-topa.230 =============== Item was added: + ----- Method: OrderedDictionaryTest>>testAtIndex (in category 'tests - accessing') ----- + testAtIndex + + 1 to: 10 do: [:ea | + sut at: ea put: nil]. + + 1 to: 10 do: [:index | + self assert: index equals: (sut atIndex: index) key].! Item was added: + ----- Method: OrderedDictionaryTest>>testCopy (in category 'tests - copying') ----- + testCopy + + sut + at: 1 put: nil; + at: 2 put: nil; + at: 1 put: nil. + + sut copy in: [:copy | + self assert: sut keys equals: copy keys. + copy at: 2 put: nil. + self + assert: sut keys size = copy keys size; + assert: sut keys ~= copy keys].! Item was added: + ----- Method: OrderedDictionaryTest>>testFirst (in category 'tests - accessing') ----- + testFirst + + 1 to: 10 do: [:ea | + sut at: ea put: nil]. + + #(first second third fourth fifth sixth seventh eighth ninth) withIndexDo: [:selector :index | + self assert: index equals: (sut perform: selector) key].! Item was added: + ----- Method: OrderedDictionaryTest>>testIsSorted (in category 'tests - sorting') ----- + testIsSorted + + 10 to: 1 by: -1 do: [:ea | + sut at: ea put: nil]. + + self assert: sut isSorted not. + sut sort. + self assert: sut isSorted.! Item was added: + ----- Method: OrderedDictionaryTest>>testSort (in category 'tests - sorting') ----- + testSort + + 10 to: 1 by: -1 do: [:ea | + sut at: ea put: nil]. + + self assert: (10 to: 1 by: -1) asArray equals: sut keys. + sut sort. + self assert: (1 to: 10) asArray equals: sut keys.! Item was added: + ----- Method: OrderedDictionaryTest>>testSortAfterOverwrite (in category 'tests - sorting') ----- + testSortAfterOverwrite + + 10 to: 1 by: -1 do: [:ea | + sut at: ea put: nil]. + + sut at: 5 put: nil. + sut sort. + self assert: (1 to: 10) asArray equals: sut keys.! Item was added: + ----- Method: OrderedDictionaryTest>>testSortCustom (in category 'tests - sorting') ----- + testSortCustom + + | values | + values := #(The quick brown fox jumps over the lazy dog). + 1 to: 9 do: [:ea | + sut at: ea put: (values at: ea)]. + sut sort: [:a1 :a2 | a1 value <= a2 value]. + self assert: values sorted equals: sut values. + ! Item was added: + ----- Method: OrderedDictionaryTest>>testSorted (in category 'tests - sorting') ----- + testSorted + + 10 to: 1 by: -1 do: [:ea | + sut at: ea put: nil]. + + sut sorted in: [:copy | + self + assert: copy ~~ sut; + assert: copy keys = sut keys reversed].! From commits at source.squeak.org Fri Jan 16 09:58:23 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 09:58:23 2015 Subject: [squeak-dev] The Trunk: Collections-mt.597.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.597.mcz ==================== Summary ==================== Name: Collections-mt.597 Author: mt Time: 16 January 2015, 10:58:06.65 am UUID: 30d20939-3981-af4d-88b7-8e85c4f29201 Ancestors: Collections-mt.596 Removed non-working #first: from OrderedDictionary. Was committed by accident. ^__^ =============== Diff against Collections-mt.596 =============== Item was removed: - ----- Method: OrderedDictionary>>first: (in category 'accessing') ----- - first: n - - "Answer the first n elements of the receiver. - Raise an error if there are not enough elements." - - ^ self copyFrom: 1 to: n! From bert at freudenbergs.de Fri Jan 16 11:13:00 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Fri Jan 16 11:13:03 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <1421397595217-4799843.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> Message-ID: On 16.01.2015, at 09:39, Marcel Taeumel wrote: > > https://www.python.org/dev/peps/pep-0372/ Interesting. This states that the order is never updated: when an existing element is overwritten, it is not moved to the end. Only new keys are appended. This allows for a more efficient implementation (such as suggested by Levente). I think an OrderedDictionary would most often be used to preserve the original order of keys. Assigning a new value should not move the item to the end. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150116/79fc922b/smime.bin From marcel.taeumel at student.hpi.uni-potsdam.de Fri Jan 16 13:26:11 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri Jan 16 13:29:03 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> Message-ID: <1421414771064-4799882.post@n4.nabble.com> Hmm... you're right. It seems that in C#, it is just an overwrite, too. Which could imply no update of the order. http://msdn.microsoft.com/en-us/library/system.collections.specialized.ordereddictionary.add%28v=vs.100%29.aspx I cannot verify that right now. However, this would really make the implementation simpler and maybe more flexible. Still, I have to look into this linking of values. Did not get it yet... :) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799882.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From leves at elte.hu Fri Jan 16 13:31:02 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri Jan 16 13:31:08 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <1421397595217-4799843.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> Message-ID: On Fri, 16 Jan 2015, Marcel Taeumel wrote: > Hi Levente, > > thank you for the quick code review. I did some fixes. :) > > For the LinkedDictionary: When do you establish the desired order > (insertion, lexical, ... someBlock) for the associations? I'm not sure if I understand this question right, so I'll try do my best to give a meaningful answer. If the goal is to keep the insertion order, then #atNewIndex:put: is the right place. If you want it to reflect the order of modifications (insert + update), then #add: and #at:put: has to be modified too. If you want the order to reflect the order of accesses, then all other methods have to be changed which access the value (or the key?). For the list implementation, I always prefer the circular doubly-linked list with a head element (Not sure if this is the right term in english. It means a separate element with no value, just the next and the previous links. This allows the code to be simpler, because the list always has at least one element). This list provides O(1) time removal, and insertion next to the head (or any other known element). This is why any kind of ordering can be implemented with O(1) extra time, as long as the elements are moved to the front. The only drawback this dictionary implementation has is that the associations added with #add: can't be used, unless they are from the right class (the one which has the two links). In Java this collection is called LinkedHashMap: http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html This supports two kind of ordering: access-order and insertion-order. Levente > > Use cases are similar to OrderedCollection. But instead of accessing items > via index (someItems at: 5), you can access it with a more descriptive key > (e.g., someItems at: #foobar). I will look for a more concrete one. > > To be better comparable with OrderedCollection, there might be an additional > protocol to support #atFirst and others... Hmmm... > > Here are more references to the concept itself: > https://www.python.org/dev/peps/pep-0372/ > https://docs.python.org/3/library/collections.html#collections.OrderedDict > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799843.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From marcel.taeumel at student.hpi.uni-potsdam.de Fri Jan 16 13:54:20 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri Jan 16 13:57:11 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> Message-ID: <1421416460175-4799893.post@n4.nabble.com> Ah, okay. I was curious about the performance of iterating over an array vs. the linked list: a := Array new: 1000. l := LinkedList new. 1000 timesRepeat: [l add: (StackLink with: nil)]. [a do: [:ea | 1 + 2]] bench. "'94,600 per second.'" [l do: [:ea | 1 + 2]] bench. "'159,000 per second.'" I expected the opposite! :-O Why is that so? Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799893.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From leves at elte.hu Fri Jan 16 14:07:30 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri Jan 16 14:07:35 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <1421414771064-4799882.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421414771064-4799882.post@n4.nabble.com> Message-ID: On Fri, 16 Jan 2015, Marcel Taeumel wrote: > Hmm... you're right. It seems that in C#, it is just an overwrite, too. Which > could imply no update of the order. > > http://msdn.microsoft.com/en-us/library/system.collections.specialized.ordereddictionary.add%28v=vs.100%29.aspx > > I cannot verify that right now. However, this would really make the > implementation simpler and maybe more flexible. > > Still, I have to look into this linking of values. Did not get it yet... :) I've uploaded a quick implementation, which uses the insertion order. http://leves.web.elte.hu/squeak/LinkedDictionary-ul.1.mcz Levente > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799882.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From Das.Linux at gmx.de Fri Jan 16 15:00:30 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri Jan 16 15:00:34 2015 Subject: [squeak-dev] The Trunk: Collections-mt.595.mcz Message-ID: <25DA40C7-58A9-4287-88D0-BFE7373DE755@gmx.de> Hi, On 16.01.2015, at 08:09, commits@source.squeak.org wrote: > The index is updated in O(1) [time] when inserting new keys. For present keys, that insertion involves actions in O(n) to move the respective element to the end of the order. Why? I would expect, that first insert wins: (OrderedDictionary new at: 'foo' put: 100; at: 'bar' put: 20; at: 'foo' put: 59; yourself) keysAndValuesDo: [:key :value | Transcript show: key asString, ' > ', value asString; cr. ] "Should print: foo > 59 bar > 20 " Don't you think? Best -Tobias From Das.Linux at gmx.de Fri Jan 16 15:01:24 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri Jan 16 15:01:40 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> Message-ID: On 16.01.2015, at 12:13, Bert Freudenberg wrote: > On 16.01.2015, at 09:39, Marcel Taeumel wrote: >> >> https://www.python.org/dev/peps/pep-0372/ > > Interesting. This states that the order is never updated: when an existing element is overwritten, it is not moved to the end. Only new keys are appended. This allows for a more efficient implementation (such as suggested by Levente). > > I think an OrderedDictionary would most often be used to preserve the original order of keys. Assigning a new value should not move the item to the end. > ACK. See other mail. Best -Tobias > - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 1625 bytes Desc: Message signed with OpenPGP using GPGMail Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150116/07fbccff/signature.pgp From eliot.miranda at gmail.com Fri Jan 16 15:21:37 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 15:21:44 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> Message-ID: <32F499BE-C6D5-4C2A-BB6F-FE51BE1FE7B5@gmail.com> On Jan 16, 2015, at 3:13 AM, Bert Freudenberg wrote: > On 16.01.2015, at 09:39, Marcel Taeumel wrote: >> >> https://www.python.org/dev/peps/pep-0372/ > > Interesting. This states that the order is never updated: when an existing element is overwritten, it is not moved to the end. Only new keys are appended. This allows for a more efficient implementation (such as suggested by Levente). > > I think an OrderedDictionary would most often be used to preserve the original order of keys. Assigning a new value should not move the item to the end. +1 From eliot.miranda at gmail.com Fri Jan 16 15:36:56 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 15:37:03 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <1421416460175-4799893.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> Message-ID: Hi Marcel, On Jan 16, 2015, at 5:54 AM, Marcel Taeumel wrote: > Ah, okay. I was curious about the performance of iterating over an array vs. > the linked list: > > a := Array new: 1000. > l := LinkedList new. > > 1000 timesRepeat: [l add: (StackLink with: nil)]. > > [a do: [:ea | 1 + 2]] bench. "'94,600 per second.'" > > [l do: [:ea | 1 + 2]] bench. "'159,000 per second.'" > > I expected the opposite! :-O Why is that so? Look at the implementations of do:. In the Array case we iterate over the indices using SmallIntegers (fast arithmetic with no allocation) and dereference each element using the Object>>at: primitive, which (apart from type and bounds checking) is simple indexed memory access. So one read per element. In the LinkedList case each list element is fetched from the previous element and each value fetched from the element, so two reads per element. > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799893.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From bert at freudenbergs.de Fri Jan 16 15:53:11 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Fri Jan 16 15:53:15 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> Message-ID: <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> > On 16.01.2015, at 16:36, Eliot Miranda wrote: > > Hi Marcel, > > On Jan 16, 2015, at 5:54 AM, Marcel Taeumel wrote: > >> Ah, okay. I was curious about the performance of iterating over an array vs. >> the linked list: >> >> a := Array new: 1000. >> l := LinkedList new. >> >> 1000 timesRepeat: [l add: (StackLink with: nil)]. >> >> [a do: [:ea | 1 + 2]] bench. "'94,600 per second.'" >> >> [l do: [:ea | 1 + 2]] bench. "'159,000 per second.'" >> >> I expected the opposite! :-O Why is that so? > > Look at the implementations of do:. > > In the Array case we iterate over the indices using SmallIntegers (fast arithmetic with no allocation) and dereference each element using the Object>>at: primitive, which (apart from type and bounds checking) is simple indexed memory access. So one read per element. > > In the LinkedList case each list element is fetched from the previous element and each value fetched from the element, so two reads per element. Making it all the more surprising that the linked list is twice as fast. My guess would be that the two inst var reads are way more efficient than the at: primitive. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150116/03ff2ec6/smime.bin From eliot.miranda at gmail.com Fri Jan 16 15:55:27 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 15:55:33 2015 Subject: [squeak-dev] Understanding Object Structures In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> Message-ID: <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> Hi All, On Jan 16, 2015, at 7:36 AM, Eliot Miranda wrote: > Hi Marcel, > > On Jan 16, 2015, at 5:54 AM, Marcel Taeumel wrote: > >> Ah, okay. I was curious about the performance of iterating over an array vs. >> the linked list: >> >> a := Array new: 1000. >> l := LinkedList new. >> >> 1000 timesRepeat: [l add: (StackLink with: nil)]. >> >> [a do: [:ea | 1 + 2]] bench. "'94,600 per second.'" >> >> [l do: [:ea | 1 + 2]] bench. "'159,000 per second.'" >> >> I expected the opposite! :-O Why is that so? > > Look at the implementations of do:. > > In the Array case we iterate over the indices using SmallIntegers (fast arithmetic with no allocation) and dereference each element using the Object>>at: primitive, which (apart from type and bounds checking) is simple indexed memory access. So one read per element. > > In the LinkedList case each list element is fetched from the previous element and each value fetched from the element, so two reads per element. This is interesting. (Marcel, Chris, forgive me; I'm presuming; please don't take this personally). Marcel above appears to lack an intuition about the structure of Array vs LinkedList. And in developing a hash algorithm for a 32-bit subset of Floats a few weeks ago Chris appeared to lack an I tuition about Floats being boxed, assuming they were value types, not containers. As a VM implementer I carry around a clear picture (literally, I am a visual thinker) of objects in my head. Those pictures are key to my approach to design and optimization. I presume that for someone approaching the system given only a textual description of object structures, through class comments and method source it is difficult to develop a good picture or mental model. For me, I read the blue book first, which is replete with pictures. I know that historically visual inspector frameworks such as Jun have been able to auto-generate pictorial representations of specific object graphs. I wonder how useful it would be to provide support for designers to include pictorial representations in class comments. Again I presume that the text model would have to support inclusion of simple bitmaps (to avoid having to include a full drawing framework in the system) and that the designer would construct a sample graph, generate a diagram using a visual inspector framework using eg Jun, render it to a bitmap and include it in the class comment. A more elaborate system could of course include the sample graph and render it dynamically, that would allow exploration. Either approach would make an interesting project, yes? >> Best, >> Marcel >> >> >> >> -- >> View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799893.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> From eliot.miranda at gmail.com Fri Jan 16 16:00:36 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 16:00:42 2015 Subject: [squeak-dev] Re: Understanding Object Structures In-Reply-To: <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> Message-ID: <811DD043-102D-452A-B12B-C737EC4852DF@gmail.com> On Jan 16, 2015, at 7:55 AM, Eliot Miranda wrote: > Hi All, > > On Jan 16, 2015, at 7:36 AM, Eliot Miranda wrote: > >> Hi Marcel, >> >> On Jan 16, 2015, at 5:54 AM, Marcel Taeumel wrote: >> >>> Ah, okay. I was curious about the performance of iterating over an array vs. >>> the linked list: >>> >>> a := Array new: 1000. >>> l := LinkedList new. >>> >>> 1000 timesRepeat: [l add: (StackLink with: nil)]. >>> >>> [a do: [:ea | 1 + 2]] bench. "'94,600 per second.'" >>> >>> [l do: [:ea | 1 + 2]] bench. "'159,000 per second.'" >>> >>> I expected the opposite! :-O Why is that so? >> >> Look at the implementations of do:. >> >> In the Array case we iterate over the indices using SmallIntegers (fast arithmetic with no allocation) and dereference each element using the Object>>at: primitive, which (apart from type and bounds checking) is simple indexed memory access. So one read per element. >> >> In the LinkedList case each list element is fetched from the previous element and each value fetched from the element, so two reads per element. > > This is interesting. (Marcel, Chris, forgive me; I'm presuming; please don't take this personally). Marcel above appears to lack an intuition about the structure of Array vs LinkedList. And in developing a hash algorithm for a 32-bit subset of Floats a few weeks ago Chris appeared to lack an I tuition about Floats being boxed, assuming they were value types, not containers. > > As a VM implementer I carry around a clear picture (literally, I am a visual thinker) of objects in my head. Those pictures are key to my approach to design and optimization. > and lest anyone think I have no problem developing these pictures, elsewhere in the thread Levente discussed the linked hash map organization of OrderedDictionary. It took me the few minutes in which I drafted an erroneous and unsent email to develop the picture that made me realize Levente was right about lookup being O(1) because I didn't have the picture of a link in my head when I started writing the email. > I presume that for someone approaching the system given only a textual description of object structures, through class comments and method source it is difficult to develop a good picture or mental model. For me, I read the blue book first, which is replete with pictures. > > I know that historically visual inspector frameworks such as Jun have been able to auto-generate pictorial representations of specific object graphs. I wonder how useful it would be to provide support for designers to include pictorial representations in class comments. > > Again I presume that the text model would have to support inclusion of simple bitmaps (to avoid having to include a full drawing framework in the system) and that the designer would construct a sample graph, generate a diagram using a visual inspector framework using eg Jun, render it to a bitmap and include it in the class comment. > > A more elaborate system could of course include the sample graph and render it dynamically, that would allow exploration. > > Either approach would make an interesting project, yes? > >>> Best, >>> Marcel >>> >>> >>> >>> -- >>> View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799893.html >>> Sent from the Squeak - Dev mailing list archive at Nabble.com. >>> From marcel.taeumel at student.hpi.uni-potsdam.de Fri Jan 16 16:16:56 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri Jan 16 16:19:49 2015 Subject: [squeak-dev] Re: Understanding Object Structures In-Reply-To: <811DD043-102D-452A-B12B-C737EC4852DF@gmail.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> <811DD043-102D-452A-B12B-C737EC4852DF@gmail.com> Message-ID: <1421425016972-4799945.post@n4.nabble.com> Ah, I just thought of an array as being some contiguous memory area. Mea culpa. :) @ Levente: Thanks for the implementation of LinkedDictionary! Now I see, what you meant. The links are still an addition to the array of Dictionary. I misunderstood that part. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799945.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From eliot.miranda at gmail.com Fri Jan 16 16:27:53 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 16:27:59 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> Message-ID: <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> On Jan 16, 2015, at 7:53 AM, Bert Freudenberg wrote: > >> On 16.01.2015, at 16:36, Eliot Miranda wrote: >> >> Hi Marcel, >> >> On Jan 16, 2015, at 5:54 AM, Marcel Taeumel wrote: >> >>> Ah, okay. I was curious about the performance of iterating over an array vs. >>> the linked list: >>> >>> a := Array new: 1000. >>> l := LinkedList new. >>> >>> 1000 timesRepeat: [l add: (StackLink with: nil)]. >>> >>> [a do: [:ea | 1 + 2]] bench. "'94,600 per second.'" >>> >>> [l do: [:ea | 1 + 2]] bench. "'159,000 per second.'" >>> >>> I expected the opposite! :-O Why is that so? >> >> Look at the implementations of do:. >> >> In the Array case we iterate over the indices using SmallIntegers (fast arithmetic with no allocation) and dereference each element using the Object>>at: primitive, which (apart from type and bounds checking) is simple indexed memory access. So one read per element. >> >> In the LinkedList case each list element is fetched from the previous element and each value fetched from the element, so two reads per element. > > Making it all the more surprising that the linked list is twice as fast. Ugh. I was blindsided. I saw the numbers as times not rates. Marcel, I'm sorry. OK indeed the difference would be the cost of the bounds check in each array access. Interesting to see at what point the poorer memory locality of the list makes it worse. Difficult to measure given the locality is decided by history and the GC. > > My guess would be that the two inst var reads are way more efficient than the at: primitive. > > - Bert - > > > From marcel.taeumel at student.hpi.uni-potsdam.de Fri Jan 16 16:28:47 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri Jan 16 16:31:39 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> Message-ID: <1421425727350-4799947.post@n4.nabble.com> Okay, the Array >> #do: comes down to Number's: to: stop do: aBlock "Normally compiled in-line, and therefore not overridable. Evaluate aBlock for each element of the interval (self to: stop by: 1)." | nextValue | nextValue := self. [nextValue <= stop] whileTrue: [aBlock value: nextValue. nextValue := nextValue + 1] And the LinkedList >> #do: is: do: aBlock | aLink | aLink := firstLink. [aLink == nil] whileFalse: [aBlock value: aLink. aLink := aLink nextLink] So Array iteration has the incrementation of 1 in each iteration. That makes the difference? I thought that #to:do: is optimized as it does not appear on the stack... :) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799947.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From eliot.miranda at gmail.com Fri Jan 16 16:33:55 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 16:34:00 2015 Subject: [squeak-dev] Re: Understanding Object Structures In-Reply-To: <1421425016972-4799945.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> <811DD043-102D-452A-B12B-C737EC4852DF@gmail.com> <1421425016972-4799945.post@n4.nabble.com> Message-ID: <47627E47-B01B-4B16-8262-ECC57D2366BD@gmail.com> On Jan 16, 2015, at 8:16 AM, Marcel Taeumel wrote: > Ah, I just thought of an array as being some contiguous memory area. Mea > culpa. : That's exactly what it is. I've made a fool if myself replying to email b4 I've properly woken up :-/ > > @ Levente: Thanks for the implementation of LinkedDictionary! Now I see, > what you meant. The links are still an addition to the array of Dictionary. > I misunderstood that part. > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799945.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From eliot.miranda at gmail.com Fri Jan 16 16:39:34 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 16:39:39 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <1421425727350-4799947.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> <1421425727350-4799947.post@n4.nabble.com> Message-ID: <27BEF4D8-F52E-4E5A-B736-E3A9CEAF96B1@gmail.com> Hi Marcel, On Jan 16, 2015, at 8:28 AM, Marcel Taeumel wrote: > Okay, the Array >> #do: comes down to Number's: > > to: stop do: aBlock > "Normally compiled in-line, and therefore not overridable. > Evaluate aBlock for each element of the interval (self to: stop by: 1)." > | nextValue | > nextValue := self. > [nextValue <= stop] > whileTrue: > [aBlock value: nextValue. > nextValue := nextValue + 1] > > And the LinkedList >> #do: is: > > do: aBlock > | aLink | > aLink := firstLink. > [aLink == nil] whileFalse: > [aBlock value: aLink. > aLink := aLink nextLink] > > So Array iteration has the incrementation of 1 in each iteration. That makes > the difference? I thought that #to:do: is optimized as it does not appear on > the stack... :) Ghhh, it's too early :-). Only just now drinking some tea. The Array implementation is compiled to an unlined while loop so all the overhead is in each application of at: that does bounds checking every time. I'll profile this with the VMProfiler in a few minutes. This is great news for Sista because this is some of the overhead it will eliminate. > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799947.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From bert at freudenbergs.de Fri Jan 16 16:50:55 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Fri Jan 16 16:50:59 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <1421425727350-4799947.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> <1421425727350-4799947.post@n4.nabble.com> Message-ID: On 16.01.2015, at 17:28, Marcel Taeumel wrote: > > Okay, the Array >> #do: comes down to Number's: > > to: stop do: aBlock > "Normally compiled in-line, and therefore not overridable. > Evaluate aBlock for each element of the interval (self to: stop by: 1)." > | nextValue | > nextValue := self. > [nextValue <= stop] > whileTrue: > [aBlock value: nextValue. > nextValue := nextValue + 1] No, the to:do: is inlined. Look at the bytecodes ... do: aBlock 1 to: self size do: [:index | aBlock value: (self at: index)] > And the LinkedList >> #do: is: > > do: aBlock > | aLink | > aLink := firstLink. > [aLink == nil] whileFalse: > [aBlock value: aLink. > aLink := aLink nextLink] > > So Array iteration has the incrementation of 1 in each iteration. That makes > the difference? I thought that #to:do: is optimized as it does not appear on > the stack... :) The difference is that #at: is much more expensive than #nextLink. Interestingly, on the interpreter VM the Array version is ever so slightly faster. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150116/4ad4f92b/smime.bin From leves at elte.hu Fri Jan 16 16:55:23 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri Jan 16 16:55:27 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> Message-ID: On Fri, 16 Jan 2015, Eliot Miranda wrote: > > > On Jan 16, 2015, at 7:53 AM, Bert Freudenberg wrote: > >> >>> On 16.01.2015, at 16:36, Eliot Miranda wrote: >>> >>> Hi Marcel, >>> >>> On Jan 16, 2015, at 5:54 AM, Marcel Taeumel wrote: >>> >>>> Ah, okay. I was curious about the performance of iterating over an array vs. >>>> the linked list: >>>> >>>> a := Array new: 1000. >>>> l := LinkedList new. >>>> >>>> 1000 timesRepeat: [l add: (StackLink with: nil)]. >>>> >>>> [a do: [:ea | 1 + 2]] bench. "'94,600 per second.'" >>>> >>>> [l do: [:ea | 1 + 2]] bench. "'159,000 per second.'" >>>> >>>> I expected the opposite! :-O Why is that so? >>> >>> Look at the implementations of do:. >>> >>> In the Array case we iterate over the indices using SmallIntegers (fast arithmetic with no allocation) and dereference each element using the Object>>at: primitive, which (apart from type and bounds checking) is simple indexed memory access. So one read per element. >>> >>> In the LinkedList case each list element is fetched from the previous element and each value fetched from the element, so two reads per element. >> >> Making it all the more surprising that the linked list is twice as fast. > > Ugh. I was blindsided. I saw the numbers as times not rates. Marcel, I'm sorry. OK indeed the difference would be the cost of the bounds check in each array access. Interesting to see at what point the poorer memory locality of the list makes it worse. Difficult to measure given the locality is decided by history and the GC. In general the locality of the links are worse. In the example they are allocated almost next to each other. A slightly better example would be this: | buffer | buffer := Array new: 1000. "This will hold the filler objects." #(1024 2048 4096 8192 16384 32768 65536) collect: [ :fillerSize | | list | list := LinkedList new. 1 to: 1000 do: [ :index | list add: (StackLink with: nil). buffer at: index put: (Array new: fillerSize) ]. Smalltalk garbageCollect. fillerSize -> [ list do: [ :ea | 1 + 2 ] ] bench ] { "gap between nodes (x4 bytes)" -> "runs" 1024->'78,000 per second.'. 2048->'78,600 per second.'. 4096->'77,500 per second.'. 8192->'73,300 per second.'. 16384->'70,200 per second.'. 32768->'66,400 per second.'. 65536->'56,400 per second.'} (The result is '45,700 per second.' for Arrays) The results depend on the CPU (and probably on the OS too), but the numbers are still pretty good. Probably a longer list would cause more problem for the caches. The same for 10k elements in the list: { 1024->'3,770 per second.'. 2048->'4,780 per second.'. 4096->'4,220 per second.'. 8192->'2,480 per second.'. 16384->'2,110 per second.'} (The result is '4,380 per second.' for Arrays) So the speed of a list depends on the cache locality of its elements. The performance is still comparable with arrays for practical cases, but may be both faster and slower depending on the cache locality. Levente > > >> >> My guess would be that the two inst var reads are way more efficient than the at: primitive. >> >> - Bert - >> >> >> > > From Das.Linux at gmx.de Fri Jan 16 17:30:12 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri Jan 16 17:30:16 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> Message-ID: <575D49A8-797D-481E-B37E-97E020D4DF81@gmx.de> On 16.01.2015, at 17:55, Levente Uzonyi wrote: > On Fri, 16 Jan 2015, Eliot Miranda wrote: > >> >> >> On Jan 16, 2015, at 7:53 AM, Bert Freudenberg wrote: >> >>> >>>> On 16.01.2015, at 16:36, Eliot Miranda wrote: >>>> >>>> Hi Marcel, [snip] These kind of discussions is why I love squeak-dev :) I always lern. Best -Tobias From Das.Linux at gmx.de Fri Jan 16 17:31:55 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri Jan 16 17:31:59 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <575D49A8-797D-481E-B37E-97E020D4DF81@gmx.de> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> <575D49A8-797D-481E-B37E-97E020D4DF81@gmx.de> Message-ID: <93D3F6AA-FC5F-45EC-A7E2-92E7689D91C2@gmx.de> On 16.01.2015, at 18:30, Tobias Pape wrote: > > On 16.01.2015, at 17:55, Levente Uzonyi wrote: > >> On Fri, 16 Jan 2015, Eliot Miranda wrote: >> >>> >>> >>> On Jan 16, 2015, at 7:53 AM, Bert Freudenberg wrote: >>> >>>> >>>>> On 16.01.2015, at 16:36, Eliot Miranda wrote: >>>>> >>>>> Hi Marcel, > [snip] > > These kind of discussions is why I love squeak-dev :) > I always lern. (save spelling, apparently -.-') > > Best > -Tobias From bert at freudenbergs.de Fri Jan 16 17:45:50 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Fri Jan 16 17:45:53 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <93D3F6AA-FC5F-45EC-A7E2-92E7689D91C2@gmx.de> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> <575D49A8-797D-481E-B37E-97E020D4DF81@gmx.de> <93D3F6AA-FC5F-45EC-A7E2-92E7689D91C2@gmx.de> Message-ID: > On 16.01.2015, at 18:31, Tobias Pape wrote: > > > On 16.01.2015, at 18:30, Tobias Pape wrote: > >> >> On 16.01.2015, at 17:55, Levente Uzonyi wrote: >> >>> On Fri, 16 Jan 2015, Eliot Miranda wrote: >>> >>>> >>>> >>>> On Jan 16, 2015, at 7:53 AM, Bert Freudenberg wrote: >>>> >>>>> >>>>>> On 16.01.2015, at 16:36, Eliot Miranda wrote: >>>>>> >>>>>> Hi Marcel, >> [snip] >> >> These kind of discussions is why I love squeak-dev :) >> I always lern. > > (save spelling, apparently -.-') That was perfect Germanish ;) - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150116/edf27cab/smime.bin From asqueaker at gmail.com Fri Jan 16 18:41:55 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri Jan 16 18:42:01 2015 Subject: [squeak-dev] Understanding Object Structures In-Reply-To: <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> Message-ID: > I presume that for someone approaching the system given only a textual description of object structures, through class comments and method source it is difficult to develop a good picture or mental model. For me, I read the blue book first, which is replete with pictures. I like to envision the physical model in my mind. I look at the class definitions to identify the object links (for pointer objects) and then the methods which modifies those vars. Once I have that picture of the physical model in my head, I then in my mind think about that shape model with each node "suited up" with its behaviors. Knowing their underlying links to other objects even helps me evaluate the consistency and nuance of the API). > I know that historically visual inspector frameworks such as Jun have been able to auto-generate pictorial representations of specific object graphs. I wonder how useful it would be to provide support for designers to include pictorial representations in class comments. For years, I have been /totally/ interested in Alexandre's project, not just to represent in-memory models but large Magma models, visually. Roassal might struggle to perform with millions of nodes, I don't know, but I know Craig used Walrus to render a large model. Unfortunately I just haven't had the time to dig into these projects.. > Again I presume that the text model would have to support inclusion of simple bitmaps (to avoid having to include a full drawing framework in the system) and that the designer would construct a sample graph, generate a diagram using a visual inspector framework using eg Jun, render it to a bitmap and include it in the class comment. Squeak's Text model actually supports the inclusion of any Morph embedded as a single character. Maui uses that for its "documents" it actually works very well. Seeing animated, fully-functioning Morphs as characters in a document is kind'a cool. > A more elaborate system could of course include the sample graph and render it dynamically, that would allow exploration. > > Either approach would make an interesting project, yes? > >>> Best, >>> Marcel >>> >>> >>> >>> -- >>> View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4799893.html >>> Sent from the Squeak - Dev mailing list archive at Nabble.com. >>> > From pdebruic at gmail.com Fri Jan 16 19:36:00 2015 From: pdebruic at gmail.com (Paul DeBruicker) Date: Fri Jan 16 19:38:53 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> Message-ID: <1421436960719-4800035.post@n4.nabble.com> Eliot Miranda-2 wrote > Ugh. I was blindsided. I saw the numbers as times not rates. Marcel, > I'm sorry. OK indeed the difference would be the cost of the bounds check > in each array access. Interesting to see at what point the poorer memory > locality of the list makes it worse. Difficult to measure given the > locality is decided by history and the GC. With Spur could you use object pinning to make a dense linked list? And then use that for arrays that need to be fast? -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4800035.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From eliot.miranda at gmail.com Fri Jan 16 19:47:55 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 19:47:57 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <1421436960719-4800035.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> <1421436960719-4800035.post@n4.nabble.com> Message-ID: Hi Paul, On Fri, Jan 16, 2015 at 11:36 AM, Paul DeBruicker wrote: > Eliot Miranda-2 wrote > > Ugh. I was blindsided. I saw the numbers as times not rates. Marcel, > > I'm sorry. OK indeed the difference would be the cost of the bounds > check > > in each array access. Interesting to see at what point the poorer memory > > locality of the list makes it worse. Difficult to measure given the > > locality is decided by history and the GC. > > With Spur could you use object pinning to make a dense linked list? And > then > use that for arrays that need to be fast? > It might make some difference but I doubt it'll work well. There is code to cluster pinned objects in the segment or segments that contain pinned objects. But it's not going to work well; if the object is in new space then it is copied to old space and forwarded, plus some scanning of stack pages. Thats a lot of overhead. If it's in old space anyway the GC just sets the bit. Pinning is really there for objects to be passed through the FFI or space needed to be referred to from machine code, such as conditional branch counters in Sista. it's not there to control locality. Hence it is unoptimised. But that's an interesting idea :-). A more general solution would be to have some sort of reorganisation in the VM. Currently the compaction algorithm used with global GC scrambles things. It would be nice if the incremental global compactor could not scramble, and its my intent to at least avoid scrambling, if not undo it in the incremental global gc (which has yet to be started). -- > View this message in context: > http://forum.world.st/The-Trunk-Collections-mt-593-mcz-tp4799750p4800035.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150116/a64f57d8/attachment.htm From asqueaker at gmail.com Fri Jan 16 19:49:34 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri Jan 16 19:49:36 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> Message-ID: > In general the locality of the links are worse. In the example they are > allocated almost next to each other. > A slightly better example would be this: > > | buffer | > buffer := Array new: 1000. "This will hold the filler objects." > #(1024 2048 4096 8192 16384 32768 65536) collect: [ :fillerSize | > | list | > list := LinkedList new. > 1 to: 1000 do: [ :index | > list add: (StackLink with: nil). > buffer at: index put: (Array new: fillerSize) ]. > Smalltalk garbageCollect. > fillerSize -> [ list do: [ :ea | 1 + 2 ] ] bench ] > > { "gap between nodes (x4 bytes)" -> "runs" > 1024->'78,000 per second.'. > 2048->'78,600 per second.'. > 4096->'77,500 per second.'. > 8192->'73,300 per second.'. > 16384->'70,200 per second.'. 32768->'66,400 per second.'. > 65536->'56,400 per second.'} > > (The result is '45,700 per second.' for Arrays) > > The results depend on the CPU (and probably on the OS too), but the numbers > are still pretty good. Probably a longer list would cause more problem for > the caches. > The same for 10k elements in the list: > > { > 1024->'3,770 per second.'. > 2048->'4,780 per second.'. > 4096->'4,220 per second.'. > 8192->'2,480 per second.'. > 16384->'2,110 per second.'} > > (The result is '4,380 per second.' for Arrays) > > So the speed of a list depends on the cache locality of its elements. The > performance is still comparable with arrays for practical cases, but may be > both faster and slower depending on the cache locality. Geez you guys /seriously/ rock. I never thought down to that level of (CPU) cache locality. You've got me feeling like I should go back to some performance-critical code which is enumerating Array's and see about converting them to LinkedLists.. too bad I don't have time to do that! From asqueaker at gmail.com Fri Jan 16 19:54:20 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri Jan 16 19:54:22 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: <94B66B30-ADDF-48C6-9806-C74A211E9F79@gmx.de> References: <94B66B30-ADDF-48C6-9806-C74A211E9F79@gmx.de> Message-ID: I'm starting to suspect Environments. The last-literal binding is not updated after rename.. Object compile: 'test ^''Hello from Object'''. (Object subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test') compile: 'test ^ super halt test, ''my super call lands on itself!'''. ((Smalltalk classNamed: #MyClass) methodDictionary at: #test) explore. self halt: 'About to rename'. (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. ((Smalltalk classNamed: #MyNewAbstraction) methodDictionary at: #test) explore. self halt: 'About to add MyClass as subclass'. ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test'). (Smalltalk classNamed: #MyNewAbstraction) new test On Thu, Jan 15, 2015 at 5:11 PM, Tobias Pape wrote: > Hi, > > On 15.01.2015, at 23:48, Chris Muller wrote: > >> I did a minor class-hierarchy refactoring today which resulted in a an >> invalid super pointer, resulting in a confusing image lock up due to >> tight recursion. The script, below, demonstrates the issue in trunk: >> >> Object compile: 'test ^''Hello from Object'''. >> (Object subclass: #MyClass instanceVariableNames: '' >> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >> 'test ^ super halt test, ''my super call lands on myself!'''. >> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass >> instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' >> category: 'Test'). >> (Smalltalk classNamed: #MyNewAbstraction) new test >> >> But an existing method in the original MyClass had a call to super >> which now lands in itself, resulting in a tight recursion. >> >> The same script without creating the new subclass results in an >> instant VM crash (both interpreter 2357 and cog 3205): >> >> Object compile: 'test ^''Hello from Object'''. >> (Object subclass: #MyClass instanceVariableNames: '' >> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >> 'test ^ super halt test, ''my super call lands on itself!'''. >> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> (Smalltalk classNamed: #MyNewAbstraction) new test >> >> I even tried recompiling my entire class hierarchy which was renamed, >> but it didn't help. >> >> How can this be? I _KNOW_ I've used rename class many times in the >> past... A regression? >> >> I went all the way back to 4.2. The above script doesn't crash the VM >> in 4.2 or 4.3. Squeak 4.4 and 4.5 and trunk all crash by the above >> script. >> >> All of those images (4.2 -- trunk) had the problem with the super >> pointer back to itself.. > > I experienced this very problem in these minutes also. > > Best > -Tobias > > > From craig at netjam.org Fri Jan 16 20:01:48 2015 From: craig at netjam.org (Craig Latta) Date: Fri Jan 16 20:01:57 2015 Subject: [squeak-dev] Context status 2015-01-16 Message-ID: Hoi all-- Context[1] is the umbrella project for Naiad (a distributed module system for all Smalltalks[2]), Spoon (a minimal object memory that provides the starting point for Naiad), and Lightning (a remote-messaging framework which performs live serialization, used by Naiad for moving methods and other objects between systems). I intend for it to be a future release of Squeak, and a launcher and module system for all the other Smalltalks. I'm writing Context apps for cloud computing, web services, and distributed computation. Commits b7676ba2cc and later of the Context git repo[3] have: - Support for installable object memories as git submodule repos. - Submodule repos for memories for each of the known Smalltalk dialects, with Naiad support pre-loaded. I'm currently working on the submodules for Squeak[4] and Pharo[5]. - A web-browser-based console for launching and managing object memories. - A WebDAV-based virtual filesystem that enables Smalltalk to appear as a network-attached storage device, and mappings of the system to that filesystem that make Smalltalk accessible from external text editors (e.g., for editing code, managing processes and object memories). - Remote code and process browsers. Live discussion at [6]. Mailing list at [7]. The newsgroup is gmane.comp.lang.smalltalk.squeak.context. Thanks for checking it out! -C [1] http://thiscontext.com [2] http://thiscontext.com/a-detailed-naiad-description [3] https://github.com/ccrraaiigg/context [4] https://github.com/ccrraaiigg/3EAD9A45-F65F-445F-89C1-4CA0A9D5C2F8 [5] https://github.com/ccrraaiigg/CFE10A14-D883-4ACE-990A-0DDA86AA362B [6] http://squeak.slack.com [7] mailto:context@lists.squeakfoundation.org -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From eliot.miranda at gmail.com Fri Jan 16 20:06:35 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 20:06:37 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <6C72E0AC-E572-44C8-B6E9-EBEBBDD1A95D@freudenbergs.de> <3D7FF013-C178-4C4C-8A2D-BEAA8C74AE6F@gmail.com> Message-ID: On Fri, Jan 16, 2015 at 11:49 AM, Chris Muller wrote: > > In general the locality of the links are worse. In the example they are > > allocated almost next to each other. > > A slightly better example would be this: > > > > | buffer | > > buffer := Array new: 1000. "This will hold the filler objects." > > #(1024 2048 4096 8192 16384 32768 65536) collect: [ :fillerSize | > > | list | > > list := LinkedList new. > > 1 to: 1000 do: [ :index | > > list add: (StackLink with: nil). > > buffer at: index put: (Array new: fillerSize) ]. > > Smalltalk garbageCollect. > > fillerSize -> [ list do: [ :ea | 1 + 2 ] ] bench ] > > > > { "gap between nodes (x4 bytes)" -> "runs" > > 1024->'78,000 per second.'. > > 2048->'78,600 per second.'. > > 4096->'77,500 per second.'. > > 8192->'73,300 per second.'. > > 16384->'70,200 per second.'. 32768->'66,400 per second.'. > > 65536->'56,400 per second.'} > > > > (The result is '45,700 per second.' for Arrays) > > > > The results depend on the CPU (and probably on the OS too), but the > numbers > > are still pretty good. Probably a longer list would cause more problem > for > > the caches. > > The same for 10k elements in the list: > > > > { > > 1024->'3,770 per second.'. > > 2048->'4,780 per second.'. > > 4096->'4,220 per second.'. > > 8192->'2,480 per second.'. > > 16384->'2,110 per second.'} > > > > (The result is '4,380 per second.' for Arrays) > > > > So the speed of a list depends on the cache locality of its elements. The > > performance is still comparable with arrays for practical cases, but may > be > > both faster and slower depending on the cache locality. > > Geez you guys /seriously/ rock. I never thought down to that level of > (CPU) cache locality. > > You've got me feeling like I should go back to some > performance-critical code which is enumerating Array's and see about > converting them to LinkedLists.. too bad I don't have time to do > that! > Please, folks, unless you're really pressed don't bother. We should have Sista deployed this year and that will take care of this nicely. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150116/fb07aaa1/attachment.htm From commits at source.squeak.org Fri Jan 16 20:40:54 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 20:40:55 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz Message-ID: A new version of Environments was added to project The Inbox: http://source.squeak.org/inbox/Environments-cmm.52.mcz ==================== Summary ==================== Name: Environments-cmm.52 Author: cmm Time: 16 January 2015, 2:40:52.666 pm UUID: 3da327fd-f1d6-49e1-ac81-0207b9264153 Ancestors: Environments-cmm.51, Environments-nice.47 - Roll back cwp.50 because creating a new binding leaves the CM-literal bindings in their old state. - Don't signal #binding:removedFrom: because it's becoming the literal in CM's to a newly created Undeclared literal with the old name. - So since we no longer signal removed: don't signal #binding:addedTo: either. Renaming is a updating of a binding, not a removing or adding. =============== Diff against Environments-cmm.51 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. + binding := self associationAt: oldName. - binding := self declarationOf: oldName. declarations removeKey: oldName. + " self binding: binding removedFrom: self." - self binding: binding removedFrom: self. + binding key: newName. - binding := newName => aClass. declarations add: binding. + " self binding: binding addedTo: self." - self binding: binding addedTo: self. Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From asqueaker at gmail.com Fri Jan 16 20:48:50 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri Jan 16 20:48:53 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz In-Reply-To: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> References: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: First fix for problem described in the other thread ("renaming a class causes invalid super pointer"). This fixes the VM crash but not the issue with the super call recursion.. Anyone have any ideas about that? It appears to be a problem somewhere in ClassBuilder.. On Fri, Jan 16, 2015 at 2:40 PM, wrote: > A new version of Environments was added to project The Inbox: > http://source.squeak.org/inbox/Environments-cmm.52.mcz > > ==================== Summary ==================== > > Name: Environments-cmm.52 > Author: cmm > Time: 16 January 2015, 2:40:52.666 pm > UUID: 3da327fd-f1d6-49e1-ac81-0207b9264153 > Ancestors: Environments-cmm.51, Environments-nice.47 > > - Roll back cwp.50 because creating a new binding leaves the CM-literal bindings in their old state. > - Don't signal #binding:removedFrom: because it's becoming the literal in CM's to a newly created Undeclared literal with the old name. > - So since we no longer signal removed: don't signal #binding:addedTo: either. > Renaming is a updating of a binding, not a removing or adding. > > =============== Diff against Environments-cmm.51 =============== > > Item was changed: > ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- > renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | binding category | > category := self organization categoryOfElement: oldName. > self organization classify: newName under: category suppressIfDefault: true. > self organization removeElement: oldName. > > + binding := self associationAt: oldName. > - binding := self declarationOf: oldName. > declarations removeKey: oldName. > + " self binding: binding removedFrom: self." > - self binding: binding removedFrom: self. > > + binding key: newName. > - binding := newName => aClass. > declarations add: binding. > + " self binding: binding addedTo: self." > - self binding: binding addedTo: self. > > Smalltalk renamedClass: aClass from: oldName to: newName. > SystemChangeNotifier uniqueInstance > classRenamed: aClass > from: oldName > to: newName > inCategory: category! > > From commits at source.squeak.org Fri Jan 16 20:54:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 20:54:29 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.53.mcz Message-ID: A new version of Environments was added to project The Inbox: http://source.squeak.org/inbox/Environments-cmm.53.mcz ==================== Summary ==================== Name: Environments-cmm.53 Author: cmm Time: 16 January 2015, 2:54:24.767 pm UUID: 69b32fc7-98f1-4c19-9976-a38106a9ee63 Ancestors: Environments-cmm.52 - Only change key when it is NOT in the 'bindings' Dictionary, otherwise it would be in a state inconsistent with its new hash. =============== Diff against Environments-cmm.52 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. binding := self associationAt: oldName. declarations removeKey: oldName. + bindings removeKey: oldName. " self binding: binding removedFrom: self." binding key: newName. + declarations add: binding. + bindings add: binding. - declarations add: binding. " self binding: binding addedTo: self." Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From asqueaker at gmail.com Fri Jan 16 21:05:50 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri Jan 16 21:05:54 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz In-Reply-To: References: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: After the rename, everything still looks fine. Bytecodes are exactly the same, and CM literal binding looks good and subclasses / superclass structure looks correct. I can't know what to fix if I can't see what's wrong.. -------------- next part -------------- A non-text attachment was scrubbed... Name: after-rename.png Type: image/png Size: 59866 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150116/5d8f2d6d/after-rename-0001.png From craig at netjam.org Fri Jan 16 21:23:58 2015 From: craig at netjam.org (Craig Latta) Date: Fri Jan 16 21:24:05 2015 Subject: [squeak-dev] re: Understanding Object Structures In-Reply-To: References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> Message-ID: Hi Chris-- > For years, I have been /totally/ interested in Alexandre's project, > not just to represent in-memory models but large Magma models, > visually. Roassal might struggle to perform with millions of nodes, I > don't know, but I know Craig used Walrus to render a large model. Yes, Walrus is fantastic. There's still nothing else that does interactive hyperbolic trees, as far as I know. -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From commits at source.squeak.org Fri Jan 16 21:27:46 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 21:27:47 2015 Subject: [squeak-dev] The Trunk: CommandLine-cmm.4.mcz Message-ID: Chris Muller uploaded a new version of CommandLine to project The Trunk: http://source.squeak.org/trunk/CommandLine-cmm.4.mcz ==================== Summary ==================== Name: CommandLine-cmm.4 Author: cmm Time: 16 January 2015, 3:27:43.102 pm UUID: 0a2ab805-2910-49f5-81dc-c7de4581f4f6 Ancestors: CommandLine-fbs.3 Let Errors print themselves. =============== Diff against CommandLine-fbs.3 =============== Item was changed: ----- Method: CommandLineToolSet class>>debugError: (in category 'debugging') ----- + debugError: anError - debugError: anError "Print out a sensible stack trace and bail" + self saveSnapshotOnError ifTrue: [ Smalltalk saveAs: 'Debug-' , Smalltalk imageEntry name ]. + anError printVerboseOn: FileStream stderr. + FileStream stderr flush. + Smalltalk + snapshot: false + andQuit: true! - | problemPlace s | - self saveSnapshotOnError - ifTrue: [Smalltalk saveAs: 'Debug-' , (Smalltalk imageName subStrings: '/') last]. - problemPlace := anError signalerContext. - s := FileStream stderr. - (anError isKindOf: MessageNotUnderstood) ifTrue: [ - s - nextPutAll: anError messageText; cr; - nextPutAll: problemPlace sender methodNode printString; cr]. - (problemPlace stackOfSize: 20) do: [:ctx | s cr. ctx printOn: s]. - s flush. - - Smalltalk snapshot: false andQuit: true! Item was changed: ----- Method: CommandLineToolSet class>>debugSyntaxError: (in category 'debugging') ----- + debugSyntaxError: anError + FileStream stderr + nextPutAll: '----- Syntax error -----' ; + cr ; + nextPutAll: anError errorCode ; + cr ; + nextPutAll: '----- Syntax error -----' ; + cr ; + flush. - debugSyntaxError: anError - | s | - s := FileStream stderr. - s nextPutAll: '----- Syntax error -----'; cr. - s nextPutAll: anError errorCode; cr. - s nextPutAll: '----- Syntax error -----'; cr. - self debugError: anError! From eliot.miranda at gmail.com Fri Jan 16 21:39:40 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 16 21:39:45 2015 Subject: OrderedDictionary (was: Re: [squeak-dev] Re: The Trunk: Collections-mt.593.mcz) In-Reply-To: <1421416460175-4799893.post@n4.nabble.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> Message-ID: Hi Marcel, On Fri, Jan 16, 2015 at 5:54 AM, Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > Ah, okay. I was curious about the performance of iterating over an array > vs. > the linked list: > > a := Array new: 1000. > l := LinkedList new. > > 1000 timesRepeat: [l add: (StackLink with: nil)]. > > [a do: [:ea | 1 + 2]] bench. "'94,600 per second.'" > > [l do: [:ea | 1 + 2]] bench. "'159,000 per second.'" > > I expected the opposite! :-O Why is that so? > > Best, > Marcel > OK, here's the profiling results, all on a .2GHz Core i7 MBP (and these numbers are noisy; there's a lot else going on on my machine). First, using Cog and a slightly modified benchmark that uses the elements of the collections so that the benchmark is "real", and so that each block does the same ammount of work | a l | a := Array new: 1000 withAll: 1 -> 1. l := LinkedList new. 1000 timesRepeat: [l add: (StackLink with: 1)]. { [| t | t := 0. a do: [:ea | t := t + ea key]. t] bench. [| t | t := 0. l do: [:ea | t := t + ea element]. t] bench} #('51,900 per second.' '70,400 per second.') Now the same code on Spur: #('57,100 per second.' '63,300 per second.') at: is faster, but (alas) LinkedList>>do: is slower because in Spur #== requires a read barrier to check for possible forwarders, so in "[aLink == nil] whileFalse:" Spur has to fetch a field from aLink to ensure it is not forwarded. At the VM level we can see that Object>>at: is expensive, but the block overhead dominates. First Cog /Users/eliot/Cog/oscogvm/build.macos32x86/squeak.cog.v3/Fast.app/Contents/MacOS/Squeak 1/16/2015 eden size: 2,097,152 stack pages: 160 code size: 1,048,576 | a | a := Array new: 1000 withAll: 1 -> 1. [| t | t := 0. a do: [:ea | t := t + ea key]. t] bench gc prior. clear prior. 5.004 seconds; sampling frequency 1471 hz 7340 samples in the VM (7363 samples in the entire program) 99.69% of total 7302 samples in generated vm code 99.48% of entire vm (99.17% of total) 38 samples in vanilla vm code 0.52% of entire vm ( 0.52% of total) % of generated vm code (% of total) (samples) (cumulative) 30.33% (30.08%) BlockClosure>>value: (2215) (30.33%) 18.47% (18.32%) Object>>at: (1349) (48.81%) 16.83% (16.69%) UndefinedObject>>DoIt (1229) (65.64%) 14.43% (14.31%) SequenceableCollection>>do: (1054) (80.07%) 9.57% ( 9.49%) LookupKey>>key (699) (89.65%) 6.35% ( 6.30%) SmallInteger>>+ (464) (96.00%) 3.75% ( 3.72%) PIC at: (274) (99.75%) 0.07% ( 0.07%) BlockClosure>>value (5) (99.82%) 0.05% ( 0.05%) BlockClosure>>bench (4) (99.88%) 0.04% ( 0.04%) PIC size (3) (99.92%) 0.04% ( 0.04%) ceClosureCopyTrampoline (3) (99.96%) 0.03% ( 0.03%) Time class>>mi...condClockValue (2) (99.99%) 0.01% ( 0.01%) ArrayedCollection>>size (1) (100.0%) | l | l := LinkedList new. 1000 timesRepeat: [l add: (StackLink with: 1)]. [| t | t := 0. l do: [:ea | t := t + ea element]. t] bench gc prior. clear prior. 5.001 seconds; sampling frequency 1452 hz 7240 samples in the VM (7260 samples in the entire program) 99.72% of total 7186 samples in generated vm code 99.25% of entire vm (98.98% of total) 54 samples in vanilla vm code 0.75% of entire vm ( 0.74% of total) % of generated vm code (% of total) (samples) (cumulative) 29.22% (28.93%) BlockClosure>>value: (2100) (29.22%) 26.32% (26.05%) UndefinedObject>>DoIt (1891) (55.54%) 22.92% (22.69%) LinkedList>>do: (1647) (78.46%) 8.14% ( 8.06%) SmallInteger>>+ (585) (86.60%) 6.76% ( 6.69%) StackLink>>element (486) (93.36%) 6.46% ( 6.39%) Link>>nextLink (464) (99.82%) 0.08% ( 0.08%) Time class>>...ndClockValue (6) (99.90%) 0.04% ( 0.04%) BlockClosure>>bench (3) (99.94%) 0.03% ( 0.03%) BlockClosure>>value (2) (99.97%) 0.01% ( 0.01%) ceClosureCopyTrampoline (1) (99.99%) 0.01% ( 0.01%) ceCreateNew...Trampoline (1) (100.0%) and then Spur: /Users/eliot/Cog/oscogvm/build.macos32x86/squeak.cog.spur/Fast.app/Contents/MacOS/Squeak 1/16/2015 eden size: 4,101,312 stack pages: 160 code size: 1,048,576 | a | a := Array new: 1000 withAll: 1 -> 1. [| t | t := 0. a do: [:ea | t := t + ea key]. t] bench gc prior. clear prior. 5.002 seconds; sampling frequency 1471 hz 7340 samples in the VM (7359 samples in the entire program) 99.74% of total 7330 samples in generated vm code 99.86% of entire vm (99.61% of total) 10 samples in vanilla vm code 0.14% of entire vm ( 0.14% of total) % of generated vm code (% of total) (samples) (cumulative) 33.06% (32.93%) BlockClosure>>value: (2423) (33.06%) 18.66% (18.59%) UndefinedObject>>DoIt (1368) (51.72%) 17.97% (17.90%) SequenceableCollection>>do: (1317) (69.69%) 13.33% (13.28%) Object>>at: (977) (83.02%) 8.84% ( 8.81%) SmallInteger>>+ (648) (91.86%) 4.90% ( 4.88%) PIC at: (359) (96.75%) 3.08% ( 3.07%) LookupKey>>key (226) (99.84%) 0.05% ( 0.05%) ceSmallBlockContext (4) (99.89%) 0.04% ( 0.04%) BlockClosure>>value (3) (99.93%) 0.03% ( 0.03%) Time class>>mi...condClockValue (2) (99.96%) 0.01% ( 0.01%) ArrayedCollection>>size (1) (99.97%) 0.01% ( 0.01%) BlockClosure>>bench (1) (99.99%) 0.01% ( 0.01%) EventSensor>>eventTickler (1) (100.0%) | l | l := LinkedList new. 1000 timesRepeat: [l add: (StackLink with: 1)]. [| t | t := 0. l do: [:ea | t := t + ea element]. t] bench gc prior. clear prior. 5.002 seconds; sampling frequency 1464 hz 7315 samples in the VM (7321 samples in the entire program) 99.92% of total 7307 samples in generated vm code 99.89% of entire vm (99.81% of total) 8 samples in vanilla vm code 0.11% of entire vm ( 0.11% of total) % of generated vm code (% of total) (samples) (cumulative) 27.33% (27.28%) UndefinedObject>>DoIt (1997) (27.33%) 27.11% (27.06%) LinkedList>>do: (1981) (54.44%) 24.39% (24.34%) BlockClosure>>value: (1782) (78.83%) 11.15% (11.13%) SmallInteger>>+ (815) (89.98%) 5.30% ( 5.29%) Link>>nextLink (387) (95.28%) 4.50% ( 4.49%) StackLink>>element (329) (99.78%) 0.12% ( 0.12%) BlockClosure>>bench (9) (99.90%) 0.07% ( 0.07%) Time class>>...ndClockValue (5) (99.97%) 0.01% ( 0.01%) ceSmallBlockContext (1) (99.99%) 0.01% ( 0.01%) BlockClosure>>value (1) (100.0%) So to try and make sense of this we can say that the cost of at: vs the cost of block evaluation is, in Cog 1349 + 274 / 2215 ~= 0.73 and in Spur 977 + 359 / 2423 ~= 0.55 at: being much faster in Spur because the object representation makes it much simpler to do the type analysis (since Object>>at: works on any indexable class) and bounds check. and approximately the difference between the Array and the LinkedList comes down to the relative costs of at: & SequenceableCollection>>#do: vs nextLink & LinkedList>>#do:, in Cog 1349 + 274 + 1054 / (1647 + 464) ~= 1.27 and in Spur 977 + 359 / (1981 + 387) ~= 0.56 Now Sista will make a big difference because it won't just eliminate the bounds checking overhead in at:, it'll also inline the block, so it'll be much more like | a | a := Array new: 1000 withAll: 1 -> 1. [| t | t := 0. 1 to: 1000 do: [:i| t := t + (a at: i) key]. t] bench Cog: 72,700 per second. Spur: 87,300 per second. but faster still because the bounds check in at: is completely eliminated. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150116/dbdc1612/attachment.htm From commits at source.squeak.org Fri Jan 16 21:45:01 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri Jan 16 21:45:03 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz Message-ID: Chris Muller uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-cmm.694.mcz ==================== Summary ==================== Name: System-cmm.694 Author: cmm Time: 16 January 2015, 3:44:19.079 pm UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 Ancestors: System-dtl.693 - #flush stdout and stderr after writing error information to them. - After that, if the exception is resumable (i.e. a Warning), resume it. Except if its a MessageNotUnderstood -- that is not an error you want to resume in a headless environment. =============== Diff against System-dtl.693 =============== Item was changed: ----- Method: SmalltalkImage>>run: (in category 'command line') ----- + run: aBlock - run: aBlock [ [ (aBlock numArgs = 1 and: [ self arguments size > 1 ]) + ifTrue: [ "Allow a large, variable number of arguments to be passed as an Array to aBlock." - ifTrue: - [ "Allow a large, variable number of arguments to be passed as an Array to aBlock." aBlock value: self arguments ] ifFalse: [ aBlock valueWithEnoughArguments: self arguments ] ] on: ProgressInitiationException do: [ : pie | "Don't want to log this notification." pie defaultAction ] ] on: Notification , Warning do: [ : noti | FileStream stdout nextPutAll: DateAndTime now asString ; space ; nextPutAll: noti description ; cr. noti resume ] on: SyntaxErrorNotification do: [ : err | FileStream stdout nextPutAll: err errorCode ; + cr; flush. - cr. self haltOrQuit ] on: Error do: [ : err | err printVerboseOn: FileStream stderr. + FileStream stderr flush. + (err isResumable and: [ (err isKindOf: MessageNotUnderstood) not ]) + ifTrue: [ err resume ] + ifFalse: [ self haltOrQuit ] ]! - self haltOrQuit. - err isResumable ifTrue: [ err resume ] ]! From asqueaker at gmail.com Fri Jan 16 22:47:30 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri Jan 16 22:47:33 2015 Subject: [squeak-dev] Context status 2015-01-16 In-Reply-To: References: Message-ID: That sounds awesome Craig, congratulations. If you ever do a video of a reasonably-sized imprinting experiment onto your core-classes image from a modern Squeak image, I will be very interested to see it! On Fri, Jan 16, 2015 at 2:01 PM, Craig Latta wrote: > > Hoi all-- > > Context[1] is the umbrella project for Naiad (a distributed module > system for all Smalltalks[2]), Spoon (a minimal object memory that > provides the starting point for Naiad), and Lightning (a > remote-messaging framework which performs live serialization, used by > Naiad for moving methods and other objects between systems). I intend > for it to be a future release of Squeak, and a launcher and module > system for all the other Smalltalks. I'm writing Context apps for cloud > computing, web services, and distributed computation. > > Commits b7676ba2cc and later of the Context git repo[3] have: > > - Support for installable object memories as git submodule repos. > > - Submodule repos for memories for each of the known Smalltalk > dialects, with Naiad support pre-loaded. I'm currently working on > the submodules for Squeak[4] and Pharo[5]. > > - A web-browser-based console for launching and managing object > memories. > > - A WebDAV-based virtual filesystem that enables Smalltalk to appear > as a network-attached storage device, and mappings of the system > to that filesystem that make Smalltalk accessible from external > text editors (e.g., for editing code, managing processes and > object memories). > > - Remote code and process browsers. > > Live discussion at [6]. Mailing list at [7]. The newsgroup is > gmane.comp.lang.smalltalk.squeak.context. > > > Thanks for checking it out! > > -C > > [1] http://thiscontext.com > [2] http://thiscontext.com/a-detailed-naiad-description > [3] https://github.com/ccrraaiigg/context > [4] https://github.com/ccrraaiigg/3EAD9A45-F65F-445F-89C1-4CA0A9D5C2F8 > [5] https://github.com/ccrraaiigg/CFE10A14-D883-4ACE-990A-0DDA86AA362B > [6] http://squeak.slack.com > [7] mailto:context@lists.squeakfoundation.org > > -- > Craig Latta > netjam.org > +31 6 2757 7177 (SMS ok) > + 1 415 287 3547 (no SMS) > > From craig at netjam.org Fri Jan 16 23:38:01 2015 From: craig at netjam.org (Craig Latta) Date: Fri Jan 16 23:38:11 2015 Subject: [squeak-dev] re: Context status 2015-01-16 In-Reply-To: References: Message-ID: <54B9A0D9.5000707@netjam.org> > If you ever do a video of a reasonably-sized imprinting experiment > onto your core-classes image from a modern Squeak image, I will be > very interested to see it! Sure, right now you can browse the kernel memory from Squeak 4.5. Every time you accept a method, you're compiling it in Squeak 4.5 and imprinting it onto the kernel. But you're referring to imprinting driven by method execution? (Each method that is run is imprinted elsewhere, as a side-effect.) What code would you like to see imprinted? In any case, I do plan to make videos showing all the top-level features. thanks, -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From lewis at mail.msen.com Sat Jan 17 01:24:12 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat Jan 17 01:24:16 2015 Subject: [squeak-dev] Context status 2015-01-16 In-Reply-To: References: Message-ID: <20150117012412.GB22755@shell.msen.com> On Fri, Jan 16, 2015 at 09:01:48PM +0100, Craig Latta wrote: > > Hoi all-- > > Context[1] is the umbrella project for Naiad (a distributed module > system for all Smalltalks[2]), Spoon (a minimal object memory that > provides the starting point for Naiad), and Lightning (a > remote-messaging framework which performs live serialization, used by > Naiad for moving methods and other objects between systems). I intend > for it to be a future release of Squeak, and a launcher and module > system for all the other Smalltalks. I'm writing Context apps for cloud > computing, web services, and distributed computation. Hi Craig, I'm not fully up to speed on a lot of this, but I have to ask - Is it possible to get a Spoon memory with Context running under SqueakJS? I mean not just in theory, but can this actually be done in practice, such that it can be demonstrated on the little-known but otherwise amazing run.squeak.org? I'm not sure that I have fully wrapped my head around the possibilities here, but the idea of incrementally growing an image from a tiny Spur memory using SqueakJS in a modern web browser seems like it might have some potential. If it is possible, then what needs to be done to make it happen? More funding? More beer? Dave From craig at netjam.org Sat Jan 17 10:16:36 2015 From: craig at netjam.org (Craig Latta) Date: Sat Jan 17 10:16:48 2015 Subject: [squeak-dev] re: Context status 2015-01-16 In-Reply-To: <20150117012412.GB22755@shell.msen.com> References: <20150117012412.GB22755@shell.msen.com> Message-ID: Hi Dave-- > Is it possible to get a Spoon memory with Context running under > SqueakJS? I mean not just in theory, but can this actually be done in > practice, such that it can be demonstrated on the little-known but > otherwise amazing run.squeak.org? Yes indeed. I'll do it next after Pharo. > I'm not sure that I have fully wrapped my head around the > possibilities here, but the idea of incrementally growing an image > from a tiny Spur memory using SqueakJS in a modern web browser seems > like it might have some potential. Definitely! There are all sorts of interesting web apps you could write with that. > ...what needs to be done to make it happen? More funding? More beer? More funding is always good! That would increase the time I can spend on it, and make it happen sooner. Is there funding available? -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From trygver at ifi.uio.no Sat Jan 17 11:06:23 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Sat Jan 17 11:06:30 2015 Subject: [squeak-dev] Understanding Object Structures In-Reply-To: <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> References: <1421338534267-4799754.post@n4.nabble.com> <1421397595217-4799843.post@n4.nabble.com> <1421416460175-4799893.post@n4.nabble.com> <5C2F4202-7E7C-414F-AD32-3D36CEE52368@gmail.com> Message-ID: <54BA422F.2090304@ifi.uio.no> Eliot, I suggest using BabySRI to help students internalize the difference between a class oriented and an object oriented mindset. My message "A puzzle for the New Year" of 02.01.2015 12:01 has an example. --Trygve On 16.01.2015 16:55, Eliot Miranda wrote: > Hi All, > > On Jan 16, 2015, at 7:36 AM, Eliot Miranda wrote: > > +++ > This is interesting. (Marcel, Chris, forgive me; I'm presuming; please don't take this personally). Marcel above appears to lack an intuition about the structure of Array vs LinkedList. And in developing a hash algorithm for a 32-bit subset of Floats a few weeks ago Chris appeared to lack an I tuition about Floats being boxed, assuming they were value types, not containers. > > As a VM implementer I carry around a clear picture (literally, I am a visual thinker) of objects in my head. Those pictures are key to my approach to design and optimization. > > I presume that for someone approaching the system given only a textual description of object structures, through class comments and method source it is difficult to develop a good picture or mental model. For me, I read the blue book first, which is replete with pictures. > > I know that historically visual inspector frameworks such as Jun have been able to auto-generate pictorial representations of specific object graphs. I wonder how useful it would be to provide support for designers to include pictorial representations in class comments. > > Again I presume that the text model would have to support inclusion of simple bitmaps (to avoid having to include a full drawing framework in the system) and that the designer would construct a sample graph, generate a diagram using a visual inspector framework using eg Jun, render it to a bitmap and include it in the class comment. > > A more elaborate system could of course include the sample graph and render it dynamically, that would allow exploration. > > Either approach would make an interesting project, yes? > -- The essence of object orientation is that objects collaborate to achieve a goal. The class hierarchy is in the nature of a comment; it has no run time significance. --- Trygve Reenskaug mailto: trygver@ifi.uio.no Morgedalsvn. 5A http://folk.uio.no/trygver/ N-0378 Oslo http://fullOO.info Norway Tel: (+47) 22 49 57 27 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/d87998da/attachment.htm From frank.shearar at gmail.com Sat Jan 17 11:39:09 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Sat Jan 17 11:39:11 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz In-Reply-To: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> References: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 16 January 2015 at 21:44, wrote: > Chris Muller uploaded a new version of System to project The Trunk: > http://source.squeak.org/trunk/System-cmm.694.mcz > > ==================== Summary ==================== > > Name: System-cmm.694 > Author: cmm > Time: 16 January 2015, 3:44:19.079 pm > UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 > Ancestors: System-dtl.693 > > - #flush stdout and stderr after writing error information to them. > - After that, if the exception is resumable (i.e. a Warning), resume it. Except if its a MessageNotUnderstood -- that is not an error you want to resume in a headless environment. Why? It's probably a rare use case for a #run: script to catch MNUs to do something fancy, I guess? Maybe it's because #run: is usually (always?) the top level of the program? Catching only MNUs seems very specific. Maybe there could be a #run: version that says "and here's a function you can use to control which exceptions are OK to resume, and which not"? frank From frank.shearar at gmail.com Sat Jan 17 11:44:00 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Sat Jan 17 11:44:02 2015 Subject: [squeak-dev] GSoC project ideas Message-ID: I had a calendar reminder that we should start gathering ideas for GSoC projects, so we don't have last year's scenario of a last-minute scramble. So.... over to the audience. frank From eliot.miranda at gmail.com Sat Jan 17 13:23:25 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sat Jan 17 13:23:29 2015 Subject: [squeak-dev] Studies on group effectiveness Message-ID: http://mobile.nytimes.com/2015/01/18/opinion/sunday/why-some-teams-are-smarter-than-others.html The studies find that smart teams are distinguished by three characteristics, sharing time evenly between members, being good at reading each other's emotional states, and having more women. On-line groups are distinguished by the /same/ three characteristics. Eliot (phone) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/4526094c/attachment.htm From trygver at ifi.uio.no Sat Jan 17 13:53:52 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Sat Jan 17 13:54:30 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? In-Reply-To: References: <54B55124.2000903@ifi.uio.no> <54B6706C.5090208@ifi.uio.no> <9B75BDE1-CFCA-47DF-9C2E-6D6EC507EF03@freudenbergs.de> Message-ID: <54BA6970.4090001@ifi.uio.no> I've had quite an odyssey to come to my present understanding of the SqueakMap package loader. The way I now understand it is as follows: 1. SqueakMap packages can be seen in the middle-left list pane of SqueakMap Package Loader. The context menu in this pane filters which packages to show. The bottom-left list pane appears to be another selection filter. I deselect all to avoid surprises. 2. Details about the selected package are shown in the right pane. 3. A selected SqueakMap package can contain releases. Available releases are listed below the package name in the SqueakMap Package Loader. A new release can be created though the context menu of a selected package: "Create new Release". (There are more alternatives that I haven't investigated.) 4. Details about a selected release are shown in the right pane. One detail shown for every release is called "/Download: /". The URL identifies a file that specifies the installation. I have seen an .st file that will be executed as a doIt, and a .sar file that contains 3 .st files: a preamble, an installation file, and a postscript. 5. One command available for a selected release is "Edit release". This opens a "fill-in-the-form" called a Release browser. Most fields are explained by hovering the mouse above the field. The exception is the bottom field; it can contain a script for the installation. I haven't found a good explanation for this script anywhere. I first thought it wasn't important because most releases shown in the package loader leave the script empty. I now see the field as an input field. Fill it with executable Squeak code and save it. It will then be transformed into file, stored somewhere, and become retrievable through the URL in the "/Download: ///". This scheme seems extremely powerful but only for the person who knows the various installation mechanisms. * Chris pointed me to a script statement for downloading a SqueakSource package known by its URL. e.g., (Installer repository: 'http://www.squeaksource.com/DCI') install: 'BBAllInOne-TRee.18' . this happens to be an Monticello configuration file, BBAllInOne-TRee.18.mcm. * Another statement I have seen is SMSqueakMap default installPackageNamed: '' version: '' I couldn't make it work for me, but suspect that the package shall be stored as a versioned file in SqueakMap itself. This is as far as I've got. I hope somebody will correct the explanation where it is wrong so that other people may make use of it. I would have been spared considerable time and frustration if I had seen it a couple of weeks ago. Cheers --Trygve On 15.01.2015 20:52, Chris Muller wrote: > On Thu, Jan 15, 2015 at 4:02 AM, Bert Freudenberg wrote: >> On 14.01.2015, at 21:32, Chris Muller wrote: >>>> Most SqueakMap packages do not have a script; they >>>> only have a "Download URL". >>> They /all/ have a Download URL. What varies is what type of file is >>> found at that url. When you entered the script above and clicked >>> "Save" in the Release Editor browser, it saved it as a ".st" file on >>> the SM server, with the "Download URL" field pointing to it. >>> SqueakMap will still interpret .mcz, .sar, as well as .st files and >>> "do the right thing" for each type. >> Curious, does it handle .mcm directly nowadays? > It appears not but could be done by adding new subclass of SMSimpleInstaller. > > > -- The essence of object orientation is that objects collaborate to achieve a goal. The class hierarchy is in the nature of a comment; it has no run time significance. --- Trygve Reenskaug mailto: trygver@ifi.uio.no Morgedalsvn. 5A http://folk.uio.no/trygver/ N-0378 Oslo http://fullOO.info Norway Tel: (+47) 22 49 57 27 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/4624feac/attachment-0001.htm From lewis at mail.msen.com Sat Jan 17 14:06:07 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat Jan 17 14:06:08 2015 Subject: [squeak-dev] re: Context status 2015-01-16 In-Reply-To: References: <20150117012412.GB22755@shell.msen.com> Message-ID: <20150117140607.GA57621@shell.msen.com> On Sat, Jan 17, 2015 at 11:16:36AM +0100, Craig Latta wrote: > > Hi Dave-- > > > Is it possible to get a Spoon memory with Context running under > > SqueakJS? I mean not just in theory, but can this actually be done in > > practice, such that it can be demonstrated on the little-known but > > otherwise amazing run.squeak.org? > > Yes indeed. I'll do it next after Pharo. Cool! I am looking forward to this. > > > I'm not sure that I have fully wrapped my head around the > > possibilities here, but the idea of incrementally growing an image > > from a tiny Spur memory using SqueakJS in a modern web browser seems > > like it might have some potential. > > Definitely! There are all sorts of interesting web apps you could > write with that. > > > ...what needs to be done to make it happen? More funding? More beer? > > More funding is always good! That would increase the time I can > spend on it, and make it happen sooner. Is there funding available? > I am no so sure about funding, but I will be happy to buy you a beer :-) Dave From lewis at mail.msen.com Sat Jan 17 14:43:01 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat Jan 17 14:43:09 2015 Subject: [squeak-dev] Studies on group effectiveness In-Reply-To: References: Message-ID: <20150117144301.GA60130@shell.msen.com> On Sat, Jan 17, 2015 at 05:23:25AM -0800, Eliot Miranda wrote: > http://mobile.nytimes.com/2015/01/18/opinion/sunday/why-some-teams-are-smarter-than-others.html > > The studies find that smart teams are distinguished by three characteristics, > sharing time evenly between members, being good at reading each other's > emotional states, and having more women. On-line groups are distinguished > by the /same/ three characteristics. Eliot, Thanks for sharing this link. As we were discussing in the Squeak oversight board meeting last week, getting more women involved in the community, as well as promoting an overall feeling of inclusiveness, is really important. It is not just a matter of being fair with people, it is very much a matter of having a more effective and productive community. I am probably older than most of the folks on this list. I am not, and never have been, a software engineer. But I do have a lot of experience leading and participating in technical teams in industry. The conclusions in this article are 100% consistent with my personal experience. If I could advise an aspiring young software engineer to read just one paper to improve their chances of success in business and industry, this would be it. Dave From Das.Linux at gmx.de Sat Jan 17 15:23:37 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Sat Jan 17 15:23:42 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz In-Reply-To: References: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <296A7AD2-61C7-48B5-AA9B-A11C3E05B0BF@gmx.de> Hey, On 16.01.2015, at 22:05, Chris Muller wrote: > After the rename, everything still looks fine. Bytecodes are exactly > the same, and CM literal binding looks good and subclasses / > superclass structure looks correct. > > I can't know what to fix if I can't see what's wrong.. If this is good, can we backport it to 4.5? Best -Tobias From eliot.miranda at gmail.com Sat Jan 17 18:35:52 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sat Jan 17 18:35:58 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz In-Reply-To: References: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Hi Frank, On Jan 17, 2015, at 3:39 AM, Frank Shearar wrote: > On 16 January 2015 at 21:44, wrote: >> Chris Muller uploaded a new version of System to project The Trunk: >> http://source.squeak.org/trunk/System-cmm.694.mcz >> >> ==================== Summary ==================== >> >> Name: System-cmm.694 >> Author: cmm >> Time: 16 January 2015, 3:44:19.079 pm >> UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 >> Ancestors: System-dtl.693 >> >> - #flush stdout and stderr after writing error information to them. >> - After that, if the exception is resumable (i.e. a Warning), resume it. Except if its a MessageNotUnderstood -- that is not an error you want to resume in a headless environment. > > Why? It's probably a rare use case for a #run: script to catch MNUs to > do something fancy, I guess? Maybe it's because #run: is usually > (always?) the top level of the program? One reason is that resuming an MNU simply resends from the diesNotUnderstand: method, so resuming will result in infinite recursion. I suppose the handler could allow one repeat but that seems arbitrary. There's nothing to stop one including a resuming MNU handler in the expression if one wants to override the default behaviour. > > Catching only MNUs seems very specific. Maybe there could be a #run: > version that says "and here's a function you can use to control which > exceptions are OK to resume, and which not"? Well there is Notification and Warning but (rightly) MessageNotUnderstood is an Error. Reporting Notifications and Warnings to the output and continuing, but aborting for other exceptions seems the right thing to do, rather than basing it in resumability, yes? What am I missing? Whether an exception is resumability or not is to do with whether one can usefully provide a value with which to continue, not to do with the severity of the error. For example, being able to resume with nil for a permissions violation when opening a file or directory might make it really easy to implement a find(1) like search over directories where some may be unreadable due to permissions. Being able to resume doesn't make the permissions violation any the less severe, but it dies give us a nice way if handling it, certainly less complex than having to explicitly check for permissions during the traversal. Likewise, being able to substitute a value for an MNU allows all sorts of conveniences, eg see my code for disassembling methods to bytecode messages. So IMO the system should be reporting Notifications and Warnings and aborting for anything else. > > frank Eliot (phone) From tim at rowledge.org Sat Jan 17 18:56:18 2015 From: tim at rowledge.org (tim Rowledge) Date: Sat Jan 17 18:56:21 2015 Subject: [squeak-dev] Studies on group effectiveness In-Reply-To: <20150117144301.GA60130@shell.msen.com> References: <20150117144301.GA60130@shell.msen.com> Message-ID: <0457F6EB-37A2-4E18-A9CA-71C8558D3FCC@rowledge.org> On 17-01-2015, at 6:43 AM, David T. Lewis wrote: > On Sat, Jan 17, 2015 at 05:23:25AM -0800, Eliot Miranda wrote: >> http://mobile.nytimes.com/2015/01/18/opinion/sunday/why-some-teams-are-smarter-than-others.html > [snip] > > If I could advise an aspiring young software engineer to read just > one paper to improve their chances of success in business and industry, > this would be it. I?d also suggest reading http://cacm.acm.org/magazines/2014/11/179827-the-data-on-diversity/fulltext tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: PHP: Put Hackers into Privileged mode From eliot.miranda at gmail.com Sat Jan 17 22:03:19 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sat Jan 17 22:03:22 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz In-Reply-To: References: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Hi, On Sat, Jan 17, 2015 at 10:35 AM, Eliot Miranda wrote: > Hi Frank, > > On Jan 17, 2015, at 3:39 AM, Frank Shearar > wrote: > > > On 16 January 2015 at 21:44, wrote: > >> Chris Muller uploaded a new version of System to project The Trunk: > >> http://source.squeak.org/trunk/System-cmm.694.mcz > >> > >> ==================== Summary ==================== > >> > >> Name: System-cmm.694 > >> Author: cmm > >> Time: 16 January 2015, 3:44:19.079 pm > >> UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 > >> Ancestors: System-dtl.693 > >> > >> - #flush stdout and stderr after writing error information to them. > >> - After that, if the exception is resumable (i.e. a Warning), resume > it. Except if its a MessageNotUnderstood -- that is not an error you want > to resume in a headless environment. > > > > Why? It's probably a rare use case for a #run: script to catch MNUs to > > do something fancy, I guess? Maybe it's because #run: is usually > > (always?) the top level of the program? > > One reason is that resuming an MNU simply resends from the > diesNotUnderstand: method, so resuming will result in infinite recursion. > I suppose the handler could allow one repeat but that seems arbitrary. > There's nothing to stop one including a resuming MNU handler in the > expression if one wants to override the default behaviour. > > > > > Catching only MNUs seems very specific. Maybe there could be a #run: > > version that says "and here's a function you can use to control which > > exceptions are OK to resume, and which not"? > > Well there is Notification and Warning but (rightly) MessageNotUnderstood > is an Error. Reporting Notifications and Warnings to the output and > continuing, but aborting for other exceptions seems the right thing to do, > rather than basing it in resumability, yes? What am I missing? > > Whether an exception is resumability or not is to do with whether one can > usefully provide a value with which to continue, not to do with the > severity of the error. For example, being able to resume with nil for a > permissions violation when opening a file or directory might make it really > easy to implement a find(1) like search over directories where some may be > unreadable due to permissions. Being able to resume doesn't make the > permissions violation any the less severe, but it dies give us a nice way > if handling it, certainly less complex than having to explicitly check for > permissions during the traversal. Likewise, being able to substitute a > value for an MNU allows all sorts of conveniences, eg see my code for > disassembling methods to bytecode messages. > > So IMO the system should be reporting Notifications and Warnings and > aborting for anything else. > > > > > frank > > Eliot (phone) See the Error handler in SmalltalkImage>>run: on: Error do: [ : err | err printVerboseOn: FileStream stderr. + FileStream stderr flush. + (err isResumable and: [ (err isKindOf: MessageNotUnderstood) not ]) + ifTrue: [ err resume ] + ifFalse: [ self haltOrQuit ] ]! - self haltOrQuit. - err isResumable ifTrue: [ err resume ] ]! IMO, this should read on: Error do: [ : err | err printVerboseOn: FileStream stderr. FileStream stderr flush. self haltOrQuit]! Resuming is definitely not safe; it could cause the software to attempt something damaging right? And whatever is caught here is an error, no haltOrWuit is the only valid response, no? I'm happy to make the change. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/6fd422d3/attachment.htm From lewis at mail.msen.com Sat Jan 17 22:36:34 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat Jan 17 22:36:35 2015 Subject: [squeak-dev] Studies on group effectiveness In-Reply-To: <0457F6EB-37A2-4E18-A9CA-71C8558D3FCC@rowledge.org> References: <20150117144301.GA60130@shell.msen.com> <0457F6EB-37A2-4E18-A9CA-71C8558D3FCC@rowledge.org> Message-ID: <20150117223634.GA37183@shell.msen.com> On Sat, Jan 17, 2015 at 10:56:18AM -0800, tim Rowledge wrote: > > On 17-01-2015, at 6:43 AM, David T. Lewis wrote: > > > On Sat, Jan 17, 2015 at 05:23:25AM -0800, Eliot Miranda wrote: > >> http://mobile.nytimes.com/2015/01/18/opinion/sunday/why-some-teams-are-smarter-than-others.html > > > > [snip] > > > > If I could advise an aspiring young software engineer to read just > > one paper to improve their chances of success in business and industry, > > this would be it. > > I?d also suggest reading > http://cacm.acm.org/magazines/2014/11/179827-the-data-on-diversity/fulltext Thanks, that's good reading also. Dave From asqueaker at gmail.com Sat Jan 17 23:27:59 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sat Jan 17 23:28:02 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? In-Reply-To: <54BA6970.4090001@ifi.uio.no> References: <54B55124.2000903@ifi.uio.no> <54B6706C.5090208@ifi.uio.no> <9B75BDE1-CFCA-47DF-9C2E-6D6EC507EF03@freudenbergs.de> <54BA6970.4090001@ifi.uio.no> Message-ID: > I've had quite an odyssey to come to my present understanding of the > SqueakMap package loader. The way I now understand it is as follows: > > SqueakMap packages can be seen in the middle-left list pane of SqueakMap > Package Loader. The context menu in this pane filters which packages to > show. The bottom-left list pane appears to be another selection filter. I > deselect all to avoid surprises. Yea that sounds right. Honestly I really do not like the hierarchical list I would prefer a more Smalltalk-like browser approach with packages in left pane, releases in middle pane, details in bottom pane, etc. > Details about the selected package are shown in the right pane. > A selected SqueakMap package can contain releases. Available releases are > listed below the package name in the SqueakMap Package Loader. A new > release can be created though the context menu of a selected package: > "Create new Release". (There are more alternatives that I haven't > investigated.) > Details about a selected release are shown in the right pane. One detail > shown for every release is called "Download: ". The URL identifies a > file that specifies the installation. I have seen an .st file that will be > executed as a doIt, and a .sar file that contains 3 .st files: a preamble, > an installation file, and a postscript. A .sar file would also contain whatever /resources/ were needed for that application to run. Many catalog entries do not need resources, but the ones that do, can use SAR files as a means of one-click deployment. Otherwise, a plain .st script can be used to download resources from some location (along with code packages for a correct configuration). Normally each correct configuration script is specified for a specific version of Squeak. > One command available for a selected release is "Edit release". This opens > a "fill-in-the-form" called a Release browser. Most fields are explained by > hovering the mouse above the field. The exception is the bottom field; it > can contain a script for the installation. I haven't found a good > explanation for this script anywhere. Yes it's the .st script which performs the installation. There is a detailed description with example here: http://wiki.squeak.org/squeak/6182 It explains the two kinds of scripts that should be written for each SqueakMap catalog entry, 1) the fixed-configuration (for specific Squeak version) and 2) the head release (latest code). It explains the rationale for when you would want just #1, or both #1 + #2. > I first thought it wasn't important > because most releases shown in the package loader leave the script empty. That's only because most packages on SM are from before the time this ability to "Edit Release" was written in 2012. At that time, I started trying to encourage people to use SM as a Catalog and not a SCM tool. IOW, use .st scripts only (unless embedded resources are needed, then a SAR). I personally am not going to store any more .mcz's on SqueakMap. I only want my .mcz's in the SCM repository (SqueakSource, SS3, etc.). The rationale for this is in those wiki pages linked together. > I > now see the field as an input field. Fill it with executable Squeak code and > save it. It will then be transformed into file, stored somewhere, and become > retrievable through the URL in the "Download: ". This scheme seems > extremely powerful but only for the person who knows the various > installation mechanisms. That's true but all catalog entry's can generally follow the same format of script, so you can clone pretty easily one and get all the great features like dependencies for literally just a few lines of code. The format of every "fixed-configuration" script is: (check if first required dependency is already loaded) ifFalse: [ SMSqueakMap default installPackageNamed: 'The Dependent Package' version: '1.1' ]. (check if 2nd required dependency is already loaded) ifFalse: [ SMSqueakMap default installPackageNamed: 'The Dependent Package' version: '1.1' ]. #('My-Core-Package-cmm.123' 'My-Tests-Package-cmm.123') do: [ : each | (Installer repository: ' http://ss3.gemstone.com/ss/Ma-Client-Server') install: each ] The way I check for the presence of required dependencies is simply (Smalltalk hasClassNamed: #SomeClass) where I know SomeClass only exists in that other package. I know this is not ideal but the good news everyone can do precisely what's ideal for each project. See an example on SM for an example of a proper "head" script. It's basically the same except instead of loading specific package versions it uses McmUpdater, the same mechanism we use for trunk, so that each SM project can have community features too. > Chris pointed me to a script statement for downloading a SqueakSource > package known by its URL. e.g., > (Installer repository: 'http://www.squeaksource.com/DCI') install: > 'BBAllInOne-TRee.18' . > this happens to be an Monticello configuration file, > BBAllInOne-TRee.18.mcm. Installer can install .mcm file fine. > Another statement I have seen is > SMSqueakMap default installPackageNamed: '' version: > '' > I couldn't make it work for me, but suspect that the package shall be stored > as a versioned file in SqueakMap itself. That should work as long as '' of '' exists -- it will simply run that file at Download URL for that package and this is how pre-reqs are done. I tested it yesterday and it worked, which one is not working fo ryou? > This is as far as I've got. I hope somebody will correct the explanation > where it is wrong so that other people may make use of it. I would have > been spared considerable time and frustration if I had seen it a couple of > weeks ago. Good that you persevered since you now can easily publish packages that can use any SCM technology with resources, demos, etc. Cheers. > Cheers > --Trygve > > > > On 15.01.2015 20:52, Chris Muller wrote: > > On Thu, Jan 15, 2015 at 4:02 AM, Bert Freudenberg > wrote: > > On 14.01.2015, at 21:32, Chris Muller wrote: > > Most SqueakMap packages do not have a script; they > only have a "Download URL". > > They /all/ have a Download URL. What varies is what type of file is > found at that url. When you entered the script above and clicked > "Save" in the Release Editor browser, it saved it as a ".st" file on > the SM server, with the "Download URL" field pointing to it. > SqueakMap will still interpret .mcz, .sar, as well as .st files and > "do the right thing" for each type. > > Curious, does it handle .mcm directly nowadays? > > It appears not but could be done by adding new subclass of > SMSimpleInstaller. > > > > > -- > > The essence of object orientation is that > objects collaborate to achieve a goal. > The class hierarchy is in the nature of a comment; > it has no run time significance. > --- > Trygve Reenskaug mailto: trygver@ifi.uio.no > Morgedalsvn. 5A http://folk.uio.no/trygver/ > N-0378 Oslo http://fullOO.info > Norway Tel: (+47) 22 49 57 27 > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/1ddbb64f/attachment.htm From asqueaker at gmail.com Sat Jan 17 23:45:44 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sat Jan 17 23:45:48 2015 Subject: [squeak-dev] re: Context status 2015-01-16 In-Reply-To: <54B9A0D9.5000707@netjam.org> References: <54B9A0D9.5000707@netjam.org> Message-ID: > > Sure, right now you can browse the kernel memory from Squeak 4.5. > Every time you accept a method, you're compiling it in Squeak 4.5 and > imprinting it onto the kernel. But you're referring to imprinting driven > by method execution? Yes exactly! > (Each method that is run is imprinted elsewhere, as > a side-effect.) What code would you like to see imprinted? > Test suites. To me, the holy-grail of deployment scaling is I first I develop and configure in a big luxurious Cadillac image loaded with tools until I'm ready to deploy. When I'm ready to deplooy I fire up a copy of your 1MB core image as the "target" with my luxury image as the 'source' and then I simply bring over a top-level test-suite method into the target and run it. As the methods are executed and found to be missing in the 1MB target, they are brought over from the source. By the time the tests are done, /all/ and /only/ the methods which were needed to run the tests were brought over by Spoon / Naiad. Now I want to save that target image (maybe 5MB now) and deploy it. I will want to run many multiple copies of of that 5MB image but since my tests probably don't have 100% coverage it would be too risky to run in production unless each of those 5MB images could have backup Spoon access to a single running copy of my mother Caddi' image, in case one more method is found to be needed... So I see Spoon as a way for learning about systems like you, but also as a solution for scaling -- from the smallest single core for limited hardware <---> to the largest multi-core, applications because one can run MORE images concurrently due to their smaller size. > In any case, I do plan to make videos showing all the top-level > features. > > > thanks, > > -C > > -- > Craig Latta > netjam.org > +31 6 2757 7177 (SMS ok) > + 1 415 287 3547 (no SMS) > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/453d1d50/attachment.htm From lewis at mail.msen.com Sat Jan 17 23:46:36 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat Jan 17 23:46:37 2015 Subject: [squeak-dev] How do I create SqueakMap package for loading an MCConfiguration? In-Reply-To: <54BA6970.4090001@ifi.uio.no> References: <54B55124.2000903@ifi.uio.no> <54B6706C.5090208@ifi.uio.no> <9B75BDE1-CFCA-47DF-9C2E-6D6EC507EF03@freudenbergs.de> <54BA6970.4090001@ifi.uio.no> Message-ID: <20150117234636.GA47414@shell.msen.com> On Sat, Jan 17, 2015 at 02:53:52PM +0100, Trygve Reenskaug wrote: > I've had quite an odyssey to come to my present understanding of the > SqueakMap package loader. The way I now understand it is as follows: > > 1. SqueakMap packages can be seen in the middle-left list pane of > SqueakMap Package Loader. The context menu in this pane filters > which packages to show. The bottom-left list pane appears to be > another selection filter. I deselect all to avoid surprises. > 2. Details about the selected package are shown in the right pane. > 3. A selected SqueakMap package can contain releases. Available > releases are listed below the package name in the SqueakMap Package > Loader. A new release can be created though the context menu of a > selected package: "Create new Release". (There are more alternatives > that I haven't investigated.) > 4. Details about a selected release are shown in the right pane. One > detail shown for every release is called "/Download: /". The > URL identifies a file that specifies the installation. I have seen > an .st file that will be executed as a doIt, and a .sar file that > contains 3 .st files: a preamble, an installation file, and a > postscript. > 5. One command available for a selected release is "Edit release". > This opens a "fill-in-the-form" called a Release browser. Most > fields are explained by hovering the mouse above the field. The > exception is the bottom field; it can contain a script for the > installation. I haven't found a good explanation for this script > anywhere. I first thought it wasn't important because most releases > shown in the package loader leave the script empty. I now see the > field as an input field. Fill it with executable Squeak code and > save it. It will then be transformed into file, stored somewhere, > and become retrievable through the URL in the "/Download: ///". > This scheme seems extremely powerful but only for the person who > knows the various installation mechanisms. > > * Chris pointed me to a script statement for downloading a > SqueakSource package known by its URL. e.g., > (Installer repository: > 'http://www.squeaksource.com/DCI') install: 'BBAllInOne-TRee.18' . > this happens to be an Monticello configuration file, > BBAllInOne-TRee.18.mcm. > * Another statement I have seen is > SMSqueakMap default installPackageNamed: '' > version: '' > I couldn't make it work for me, but suspect that the package > shall be stored as a versioned file in SqueakMap itself. > > This is as far as I've got. I hope somebody will correct the explanation > where it is wrong so that other people may make use of it. I would have > been spared considerable time and frustration if I had seen it a couple > of weeks ago. > > Cheers > --Trygve > This looks like useful information. There is a "Help" button on the SqueakMap Package Loader that does not seem to do anything very helpful any more. Maybe we could capture Trygve's summary there? And/or in the help browser? Dave From asqueaker at gmail.com Sun Jan 18 00:01:55 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sun Jan 18 00:01:58 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz In-Reply-To: <296A7AD2-61C7-48B5-AA9B-A11C3E05B0BF@gmx.de> References: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> <296A7AD2-61C7-48B5-AA9B-A11C3E05B0BF@gmx.de> Message-ID: Of course! I think everyone who has trunk access probably can copy it to squeak45. That will make it available via "Update Squeak". But keep in mind we still have the bug where when we rename a class and then reuse the old name, the image will be hosed. I need help from Eliot or someone else who knows why the super pointer is jacked. On Sat, Jan 17, 2015 at 9:23 AM, Tobias Pape wrote: > Hey, > > On 16.01.2015, at 22:05, Chris Muller wrote: > > > After the rename, everything still looks fine. Bytecodes are exactly > > the same, and CM literal binding looks good and subclasses / > > superclass structure looks correct. > > > > I can't know what to fix if I can't see what's wrong.. > > If this is good, can we backport it to 4.5? > > Best > -Tobias > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/4559a576/attachment.htm From asqueaker at gmail.com Sun Jan 18 00:23:50 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sun Jan 18 00:23:52 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz In-Reply-To: References: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Sat, Jan 17, 2015 at 5:39 AM, Frank Shearar wrote: > On 16 January 2015 at 21:44, wrote: > > Chris Muller uploaded a new version of System to project The Trunk: > > http://source.squeak.org/trunk/System-cmm.694.mcz > > > > ==================== Summary ==================== > > > > Name: System-cmm.694 > > Author: cmm > > Time: 16 January 2015, 3:44:19.079 pm > > UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 > > Ancestors: System-dtl.693 > > > > - #flush stdout and stderr after writing error information to them. > > - After that, if the exception is resumable (i.e. a Warning), resume > it. Except if its a MessageNotUnderstood -- that is not an error you want > to resume in a headless environment. > > Why? It's probably a rare use case for a #run: script to catch MNUs to > do something fancy, I guess? Maybe it's because #run: is usually > (always?) the top level of the program? > Exactly. #run: is for initiating long-running batch processes, typically in headless mode. > > Catching only MNUs seems very specific. Maybe there could be a #run: > version that says "and here's a function you can use to control which > exceptions are OK to resume, and which not"? > It could, but the goal is for #run: to make it easy to run batch operations and do-the-right-thing while demanding the bare minimum of configuration from the user. I smell the same thing you do. I really don't like the smell of MessageNotUnderstood check, but let me explain my rationale in response to Eliots note and we can go from there. > > frank > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/2d75a9f1/attachment.htm From asqueaker at gmail.com Sun Jan 18 00:45:17 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sun Jan 18 00:45:20 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz In-Reply-To: References: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Sat, Jan 17, 2015 at 4:03 PM, Eliot Miranda wrote: > Hi, > > On Sat, Jan 17, 2015 at 10:35 AM, Eliot Miranda > wrote: > >> Hi Frank, >> >> On Jan 17, 2015, at 3:39 AM, Frank Shearar >> wrote: >> >> > On 16 January 2015 at 21:44, wrote: >> >> Chris Muller uploaded a new version of System to project The Trunk: >> >> http://source.squeak.org/trunk/System-cmm.694.mcz >> >> >> >> ==================== Summary ==================== >> >> >> >> Name: System-cmm.694 >> >> Author: cmm >> >> Time: 16 January 2015, 3:44:19.079 pm >> >> UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 >> >> Ancestors: System-dtl.693 >> >> >> >> - #flush stdout and stderr after writing error information to them. >> >> - After that, if the exception is resumable (i.e. a Warning), resume >> it. Except if its a MessageNotUnderstood -- that is not an error you want >> to resume in a headless environment. >> > >> > Why? It's probably a rare use case for a #run: script to catch MNUs to >> > do something fancy, I guess? Maybe it's because #run: is usually >> > (always?) the top level of the program? >> >> One reason is that resuming an MNU simply resends from the >> diesNotUnderstand: method, so resuming will result in infinite recursion. >> I suppose the handler could allow one repeat but that seems arbitrary. >> There's nothing to stop one including a resuming MNU handler in the >> expression if one wants to override the default behaviour. >> >> > >> > Catching only MNUs seems very specific. Maybe there could be a #run: >> > version that says "and here's a function you can use to control which >> > exceptions are OK to resume, and which not"? >> >> Well there is Notification and Warning but (rightly) MessageNotUnderstood >> is an Error. Reporting Notifications and Warnings to the output and >> continuing, but aborting for other exceptions seems the right thing to do, >> rather than basing it in resumability, yes? What am I missing? >> >> Whether an exception is resumability or not is to do with whether one can >> usefully provide a value with which to continue, not to do with the >> severity of the error. For example, being able to resume with nil for a >> permissions violation when opening a file or directory might make it really >> easy to implement a find(1) like search over directories where some may be >> unreadable due to permissions. Being able to resume doesn't make the >> permissions violation any the less severe, but it dies give us a nice way >> if handling it, certainly less complex than having to explicitly check for >> permissions during the traversal. Likewise, being able to substitute a >> value for an MNU allows all sorts of conveniences, eg see my code for >> disassembling methods to bytecode messages. >> >> So IMO the system should be reporting Notifications and Warnings and >> aborting for anything else. >> >> > >> > frank >> >> Eliot (phone) > > > See the Error handler in SmalltalkImage>>run: > > on: Error > do: > [ : err | err printVerboseOn: FileStream stderr. > + FileStream stderr flush. > + (err isResumable and: [ (err isKindOf: > MessageNotUnderstood) not ]) > + ifTrue: [ err resume ] > + ifFalse: [ self haltOrQuit ] ]! > - self haltOrQuit. > - err isResumable ifTrue: [ err resume ] ]! > > > IMO, this should read > > on: Error > do: > [ : err | > err printVerboseOn: FileStream stderr. > FileStream stderr flush. > self haltOrQuit]! > > Resuming is definitely not safe; it could cause the software to attempt > something damaging right? And whatever is caught here is an error, no > haltOrWuit is the only valid response, no? I'm happy to make the change. > Actually, I think I should put it back to my original code. on: Error do: [ : err | err printVerboseOn: FileStream stderr. FileStream stderr flush. err isResumable ifTrue: [ self haltOrQuit ] ]! That way, if its headless, it'll exit every time. If it's headful, the user will have the chance to fix the Error before clicking Proceed in the debugger. > -- > best, > Eliot > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/e9f8ed4b/attachment.htm From eliot.miranda at gmail.com Sun Jan 18 00:59:18 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun Jan 18 00:59:25 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz In-Reply-To: References: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Hi Chris, On Jan 17, 2015, at 4:45 PM, Chris Muller wrote: > On Sat, Jan 17, 2015 at 4:03 PM, Eliot Miranda wrote: >> Hi, >> >> On Sat, Jan 17, 2015 at 10:35 AM, Eliot Miranda wrote: >>> Hi Frank, >>> >>> On Jan 17, 2015, at 3:39 AM, Frank Shearar wrote: >>> >>> > On 16 January 2015 at 21:44, wrote: >>> >> Chris Muller uploaded a new version of System to project The Trunk: >>> >> http://source.squeak.org/trunk/System-cmm.694.mcz >>> >> >>> >> ==================== Summary ==================== >>> >> >>> >> Name: System-cmm.694 >>> >> Author: cmm >>> >> Time: 16 January 2015, 3:44:19.079 pm >>> >> UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 >>> >> Ancestors: System-dtl.693 >>> >> >>> >> - #flush stdout and stderr after writing error information to them. >>> >> - After that, if the exception is resumable (i.e. a Warning), resume it. Except if its a MessageNotUnderstood -- that is not an error you want to resume in a headless environment. >>> > >>> > Why? It's probably a rare use case for a #run: script to catch MNUs to >>> > do something fancy, I guess? Maybe it's because #run: is usually >>> > (always?) the top level of the program? >>> >>> One reason is that resuming an MNU simply resends from the diesNotUnderstand: method, so resuming will result in infinite recursion. I suppose the handler could allow one repeat but that seems arbitrary. There's nothing to stop one including a resuming MNU handler in the expression if one wants to override the default behaviour. >>> >>> > >>> > Catching only MNUs seems very specific. Maybe there could be a #run: >>> > version that says "and here's a function you can use to control which >>> > exceptions are OK to resume, and which not"? >>> >>> Well there is Notification and Warning but (rightly) MessageNotUnderstood is an Error. Reporting Notifications and Warnings to the output and continuing, but aborting for other exceptions seems the right thing to do, rather than basing it in resumability, yes? What am I missing? >>> >>> Whether an exception is resumability or not is to do with whether one can usefully provide a value with which to continue, not to do with the severity of the error. For example, being able to resume with nil for a permissions violation when opening a file or directory might make it really easy to implement a find(1) like search over directories where some may be unreadable due to permissions. Being able to resume doesn't make the permissions violation any the less severe, but it dies give us a nice way if handling it, certainly less complex than having to explicitly check for permissions during the traversal. Likewise, being able to substitute a value for an MNU allows all sorts of conveniences, eg see my code for disassembling methods to bytecode messages. >>> >>> So IMO the system should be reporting Notifications and Warnings and aborting for anything else. >>> >>> > >>> > frank >>> >>> Eliot (phone) >> >> See the Error handler in SmalltalkImage>>run: >> >> on: Error >> do: >> [ : err | err printVerboseOn: FileStream stderr. >> + FileStream stderr flush. >> + (err isResumable and: [ (err isKindOf: MessageNotUnderstood) not ]) >> + ifTrue: [ err resume ] >> + ifFalse: [ self haltOrQuit ] ]! >> - self haltOrQuit. >> - err isResumable ifTrue: [ err resume ] ]! >> >> >> IMO, this should read >> >> on: Error >> do: >> [ : err | >> err printVerboseOn: FileStream stderr. >> FileStream stderr flush. >> self haltOrQuit]! >> >> Resuming is definitely not safe; it could cause the software to attempt something damaging right? And whatever is caught here is an error, no haltOrWuit is the only valid response, no? I'm happy to make the change. > > Actually, I think I should put it back to my original code. > > on: Error > do: > [ : err | > err printVerboseOn: FileStream stderr. > FileStream stderr flush. > err isResumable ifTrue: [ self haltOrQuit ] ]! > > That way, if its headless, it'll exit every time. If it's headful, the user will have the chance to fix the Error before clicking Proceed in the debugger. Agreed. That's good behavior. But it's entirely non-obvious that that's the effect of err isResumable ifTrue: [self haltOrQuit] So there needs to be a comment immediately before that statement that explains what happens, just "If we're headless, this will exit every time. If we're headful, the user will have the chance to fix the Error before clicking Proceed in the debugger." >> -- >> best, >> Eliot > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/4fe9426f/attachment-0001.htm From commits at source.squeak.org Sun Jan 18 01:01:15 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun Jan 18 01:01:17 2015 Subject: [squeak-dev] The Trunk: System-cmm.696.mcz Message-ID: Chris Muller uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-cmm.696.mcz ==================== Summary ==================== Name: System-cmm.696 Author: cmm Time: 17 January 2015, 7:00:32.693 pm UUID: e13e847b-b9e1-4068-bb77-48d54a9cd005 Ancestors: System-kfr.695, System-cmm.694 - Remove the crazy check for MessageNotUnderstood in Smalltalk #run:.. Headless mode should always exit on any Error. - In fact, even when not in headless mode, we don't need to halt but simply #pass the Error to the default handler for Errors do what it does, whether that's popping a debugger which could be resumed (if the Error isResumable) or something else. =============== Diff against System-kfr.695 =============== Item was removed: - ----- Method: SmalltalkImage>>haltOrQuit (in category 'command line') ----- - haltOrQuit - self isHeadless - ifTrue: - [ self - snapshot: false - andQuit: true ] - ifFalse: [ self halt ]! Item was changed: ----- Method: SmalltalkImage>>run: (in category 'command line') ----- + run: aBlock - run: aBlock [ [ (aBlock numArgs = 1 and: [ self arguments size > 1 ]) + ifTrue: [ "Allow a large, variable number of arguments to be passed as an Array to aBlock." - ifTrue: - [ "Allow a large, variable number of arguments to be passed as an Array to aBlock." aBlock value: self arguments ] ifFalse: [ aBlock valueWithEnoughArguments: self arguments ] ] on: ProgressInitiationException do: [ : pie | "Don't want to log this notification." pie defaultAction ] ] on: Notification , Warning do: [ : noti | FileStream stdout nextPutAll: DateAndTime now asString ; space ; nextPutAll: noti description ; cr. noti resume ] on: SyntaxErrorNotification do: [ : err | FileStream stdout nextPutAll: err errorCode ; + cr; flush. + self isHeadless + ifTrue: [ self snapshot: false andQuit: true ] + ifFalse: [ err pass ] ] - cr. - self haltOrQuit ] on: Error do: [ : err | err printVerboseOn: FileStream stderr. + FileStream stderr flush. + self isHeadless + ifTrue: [ self snapshot: false andQuit: true ] + ifFalse: [ err pass ] ]! - self haltOrQuit. - err isResumable ifTrue: [ err resume ] ]! Item was changed: ----- Method: SmalltalkImage>>vmStatisticsReportString (in category 'vm statistics') ----- vmStatisticsReportString "(Workspace new contents: Smalltalk vmStatisticsReportString) openLabel: 'VM Statistics'" "StringHolderView open: (StringHolder new contents: Smalltalk vmStatisticsReportString) label: 'VM Statistics'" | params onSpur oldSpaceEnd youngSpaceEnd memorySize fullGCs fullGCTime incrGCs incrGCTime tenureCount upTime upTime2 fullGCs2 fullGCTime2 incrGCs2 incrGCTime2 tenureCount2 str freeSize youngSize used | params := self getVMParameters. + onSpur := (params at: 41 ifAbsent: [ 0 ]) anyMask: 16. - onSpur := (params at: 41) anyMask: 16. oldSpaceEnd := params at: 1. youngSpaceEnd := params at: 2. memorySize := params at: 3. fullGCs := params at: 7. fullGCTime := params at: 8. incrGCs := params at: 9. incrGCTime := params at: 10. tenureCount := params at: 11. upTime := Time millisecondClockValue. str := WriteStream on: (String new: 700). str nextPutAll: 'uptime '; print: (upTime / 1000 / 60 // 60); nextPut: $h; print: (upTime / 1000 / 60 \\ 60) asInteger; nextPut: $m; print: (upTime / 1000 \\ 60) asInteger; nextPut: $s; cr. str nextPutAll: 'memory '; nextPutAll: memorySize asStringWithCommas; nextPutAll: ' bytes'; cr. str nextPutAll: ' old '; nextPutAll: oldSpaceEnd asStringWithCommas; nextPutAll: ' bytes ('; print: (oldSpaceEnd / memorySize * 100) maxDecimalPlaces: 1; nextPutAll: '%)'; cr. youngSize := onSpur ifTrue: [params at: 44 "eden size"] "Spur" ifFalse: [youngSpaceEnd - oldSpaceEnd]. "Squeak V3" str nextPutAll: ' young '; nextPutAll: youngSize asStringWithCommas; nextPutAll: ' bytes ('; print: youngSize / memorySize * 100 maxDecimalPlaces: 1; nextPutAll: '%)'; cr. onSpur ifTrue: [youngSize := youngSpaceEnd "used eden"]. freeSize := onSpur ifTrue: [(params at: 54) + (params at: 44) - youngSize] "Spur" ifFalse: [memorySize - youngSpaceEnd] "Squeak V3". used := onSpur ifTrue: [youngSize + oldSpaceEnd - freeSize] "Spur" ifFalse: [youngSpaceEnd]. "Squeak V3" str nextPutAll: ' used '; nextPutAll: used asStringWithCommas; nextPutAll: ' bytes ('; print: used / memorySize * 100 maxDecimalPlaces: 1; nextPutAll: '%)'; cr. str nextPutAll: ' free '; nextPutAll: freeSize asStringWithCommas; nextPutAll: ' bytes ('; print: freeSize / memorySize * 100 maxDecimalPlaces: 1; nextPutAll: '%)'; cr. str nextPutAll: 'GCs '; nextPutAll: (fullGCs + incrGCs) asStringWithCommas. fullGCs + incrGCs > 0 ifTrue: [ str nextPutAll: ' ('; print: (upTime / (fullGCs + incrGCs)) maxDecimalPlaces: 1; nextPutAll: ' ms between GCs)' ]. str cr. str nextPutAll: ' full '; nextPutAll: fullGCs asStringWithCommas; nextPutAll: ' totalling '; nextPutAll: fullGCTime asStringWithCommas; nextPutAll: ' ms ('; print: (fullGCTime / upTime * 100) maxDecimalPlaces: 1; nextPutAll: '% uptime)'. fullGCs = 0 ifFalse: [str nextPutAll: ', avg '; print: (fullGCTime / fullGCs) maxDecimalPlaces: 1; nextPutAll: ' ms']. str cr. str nextPutAll: ' incr '; nextPutAll: incrGCs asStringWithCommas; nextPutAll: ' totalling '; nextPutAll: incrGCTime asStringWithCommas; nextPutAll: ' ms ('; print: (incrGCTime / upTime * 100) maxDecimalPlaces: 1; nextPutAll: '% uptime), avg '; print: (incrGCTime / incrGCs) maxDecimalPlaces: 1; nextPutAll: ' ms'; cr. str nextPutAll: ' tenures '; nextPutAll: tenureCount asStringWithCommas. tenureCount = 0 ifFalse: [str nextPutAll: ' (avg '; print: incrGCs // tenureCount; nextPutAll: ' GCs/tenure)']. str cr. LastStats ifNil: [LastStats := Array new: 6] ifNotNil: [ upTime2 := upTime - (LastStats at: 1). fullGCs2 := fullGCs - (LastStats at: 2). fullGCTime2 := fullGCTime - (LastStats at: 3). incrGCs2 := incrGCs - (LastStats at: 4). incrGCTime2 := incrGCTime - (LastStats at: 5). tenureCount2 := tenureCount - (LastStats at: 6). str nextPutAll: self textMarkerForShortReport ; nextPutAll: (fullGCs2 + incrGCs2) asStringWithCommas. fullGCs2 + incrGCs2 > 0 ifTrue: [ str nextPutAll: ' ('; print: upTime2 // (fullGCs2 + incrGCs2); nextPutAll: ' ms between GCs)'. ]. str cr. str nextPutAll: ' uptime '; print: (upTime2 / 1000.0) maxDecimalPlaces: 1; nextPutAll: ' s'; cr. str nextPutAll: ' full '; nextPutAll: fullGCs2 asStringWithCommas; nextPutAll: ' totalling '; nextPutAll: fullGCTime2 asStringWithCommas; nextPutAll: ' ms ('; print: (fullGCTime2 / upTime2 * 100) maxDecimalPlaces: 1; nextPutAll: '% uptime)'. fullGCs2 = 0 ifFalse: [str nextPutAll: ', avg '; print: (fullGCTime2 / fullGCs2) maxDecimalPlaces: 1; nextPutAll: ' ms']. str cr. str nextPutAll: ' incr '; nextPutAll: incrGCs2 asStringWithCommas; nextPutAll: ' totalling '; nextPutAll: incrGCTime2 asStringWithCommas; nextPutAll: ' ms ('; print: (incrGCTime2 / upTime2 * 100) maxDecimalPlaces: 1; nextPutAll: '% uptime), avg '. incrGCs2 > 0 ifTrue: [ str print: (incrGCTime2 / incrGCs2) maxDecimalPlaces: 1; nextPutAll: ' ms' ]. str cr. str nextPutAll: ' tenures '; nextPutAll: tenureCount2 asStringWithCommas. tenureCount2 = 0 ifFalse: [str nextPutAll: ' (avg '; print: incrGCs2 // tenureCount2; nextPutAll: ' GCs/tenure)']. str cr. ]. LastStats at: 1 put: upTime. LastStats at: 2 put: fullGCs. LastStats at: 3 put: fullGCTime. LastStats at: 4 put: incrGCs. LastStats at: 5 put: incrGCTime. LastStats at: 6 put: tenureCount. ^ str contents ! From asqueaker at gmail.com Sun Jan 18 01:03:28 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sun Jan 18 01:03:31 2015 Subject: [squeak-dev] The Trunk: System-cmm.696.mcz In-Reply-To: <54bb05df.854fe00a.77a3.3982SMTPIN_ADDED_MISSING@mx.google.com> References: <54bb05df.854fe00a.77a3.3982SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: I went one step further and simply pass Errors and letting default handler resume them if they are resumable. Since the code is now so explicit about quitting or passing, it seems a comment is not needed. On Sat, Jan 17, 2015 at 7:00 PM, wrote: > Chris Muller uploaded a new version of System to project The Trunk: > http://source.squeak.org/trunk/System-cmm.696.mcz > > ==================== Summary ==================== > > Name: System-cmm.696 > Author: cmm > Time: 17 January 2015, 7:00:32.693 pm > UUID: e13e847b-b9e1-4068-bb77-48d54a9cd005 > Ancestors: System-kfr.695, System-cmm.694 > > - Remove the crazy check for MessageNotUnderstood in Smalltalk #run:.. > Headless mode should always exit on any Error. > - In fact, even when not in headless mode, we don't need to halt but > simply #pass the Error to the default handler for Errors do what it does, > whether that's popping a debugger which could be resumed (if the Error > isResumable) or something else. > > =============== Diff against System-kfr.695 =============== > > Item was removed: > - ----- Method: SmalltalkImage>>haltOrQuit (in category 'command line') > ----- > - haltOrQuit > - self isHeadless > - ifTrue: > - [ self > - snapshot: false > - andQuit: true ] > - ifFalse: [ self halt ]! > > Item was changed: > ----- Method: SmalltalkImage>>run: (in category 'command line') ----- > + run: aBlock > - run: aBlock > [ [ (aBlock numArgs = 1 and: [ self arguments size > 1 ]) > + ifTrue: [ "Allow a large, variable number of arguments to > be passed as an Array to aBlock." > - ifTrue: > - [ "Allow a large, variable number of arguments to > be passed as an Array to aBlock." > aBlock value: self arguments ] > ifFalse: [ aBlock valueWithEnoughArguments: self arguments > ] ] > on: ProgressInitiationException > do: > [ : pie | "Don't want to log this notification." > pie defaultAction ] ] > on: Notification , Warning > do: > [ : noti | FileStream stdout > nextPutAll: DateAndTime now asString ; > space ; > nextPutAll: noti description ; > cr. > noti resume ] > on: SyntaxErrorNotification > do: > [ : err | FileStream stdout > nextPutAll: err errorCode ; > + cr; flush. > + self isHeadless > + ifTrue: [ self snapshot: false andQuit: > true ] > + ifFalse: [ err pass ] ] > - cr. > - self haltOrQuit ] > on: Error > do: > [ : err | err printVerboseOn: FileStream stderr. > + FileStream stderr flush. > + self isHeadless > + ifTrue: [ self snapshot: false andQuit: > true ] > + ifFalse: [ err pass ] ]! > - self haltOrQuit. > - err isResumable ifTrue: [ err resume ] ]! > > Item was changed: > ----- Method: SmalltalkImage>>vmStatisticsReportString (in category 'vm > statistics') ----- > vmStatisticsReportString > "(Workspace new contents: Smalltalk vmStatisticsReportString) > openLabel: 'VM Statistics'" > "StringHolderView > open: (StringHolder new contents: Smalltalk > vmStatisticsReportString) > label: 'VM Statistics'" > > | params onSpur oldSpaceEnd youngSpaceEnd memorySize fullGCs > fullGCTime incrGCs incrGCTime tenureCount upTime upTime2 fullGCs2 > fullGCTime2 incrGCs2 incrGCTime2 tenureCount2 str freeSize youngSize used | > params := self getVMParameters. > + onSpur := (params at: 41 ifAbsent: [ 0 ]) anyMask: 16. > - onSpur := (params at: 41) anyMask: 16. > oldSpaceEnd := params at: 1. > youngSpaceEnd := params at: 2. > memorySize := params at: 3. > fullGCs := params at: 7. > fullGCTime := params at: 8. > incrGCs := params at: 9. > incrGCTime := params at: 10. > tenureCount := params at: 11. > upTime := Time millisecondClockValue. > > str := WriteStream on: (String new: 700). > str nextPutAll: 'uptime '; > print: (upTime / 1000 / 60 // 60); nextPut: $h; > print: (upTime / 1000 / 60 \\ 60) asInteger; nextPut: $m; > print: (upTime / 1000 \\ 60) asInteger; nextPut: $s; cr. > > str nextPutAll: 'memory '; > nextPutAll: memorySize asStringWithCommas; nextPutAll: ' > bytes'; cr. > str nextPutAll: ' old '; > nextPutAll: oldSpaceEnd asStringWithCommas; nextPutAll: ' > bytes ('; > print: (oldSpaceEnd / memorySize * 100) maxDecimalPlaces: > 1; nextPutAll: '%)'; cr. > youngSize := onSpur > ifTrue: [params at: 44 > "eden size"] "Spur" > ifFalse: [youngSpaceEnd - > oldSpaceEnd]. "Squeak V3" > str nextPutAll: ' young '; > nextPutAll: youngSize asStringWithCommas; nextPutAll: ' > bytes ('; > print: youngSize / memorySize * 100 maxDecimalPlaces: 1; > nextPutAll: '%)'; cr. > onSpur ifTrue: [youngSize := youngSpaceEnd "used eden"]. > freeSize := onSpur > ifTrue: [(params at: 54) + > (params at: 44) - youngSize] "Spur" > ifFalse: [memorySize - > youngSpaceEnd] "Squeak V3". > used := onSpur > ifTrue: [youngSize + oldSpaceEnd - > freeSize] "Spur" > ifFalse: [youngSpaceEnd]. "Squeak V3" > str nextPutAll: ' used '; > nextPutAll: used asStringWithCommas; nextPutAll: ' bytes > ('; > print: used / memorySize * 100 maxDecimalPlaces: 1; > nextPutAll: '%)'; cr. > str nextPutAll: ' free '; > nextPutAll: freeSize asStringWithCommas; nextPutAll: ' > bytes ('; > print: freeSize / memorySize * 100 maxDecimalPlaces: 1; > nextPutAll: '%)'; cr. > > str nextPutAll: 'GCs '; > nextPutAll: (fullGCs + incrGCs) asStringWithCommas. > fullGCs + incrGCs > 0 ifTrue: [ > str > nextPutAll: ' ('; > print: (upTime / (fullGCs + incrGCs)) > maxDecimalPlaces: 1; > nextPutAll: ' ms between GCs)' > ]. > str cr. > str nextPutAll: ' full '; > nextPutAll: fullGCs asStringWithCommas; nextPutAll: ' > totalling '; nextPutAll: fullGCTime asStringWithCommas; nextPutAll: ' ms ('; > print: (fullGCTime / upTime * 100) maxDecimalPlaces: 1; > nextPutAll: '% uptime)'. > fullGCs = 0 ifFalse: > [str nextPutAll: ', avg '; print: (fullGCTime / > fullGCs) maxDecimalPlaces: 1; nextPutAll: ' ms']. > str cr. > str nextPutAll: ' incr '; > nextPutAll: incrGCs asStringWithCommas; nextPutAll: ' > totalling '; nextPutAll: incrGCTime asStringWithCommas; nextPutAll: ' ms ('; > print: (incrGCTime / upTime * 100) maxDecimalPlaces: 1; > nextPutAll: '% uptime), avg '; print: (incrGCTime / > incrGCs) maxDecimalPlaces: 1; nextPutAll: ' ms'; cr. > str nextPutAll: ' tenures '; > nextPutAll: tenureCount asStringWithCommas. > tenureCount = 0 ifFalse: > [str nextPutAll: ' (avg '; print: incrGCs // tenureCount; > nextPutAll: ' GCs/tenure)']. > str cr. > > LastStats ifNil: [LastStats := Array new: 6] > ifNotNil: [ > upTime2 := upTime - (LastStats at: 1). > fullGCs2 := fullGCs - (LastStats at: 2). > fullGCTime2 := fullGCTime - (LastStats at: 3). > incrGCs2 := incrGCs - (LastStats at: 4). > incrGCTime2 := incrGCTime - (LastStats at: 5). > tenureCount2 := tenureCount - (LastStats at: 6). > > str nextPutAll: self textMarkerForShortReport ; > nextPutAll: (fullGCs2 + incrGCs2) asStringWithCommas. > fullGCs2 + incrGCs2 > 0 ifTrue: [ > str > nextPutAll: ' ('; > print: upTime2 // (fullGCs2 + incrGCs2); > nextPutAll: ' ms between GCs)'. > ]. > str cr. > str nextPutAll: ' uptime '; print: (upTime2 / > 1000.0) maxDecimalPlaces: 1; nextPutAll: ' s'; cr. > str nextPutAll: ' full '; > nextPutAll: fullGCs2 asStringWithCommas; nextPutAll: ' > totalling '; nextPutAll: fullGCTime2 asStringWithCommas; nextPutAll: ' ms > ('; > print: (fullGCTime2 / upTime2 * 100) maxDecimalPlaces: 1; > nextPutAll: '% uptime)'. > fullGCs2 = 0 ifFalse: > [str nextPutAll: ', avg '; print: (fullGCTime2 / > fullGCs2) maxDecimalPlaces: 1; nextPutAll: ' ms']. > str cr. > str nextPutAll: ' incr '; > nextPutAll: incrGCs2 asStringWithCommas; nextPutAll: ' > totalling '; nextPutAll: incrGCTime2 asStringWithCommas; nextPutAll: ' ms > ('; > print: (incrGCTime2 / upTime2 * 100) maxDecimalPlaces: 1; > nextPutAll: '% uptime), avg '. > incrGCs2 > 0 ifTrue: [ > str print: (incrGCTime2 / incrGCs2) maxDecimalPlaces: 1; > nextPutAll: ' ms' > ]. > str cr. > str nextPutAll: ' tenures '; > nextPutAll: tenureCount2 asStringWithCommas. > tenureCount2 = 0 ifFalse: > [str nextPutAll: ' (avg '; print: incrGCs2 // > tenureCount2; nextPutAll: ' GCs/tenure)']. > str cr. > ]. > LastStats at: 1 put: upTime. > LastStats at: 2 put: fullGCs. > LastStats at: 3 put: fullGCTime. > LastStats at: 4 put: incrGCs. > LastStats at: 5 put: incrGCTime. > LastStats at: 6 put: tenureCount. > > ^ str contents > ! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150117/88b7f1dc/attachment.htm From craig at netjam.org Sun Jan 18 03:50:57 2015 From: craig at netjam.org (Craig Latta) Date: Sun Jan 18 03:51:17 2015 Subject: [squeak-dev] SqueakJS WebSocket test passes; Flow, Lightning, Naiad to follow Message-ID: Hoi-- http://tinyurl.com/mbhry6z (thiscontext.com blog post) Well, this is perverse fun. :) The JavaScript WebSocket API works from SqueakJS[1], so I guess I'll write a WebSocket server to proxy peer-to-peer traffic between SqueakJS clients. This will let me implement the Flow external streaming "primitive" interface, using only the JavaScript bridge and no actual primitives. That will enable the Lightning remote messaging protocol, and then Naiad. I'll run the server on try.squeak.org and any other site that wants to be a Lightning node. -C *** "Test the WebSocket API with an echo server." | report websocket | Transcript clear. report := [:label :data | Transcript cr; nextPutAll: label; print: data; endEntry]. websocket := ( (JS Object new) at: #newWebSocket put: (JS Function new: 'return new WebSocket("ws://echo.websocket.org");'); newWebSocket). websocket at: #onopen put: [:event | report value: 'opened: ' value: event. websocket send: 'hey there']; at: #onclose put: [:event | report value: 'closed: ' value: event]; at: #onmessage put: [:event | report value: 'data: ' value: event data. websocket close]; at: #onerror put: [:event | report value: 'error: ' value: event data] *** [1] http://try.squeak.org -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From craig at netjam.org Sun Jan 18 13:08:08 2015 From: craig at netjam.org (Craig Latta) Date: Sun Jan 18 13:08:20 2015 Subject: [squeak-dev] SqueakJS discussion on squeak.slack.com Message-ID: Oh, and please join the discussion in the #squeakjs channel on http://squeak.slack.com. Just let me know your email address privately for an invite. You can reach me at any address at netjam.org. -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From Das.Linux at gmx.de Sun Jan 18 14:44:22 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Sun Jan 18 14:44:25 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz In-Reply-To: References: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> <296A7AD2-61C7-48B5-AA9B-A11C3E05B0BF@gmx.de> Message-ID: <90F1D6F0-5131-4470-AE40-39CDD8BB14EA@gmx.de> Hey, On 18.01.2015, at 01:01, Chris Muller wrote: > Of course! I think everyone who has trunk access probably can copy it to squeak45. That will make it available via "Update Squeak". > I think copying is not the right way here. We should really only backport the changes? Best -tobias > But keep in mind we still have the bug where when we rename a class and then reuse the old name, the image will be hosed. I need help from Eliot or someone else who knows why the super pointer is jacked. > > On Sat, Jan 17, 2015 at 9:23 AM, Tobias Pape wrote: > Hey, > > On 16.01.2015, at 22:05, Chris Muller wrote: > >> After the rename, everything still looks fine. Bytecodes are exactly >> the same, and CM literal binding looks good and subclasses / >> superclass structure looks correct. >> >> I can't know what to fix if I can't see what's wrong.. > > If this is good, can we backport it to 4.5? > > Best > -Tobias From eliot.miranda at gmail.com Sun Jan 18 16:16:00 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun Jan 18 16:16:05 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz In-Reply-To: <90F1D6F0-5131-4470-AE40-39CDD8BB14EA@gmx.de> References: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> <296A7AD2-61C7-48B5-AA9B-A11C3E05B0BF@gmx.de> <90F1D6F0-5131-4470-AE40-39CDD8BB14EA@gmx.de> Message-ID: On Jan 18, 2015, at 6:44 AM, Tobias Pape wrote: > Hey, > > On 18.01.2015, at 01:01, Chris Muller wrote: > >> Of course! I think everyone who has trunk access probably can copy it to squeak45. That will make it available via "Update Squeak". > > I think copying is not the right way here. > We should really only backport the changes? +1. it makes sense to inly port back fixes to an older version, to keep it as stable as possible. But we don't have a fix yet, do we? > Best > -tobias > > >> But keep in mind we still have the bug where when we rename a class and then reuse the old name, the image will be hosed. I need help from Eliot or someone else who knows why the super pointer is jacked. >> >> On Sat, Jan 17, 2015 at 9:23 AM, Tobias Pape wrote: >> Hey, >> >> On 16.01.2015, at 22:05, Chris Muller wrote: >> >>> After the rename, everything still looks fine. Bytecodes are exactly >>> the same, and CM literal binding looks good and subclasses / >>> superclass structure looks correct. >>> >>> I can't know what to fix if I can't see what's wrong.. >> >> If this is good, can we backport it to 4.5? >> >> Best >> -Tobias > > > From Das.Linux at gmx.de Sun Jan 18 16:18:06 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Sun Jan 18 16:18:10 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz In-Reply-To: References: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> <296A7AD2-61C7-48B5-AA9B-A11C3E05B0BF@gmx.de> <90F1D6F0-5131-4470-AE40-39CDD8BB14EA@gmx.de> Message-ID: <0F1C1DE6-DABD-4387-8812-743EDAA926DE@gmx.de> On 18.01.2015, at 17:16, Eliot Miranda wrote: > On Jan 18, 2015, at 6:44 AM, Tobias Pape wrote: > >> Hey, >> >> On 18.01.2015, at 01:01, Chris Muller wrote: >> >>> Of course! I think everyone who has trunk access probably can copy it to squeak45. That will make it available via "Update Squeak". >> >> I think copying is not the right way here. >> We should really only backport the changes? > > +1. it makes sense to inly port back fixes to an older version, to keep it as stable as possible. > > But we don't have a fix yet, do we? Partly, if I read Chris? message right, no? best -tobias > >> Best >> -tobias >> >> >>> But keep in mind we still have the bug where when we rename a class and then reuse the old name, the image will be hosed. I need help from Eliot or someone else who knows why the super pointer is jacked. >>> >>> On Sat, Jan 17, 2015 at 9:23 AM, Tobias Pape wrote: >>> Hey, >>> >>> On 16.01.2015, at 22:05, Chris Muller wrote: >>> >>>> After the rename, everything still looks fine. Bytecodes are exactly >>>> the same, and CM literal binding looks good and subclasses / >>>> superclass structure looks correct. >>>> >>>> I can't know what to fix if I can't see what's wrong.. >>> >>> If this is good, can we backport it to 4.5? >>> >>> Best >>> -Tobias From lewis at mail.msen.com Sun Jan 18 16:24:05 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sun Jan 18 16:24:08 2015 Subject: [squeak-dev] BabyIDE now works in Squeak 4.5 In-Reply-To: <54B6830F.5080009@ifi.uio.no> References: <54B6830F.5080009@ifi.uio.no> Message-ID: <20150118162405.GA99283@shell.msen.com> On Wed, Jan 14, 2015 at 03:54:07PM +0100, Trygve Reenskaug wrote: > Hi all, > > DCI is a programming paradigm with strong separation of concerns > * Classes are used for coding system state - what the system *is*. > * DCI Contexts are used for coding system behavior - what the system > *does*. > The DCI separation of concerns enhances code readability, supports > testing, and simplifies system extension. > BabyIDE is an IDE that supports the DCI separation of concerns by > viewing the code in practically independent projections. > > BabyIDE with a number of examples is now ready for downloading into a > Squeak 4.5 image: > 1. WorldMenu > open... > SqueakMap Categories. > 2. Select "Development tools" > BBAllInOne > (1.4) > 3. Click "Install" > Example programs can be run from > WorldMenu > open... > BB5bBank etc. > The sources for an example can be edited in BabyIDE, e.g.: > WorldMenu > open... > BB1: IDE>BB5bBank > > BabyIDE with its DCI infrastructure is a non-intrusive addition to > Squeak; everything works as before and programming can be done in the > usual manner (if desired). > > DCI home page: http://fulloo.info/. > Description of the examples: http://fulloo.info/Examples/SqueakExamples > DCI mailing list: object-composition@googlegroups.com > > Enjoy > --Trygve I just installed BabyIdeAllInOne in my working trunk image. I have only just started to look at it, but I have to say right away that the browser is really interesting. It has a context view that provides an conventional browser view, and you can switch to an interaction view that shows a graphical interaction diagram. The objects in the diagram are live, and selecting one displays its methods and their implementation. Dave From florin.mateoc at gmail.com Sun Jan 18 17:32:46 2015 From: florin.mateoc at gmail.com (Florin Mateoc) Date: Sun Jan 18 17:32:33 2015 Subject: [squeak-dev] compiled squeakjs Message-ID: <54BBEE3E.8080208@gmail.com> Hi, Inspired by Bert's project, I started thinking about how to get Smalltalk compiled to Javascript instead of interpreted. I do have previous experience in compiling Smalltalk to Java (after type inference, which we thankfully don't need here). But, the requirements are a bit tighter here: we have to take an unknown image, get it translated on the fly, completely automatically, and even allow the translated image to self-modify. Plus we cannot just decree that become: cannot be used Given that the input is an image, not sources, we'd better rely on the decompiler, so I started there. I think I fixed it, so that it can now decompile everything correctly. I also implemented a few AST transformations (similar to the ones that were necessary for Java, like normalizing the various boolean constructs and making them statements). I then started to write a Javascript pretty-printer, but I stopped when I realized that there were a few things missing: while non-local returns and resumable exceptions can be implemented using exceptions and an explicit stack of handlers, preemption (and Smalltalk's processes in general) were harder. After some research I came to the conclusion that this was doable if, instead of doing a direct pretty-printing of the Smalltalk nodes to Javascript, we also used the translation process to transform the code in continuation passing style. Then non-local returns become trivial and preemption can be implemented with closures, without needing access to the underlying execution stack. An interrupted context would have a no-arg closure representing the continuation instead of a pc. In general, only preemption points (which all have a corresponding continuation closure) would have to be mapped, and this would happen at image read time as well. The exception would be the debugger - I am not sure about that one yet. The primitive code would be inlined in the primitive methods, followed by a preemption point and the failure code. Unfortunately invocation would still not be direct, but looked up (and invoking DNU if needed), but I would store all the translated methods directly in the class prototype, so there would be no need for explicit superclass chain lookup. The instvars would also be stored directly in the class prototype (but with a prefix, to not conflict with the methods or with reserved keywords), and they would be accessed directly (with dot notation), except for assignments, which would record the owner (and the index in the owner), for all non-primitive types (not sure what to do about strings). Every method (and formerly Smalltalk block closure) would have a single temp called "thisContext", which would be an owner for the actual temps. The owners info would be used for implementing become: and allReferences. The ProtoObject and Object methods coming from Smalltalk would be stored in Object.prototype. Proxy classes would have their prototypes cleared and only contain the ProtoObject methods. Primitive type classes would have to be massaged a little: Number would have a union of methods from the Smalltalk Number subclasses, as well as the methods inherited from Magnitude. String would also have the methods inherited from Collection and SequenceableCollection, as well as from Character (and Magnitude) and Symbol - this one could be a little nastier, but I think it could be made to work. I would also map Array to Array, IdentitySet to Set and IdentityDictionary to Map. Weak collections are harder, because Javascript decided to make them not enumerable. Because of this, allInstances would also be a challenge. I am not sure yet about the bootstrap process. I just have a fuzzy feeling that Craig's Context running under SqueakJS might make it easier. I hope this gives a general idea about the approach. Please do point out weaknesses that I may have missed. For me this is fun and I will proceed slowly, as time permits, since I cannot do it at work. Of course, I am very interested to hear Bert's opinion :) Florin From ma.chris.m at gmail.com Sun Jan 18 17:41:17 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Sun Jan 18 17:41:20 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz In-Reply-To: <27950307-2079-445E-8CFE-DBA2F00ACD3E@gmx.de> References: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> <296A7AD2-61C7-48B5-AA9B-A11C3E05B0BF@gmx.de> <27950307-2079-445E-8CFE-DBA2F00ACD3E@gmx.de> Message-ID: On Sun, Jan 18, 2015 at 8:43 AM, Tobias Pape wrote: > Hey, > > On 18.01.2015, at 01:01, Chris Muller wrote: > >> Of course! I think everyone who has trunk access probably can copy it to squeak45. That will make it available via "Update Squeak". >> > > I think copying is not the right way here. > We should really only backport the changes? Yes absolutely! Backport is the proper term, not "copy". From ma.chris.m at gmail.com Sun Jan 18 17:42:01 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Sun Jan 18 17:42:03 2015 Subject: [squeak-dev] The Inbox: Environments-cmm.52.mcz In-Reply-To: References: <54b9775b.c6618c0a.8242.3471SMTPIN_ADDED_MISSING@mx.google.com> <296A7AD2-61C7-48B5-AA9B-A11C3E05B0BF@gmx.de> <90F1D6F0-5131-4470-AE40-39CDD8BB14EA@gmx.de> Message-ID: On Sun, Jan 18, 2015 at 10:16 AM, Eliot Miranda wrote: > On Jan 18, 2015, at 6:44 AM, Tobias Pape wrote: > >> Hey, >> >> On 18.01.2015, at 01:01, Chris Muller wrote: >> >>> Of course! I think everyone who has trunk access probably can copy it to squeak45. That will make it available via "Update Squeak". >> >> I think copying is not the right way here. >> We should really only backport the changes? > > +1. it makes sense to inly port back fixes to an older version, to keep it as stable as possible. > > But we don't have a fix yet, do we? That's correct, we do not. From eliot.miranda at gmail.com Sun Jan 18 18:38:06 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun Jan 18 18:38:13 2015 Subject: [squeak-dev] compiled squeakjs In-Reply-To: <54BBEE3E.8080208@gmail.com> References: <54BBEE3E.8080208@gmail.com> Message-ID: <211BA32F-6BE6-4734-B5BD-CE910CC258D3@gmail.com> Hi Florin, On Jan 18, 2015, at 9:32 AM, Florin Mateoc wrote: > Hi, > > Inspired by Bert's project, I started thinking about how to get Smalltalk compiled to Javascript instead of interpreted. > I do have previous experience in compiling Smalltalk to Java (after type inference, which we thankfully don't need > here). But, the requirements are a bit tighter here: we have to take an unknown image, get it translated on the fly, > completely automatically, and even allow the translated image to self-modify. Plus we cannot just decree that become: > cannot be used > > Given that the input is an image, not sources, we'd better rely on the decompiler, so I started there. I think I fixed > it, so that it can now decompile everything correctly. > I also implemented a few AST transformations (similar to the ones that were necessary for Java, like normalizing the > various boolean constructs and making them statements). > I then started to write a Javascript pretty-printer, but I stopped when I realized that there were a few things missing: > while non-local returns and resumable exceptions can be implemented using exceptions and an explicit stack of handlers, > preemption (and Smalltalk's processes in general) were harder. After some research I came to the conclusion that this > was doable if, instead of doing a direct pretty-printing of the Smalltalk nodes to Javascript, we also used the > translation process to transform the code in continuation passing style. Then non-local returns become trivial and > preemption can be implemented with closures, without needing access to the underlying execution stack. > An interrupted context would have a no-arg closure representing the continuation instead of a pc. In general, only > preemption points (which all have a corresponding continuation closure) would have to be mapped, and this would happen > at image read time as well. The exception would be the debugger - I am not sure about that one yet. > The primitive code would be inlined in the primitive methods, followed by a preemption point and the failure code. > Unfortunately invocation would still not be direct, but looked up (and invoking DNU if needed), but I would store all > the translated methods directly in the class prototype, so there would be no need for explicit superclass chain lookup. > The instvars would also be stored directly in the class prototype (but with a prefix, to not conflict with the methods > or with reserved keywords), and they would be accessed directly (with dot notation), except for assignments, which would > record the owner (and the index in the owner), for all non-primitive types (not sure what to do about strings). > Every method (and formerly Smalltalk block closure) would have a single temp called "thisContext", which would be an > owner for the actual temps. The owners info would be used for implementing become: and allReferences. > > The ProtoObject and Object methods coming from Smalltalk would be stored in Object.prototype. Proxy classes would have > their prototypes cleared and only contain the ProtoObject methods. > Primitive type classes would have to be massaged a little: Number would have a union of methods from the Smalltalk > Number subclasses, as well as the methods inherited from Magnitude. > String would also have the methods inherited from Collection and SequenceableCollection, as well as from Character (and > Magnitude) and Symbol - this one could be a little nastier, but I think it could be made to work. > I would also map Array to Array, IdentitySet to Set and IdentityDictionary to Map. Weak collections are harder, because > Javascript decided to make them not enumerable. Because of this, allInstances would also be a challenge. > > I am not sure yet about the bootstrap process. I just have a fuzzy feeling that Craig's Context running under SqueakJS > might make it easier. > > I hope this gives a general idea about the approach. Please do point out weaknesses that I may have missed. For me this > is fun and I will proceed slowly, as time permits, since I cannot do it at work. > Of course, I am very interested to hear Bert's opinion :) I like your approach, that if making everything work, not taking the simpe approach of translating what will work directly and disallowing the rest (as does Amber and Clamato etc). You might want to talk to Ryan Macnak and Gilad Bracha about their Newspeak implementation above JavaScript (they're also doing one above Dart). I do think Bert's approach is fun, too. But I do feel extremely frustrated that no one is taking the obvious route of making a plugin to allow the Cog VM to be used directly, gaining much higher performance and reducing the number of execution platforms we have to support. A plugin would use JavaScript to collect events, to render and to access the DOM (all of this code can be stolen from Bert's VM). The JavaScript component would connect to the VM via a socket. The VM itself would be quite small (it's already only around a megabyte of executable). For me arguments about the inconvenience and slowness of downloading and installing are not compelling given the ubiquity of Flash. And then there really is /no/ difference in the execution semantics, and /no/ performance degradation, and the code is as portable as Bert's VM provided Cig runs on the platform. I'd be doing this myself if I weren't working on getting Spur released, getting 64-but Spur working, working with Cl?ment on Sista and looking at hosting Cog over Xen. Come on folks; someone out there must think this is useful and interesting. > Florin From eliot.miranda at gmail.com Sun Jan 18 18:59:32 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun Jan 18 18:59:37 2015 Subject: [squeak-dev] GSoC project ideas In-Reply-To: References: Message-ID: A modern Squeak plugin. Back in the day one could embed computation in web pages by writing web browser plugins. But the major browsers Balkanized the APIs and Netscape's simple portable scheme died the death. Nowadays JavaScript is ubiquitous and one can embed begaviour written in arbitrary languages by compiling them to JavaScript. But this approach is fraught with difficulties in performance and functionality. Only constructs which map directly to JavaScript are easy to map efficiently and particularly powerful elements of the Smalltalk execution model, such as mixed-mode arithmetic, non-local return, become and thisContext are difficult to map. One recent approach by Bert Freudenberg is to compile the Squeak /virtual machine/ to JavaScript. This provides perfect fidelity at the cost of poor performance, since the code is interpreted. Another approach is to revive the plugin architecture but use JavaScript to mate the standard Squeak VM, the Cog JIT, to various browsers. Such a plugin would use JavaScript to collect events, to render and to access the DOM (all of this code can be stolen from Bert's VM). The JavaScript component would connect to the VM via a socket. The resulting "plugin" would be quite small (the Cog VM is of the order of a megabyte of code, excluding its own plugins). It would presumably be installed much like the Flash plugin. Work on small Squeak & Pharo images is also progressing so the entire system, including image might be below 10 meg. With this architecture there is /no/ difference in the execution semantics, and /no/ performance degradation, and the code is as portable as Bert's VM provided Cog runs on the platform. This decouples the VM from the browser, allowing both to evolve in parallel. This frees Squeak & Pharo to implement rich client-side functionality without working around limitations and allows much richer client-server communication based on proven distributed Smalltalk technologies, allowing in-browser development, remote debugging, client-side state (via snapshot), etc etc. it really does open up a lot of interesting avenues. Possible mentors: Florin Mateoc Bert Freudenberg Eliot Miranda Eliot (phone) On Jan 17, 2015, at 3:44 AM, Frank Shearar wrote: > I had a calendar reminder that we should start gathering ideas for > GSoC projects, so we don't have last year's scenario of a last-minute > scramble. > > So.... over to the audience. > > frank > From commits at source.squeak.org Sun Jan 18 19:37:25 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun Jan 18 19:37:26 2015 Subject: [squeak-dev] The Trunk: Network-ul.158.mcz Message-ID: Levente Uzonyi uploaded a new version of Network to project The Trunk: http://source.squeak.org/trunk/Network-ul.158.mcz ==================== Summary ==================== Name: Network-ul.158 Author: ul Time: 18 January 2015, 8:35:56.429 pm UUID: 368b4f4c-ccd0-49d8-8b41-0909803eda8a Ancestors: Network-bf.157 Added Socket >> #setPort:interface:, which lets one bind an UDP socket to the specified IP address and port. =============== Diff against Network-bf.157 =============== Item was added: + ----- Method: Socket>>setPort:interface: (in category 'datagrams') ----- + setPort: portNumber interface: ifAddr + "Allow an UDP socket to bind to a specific interface." + + self primSocket: socketHandle listenOn: portNumber backlogSize: 0 interface: ifAddr asByteArray. + ! From commits at source.squeak.org Sun Jan 18 19:39:49 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun Jan 18 19:39:50 2015 Subject: [squeak-dev] The Trunk: Kernel-ul.893.mcz Message-ID: Levente Uzonyi uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-ul.893.mcz ==================== Summary ==================== Name: Kernel-ul.893 Author: ul Time: 18 January 2015, 8:23:34.326 pm UUID: 349e7be8-30d6-41ce-a6cb-ad5490347eed Ancestors: Kernel-ul.891, Kernel-nice.892 - Added Delay >> #delayDuration: which allows one to reuse the same Delay instance with a different duration. - Merged Kernel-ul.891: - Introduced ThreadSafeRandom, a process-local variable holding a Random instance. Replaced all uses of Collection's RandomForPicking with ThreadSafeRandom value. - Faster Magnitude >> #between:and:. - Added an accessor for Semaphore's excessSignals variable. =============== Diff against Kernel-nice.892 =============== Item was added: + ----- Method: Delay>>delayDuration: (in category 'public') ----- + delayDuration: anInteger + + anInteger < 0 ifTrue: [ self error: 'Delay times cannot be negative!!' ]. + beingWaitedOn == true ifTrue: [ self error: 'This delay is scheduled!!' ]. + delayDuration := anInteger! Item was changed: ----- Method: Integer>>atRandom (in category 'truncation and round off') ----- atRandom + "Answer a random integer from 1 to self. This implementation uses the process-local random number generator." - "Answer a random integer from 1 to self. This implementation uses a - shared generator. Heavy users should their own implementation or use - Interval>atRandom: directly." + self isZero ifTrue: [ ^0 ]. + self negative ifTrue: [ ^self negated atRandom negated ]. + ^self atRandom: ThreadSafeRandom value! - self = 0 ifTrue: [ ^0 ]. - self < 0 ifTrue: [ ^self negated atRandom negated ]. - ^Collection mutexForPicking critical: [ - self atRandom: Collection randomForPicking ]! Item was changed: ----- Method: Magnitude>>between:and: (in category 'comparing') ----- between: min and: max "Answer whether the receiver is less than or equal to the argument, max, and greater than or equal to the argument, min." + min <= self ifFalse: [ ^false ]. + ^self <= max! - ^self >= min and: [self <= max]! Item was added: + ----- Method: Semaphore>>excessSignals (in category 'accessing') ----- + excessSignals + + ^excessSignals! Item was added: + ProcessLocalVariable subclass: #ThreadSafeRandom + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'Kernel-Numbers'! + + !ThreadSafeRandom commentStamp: 'ul 12/17/2014 15:18' prior: 0! + I am a ProcessLocalVariable. I hold the an instance of Random for each process. If the process doesn't have such instance yet, then my class-side #default message will create one. The instance should not be shared among processes. + + I implement all methods of Random's accessing category on the class side, and proxy them to the instance. If you want to use any other methods, or the object itself, then use #value directly.! Item was added: + ----- Method: ThreadSafeRandom class>>default (in category 'accessing') ----- + default + + ^self value: Random new! Item was added: + ----- Method: ThreadSafeRandom class>>next (in category 'accessing') ----- + next + + ^self value next! Item was added: + ----- Method: ThreadSafeRandom class>>next: (in category 'accessing') ----- + next: anInteger + + ^self value next: anInteger! Item was added: + ----- Method: ThreadSafeRandom class>>next:into: (in category 'accessing') ----- + next: anInteger into: anArray + + ^self value next: anInteger into: anArray! Item was added: + ----- Method: ThreadSafeRandom class>>nextInt: (in category 'accessing') ----- + nextInt: anInteger + + ^self value nextInt: anInteger! From commits at source.squeak.org Sun Jan 18 19:44:21 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun Jan 18 19:44:23 2015 Subject: [squeak-dev] The Trunk: Collections-ul.598.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.598.mcz ==================== Summary ==================== Name: Collections-ul.598 Author: ul Time: 18 January 2015, 8:28:40.971 pm UUID: 9c200c9a-6210-44da-a42a-0287f65906f1 Ancestors: Collections-ul.589, Collections-mt.597 - Fix: OrderedCollection >> #asArray returns an Array instead of an instance of the class returned by the class side #arrayType method. - Slightly more efficient OrderedCollection >> #sort:. - Merged Collections-ul.589: - Deprecated Collection class >> #randomForPicking. - Replaced all accesses to RandomForPicking with ThreadSafeRandom value. - WeakKeyDictionary >> associationsDo: ignores associations with GC'd keys. This affects all enumerator methods, and makes overriding #keysDo: unnecessary. - Added a new method SequenceableCollection #>> groupsDo:, which works like #groupsOf:atATimeDo:, but uses the block's argument count as the group size. Depends on Kernel-ul.893 =============== Diff against Collections-mt.597 =============== Item was changed: ----- Method: Collection class>>randomForPicking (in category 'private') ----- randomForPicking + + self deprecated: 'Use ThreadSafeRandom value instead. It''s not thread-safe to use this instance without the unaccessible MutexForPicking semaphore.'. ^ RandomForPicking! Item was changed: ----- Method: Collection>>atRandom (in category 'accessing') ----- atRandom + "Answer a random element of the receiver. Uses the process-local random number generator. Causes an error if self has no elements." - "Answer a random element of the receiver. Uses a shared random - number generator owned by class Collection. If you use this a lot, - define your own instance of Random and use #atRandom:. Causes - an error if self has no elements." + ^self atRandom: ThreadSafeRandom value - ^ self class mutexForPicking critical: [ - self atRandom: self class randomForPicking ] "Examples: #('one' 'or' 'the' 'other') atRandom (1 to: 10) atRandom 'Just pick one of these letters at random' atRandom #(3 7 4 9 21) asSet atRandom (just to show it also works for Sets) "! Item was changed: ----- Method: OrderedCollection>>asArray (in category 'converting') ----- asArray "Overriden for speed" + + | result | + result := Array new: self size. + result + replaceFrom: 1 + to: result size + with: array + startingAt: firstIndex. + ^result! - ^array copyFrom: firstIndex to: lastIndex! Item was changed: ----- Method: OrderedCollection>>sort: (in category 'sorting') ----- sort: aSortBlock + "Sort this collection using aSortBlock. The block should take two arguments and return true if the first element should preceed the second one. If aSortBlock is nil then <= is used for comparison." - "Sort this collection using aSortBlock. The block should take two arguments - and return true if the first element should preceed the second one. - If aSortBlock is nil then <= is used for comparison." + self size <= 1 ifTrue: [ ^self ]. + array + mergeSortFrom: firstIndex + to: lastIndex + by: aSortBlock! - self ifNotEmpty: [ - array - mergeSortFrom: firstIndex - to: lastIndex - by: aSortBlock ]! Item was added: + ----- Method: SequenceableCollection>>groupsDo: (in category 'enumerating') ----- + groupsDo: aBlock + "Evaluate aBlock with my elements taken n at a time, where n is the number of arguments of aBlock. Ignore any leftovers at the end." + + | index argumentArray numArgs endIndex | + numArgs := aBlock numArgs. + numArgs + caseOf: { + [ 0 ] -> [ ^self error: 'At least one block argument expected.' ]. + [ 1 ] -> [ ^self do: aBlock ]. + [ 2 ] -> [ ^self pairsDo: aBlock ] } + otherwise: []. + argumentArray := Array new: numArgs. + index := 1. + endIndex := self size - numArgs + 1. + [ index <= endIndex ] whileTrue: [ + argumentArray + replaceFrom: 1 + to: numArgs + with: self + startingAt: index. + aBlock valueWithArguments: argumentArray. + index := index + numArgs ].! Item was changed: ----- Method: SequenceableCollection>>shuffle (in category 'shuffling') ----- shuffle + ^self shuffleBy: ThreadSafeRandom value! - ^self shuffleBy: Collection randomForPicking! Item was changed: ----- Method: SequenceableCollection>>shuffled (in category 'copying') ----- shuffled + ^ self shuffledBy: ThreadSafeRandom value - ^ self shuffledBy: Collection randomForPicking "Examples: ($A to: $Z) shuffled "! Item was added: + ----- Method: WeakKeyDictionary>>associationsDo: (in category 'enumerating') ----- + associationsDo: aBlock + "Evaluate aBlock for each of the receiver's elements (key/value + associations)." + + tally = 0 ifTrue: [ ^self]. + 1 to: array size do: [ :index | + (array at: index) ifNotNil: [ :association | + association key ifNotNil: [ :key | "Don't let the key go away." + aBlock value: association ] ] ]! Item was removed: - ----- Method: WeakKeyDictionary>>keysDo: (in category 'enumerating') ----- - keysDo: aBlock - "Evaluate aBlock for each of the receiver's keys." - - self associationsDo: [ :association | - association key ifNotNil: [ :key | "Don't let the key go away" - aBlock value: key ] ].! From commits at source.squeak.org Sun Jan 18 19:47:03 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun Jan 18 19:47:04 2015 Subject: [squeak-dev] The Inbox: Morphic-ul.754.mcz Message-ID: Levente Uzonyi uploaded a new version of Morphic to project The Inbox: http://source.squeak.org/inbox/Morphic-ul.754.mcz ==================== Summary ==================== Name: Morphic-ul.754 Author: ul Time: 18 January 2015, 8:33:51.264 pm UUID: 2e6f7fa2-e377-4374-99db-5be8fbad0013 Ancestors: Morphic-bf.753 Simplified and improved WorldState >> #interCyclePause: - don't create a new Delay (along with a new Semaphore) every 20 (or 50) milliseconds - use #millisecondsSince: to avoid the effects of the clock rollover - separated the code of time calculation and actual waiting Depends on Kernel-ul.893 =============== Diff against Morphic-bf.753 =============== Item was changed: Object subclass: #WorldState + instanceVariableNames: 'hands activeHand viewBox canvas damageRecorder stepList lastStepTime lastStepMessage lastCycleTime commandHistory alarms lastAlarmTime remoteServer multiCanvas interCycleDelay' - instanceVariableNames: 'hands activeHand viewBox canvas damageRecorder stepList lastStepTime lastStepMessage lastCycleTime commandHistory alarms lastAlarmTime remoteServer multiCanvas' classVariableNames: 'CanSurrenderToOS DeferredUIMessages DisableDeferredUpdates LastCycleTime MinCycleLapse' poolDictionaries: '' category: 'Morphic-Worlds'! !WorldState commentStamp: 'ls 7/10/2003 19:30' prior: 0! The state of a Morphic world. (This needs some serious commenting!!!!) The MinCycleLapse variable holds the minimum amount of time that a morphic cycle is allowed to take. If a cycle takes less than this, then interCyclePause: will wait until the full time has been used up.! Item was changed: ----- Method: WorldState>>interCyclePause: (in category 'update cycle') ----- interCyclePause: milliSecs "delay enough that the previous cycle plus the amount of delay will equal milliSecs. If the cycle is already expensive, then no delay occurs. However, if the system is idly waiting for interaction from the user, the method will delay for a proportionally long time and cause the overall CPU usage of Squeak to be low. If the preference #serverMode is enabled, always do a complete delay of 50ms, independant of my argument. This prevents the freezing problem described in Mantis #6581" + | millisecondsToWait | + millisecondsToWait := Preferences serverMode + ifTrue: [ 50 ] - | currentTime wait | - Preferences serverMode ifFalse: [ + (lastCycleTime notNil and: [CanSurrenderToOS ~~ false]) + ifTrue: [ milliSecs - (Time millisecondsSince: lastCycleTime) ] + ifFalse: [ 0 ] ]. + millisecondsToWait > 0 ifTrue: [ + interCycleDelay + ifNil: [ interCycleDelay := Delay forMilliseconds: millisecondsToWait ] + ifNotNil: [ interCycleDelay delayDuration: millisecondsToWait ]. + interCycleDelay wait ]. - (lastCycleTime notNil and: [CanSurrenderToOS ~~ false]) ifTrue: [ - currentTime := Time millisecondClockValue. - wait := lastCycleTime + milliSecs - currentTime. - (wait > 0 and: [ wait <= milliSecs ] ) ifTrue: [ - (Delay forMilliseconds: wait) wait ] ] ] - ifTrue: [ (Delay forMilliseconds: 50) wait ]. - lastCycleTime := Time millisecondClockValue. CanSurrenderToOS := true.! From florin.mateoc at gmail.com Sun Jan 18 20:29:05 2015 From: florin.mateoc at gmail.com (Florin Mateoc) Date: Sun Jan 18 20:28:51 2015 Subject: [Vm-dev] Re: [squeak-dev] compiled squeakjs In-Reply-To: <211BA32F-6BE6-4734-B5BD-CE910CC258D3@gmail.com> References: <54BBEE3E.8080208@gmail.com> <211BA32F-6BE6-4734-B5BD-CE910CC258D3@gmail.com> Message-ID: <54BC1791.5030801@gmail.com> Hi Eliot, On 1/18/2015 1:38 PM, Eliot Miranda wrote: > I like your approach, that if making everything work, not taking the simpe approach of translating what will work > directly and disallowing the rest (as does Amber and Clamato etc). You might want to talk to Ryan Macnak and Gilad > Bracha about their Newspeak implementation above JavaScript (they're also doing one above Dart). Thank you for the reference to the Newspeak compilation to JavaScript, I might steal some ideas. > I do think Bert's approach is fun, too. But I do feel extremely frustrated that no one is taking the obvious route of making a plugin to allow the Cog VM to be used directly, gaining much higher performance and reducing the number of execution platforms we have to support. > > A plugin would use JavaScript to collect events, to render and to access the DOM (all of this code can be stolen from Bert's VM). The JavaScript component would connect to the VM via a socket. The VM itself would be quite small (it's already only around a megabyte of executable). For me arguments about the inconvenience and slowness of downloading and installing are not compelling given the ubiquity of Flash. > > And then there really is /no/ difference in the execution semantics, and /no/ performance degradation, and the code is as portable as Bert's VM provided Cig runs on the platform. > > I'd be doing this myself if I weren't working on getting Spur released, getting 64-but Spur working, working with Cl?ment on Sista and looking at hosting Cog over Xen. Come on folks; someone out there must think this is useful and interesting. Let's hope this gets accepted as a GSOC project Florin From florin.mateoc at gmail.com Sun Jan 18 20:59:48 2015 From: florin.mateoc at gmail.com (florin.mateoc@gmail.com) Date: Sun Jan 18 20:59:50 2015 Subject: [squeak-dev] compiled squeakjs In-Reply-To: <211BA32F-6BE6-4734-B5BD-CE910CC258D3@gmail.com> References: <54BBEE3E.8080208@gmail.com> <211BA32F-6BE6-4734-B5BD-CE910CC258D3@gmail.com> Message-ID: <5d8805ae-8fa1-4ee1-824c-1c8102816bcb@googlegroups.com> Skipped content of type multipart/alternative From commits at source.squeak.org Sun Jan 18 23:44:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun Jan 18 23:44:40 2015 Subject: [squeak-dev] The Trunk: Environments-cmm.53.mcz Message-ID: Chris Muller uploaded a new version of Environments to project The Trunk: http://source.squeak.org/trunk/Environments-cmm.53.mcz ==================== Summary ==================== Name: Environments-cmm.53 Author: cmm Time: 16 January 2015, 2:54:24.767 pm UUID: 69b32fc7-98f1-4c19-9976-a38106a9ee63 Ancestors: Environments-cmm.52 - Only change key when it is NOT in the 'bindings' Dictionary, otherwise it would be in a state inconsistent with its new hash. =============== Diff against Environments-cmm.51 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. + binding := self associationAt: oldName. - binding := self declarationOf: oldName. declarations removeKey: oldName. + bindings removeKey: oldName. + " self binding: binding removedFrom: self." - self binding: binding removedFrom: self. + binding key: newName. + declarations add: binding. + bindings add: binding. + " self binding: binding addedTo: self." - binding := newName => aClass. - declarations add: binding. - self binding: binding addedTo: self. Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From asqueaker at gmail.com Mon Jan 19 00:17:28 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon Jan 19 00:17:30 2015 Subject: [squeak-dev] The Trunk: Environments-cmm.53.mcz In-Reply-To: <54bc456d.c9abe00a.1fca.ffffda72SMTPIN_ADDED_MISSING@mx.google.com> References: <54bc456d.c9abe00a.1fca.ffffda72SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: I'm moving this to trunk now because I've just noticed a painful side-effect of this bug [1]. After renaming a class, the ClassBindings in the methods of the renamed class will be corrupted. Know that if you try to save the package with the renamed class, Monticello will \silently exclude/ methods of the renamed class (because MC will only save methods with #isLocalSelector). I didn't realize that until I found myself in my newly-built image with several methods missing from my MC package. Thankfully I still had the old image to develop and run this script [2] to identify and replace the incorrect ClassBindings in the CM's of the Class which was renamed. If anyone else has used rename on the class menu, I hope this script will help you fix your image. If you had already saved a package after a class rename, be sure to select "check all packages for changes" from the MC working copy menu after running the script. - Chris [1] -- We have two bugs. "this bug" refers to the one fixed here in #renameClass:from:to:. The other one is the invalid super pointer and still unfixed. That problem is easy to reproduce by that script in my original email ("invalid super pointer"), and we really could use a CM-structure / Bytecode expert to take a look, as it is also a pretty nasty bug. Thanks! [2] | notAtHome | notAtHome := Array streamContents: [ : stream | Smalltalk allClasses do: [ : eachClass | eachClass methodDictionary valuesDo: [ : eachCm | eachCm methodHome = eachClass ifFalse: [ stream nextPut: eachCm -> eachClass ]]] ]. notAtHome ifNotEmpty: [ Warning signal: 'The following methods were found to have a methodHome that was not their containing Class. They will be rehomed. ', (notAtHome) ]. notAtHome do: [ : eachCmAndCorrectHome | eachCmAndCorrectHome key literalAt: eachCmAndCorrectHome key numLiterals put: (Smalltalk environment bindingOf: eachCmAndCorrectHome value name) ] On Sun, Jan 18, 2015 at 5:44 PM, wrote: > Chris Muller uploaded a new version of Environments to project The Trunk: > http://source.squeak.org/trunk/Environments-cmm.53.mcz > > ==================== Summary ==================== > > Name: Environments-cmm.53 > Author: cmm > Time: 16 January 2015, 2:54:24.767 pm > UUID: 69b32fc7-98f1-4c19-9976-a38106a9ee63 > Ancestors: Environments-cmm.52 > > - Only change key when it is NOT in the 'bindings' Dictionary, otherwise > it would be in a state inconsistent with its new hash. > > =============== Diff against Environments-cmm.51 =============== > > Item was changed: > ----- Method: Environment>>renameClass:from:to: (in category 'classes > and traits') ----- > renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | binding category | > category := self organization categoryOfElement: oldName. > self organization classify: newName under: category > suppressIfDefault: true. > self organization removeElement: oldName. > > + binding := self associationAt: oldName. > - binding := self declarationOf: oldName. > declarations removeKey: oldName. > + bindings removeKey: oldName. > + " self binding: binding removedFrom: self." > - self binding: binding removedFrom: self. > > + binding key: newName. > + declarations add: binding. > + bindings add: binding. > + " self binding: binding addedTo: self." > - binding := newName => aClass. > - declarations add: binding. > - self binding: binding addedTo: self. > > Smalltalk renamedClass: aClass from: oldName to: newName. > SystemChangeNotifier uniqueInstance > classRenamed: aClass > from: oldName > to: newName > inCategory: category! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150118/0694a0b5/attachment.htm From commits at source.squeak.org Mon Jan 19 00:25:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon Jan 19 00:25:13 2015 Subject: [squeak-dev] The Trunk: Environments-cmm.52.mcz Message-ID: Chris Muller uploaded a new version of Environments to project The Trunk: http://source.squeak.org/trunk/Environments-cmm.52.mcz ==================== Summary ==================== Name: Environments-cmm.52 Author: cmm Time: 16 January 2015, 2:40:52.666 pm UUID: 3da327fd-f1d6-49e1-ac81-0207b9264153 Ancestors: Environments-cmm.51, Environments-nice.47 - Roll back cwp.50 because creating a new binding leaves the CM-literal bindings in their old state. - Don't signal #binding:removedFrom: because it's becoming the literal in CM's to a newly created Undeclared literal with the old name. - So since we no longer signal removed: don't signal #binding:addedTo: either. Renaming is a updating of a binding, not a removing or adding. =============== Diff against Environments-cmm.51 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. + binding := self associationAt: oldName. - binding := self declarationOf: oldName. declarations removeKey: oldName. + " self binding: binding removedFrom: self." - self binding: binding removedFrom: self. + binding key: newName. - binding := newName => aClass. declarations add: binding. + " self binding: binding addedTo: self." - self binding: binding addedTo: self. Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From eliot.miranda at gmail.com Mon Jan 19 01:05:39 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon Jan 19 01:05:42 2015 Subject: [squeak-dev] compiled squeakjs In-Reply-To: References: <54BBEE3E.8080208@gmail.com> <211BA32F-6BE6-4734-B5BD-CE910CC258D3@gmail.com> Message-ID: On Sun, Jan 18, 2015 at 4:17 PM, Ryan Macnak wrote: > On Sun, Jan 18, 2015 at 10:38 AM, Eliot Miranda > wrote: > >> I do feel extremely frustrated that no one is taking the obvious route of >> making a plugin to allow the Cog VM to be used directly, gaining much >> higher performance and reducing the number of execution platforms we have >> to support. > > > I thought there were already a few projects that attached a Squeak VM to > NaCl. > As I understand it, running under NaCl requires reworking the JIT and has real problems doing the self-modifying code involved in inline caches, etc. I want something that doesn't involve running under a managed run-time (the VM is a managed run-time, layering two on top of each other has always seemed like a poor choice to me). And if NaCl made it really easy to do why haven't any of these projects delivered yet? -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150118/e3d48e1a/attachment.htm From commits at source.squeak.org Mon Jan 19 03:01:06 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon Jan 19 03:01:08 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-ul.232.mcz Message-ID: Levente Uzonyi uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-ul.232.mcz ==================== Summary ==================== Name: CollectionsTests-ul.232 Author: ul Time: 19 January 2015, 4:00:23.595 am UUID: a71e6150-de64-4b54-891d-8df2e78704d2 Ancestors: CollectionsTests-mt.231 - Fixed FloatCollectionTest >> #testAdd. #asArray returns an Array. #asFloatArray returns a FloatArray. - Added a test for #groupsDo:. =============== Diff against CollectionsTests-mt.231 =============== Item was changed: ----- Method: FloatCollectionTest>>testAdd (in category 'tests') ----- testAdd | fc | fc := #(1 2 3 4 ) as: FloatCollection. fc add: 88. + self assert: #(1.0 2.0 3.0 4.0 88.0 ) asFloatArray equals: fc asFloatArray. - self assert: fc asArray = #(1.0 2.0 3.0 4.0 88.0 ) asFloatArray. fc add: 99. + self assert: (#(1 2 3 4 88 99 ) as: FloatCollection) equals: fc! - self assert: fc = (#(1 2 3 4 88 99 ) as: FloatCollection)! Item was added: + ----- Method: SequenceableCollectionTest>>testGroupsDo (in category 'tests - copying') ----- + testGroupsDo + + | array | + array := (1 to: 12) asArray. + self should: [ array groupsDo: [ ] ] raise: Error. + self assert: array equals: (Array streamContents: [ :stream | + array groupsDo: [ :each | stream nextPut: each ] ]). + self assert: #((1 2) (3 4) (5 6) (7 8) (9 10) (11 12)) equals: (Array streamContents: [ :stream | + array groupsDo: [ :a :b | + stream nextPut: { a. b } ] ]). + self assert: #((1 2 3) (4 5 6) (7 8 9) (10 11 12)) equals: (Array streamContents: [ :stream | + array groupsDo: [ :a :b :c | + stream nextPut: { a. b. c } ] ]). + self assert: #((1 2 3 4) (5 6 7 8) (9 10 11 12)) equals: (Array streamContents: [ :stream | + array groupsDo: [ :a :b :c :d | + stream nextPut: { a. b. c. d } ] ]). + self assert: #((1 2 3 4 5) (6 7 8 9 10)) equals: (Array streamContents: [ :stream | + array groupsDo: [ :a :b :c :d :e | + stream nextPut: { a. b. c. d. e } ] ]). + self assert: #((1 2 3 4 5 6) (7 8 9 10 11 12)) equals: (Array streamContents: [ :stream | + array groupsDo: [ :a :b :c :d :e :f | + stream nextPut: { a. b. c. d. e. f } ] ]). + self assert: #((1 2 3 4 5 6 7)) equals: (Array streamContents: [ :stream | + array groupsDo: [ :a :b :c :d :e :f :g | + stream nextPut: { a. b. c. d. e. f. g } ] ]). + self assert: #() equals: (Array streamContents: [ :stream | + #(1 2 3) groupsDo: [ :a :b :c :d | stream nextPut: { a. b. c. d } ] ]) + + ! From leves at elte.hu Mon Jan 19 03:13:41 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon Jan 19 03:13:45 2015 Subject: [squeak-dev] The Trunk: Environments-cmm.53.mcz In-Reply-To: References: Message-ID: On Sun, 18 Jan 2015, commits@source.squeak.org wrote: > Chris Muller uploaded a new version of Environments to project The Trunk: > http://source.squeak.org/trunk/Environments-cmm.53.mcz > > ==================== Summary ==================== > > Name: Environments-cmm.53 > Author: cmm > Time: 16 January 2015, 2:54:24.767 pm > UUID: 69b32fc7-98f1-4c19-9976-a38106a9ee63 > Ancestors: Environments-cmm.52 > > - Only change key when it is NOT in the 'bindings' Dictionary, otherwise it would be in a state inconsistent with its new hash. > > =============== Diff against Environments-cmm.51 =============== > > Item was changed: > ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- > renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | binding category | > category := self organization categoryOfElement: oldName. > self organization classify: newName under: category suppressIfDefault: true. > self organization removeElement: oldName. > > + binding := self associationAt: oldName. > - binding := self declarationOf: oldName. The Dictionary API shouldn't be used from new code, especially not from the Environments code itself. What was wrong with #declarationOf:? As I see the only difference is that it'll return nil instead of raising an error (#associationAt:). But that's not a problem, because the next line will raise an error anyway. > declarations removeKey: oldName. > + bindings removeKey: oldName. > + " self binding: binding removedFrom: self." > - self binding: binding removedFrom: self. > > + binding key: newName. > + declarations add: binding. > + bindings add: binding. > + " self binding: binding addedTo: self." > - binding := newName => aClass. > - declarations add: binding. > - self binding: binding addedTo: self. I suspect that the removal of the #binding:removedFrom: and the #binding:addedTo: sends will break Environments, because another environment which imports this environment will not be notified about changes which happen here. This problem is shadowed in case of Smalltalk - which imports itself - by the direct manipulation of the bindings dictionary. Levente > > Smalltalk renamedClass: aClass from: oldName to: newName. > SystemChangeNotifier uniqueInstance > classRenamed: aClass > from: oldName > to: newName > inCategory: category! > > > From commits at source.squeak.org Mon Jan 19 08:12:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon Jan 19 08:12:02 2015 Subject: [squeak-dev] The Trunk: Collections-mt.599.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.599.mcz ==================== Summary ==================== Name: Collections-mt.599 Author: mt Time: 19 January 2015, 9:11:48.572 am UUID: 48da0044-2d14-3048-b9f0-90a215344a36 Ancestors: Collections-ul.598 Implemented "First wins"-strategy wrt. to the order of associations. Allowed for simplifying the code. Order array does only grow to 75% to mitigate the greediness of the Dictionary. =============== Diff against Collections-ul.598 =============== Item was removed: - ----- Method: OrderedDictionary>>add: (in category 'adding') ----- - add: anAssociation - - | oldLastIndex oldCapacity | - oldLastIndex := lastIndex. - oldCapacity := self capacity. - - super add: anAssociation. - - (lastIndex = oldLastIndex or: [self capacity > oldCapacity]) ifTrue: [ - | index | - "The association was already present or we grew. We need to update the order." - index := self scanOrderFor: anAssociation key. - index = lastIndex ifFalse: [ - lastIndex := lastIndex + 1. - order at: lastIndex put: (order at: index). - order at: index put: nil. - lastIndex = order size ifTrue: [self fixEmptySlots]]]. - - ^ anAssociation! Item was removed: - ----- Method: OrderedDictionary>>at:put: (in category 'accessing') ----- - at: key put: anObject - - | oldLastIndex oldCapacity | - oldLastIndex := lastIndex. - oldCapacity := self capacity. - - super at: key put: anObject. - - (lastIndex = oldLastIndex or: [self capacity > oldCapacity]) ifTrue: [ - | index | - "The association was already present or we grew. We need to update the order." - index := self scanOrderFor: key. - index = lastIndex ifFalse: [ - lastIndex := lastIndex + 1. - order at: lastIndex put: (order at: index). - order at: index put: nil. - lastIndex = order size ifTrue: [self fixEmptySlots]]]. - - ^ anObject! Item was changed: ----- Method: OrderedDictionary>>atNewIndex:put: (in category 'private') ----- atNewIndex: index put: anObject + lastIndex = order size ifTrue: [ + self fixEmptySlots]. + lastIndex := lastIndex + 1. order at: lastIndex put: anObject. super atNewIndex: index put: anObject.! Item was changed: ----- Method: OrderedDictionary>>fixEmptySlots (in category 'private') ----- fixEmptySlots "Remove all nil slots in the order index to avoid overflow." + lastIndex = tally ifTrue: [^ self]. self fillOrderFrom: order.! Item was changed: ----- Method: OrderedDictionary>>growTo: (in category 'private') ----- growTo: anInteger | oldOrder | super growTo: anInteger. oldOrder := order. + "Grow only to 75%. See #atNewIndex:put: in HashedCollection." + order := self class arrayType new: (anInteger * (3/4)) ceiling. - order := self class arrayType new: anInteger. self fillOrderFrom: oldOrder.! Item was changed: ----- Method: OrderedDictionary>>initialize: (in category 'private') ----- initialize: n super initialize: n. + order := self class arrayType new: (n * (3/4)) ceiling. - order := self class arrayType new: n. lastIndex := 0.! Item was changed: ----- Method: OrderedDictionary>>removeKey:ifAbsent: (in category 'removing') ----- removeKey: key ifAbsent: aBlock + (self scanOrderFor: key) ifNotNil: [:index | + order at: index put: nil]. - order at: (self scanOrderFor: key) put: nil. ^ super removeKey: key ifAbsent: aBlock! Item was changed: ----- Method: OrderedDictionary>>scanOrderFor: (in category 'private') ----- scanOrderFor: anObject 1 to: lastIndex do: [:index | | element | ((element := order at: index) notNil and: [anObject = element key]) ifTrue: [^ index]]. + ^ nil! - lastIndex = order size - ifTrue: [self errorNoFreeSpace] - ifFalse: [^ order at: lastIndex + 1 "nil"].! From commits at source.squeak.org Mon Jan 19 08:16:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon Jan 19 08:16:59 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.233.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.233.mcz ==================== Summary ==================== Name: CollectionsTests-mt.233 Author: mt Time: 19 January 2015, 9:16:51.95 am UUID: d2cf5a69-1834-3b44-9a45-91b26a7a33d7 Ancestors: CollectionsTests-ul.232 Tests updated for OrderedDictionary =============== Diff against CollectionsTests-ul.232 =============== Item was changed: ----- Method: OrderedDictionaryTest>>testCopy (in category 'tests - copying') ----- testCopy sut at: 1 put: nil; at: 2 put: nil; + at: 3 put: nil. - at: 1 put: nil. sut copy in: [:copy | self assert: sut keys equals: copy keys. + copy at: 4 put: nil. + self assert: sut keys size < copy keys size].! - copy at: 2 put: nil. - self - assert: sut keys size = copy keys size; - assert: sut keys ~= copy keys].! Item was changed: ----- Method: OrderedDictionaryTest>>testGrow (in category 'tests') ----- testGrow self assert: 11 equals: sut capacity; "next prime number to 7; see #setUp" + assert: sut capacity > (sut instVarNamed: #order) size. "save memory" - assert: sut capacity equals: (sut instVarNamed: #order) size. 1 to: sut capacity do: [:ea | sut at: ea put: nil]. self assert: sut capacity > 11; + assert: sut capacity > (sut instVarNamed: #order) size. "save memory"! - assert: sut capacity equals: (sut instVarNamed: #order) size.! Item was changed: ----- Method: OrderedDictionaryTest>>testOverflow (in category 'tests') ----- testOverflow "Check whether repeated additions of the same alternating keys causes an error." self + shouldnt: [20 timesRepeat: [sut at: 1 put: nil; removeKey: 1]] - shouldnt: [20 timesRepeat: [sut at: 1 put: nil. sut at: 2 put: nil]] raise: Error. ! Item was changed: ----- Method: OrderedDictionaryTest>>testOverwriteValue (in category 'tests') ----- testOverwriteValue + "First write wins wrt. order in the dictionary." 1 to: 5 do: [:ea | sut at: ea put: nil]. sut at: 3 put: nil. + self assert: #(1 2 3 4 5) equals: sut keys.! - self assert: #(1 2 4 5 3) equals: sut keys.! Item was removed: - ----- Method: OrderedDictionaryTest>>testSortAfterOverwrite (in category 'tests - sorting') ----- - testSortAfterOverwrite - - 10 to: 1 by: -1 do: [:ea | - sut at: ea put: nil]. - - sut at: 5 put: nil. - sut sort. - self assert: (1 to: 10) asArray equals: sut keys.! From marcel.taeumel at student.hpi.uni-potsdam.de Mon Jan 19 08:19:46 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Mon Jan 19 08:22:58 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.599.mcz In-Reply-To: References: Message-ID: <1421655586903-4800301.post@n4.nabble.com> At the moment, I vote against an implementation with linked associations as suggested by Levente [1] because: - Naming reveals implementation detail (LinkedList resp. LinkedAssociation) and thus a LinkedDictionary could only be abstract like HashedCollection is - LinkedAssociation instances keep references (#next, #previous), which may interfere with automatic garbage collection if used outside the dictionary (see getter #associations) We could add automatic boxing/unboxing of linked elements (like Set does with SetElement) but this would nullify the performance gain of linked structures compared to arrays. Best, Marcel [1] http://leves.web.elte.hu/squeak/LinkedDictionary-ul.1.mcz -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-599-mcz-tp4800299p4800301.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From leves at elte.hu Mon Jan 19 09:02:05 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon Jan 19 09:02:09 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.599.mcz In-Reply-To: <1421655586903-4800301.post@n4.nabble.com> References: <1421655586903-4800301.post@n4.nabble.com> Message-ID: On Mon, 19 Jan 2015, Marcel Taeumel wrote: > At the moment, I vote against an implementation with linked associations as > suggested by Levente [1] because: > > - Naming reveals implementation detail (LinkedList resp. LinkedAssociation) > and thus a LinkedDictionary could only be abstract like HashedCollection is I used this name to make it loadable into an updated Trunk image. > - LinkedAssociation instances keep references (#next, #previous), which may > interfere with automatic garbage collection if used outside the dictionary > (see getter #associations) > > We could add automatic boxing/unboxing of linked elements (like Set does > with SetElement) but this would nullify the performance gain of linked > structures compared to arrays. That's not true for removal, which still takes O(n) time with the current implementation: | n random array | n := 10000. random := Random seed: 36rSQUEAK. array := Array new: n streamContents: [ :stream | n timesRepeat: [ stream nextPut: (random nextInt: 1073741823) -> 1 ] ]. { OrderedDictionary. LinkedDictionary } collect: [ :class | Smalltalk garbageCollect. [ | instance | instance := class new. instance addAll: array. array do: [ :each | instance removeKey: each key ] ] timeToRun ]. "==> #(892 10)" The current implementation can be modified to take only O(1) time average, by using another array, which maps the index of an association in the array variable to the index of the association in the order variable. Levente > > Best, > Marcel > > [1] http://leves.web.elte.hu/squeak/LinkedDictionary-ul.1.mcz > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-599-mcz-tp4800299p4800301.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From commits at source.squeak.org Mon Jan 19 09:14:15 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon Jan 19 09:14:17 2015 Subject: [squeak-dev] The Trunk: Collections-mt.600.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.600.mcz ==================== Summary ==================== Name: Collections-mt.600 Author: mt Time: 19 January 2015, 10:14:01.368 am UUID: 32764222-c0d1-9943-a0ae-ac6a5684f053 Ancestors: Collections-mt.599 Copy ranges of elements in OrderedDictionary. =============== Diff against Collections-mt.599 =============== Item was added: + ----- Method: OrderedDictionary>>copyFrom:to: (in category 'copying') ----- + copyFrom: startIndex to: endIndex + "Answer a copy of the receiver that contains elements from position + startIndex to endIndex." + + self fixEmptySlots. + ^ self shallowCopy postCopyFrom: startIndex to: endIndex! Item was added: + ----- Method: OrderedDictionary>>first: (in category 'accessing') ----- + first: n + "Answer the first n elements of the receiver. + Raise an error if there are not enough elements." + + ^ self copyFrom: 1 to: n! Item was changed: ----- Method: OrderedDictionary>>isSorted (in category 'sorting') ----- isSorted + "Return true if the receiver's keys are sorted by #<=." - "Return true if the receiver is sorted by #<=." self fixEmptySlots. ^ order isSortedBetween: 1 and: lastIndex! Item was added: + ----- Method: OrderedDictionary>>last: (in category 'accessing') ----- + last: n + "Answer the last n elements of the receiver. + Raise an error if there are not enough elements." + + | size | + size := self size. + ^ self copyFrom: size - n + 1 to: size! Item was added: + ----- Method: OrderedDictionary>>postCopyFrom:to: (in category 'copying') ----- + postCopyFrom: startIndex to: endIndex + "Adapted from SequenceableCollection and OrderedCollection." + + | oldOrder newArraySize newOrderSize | + newArraySize := self class goodPrimeAtLeast: ((endIndex - startIndex + 1) * (5/4) "add 25%") ceiling. + newOrderSize := (newArraySize * (3/4)) ceiling. "remove 25%" + + oldOrder := order. + order := self class arrayType new: newOrderSize. + array := self class arrayType new: newArraySize. + + startIndex to: endIndex do: [:index | | element | + element := (oldOrder at: index) copy. + order at: index - startIndex + 1 put: element. + array at: (self scanFor: element key) put: element]. + + lastIndex := endIndex - startIndex + 1. + tally := lastIndex. + + + ! From commits at source.squeak.org Mon Jan 19 09:15:29 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon Jan 19 09:15:31 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.234.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.234.mcz ==================== Summary ==================== Name: CollectionsTests-mt.234 Author: mt Time: 19 January 2015, 10:15:23.464 am UUID: 21813c5d-d99c-3b4c-85fe-7b14627f5dd1 Ancestors: CollectionsTests-mt.233 Tests about copying ranges added for OrderedDictionary =============== Diff against CollectionsTests-mt.233 =============== Item was added: + ----- Method: OrderedDictionaryTest>>testCopyFirst (in category 'tests - accessing') ----- + testCopyFirst + + 1 to: 10 do: [:ea | + sut at: ea put: nil]. + + self assert: (1 to: 5) asArray equals: (sut first: 5) keys.! Item was added: + ----- Method: OrderedDictionaryTest>>testCopyFromTo (in category 'tests - copying') ----- + testCopyFromTo + + 1 to: 10 do: [:index | + sut at: index put: nil]. + + (sut copyFrom: 3 to: 5) in: [:copy | + self assert: (3 to: 5) asArray equals: copy keys. + copy at: 3 put: #foo. + self assert: (sut at: 3) isNil.].! Item was added: + ----- Method: OrderedDictionaryTest>>testCopyLast (in category 'tests - accessing') ----- + testCopyLast + + 1 to: 10 do: [:ea | + sut at: ea put: nil]. + + self assert: (6 to: 10) asArray equals: (sut last: 5) keys.! From marcel.taeumel at student.hpi.uni-potsdam.de Mon Jan 19 09:22:30 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Mon Jan 19 09:25:41 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.599.mcz In-Reply-To: References: <1421655586903-4800301.post@n4.nabble.com> Message-ID: <1421659350139-4800312.post@n4.nabble.com> Good Idea. But how do we decide between time vs. memory? I just reduced "order" to be 25% smaller than "array" to save some memory because array starts growing anyway then. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-599-mcz-tp4800299p4800312.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Mon Jan 19 09:38:10 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Mon Jan 19 09:41:21 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.599.mcz In-Reply-To: <1421659350139-4800312.post@n4.nabble.com> References: <1421655586903-4800301.post@n4.nabble.com> <1421659350139-4800312.post@n4.nabble.com> Message-ID: <1421660290104-4800317.post@n4.nabble.com> Woah, managing such a lookup index between "array" and "order" is quite complicated with the current implementation of Dictionary. :D Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-599-mcz-tp4800299p4800317.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From frank.shearar at gmail.com Mon Jan 19 09:59:50 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Mon Jan 19 09:59:51 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz In-Reply-To: References: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 17 January 2015 at 18:35, Eliot Miranda wrote: > Hi Frank, > > On Jan 17, 2015, at 3:39 AM, Frank Shearar wrote: > >> On 16 January 2015 at 21:44, wrote: >>> Chris Muller uploaded a new version of System to project The Trunk: >>> http://source.squeak.org/trunk/System-cmm.694.mcz >>> >>> ==================== Summary ==================== >>> >>> Name: System-cmm.694 >>> Author: cmm >>> Time: 16 January 2015, 3:44:19.079 pm >>> UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 >>> Ancestors: System-dtl.693 >>> >>> - #flush stdout and stderr after writing error information to them. >>> - After that, if the exception is resumable (i.e. a Warning), resume it. Except if its a MessageNotUnderstood -- that is not an error you want to resume in a headless environment. >> >> Why? It's probably a rare use case for a #run: script to catch MNUs to >> do something fancy, I guess? Maybe it's because #run: is usually >> (always?) the top level of the program? > > One reason is that resuming an MNU simply resends from the diesNotUnderstand: method, so resuming will result in infinite recursion. I suppose the handler could allow one repeat but that seems arbitrary. There's nothing to stop one including a resuming MNU handler in the expression if one wants to override the default behaviour. > >> >> Catching only MNUs seems very specific. Maybe there could be a #run: >> version that says "and here's a function you can use to control which >> exceptions are OK to resume, and which not"? > > Well there is Notification and Warning but (rightly) MessageNotUnderstood is an Error. Reporting Notifications and Warnings to the output and continuing, but aborting for other exceptions seems the right thing to do, rather than basing it in resumability, yes? What am I missing? > > Whether an exception is resumability or not is to do with whether one can usefully provide a value with which to continue, not to do with the severity of the error. Chris has already addressed the issue, but to continue the conversation here, yes, an exception is resumable if e isResumable = true. That's exactly as it should be. But seeing as an MNU is resumable, you could write a handler that _did_ return a value. In other words, the problem that I saw - and I think Chris and you agree? - is that it looks weird to resume some resumable exceptions but not others. I agree with the point you make in a later mail, that #run: should just bail noisily on a top-level exception. frank > For example, being able to resume with nil for a permissions violation when opening a file or directory might make it really easy to implement a find(1) like search over directories where some may be unreadable due to permissions. Being able to resume doesn't make the permissions violation any the less severe, but it dies give us a nice way if handling it, certainly less complex than having to explicitly check for permissions during the traversal. Likewise, being able to substitute a value for an MNU allows all sorts of conveniences, eg see my code for disassembling methods to bytecode messages. > > So IMO the system should be reporting Notifications and Warnings and aborting for anything else. Yep. >> frank > > Eliot (phone) From marcel.taeumel at student.hpi.uni-potsdam.de Mon Jan 19 10:07:13 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Mon Jan 19 10:10:24 2015 Subject: [squeak-dev] [Performance] #printString and Array ... (Example: LRUCache) Message-ID: <1421662033656-4800322.post@n4.nabble.com> Hi, there! c := LRUCache someInstance. (c instVarNamed: #map) size. "47" [(c instVarNamed: #head) printString size] timeToRun. "1825" If this cache grows, #printString gets very slow. c := LRUCache allInstances first. (c instVarNamed: #map) size. "4952" [(c instVarNamed: #head) printString size] timeToRun. "Well..." Any ideas how to fix that? Best, Marcel -- View this message in context: http://forum.world.st/Performance-printString-and-Array-Example-LRUCache-tp4800322.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From bert at freudenbergs.de Mon Jan 19 10:22:08 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Mon Jan 19 10:22:12 2015 Subject: [squeak-dev] [Performance] #printString and Array ... (Example: LRUCache) In-Reply-To: <1421662033656-4800322.post@n4.nabble.com> References: <1421662033656-4800322.post@n4.nabble.com> Message-ID: On 19.01.2015, at 11:07, Marcel Taeumel wrote: > > Hi, there! > > c := LRUCache someInstance. > (c instVarNamed: #map) size. "47" > [(c instVarNamed: #head) printString size] timeToRun. "1825" > > If this cache grows, #printString gets very slow. > > c := LRUCache allInstances first. > (c instVarNamed: #map) size. "4952" > [(c instVarNamed: #head) printString size] timeToRun. "Well..." > > Any ideas how to fix that? > > Best, > Marcel Nodes should get their own class, not be 4-element Arrays. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/40fb74fb/smime.bin From bert at freudenbergs.de Mon Jan 19 12:12:19 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Mon Jan 19 12:12:22 2015 Subject: [squeak-dev] Squeak community inclusiveness (was: Studies on group effectiveness) In-Reply-To: <20150117223634.GA37183@shell.msen.com> References: <20150117144301.GA60130@shell.msen.com> <0457F6EB-37A2-4E18-A9CA-71C8558D3FCC@rowledge.org> <20150117223634.GA37183@shell.msen.com> Message-ID: <93419F58-1A70-4F73-8183-BE6E8CD8879E@freudenbergs.de> The hardest thing is even seeing the problem. I like to think of myself as being non-sexist, non-racist, etc. but until recently (*) I wasn't even aware of my own blindness. Leslie Hawthorn just gave an excellent talk on how to see privilege: https://www.youtube.com/watch?v=cuK45hDRlaE (if you don't have 45 minutes, watch this one instead https://www.youtube.com/watch?v=kWRCQYRZJzo ) I want Squeak to be a place welcoming all humans. Please help remove obstacles to that, especially those we cannot even see. - Bert - (*) I don't recall when I realized I had been privileged all along, but I do remember this nerdy piece being helpful for explaining it: http://whatever.scalzi.com/2012/05/15/straight-white-male-the-lowest-difficulty-setting-there-is/ -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/12e99754/smime-0001.bin From Das.Linux at gmx.de Mon Jan 19 12:45:53 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 19 12:45:58 2015 Subject: [squeak-dev] Why is source code always in files only? Message-ID: Hi all, We store method source _solely_ in files (.sources/.changes). Why? We have means to attach it to Compiled methods, in fact, more than one: CompiledMethod allInstances size. "57766." CompiledMethod allInstances count: [:m | m properties includesKey: #source]. "0." CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. "0." CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. "57700." " also interesting " (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) sortedCounts {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . 2->#TempsNamesZip} When doing some analysis on source code, it is a pain to _either_ always go to disk for the source _or_ cache the code myself (which may get out of sync sooon). Can't we just save the source code either via trailer or properties on first access? Best -Tobias From Das.Linux at gmx.de Mon Jan 19 13:56:38 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 19 13:56:43 2015 Subject: [squeak-dev] Request: new 4.5 artifact. Message-ID: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> Hey, can somebody please copy a vanilla yet recent 4.5 to the ftp/files server? The current one we can get there still has this 'About to serialize empty package' weirdness and we sure do not want to scare away people who just hit the update button with such a message? Best -Tobias From commits at source.squeak.org Mon Jan 19 14:05:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon Jan 19 14:05:29 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.754.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.754.mcz ==================== Summary ==================== Name: Morphic-mt.754 Author: mt Time: 19 January 2015, 3:04:57.121 pm UUID: 21cf3f17-77dd-814b-bbad-01dd7abefa09 Ancestors: Morphic-bf.753 Fixed conversion of StringMorph as #imageForm when text color was white. =============== Diff against Morphic-bf.753 =============== Item was changed: ----- Method: StringMorph>>imageForm:forRectangle: (in category 'drawing') ----- imageForm: depth forRectangle: rect | canvas | canvas := Display defaultCanvasClass extent: rect extent depth: depth. + canvas form fillColor: self color negated. - canvas form fillColor: Color white. canvas translateBy: rect topLeft negated during:[:tempCanvas| tempCanvas fullDrawMorph: self]. ^ canvas form offset: rect topLeft! From craig at netjam.org Mon Jan 19 14:21:37 2015 From: craig at netjam.org (Craig Latta) Date: Mon Jan 19 14:21:47 2015 Subject: [squeak-dev] re: compiled squeakjs In-Reply-To: References: <54BBEE3E.8080208@gmail.com> <211BA32F-6BE6-4734-B5BD-CE910CC258D3@gmail.com> Message-ID: > As I understand it, running under NaCl requires reworking the JIT and > has real problems doing the self-modifying code involved in inline > caches, etc. Yep, you rebuild your app to use the NaCl instruction set, and it translates to physical instructions on demand. The "safety" constraints it places on the code you generate are substantial. If you were even allowed to run the code you want, the performance goal would be demolished. But worse, you've also demolished the "run anywhere" goal from the outset, by limiting yourself to browsers that support NaCl. And I don't see how to meet this goal with any browser-plugin approach. There just isn't a widely-supported mechanism anymore, after the death of the Netscape-style plugin. -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From craig at netjam.org Mon Jan 19 14:41:19 2015 From: craig at netjam.org (Craig Latta) Date: Mon Jan 19 14:41:28 2015 Subject: [squeak-dev] re: Context status 2015-01-16 In-Reply-To: References: <54B9A0D9.5000707@netjam.org> Message-ID: <54BD178F.8090501@netjam.org> Okay, I'll add both of the execution-driven imprinters to the repository. They're called "active" and "passive" imprinting. Active imprinting is directed by the system that initially has the desired code. An ActiveImprintingServer has clients in the systems which will receive the code. Every time the server system runs a method in a certain process, it imprints that method onto each of the clients. One use case for this is giving the code of a demo to an audience as you run it. Passive imprinting is directed by the system that wants the code. The target system makes a remote-messaging connection to a system which has the code, and runs an expression which will use the code. Every time a method is missing from the target system (in any process), the target system requests the missing method from the provider system, installs it, and retries running that method. I have imprinted the exception-handling system, the compiler, and the class builder with both approaches. thanks, -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From bert at freudenbergs.de Mon Jan 19 15:37:15 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Mon Jan 19 15:37:18 2015 Subject: [squeak-dev] compiled squeakjs In-Reply-To: <54BBEE3E.8080208@gmail.com> References: <54BBEE3E.8080208@gmail.com> Message-ID: <3FEB62EA-DEF5-4C6F-849A-7E65BE2B1F1F@freudenbergs.de> Hi Florin, this sounds extremely interesting. In particular the part about using continuations to model execution flow, that thought had not occurred to me yet. Indeed, non-local returns and interruptability are the hardest to map to JS. I will have to think about this idea a while :) SqueakJS does compilation, too, by now. It has a (very simple) JIT compiler that compiles bytecodes into equivalent JavaScript, on a method-by-method basis. Read the initial comment at https://github.com/bertfreudenberg/SqueakJS/blob/master/jit.js To see it in action, open your browser's JS console and evaluate "SqueakJS.vm.method.compiled" which is the compiled version of the currently executing method. Or, if you're running a JS profiler, the generated methods will show up in that profile, too, and you can see their source. This is not a high-performance JIT yet, but it helps a lot compared to the simple interpreter. Here's the numbers on Chrome's V8: with JIT: 82315112 bytecodes/sec; 902155 sends/sec no JIT: 2775850 bytecodes/sec; 137439 sends/sec Also interesting - no JIT, before V8 deoptimization kicks in: 11494252 bytecodes/sec; 523121 sends/sec With the JIT, the code is more distributed, less polymorphic, so V8 can optimize better. Beware microbenchmarks etc, but it pays hugely to make your code "friendly" for the JS VM. Amber for example, on the same machine in the same browser, reports '2214839.4241417497 bytecodes/sec; 229042.45283018867 sends/sec' even though it directly compiles to JavaScript and does not have full Smalltalk semantics (e.g. no real thisContext, no become). I suspect deoptimization in V8. Indeed, on FireFox it reports '3007518.796992481 bytecodes/sec; 408234.4251766217 sends/sec', which is roughly the same as SqueakJS (40327662 bytecodes/sec; 516034 sends/sec). So since you're after the highest performance, it may pay off to do some experiments first. Btw, here is a very interesting talk about how to make Smalltalk-style method invocation be fast on V8. video: http://2014.jsconf.eu/speakers/vyacheslav-egorov-invokedynamic-js.html slides: http://mrale.ph/talks/jsconfeu2014/ I did not fully understand your proposal about the object memory layout, and how become would work. Also, allInstances/weak refs and finalization isn't accounted for. Do you intend this to be a fully compatible VM for Squeak? That was my goal with SqueakJS, performance being secondary (although not unimportant). SqueakJS does fully implement Squeak's execution semantics, including thisContext, non-local return, stack unwinding, DNU, process switching etc. and the object memory semantics too, including allObjects/allInstances, weak refs and finalization. Your proposed mapping to JS Arrays/Maps etc. seems to imply that it would not be fully compatible, right? Rather a Smalltalk-for-the-web with fewer compromises than Amber? Or is this even only meant as a deployment step, not as a fully self-hosted development environment? - Bert - On 18.01.2015, at 18:32, Florin Mateoc wrote: > Hi, > > Inspired by Bert's project, I started thinking about how to get Smalltalk compiled to Javascript instead of interpreted. > I do have previous experience in compiling Smalltalk to Java (after type inference, which we thankfully don't need > here). But, the requirements are a bit tighter here: we have to take an unknown image, get it translated on the fly, > completely automatically, and even allow the translated image to self-modify. Plus we cannot just decree that become: > cannot be used > > Given that the input is an image, not sources, we'd better rely on the decompiler, so I started there. I think I fixed > it, so that it can now decompile everything correctly. > I also implemented a few AST transformations (similar to the ones that were necessary for Java, like normalizing the > various boolean constructs and making them statements). > I then started to write a Javascript pretty-printer, but I stopped when I realized that there were a few things missing: > while non-local returns and resumable exceptions can be implemented using exceptions and an explicit stack of handlers, > preemption (and Smalltalk's processes in general) were harder. After some research I came to the conclusion that this > was doable if, instead of doing a direct pretty-printing of the Smalltalk nodes to Javascript, we also used the > translation process to transform the code in continuation passing style. Then non-local returns become trivial and > preemption can be implemented with closures, without needing access to the underlying execution stack. > An interrupted context would have a no-arg closure representing the continuation instead of a pc. In general, only > preemption points (which all have a corresponding continuation closure) would have to be mapped, and this would happen > at image read time as well. The exception would be the debugger - I am not sure about that one yet. > The primitive code would be inlined in the primitive methods, followed by a preemption point and the failure code. > Unfortunately invocation would still not be direct, but looked up (and invoking DNU if needed), but I would store all > the translated methods directly in the class prototype, so there would be no need for explicit superclass chain lookup. > The instvars would also be stored directly in the class prototype (but with a prefix, to not conflict with the methods > or with reserved keywords), and they would be accessed directly (with dot notation), except for assignments, which would > record the owner (and the index in the owner), for all non-primitive types (not sure what to do about strings). > Every method (and formerly Smalltalk block closure) would have a single temp called "thisContext", which would be an > owner for the actual temps. The owners info would be used for implementing become: and allReferences. > > The ProtoObject and Object methods coming from Smalltalk would be stored in Object.prototype. Proxy classes would have > their prototypes cleared and only contain the ProtoObject methods. > Primitive type classes would have to be massaged a little: Number would have a union of methods from the Smalltalk > Number subclasses, as well as the methods inherited from Magnitude. > String would also have the methods inherited from Collection and SequenceableCollection, as well as from Character (and > Magnitude) and Symbol - this one could be a little nastier, but I think it could be made to work. > I would also map Array to Array, IdentitySet to Set and IdentityDictionary to Map. Weak collections are harder, because > Javascript decided to make them not enumerable. Because of this, allInstances would also be a challenge. > > I am not sure yet about the bootstrap process. I just have a fuzzy feeling that Craig's Context running under SqueakJS > might make it easier. > > I hope this gives a general idea about the approach. Please do point out weaknesses that I may have missed. For me this > is fun and I will proceed slowly, as time permits, since I cannot do it at work. > Of course, I am very interested to hear Bert's opinion :) > > Florin -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/45e77383/smime.bin From asqueaker at gmail.com Mon Jan 19 17:23:19 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon Jan 19 17:23:21 2015 Subject: [squeak-dev] The Trunk: Environments-cmm.53.mcz In-Reply-To: References: Message-ID: On Sun, Jan 18, 2015 at 9:13 PM, Levente Uzonyi wrote: > On Sun, 18 Jan 2015, commits@source.squeak.org wrote: > > Chris Muller uploaded a new version of Environments to project The Trunk: >> http://source.squeak.org/trunk/Environments-cmm.53.mcz >> >> ==================== Summary ==================== >> >> Name: Environments-cmm.53 >> Author: cmm >> Time: 16 January 2015, 2:54:24.767 pm >> UUID: 69b32fc7-98f1-4c19-9976-a38106a9ee63 >> Ancestors: Environments-cmm.52 >> >> - Only change key when it is NOT in the 'bindings' Dictionary, otherwise >> it would be in a state inconsistent with its new hash. >> >> =============== Diff against Environments-cmm.51 =============== >> >> Item was changed: >> ----- Method: Environment>>renameClass:from:to: (in category 'classes >> and traits') ----- >> renameClass: aClass from: oldName to: newName >> "Rename the class, aClass, to have the title newName." >> >> | binding category | >> category := self organization categoryOfElement: oldName. >> self organization classify: newName under: category >> suppressIfDefault: true. >> self organization removeElement: oldName. >> >> + binding := self associationAt: oldName. >> - binding := self declarationOf: oldName. >> > > The Dictionary API shouldn't be used from new code, especially not from > the Environments code itself. > What was wrong with #declarationOf:? As I see the only difference is that > it'll return nil instead of raising an error (#associationAt:). But that's > not a problem, because the next line will raise an error anyway. Okay, we should change it back to declarationOf: then. I simply put it back like it was prior to cwp.50. declarations removeKey: oldName. >> + bindings removeKey: oldName. >> + " self binding: binding removedFrom: self." >> - self binding: binding removedFrom: self. >> >> + binding key: newName. >> + declarations add: binding. >> + bindings add: binding. >> + " self binding: binding addedTo: self." >> - binding := newName => aClass. >> - declarations add: binding. >> - self binding: binding addedTo: self. >> > > I suspect that the removal of the #binding:removedFrom: and the > #binding:addedTo: sends will break Environments, because another > environment which imports this environment will not be notified about > changes which happen here. > The calls ot those are what had rename-class so severely broken. I tried to understand a proper fix but #binding:removedFrom: does a #perform on its 'removeSelector', (#hideBinding: in this case), which ends up doing a becomeForward: on the binding from the looked-up namespace to the one in the the receiver Environments 'bindings'. That kind of code is way too smart for me, and since #hideBinding: is the removeSelector used by all of Environments main "import" API, I decided to make this temporary fix isolated to the renameClass function, to minimize the impact on Environments. In a nutshell, cwp.50 was attempting to fix rename class, but it made it worse, so this reversion lets us go back and "try again". This problem is shadowed in case of Smalltalk - which imports itself - by > the direct manipulation of the bindings dictionary. I don't care what solution we have as long as regular development works. > > Levente > > > >> Smalltalk renamedClass: aClass from: oldName to: newName. >> SystemChangeNotifier uniqueInstance >> classRenamed: aClass >> from: oldName >> to: newName >> inCategory: category! >> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/1e77f094/attachment.htm From asqueaker at gmail.com Mon Jan 19 17:34:12 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon Jan 19 17:34:15 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: Message-ID: On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape wrote: > Hi all, > > > We store method source _solely_ in files (.sources/.changes). > Why? We have means to attach it to Compiled methods, in fact, more than > one: > > > CompiledMethod allInstances size. "57766." > CompiledMethod allInstances count: [:m | m properties includesKey: > #source]. "0." > CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. "0." > CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. > "57700." > > > " also interesting " > (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) > sortedCounts > {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . > 2->#TempsNamesZip} > > > When doing some analysis on source code, it is a pain to _either_ > always go to disk for the source _or_ cache the code myself (which may > get out of sync sooon). > If you're sending messages instead of viewing private innards, why is it a pain? > Can't we just save the source code either via trailer or properties > on first access? > -1. Why do I want all of those String's in my image? > > > Best > -Tobias > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/c5038467/attachment.htm From asqueaker at gmail.com Mon Jan 19 17:37:16 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon Jan 19 17:37:19 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> Message-ID: More scary is when they would encounter a corrupted (empty) package. That message is intending to help us debug why that is happening.. On Mon, Jan 19, 2015 at 7:56 AM, Tobias Pape wrote: > Hey, > > can somebody please copy a vanilla yet recent 4.5 to the > ftp/files server? The current one we can get there still > has this 'About to serialize empty package' weirdness and > we sure do not want to scare away people who just > hit the update button with such a message? > > Best > -Tobias > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/738ff4f1/attachment.htm From florin.mateoc at gmail.com Mon Jan 19 18:03:51 2015 From: florin.mateoc at gmail.com (Florin Mateoc) Date: Mon Jan 19 18:03:37 2015 Subject: [squeak-dev] compiled squeakjs In-Reply-To: <3FEB62EA-DEF5-4C6F-849A-7E65BE2B1F1F@freudenbergs.de> References: <54BBEE3E.8080208@gmail.com> <3FEB62EA-DEF5-4C6F-849A-7E65BE2B1F1F@freudenbergs.de> Message-ID: <54BD4707.70904@gmail.com> On 1/19/2015 10:37 AM, Bert Freudenberg wrote: > Hi Florin, > > this sounds extremely interesting. In particular the part about using continuations to model execution flow, that thought had not occurred to me yet. Indeed, non-local returns and interruptability are the hardest to map to JS. I will have to think about this idea a while :) > > SqueakJS does compilation, too, by now. It has a (very simple) JIT compiler that compiles bytecodes into equivalent JavaScript, on a method-by-method basis. Read the initial comment at > https://github.com/bertfreudenberg/SqueakJS/blob/master/jit.js > > To see it in action, open your browser's JS console and evaluate "SqueakJS.vm.method.compiled" which is the compiled version of the currently executing method. Or, if you're running a JS profiler, the generated methods will show up in that profile, too, and you can see their source. > > This is not a high-performance JIT yet, but it helps a lot compared to the simple interpreter. Here's the numbers on Chrome's V8: > with JIT: 82315112 bytecodes/sec; 902155 sends/sec > no JIT: 2775850 bytecodes/sec; 137439 sends/sec > > Also interesting - no JIT, before V8 deoptimization kicks in: > 11494252 bytecodes/sec; 523121 sends/sec > With the JIT, the code is more distributed, less polymorphic, so V8 can optimize better. > > Beware microbenchmarks etc, but it pays hugely to make your code "friendly" for the JS VM. Amber for example, on the same machine in the same browser, reports '2214839.4241417497 bytecodes/sec; 229042.45283018867 sends/sec' even though it directly compiles to JavaScript and does not have full Smalltalk semantics (e.g. no real thisContext, no become). I suspect deoptimization in V8. Indeed, on FireFox it reports '3007518.796992481 bytecodes/sec; 408234.4251766217 sends/sec', which is roughly the same as SqueakJS (40327662 bytecodes/sec; 516034 sends/sec). > > So since you're after the highest performance, it may pay off to do some experiments first. > > Btw, here is a very interesting talk about how to make Smalltalk-style method invocation be fast on V8. > video: http://2014.jsconf.eu/speakers/vyacheslav-egorov-invokedynamic-js.html > slides: http://mrale.ph/talks/jsconfeu2014/ > > I did not fully understand your proposal about the object memory layout, and how become would work. Also, allInstances/weak refs and finalization isn't accounted for. > > Do you intend this to be a fully compatible VM for Squeak? That was my goal with SqueakJS, performance being secondary (although not unimportant). SqueakJS does fully implement Squeak's execution semantics, including thisContext, non-local return, stack unwinding, DNU, process switching etc. and the object memory semantics too, including allObjects/allInstances, weak refs and finalization. > > Your proposed mapping to JS Arrays/Maps etc. seems to imply that it would not be fully compatible, right? Rather a Smalltalk-for-the-web with fewer compromises than Amber? Or is this even only meant as a deployment step, not as a fully self-hosted development environment? > > - Bert - > Hi Bert, Thank you for the pointers, I will now have to go do some reading. The idea for become: goes something like this (I know that standard WeakMaps are not enumerable, but given that Google/Caja were apparently able to write a WeakMap shim without native support, I hope that code can be used as inspiration to give us enumerable ones - this would also address the more general requirement for weak collections/allInstances): assignments, as well as the at:put: and instvarAt:put: primitives, add (if not already there) to the right-hand side object a WeakMap property "owners". This happens only for non-primitive types. The keys are the owners and the values are the indexes within the owner where the owned object lives. If there is already a previous object within the owner at that index, the owner/index pair is removed from the previous object's owners. At become: time, we iterate the owners and do the replacement But to address the last part about compatibility: Having gone through the experience of successfully migrating a huge Smalltalk application to Java (more than 2000 screens, many thousands of classes and millions of lines of code), I think of it as representative enough to be confident in the general feasibility of the approach, even though we still do not have out of the box a fully automated translation solution for every particular aspect (anyway, that was not the goal). Furthermore, one aspect of the migration seemed pretty challenging: since this was an application already deployed in production at many (and vocal) customers, we wanted to ensure a smooth transition and we did not just want the general functionality to be there but essentially pixel-identical behavior for the Java incarnation. The original application also had proxies, a way of applying patching in production, it included the compiler for runtime evaluation (both for patching, debugging and for evaluating customer-specific scripts). Now, we did not implement a Smalltalk vm on top of Java, so of course we did not fully implement Smalltalk (VA) execution semantics. It turns out we did not need to. We achieved through automatic translation over 90% of the functionality, including the (99%) pixel-identical presentation (we chose SWT as a target UI framework, since it mapped closely to the original VA UI framework). For the rest we came up with ad-hoc solutions: we implemented something for the proxies (taking advantage of the specific way they were used in the original application (so no general solution)), we included the compiler and wrote a Java classloader for patching, we also wrote an inspector with Java runtime evaluation capabilities. These last ones were just functionally equivalent (the evaluated snippets are Java, not evaluating/translating on the fly Smalltalk scripts to Java - although that would have been fun). We reimplemented the db communications layer to use JDBC. All in all, this was a pragmatic approach and the application behaves the same and runs at the same speed as the original, so from the point of view of the users, it is essentially the same. This was a long-winded way of saying that I don't think exact execution semantics are that important. If you think the pc in a context is part of Smalltalk's semantics, obviously the proposed approach does not address that. Even for a more ambitious goal (we want to run (almost) any image, not just a specific one, even if huge and complex), I think this is a place where one can cheat without being caught. Even allObjects/allInstances might not be required, especially that my understanding is that the main purpose (other than debugging) for allInstances was to allow mutation. I don't think mutation presents the same challenges in JavaScript. Regarding mappings, of course one could write Smalltalk code that would catch us, but I think most "normal" usage patterns could be covered. My goal would be a Smalltalk-for-the-web that could read and run almost any Squeak image (I would not consider code purposely written to catch us cheating as a unveiling a bug, but I would consider any normal usage pattern that would not work a bug), allowing self-hosted further development (with hooks for the Smalltalk compiler to perform the same steps as the ones performed at image read time). Florin From Yoshiki.Ohshima at acm.org Mon Jan 19 18:33:01 2015 From: Yoshiki.Ohshima at acm.org (Yoshiki Ohshima) Date: Mon Jan 19 18:33:04 2015 Subject: [squeak-dev] re: compiled squeakjs In-Reply-To: References: <54BBEE3E.8080208@gmail.com> <211BA32F-6BE6-4734-B5BD-CE910CC258D3@gmail.com> Message-ID: On Mon, Jan 19, 2015 at 6:21 AM, Craig Latta wrote: > >> As I understand it, running under NaCl requires reworking the JIT and >> has real problems doing the self-modifying code involved in inline >> caches, etc. > > Yep, you rebuild your app to use the NaCl instruction set, and it > translates to physical instructions on demand. The "safety" constraints > it places on the code you generate are substantial. If you were even > allowed to run the code you want, the performance goal would be demolished. "Demolished" is probably a too strong word; The Mono JIT they ported to NaCl only slowed down something like 7%. (Not going through the PNaCl layer but just x86 nacl code.) So that is not that bad... However, > But worse, you've also demolished the "run anywhere" goal from the > outset, by limiting yourself to browsers that support NaCl. And I don't > see how to meet this goal with any browser-plugin approach. There just > isn't a widely-supported mechanism anymore, after the death of the > Netscape-style plugin. Yes, this is a real issue. In that regard, asm.js has a better chance, but still trying to stay on the JavaScript level, and taking the advantage of JavaScript's JIT is a practical solution, even though it may not give us the real Cog performance. -- -- Yoshiki From Das.Linux at gmx.de Mon Jan 19 19:05:50 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 19 19:05:51 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: Message-ID: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> On 19.01.2015, at 18:34, Chris Muller wrote: > On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape wrote: > Hi all, > > > We store method source _solely_ in files (.sources/.changes). > Why? We have means to attach it to Compiled methods, in fact, more than one: > > > CompiledMethod allInstances size. "57766." > CompiledMethod allInstances count: [:m | m properties includesKey: #source]. "0." > CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. "0." > CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. "57700." > > > " also interesting " > (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) sortedCounts > {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . 2->#TempsNamesZip} > > > When doing some analysis on source code, it is a pain to _either_ > always go to disk for the source _or_ cache the code myself (which may > get out of sync sooon). > > If you're sending messages instead of viewing private innards, why is it a pain? What do you mean? Calling getSource on a CM goes 300km to disk instead of 1m to memory (metaphorically spoken) and when I do analysis on source code I typically do stuff like that a lot. And as developer I really dislike that I have to choose between either a) bad performance due to excessive IO (yes I want to access the source a lot) b) caching things myself when already two ways of storing them are available. > > Can't we just save the source code either via trailer or properties > on first access? > > -1. Why do I want all of those String's in my image? To do stuff to them. Like, analysing how many dots are in them, or how often someone crafts a Symbol. Analysis stuff. Currently, I have a separate structure that holds onto the code once retrieved from disk. But once the method change (eg, recompilation) I have to first detect, that it happened, and second flush and refill this cache. I find this tiresome. Best -Tobias > > > > > Best > -Tobias PS: HTML-mails f*ck up quotation levels in replies :( Apple mail just flattens them when I reply. Anyone knows a workaround? From Das.Linux at gmx.de Mon Jan 19 19:07:05 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 19 19:07:05 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> Message-ID: Hi, On 19.01.2015, at 18:37, Chris Muller wrote: > More scary is when they would encounter a corrupted (empty) package. That message is intending to help us debug why that is happening.. > We had this going on fore some while and I cannot remember what the fix was in this case. Anyway, an up-to-date Squeak 4.5 would surely help. Best -Tobias > On Mon, Jan 19, 2015 at 7:56 AM, Tobias Pape wrote: > Hey, > > can somebody please copy a vanilla yet recent 4.5 to the > ftp/files server? The current one we can get there still > has this 'About to serialize empty package' weirdness and > we sure do not want to scare away people who just > hit the update button with such a message? > > Best > -Tobias From leves at elte.hu Mon Jan 19 19:29:05 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon Jan 19 19:29:07 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.599.mcz In-Reply-To: <1421660290104-4800317.post@n4.nabble.com> References: <1421655586903-4800301.post@n4.nabble.com> <1421659350139-4800312.post@n4.nabble.com> <1421660290104-4800317.post@n4.nabble.com> Message-ID: I never said it was easy. Another way to do it is to compact eagerly on removal (as it's done in Pharo). This gives better mass removal performance, and some of the code becomes significantly simpler. This results in further performance boost. Removal still takes O(n) time, which means mass removal is in O(n^2) time, but with a significantly smaller constant (~1/10), which improves the usability of the collection quite a bit: | n random array | n := 10000. random := Random seed: 36rSQUEAK. array := Array new: n streamContents: [ :stream | n timesRepeat: [ stream nextPut: (random nextInt: 1073741823) -> 1 ] ]. { OrderedDictionary. LinkedDictionary } collect: [ :class | Smalltalk garbageCollect. [ | instance | instance := class new. instance addAll: array. array do: [ :each | instance removeKey: each key ] ] timeToRun ]. "==> #(78 10)" (If n is 100k, then the result is still pretty bad: #(7055 136).) You can find these changes in the Inbox. Levente On Mon, 19 Jan 2015, Marcel Taeumel wrote: > Woah, managing such a lookup index between "array" and "order" is quite > complicated with the current implementation of Dictionary. :D > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-599-mcz-tp4800299p4800317.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From leves at elte.hu Mon Jan 19 19:32:38 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon Jan 19 19:32:44 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.599.mcz In-Reply-To: <1421660290104-4800317.post@n4.nabble.com> References: <1421655586903-4800301.post@n4.nabble.com> <1421659350139-4800312.post@n4.nabble.com> <1421660290104-4800317.post@n4.nabble.com> Message-ID: I never said it was easy. Another way to do it is to compact eagerly on removal (as it's done in Pharo). This gives better mass removal performance, and some of the code becomes significantly simpler. This results in further performance boost. Removal still takes O(n) time, which means mass removal is in O(n^2), but with a significantly smaller constant (~1/10), which improves the usability of the collection quite a bit: | n random array | n := 10000. random := Random seed: 36rSQUEAK. array := Array new: n streamContents: [ :stream | n timesRepeat: [ stream nextPut: (random nextInt: 1073741823) -> 1 ] ]. { OrderedDictionary. LinkedDictionary } collect: [ :class | Smalltalk garbageCollect. [ | instance | instance := class new. instance addAll: array. array do: [ :each | instance removeKey: each key ] ] timeToRun ]. "==> #(78 10)" (If n is 100k, then the result is still pretty bad: #(7055 136).) You can find these changes in the Inbox. Levente On Mon, 19 Jan 2015, Marcel Taeumel wrote: > Woah, managing such a lookup index between "array" and "order" is quite > complicated with the current implementation of Dictionary. :D > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-599-mcz-tp4800299p4800317.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From craig at netjam.org Mon Jan 19 19:40:24 2015 From: craig at netjam.org (Craig Latta) Date: Mon Jan 19 19:40:36 2015 Subject: [squeak-dev] re: compiled squeakjs In-Reply-To: References: <54BBEE3E.8080208@gmail.com> <211BA32F-6BE6-4734-B5BD-CE910CC258D3@gmail.com> Message-ID: > The Mono JIT they ported to NaCl only slowed down something like 7%. Well, it seems to me that Cog has higher performance aspirations than Mono, and is probably doing even more interesting instruction abuse. :) > ...asm.js has a better chance, but still trying to stay on the > JavaScript level, and taking the advantage of JavaScript's JIT is a > practical solution, even though it may not give us the real Cog > performance. Yeah, I think I could live with what Florin and Bert are discussing now. -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From commits at source.squeak.org Mon Jan 19 19:45:50 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon Jan 19 19:45:51 2015 Subject: [squeak-dev] The Inbox: Collections-ul.601.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Inbox: http://source.squeak.org/inbox/Collections-ul.601.mcz ==================== Summary ==================== Name: Collections-ul.601 Author: ul Time: 19 January 2015, 8:43:39.075 pm UUID: 02a48b9d-87a4-4ae0-9ae5-42a2f22e08ea Ancestors: Collections-mt.600 - Added FloatCollection >> #asFloatArray which gives slightly better performance. OrderedDictionary changes: - Compact eagerly on removal. This ensures that the order Array is always compact: its elements between 1..tally are the associations stored in the dictionary in insertion order. - Removed the lastIndex variable, because it's always the same as tally. - Since order is compact, access by index takes O(1) time, and to copy the order array, we can always use a fast primitive. - use nil in #sort instead of a block - #errorOutOfBounds is only understood by SequenceableCollections - avoid the use of fractions, use integer operations instead - don't sort the order array when it only has one element =============== Diff against Collections-mt.600 =============== Item was added: + ----- Method: FloatCollection>>asFloatArray (in category 'adding') ----- + asFloatArray + "Optimized version" + + ^array copyFrom: firstIndex to: lastIndex! Item was changed: Dictionary subclass: #OrderedDictionary + instanceVariableNames: 'order' - instanceVariableNames: 'order lastIndex' classVariableNames: '' poolDictionaries: '' category: 'Collections-Sequenceable'! !OrderedDictionary commentStamp: 'mt 1/16/2015 10:42' prior: 0! I am an ordered dictionary. I have an additional index (called 'order') to keep track of the insertion order of my associations. The read access is not affected by the additional index. The index is updated in O(1) [time] when inserting new keys. For present keys, that insertion involves actions in O(n) to move the respective element to the end of the order. The growth operation compacts the index and takes O(n) additional time. NOTE: This is still no instance of SequenceableCollection. Having this, some protocols are missing and may require working on #associations, which is an Array and thus sequenceable.! Item was changed: ----- Method: OrderedDictionary>>associationsDo: (in category 'enumerating') ----- associationsDo: aBlock "Iterate over the order instead of the internal array." + order from: 1 to: tally do: aBlock! - lastIndex = 0 ifTrue: [^ self]. - 1 to: lastIndex do: [:index | - (order at: index) ifNotNil: [:element | - aBlock value: element]].! Item was changed: ----- Method: OrderedDictionary>>atIndex: (in category 'accessing') ----- atIndex: integer + integer > tally ifTrue: [ self error: 'indices are out of bounds' ]. + ^order at: integer! - ^ self atIndex: integer ifAbsent: [self errorOutOfBounds]! Item was changed: ----- Method: OrderedDictionary>>atIndex:ifAbsent: (in category 'accessing') ----- atIndex: integer ifAbsent: exceptionBlock "As we are sequenceable, provide index-based access." + integer > tally ifTrue: [ ^exceptionBlock value ]. + ^order at: integer ifAbsent: exceptionBlock! - | found | - found := 0. - self associationsDo: [:element | - (found := found + 1) = integer ifTrue: [ - ^ element]]. - - ^ exceptionBlock value! Item was changed: ----- Method: OrderedDictionary>>atNewIndex:put: (in category 'private') ----- atNewIndex: index put: anObject + super atNewIndex: index put: anObject. + order at: tally put: anObject + ! - lastIndex = order size ifTrue: [ - self fixEmptySlots]. - - lastIndex := lastIndex + 1. - order at: lastIndex put: anObject. - - super atNewIndex: index put: anObject.! Item was changed: ----- Method: OrderedDictionary>>copyFrom:to: (in category 'copying') ----- copyFrom: startIndex to: endIndex "Answer a copy of the receiver that contains elements from position startIndex to endIndex." + | result | + result := self class new: endIndex + startIndex + 1. + order from: startIndex to: endIndex do: [ :association | + result add: association copy ]. + ^result! - self fixEmptySlots. - ^ self shallowCopy postCopyFrom: startIndex to: endIndex! Item was removed: - ----- Method: OrderedDictionary>>fillOrderFrom: (in category 'private') ----- - fillOrderFrom: anArray - - | arraySize | - arraySize := lastIndex. - lastIndex := 0. - 1 to: arraySize do: [:index | - (anArray at: index) ifNotNil: [:object | - lastIndex := lastIndex + 1. - order at: lastIndex put: object]].! Item was removed: - ----- Method: OrderedDictionary>>fixEmptySlots (in category 'private') ----- - fixEmptySlots - "Remove all nil slots in the order index to avoid overflow." - - lastIndex = tally ifTrue: [^ self]. - self fillOrderFrom: order.! Item was changed: ----- Method: OrderedDictionary>>growTo: (in category 'private') ----- growTo: anInteger | oldOrder | super growTo: anInteger. oldOrder := order. "Grow only to 75%. See #atNewIndex:put: in HashedCollection." + order := self class arrayType new: anInteger + 1 * 3 // 4. + order + replaceFrom: 1 + to: tally + with: oldOrder + startingAt: 1! - order := self class arrayType new: (anInteger * (3/4)) ceiling. - self fillOrderFrom: oldOrder.! Item was changed: ----- Method: OrderedDictionary>>initialize: (in category 'private') ----- initialize: n super initialize: n. + order := self class arrayType new: n + 1 * 3 // 4! - order := self class arrayType new: (n * (3/4)) ceiling. - lastIndex := 0.! Item was changed: ----- Method: OrderedDictionary>>isSorted (in category 'sorting') ----- isSorted + "Return true if the receiver is sorted by #<=." - "Return true if the receiver's keys are sorted by #<=." - self fixEmptySlots. ^ order isSortedBetween: 1 + and: tally! - and: lastIndex! Item was changed: ----- Method: OrderedDictionary>>postCopy (in category 'copying') ----- postCopy "We must not copy associations again but retrieve them from the array, which is already a copy. See super." super postCopy. + order := order copy. + 1 to: tally do: [ :index | + order at: index put: (array at: (self scanFor: (order at: index) key)) ]! - order := order collect: [:association | - association ifNotNil: [array at: (self scanFor: association key)]].! Item was removed: - ----- Method: OrderedDictionary>>postCopyFrom:to: (in category 'copying') ----- - postCopyFrom: startIndex to: endIndex - "Adapted from SequenceableCollection and OrderedCollection." - - | oldOrder newArraySize newOrderSize | - newArraySize := self class goodPrimeAtLeast: ((endIndex - startIndex + 1) * (5/4) "add 25%") ceiling. - newOrderSize := (newArraySize * (3/4)) ceiling. "remove 25%" - - oldOrder := order. - order := self class arrayType new: newOrderSize. - array := self class arrayType new: newArraySize. - - startIndex to: endIndex do: [:index | | element | - element := (oldOrder at: index) copy. - order at: index - startIndex + 1 put: element. - array at: (self scanFor: element key) put: element]. - - lastIndex := endIndex - startIndex + 1. - tally := lastIndex. - - - ! Item was changed: ----- Method: OrderedDictionary>>removeKey:ifAbsent: (in category 'removing') ----- removeKey: key ifAbsent: aBlock + | result | + result := super removeKey: key ifAbsent: [ ^aBlock value ]. + (self scanOrderFor: key) ifNotNil: [ :index | + order + replaceFrom: index + to: tally + with: order + startingAt: index + 1 ]. + . order at: tally + 1 put: nil. + ^result! - (self scanOrderFor: key) ifNotNil: [:index | - order at: index put: nil]. - ^ super removeKey: key ifAbsent: aBlock! Item was changed: ----- Method: OrderedDictionary>>scanOrderFor: (in category 'private') ----- scanOrderFor: anObject + 1 to: tally do: [ :index | + (order at: index) key = anObject ifTrue: [ ^index ] ]. + ^nil! - 1 to: lastIndex do: [:index | - | element | - ((element := order at: index) notNil and: [anObject = element key]) - ifTrue: [^ index]]. - - ^ nil! Item was changed: ----- Method: OrderedDictionary>>sort (in category 'sorting') ----- sort + self sort: nil! - self sort: [:a1 :a2| a1 key <= a2 key].! Item was changed: ----- Method: OrderedDictionary>>sort: (in category 'sorting') ----- sort: aSortBlock "Like in OrderedCollection, sort the associations according to the sort block." + tally <= 1 ifTrue: [ ^self ]. + order + mergeSortFrom: 1 + to: tally + by: aSortBlock! - self ifNotEmpty: [ - self fixEmptySlots. - order - mergeSortFrom: 1 - to: lastIndex - by: aSortBlock].! From leves at elte.hu Mon Jan 19 19:50:09 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon Jan 19 19:50:13 2015 Subject: [squeak-dev] [Performance] #printString and Array ... (Example: LRUCache) In-Reply-To: <1421662033656-4800322.post@n4.nabble.com> References: <1421662033656-4800322.post@n4.nabble.com> Message-ID: It's because I wanted the changes to be minimal, so I kept the use of Arrays in LRUCache. The head variable points to a circular array structure (a circular doubly-linked list), so the only thing that stops infinite recursion is the 50k character limit in #printString. As Bert suggested, this recursion in printing can be avoided by using a custom class for the list nodes. Levente On Mon, 19 Jan 2015, Marcel Taeumel wrote: > Hi, there! > > c := LRUCache someInstance. > (c instVarNamed: #map) size. "47" > [(c instVarNamed: #head) printString size] timeToRun. "1825" > > If this cache grows, #printString gets very slow. > > c := LRUCache allInstances first. > (c instVarNamed: #map) size. "4952" > [(c instVarNamed: #head) printString size] timeToRun. "Well..." > > Any ideas how to fix that? > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/Performance-printString-and-Array-Example-LRUCache-tp4800322.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From asqueaker at gmail.com Mon Jan 19 20:10:26 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon Jan 19 20:10:29 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> Message-ID: I just downloaded Squeak4.5-13680.zip, unzipped it, and selected "Update Squeak". It updated to 13696 just fine; no errors. When are you seeing the empty mcz message? On Mon, Jan 19, 2015 at 1:07 PM, Tobias Pape wrote: > Hi, > > On 19.01.2015, at 18:37, Chris Muller wrote: > > > More scary is when they would encounter a corrupted (empty) package. > That message is intending to help us debug why that is happening.. > > > > We had this going on fore some while and I cannot > remember what the fix was in this case. Anyway, > an up-to-date Squeak 4.5 would surely help. > > Best > -Tobias > > > > > > On Mon, Jan 19, 2015 at 7:56 AM, Tobias Pape wrote: > > Hey, > > > > can somebody please copy a vanilla yet recent 4.5 to the > > ftp/files server? The current one we can get there still > > has this 'About to serialize empty package' weirdness and > > we sure do not want to scare away people who just > > hit the update button with such a message? > > > > Best > > -Tobias > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/eb17344f/attachment.htm From leves at elte.hu Mon Jan 19 20:51:38 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon Jan 19 20:51:41 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: On Mon, 19 Jan 2015, Tobias Pape wrote: > > On 19.01.2015, at 18:34, Chris Muller wrote: > >> On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape wrote: >> Hi all, >> >> >> We store method source _solely_ in files (.sources/.changes). >> Why? We have means to attach it to Compiled methods, in fact, more than one: >> >> >> CompiledMethod allInstances size. "57766." >> CompiledMethod allInstances count: [:m | m properties includesKey: #source]. "0." >> CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. "0." >> CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. "57700." >> >> >> " also interesting " >> (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) sortedCounts >> {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . 2->#TempsNamesZip} >> >> >> When doing some analysis on source code, it is a pain to _either_ >> always go to disk for the source _or_ cache the code myself (which may >> get out of sync sooon). >> >> If you're sending messages instead of viewing private innards, why is it a pain? > > What do you mean? > > Calling getSource on a CM goes 300km to disk instead of 1m to memory (metaphorically spoken) > and when I do analysis on source code I typically do stuff like that a lot. > And as developer I really dislike that I have to choose between either > > a) bad performance due to excessive IO (yes I want to access the source a lot) > b) caching things myself when already two ways of storing them are available. On today's machines you don't have to. Once you read the data from the disk, it'll be cached in memory. It would be faster to access the sources, if they were stored in a trailer, but that would bump the image size by about 15 MB (uncompressed), or 9 MB (compressed): | size compressedSize | size := compressedSize := 0. CurrentReadOnlySourceFiles cacheDuring: [ SystemNavigation default allSelectorsAndMethodsDo: [ :behavior :selector :method | | string compressed | string := method getSource asString. compressed := string squeakToUtf8 zipped. size := size + string byteSize + ((string size > 255) asBit + 1 * 4). compressedSize := compressedSize + compressed byteSize + ((compressed size > 255) asBit + 1 * 4) ] ]. { size. compressedSize }. "==> #(15003880 9057408)" > >> >> Can't we just save the source code either via trailer or properties >> on first access? >> >> -1. Why do I want all of those String's in my image? > > To do stuff to them. > Like, analysing how many dots are in them, or how often someone crafts a Symbol. > Analysis stuff. > Currently, I have a separate structure that holds onto the code once retrieved > from disk. But once the method change (eg, recompilation) I have to first detect, > that it happened, and second flush and refill this cache. I find this tiresome. Do you flush your cache selectively? Scanning all source code for a given pattern takes less than a second (~800 ms) on my machine. What's your performance goal? Levente > > Best > -Tobias > >> >> >> >> >> Best >> -Tobias > > > > > > PS: HTML-mails f*ck up quotation levels in replies :( > Apple mail just flattens them when I reply. Anyone knows a workaround? > From Das.Linux at gmx.de Mon Jan 19 21:10:11 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 19 21:10:13 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: On 19.01.2015, at 21:51, Levente Uzonyi wrote: > On Mon, 19 Jan 2015, Tobias Pape wrote: > >> >> On 19.01.2015, at 18:34, Chris Muller wrote: >> >>> On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape wrote: >>> Hi all, >>> >>> >>> We store method source _solely_ in files (.sources/.changes). >>> Why? We have means to attach it to Compiled methods, in fact, more than one: >>> >>> >>> CompiledMethod allInstances size. "57766." >>> CompiledMethod allInstances count: [:m | m properties includesKey: #source]. "0." >>> CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. "0." >>> CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. "57700." >>> >>> >>> " also interesting " >>> (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) sortedCounts >>> {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . 2->#TempsNamesZip} >>> >>> >>> When doing some analysis on source code, it is a pain to _either_ >>> always go to disk for the source _or_ cache the code myself (which may >>> get out of sync sooon). >>> >>> If you're sending messages instead of viewing private innards, why is it a pain? >> >> What do you mean? >> >> Calling getSource on a CM goes 300km to disk instead of 1m to memory (metaphorically spoken) >> and when I do analysis on source code I typically do stuff like that a lot. >> And as developer I really dislike that I have to choose between either >> >> a) bad performance due to excessive IO (yes I want to access the source a lot) >> b) caching things myself when already two ways of storing them are available. > > On today's machines you don't have to. Once you read the data from the disk, it'll be cached in memory. It would be faster to access the sources, if they were stored in a trailer, but that would bump the image size by about 15 MB (uncompressed), or 9 MB (compressed): > I understand. But for a development image, I'd take that burden. > | size compressedSize | > size := compressedSize := 0. > CurrentReadOnlySourceFiles cacheDuring: [ > SystemNavigation default allSelectorsAndMethodsDo: [ :behavior :selector :method | > | string compressed | > string := method getSource asString. > compressed := string squeakToUtf8 zipped. > size := size + string byteSize + ((string size > 255) asBit + 1 * 4). > compressedSize := compressedSize + compressed byteSize + ((compressed size > 255) asBit + 1 * 4) ] ]. > { size. compressedSize }. > > "==> #(15003880 9057408)" What I am actually wondering about, there are two completely different ways to _access_ source stored in the image but no way to actually _store_ it there. > >> >>> >>> Can't we just save the source code either via trailer or properties >>> on first access? >>> >>> -1. Why do I want all of those String's in my image? >> >> To do stuff to them. >> Like, analysing how many dots are in them, or how often someone crafts a Symbol. >> Analysis stuff. >> Currently, I have a separate structure that holds onto the code once retrieved >> from disk. But once the method change (eg, recompilation) I have to first detect, >> that it happened, and second flush and refill this cache. I find this tiresome. > > Do you flush your cache selectively? No, I can't for reasons :) > > Scanning all source code for a given pattern takes less than a second (~800 ms) on my machine. What's your performance goal? I have ~15.000 Methods that I have to compare line by line against each other. Doing that by going to the filesystem just kills it. Best -Tobias From nicolas.cellier.aka.nice at gmail.com Mon Jan 19 21:31:01 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Mon Jan 19 21:31:03 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: Hi Tobias, are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] This is to workaround the readOnlyCopy used for thread safety which is the main killer of performance... 2015-01-19 22:10 GMT+01:00 Tobias Pape : > > On 19.01.2015, at 21:51, Levente Uzonyi wrote: > > > On Mon, 19 Jan 2015, Tobias Pape wrote: > > > >> > >> On 19.01.2015, at 18:34, Chris Muller wrote: > >> > >>> On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape wrote: > >>> Hi all, > >>> > >>> > >>> We store method source _solely_ in files (.sources/.changes). > >>> Why? We have means to attach it to Compiled methods, in fact, more > than one: > >>> > >>> > >>> CompiledMethod allInstances size. "57766." > >>> CompiledMethod allInstances count: [:m | m properties includesKey: > #source]. "0." > >>> CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. > "0." > >>> CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. > "57700." > >>> > >>> > >>> " also interesting " > >>> (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) > sortedCounts > >>> {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . > 2->#TempsNamesZip} > >>> > >>> > >>> When doing some analysis on source code, it is a pain to _either_ > >>> always go to disk for the source _or_ cache the code myself (which may > >>> get out of sync sooon). > >>> > >>> If you're sending messages instead of viewing private innards, why is > it a pain? > >> > >> What do you mean? > >> > >> Calling getSource on a CM goes 300km to disk instead of 1m to memory > (metaphorically spoken) > >> and when I do analysis on source code I typically do stuff like that a > lot. > >> And as developer I really dislike that I have to choose between either > >> > >> a) bad performance due to excessive IO (yes I want to access the source > a lot) > >> b) caching things myself when already two ways of storing them are > available. > > > > On today's machines you don't have to. Once you read the data from the > disk, it'll be cached in memory. It would be faster to access the sources, > if they were stored in a trailer, but that would bump the image size by > about 15 MB (uncompressed), or 9 MB (compressed): > > > > I understand. But for a development image, I'd take that burden. > > > | size compressedSize | > > size := compressedSize := 0. > > CurrentReadOnlySourceFiles cacheDuring: [ > > SystemNavigation default allSelectorsAndMethodsDo: [ :behavior > :selector :method | > > | string compressed | > > string := method getSource asString. > > compressed := string squeakToUtf8 zipped. > > size := size + string byteSize + ((string size > 255) > asBit + 1 * 4). > > compressedSize := compressedSize + compressed byteSize + > ((compressed size > 255) asBit + 1 * 4) ] ]. > > { size. compressedSize }. > > > > "==> #(15003880 9057408)" > > > What I am actually wondering about, > there are two completely different ways to _access_ source stored in the > image > but no way to actually _store_ it there. > > > > >> > >>> > >>> Can't we just save the source code either via trailer or properties > >>> on first access? > >>> > >>> -1. Why do I want all of those String's in my image? > >> > >> To do stuff to them. > >> Like, analysing how many dots are in them, or how often someone crafts > a Symbol. > >> Analysis stuff. > >> Currently, I have a separate structure that holds onto the code once > retrieved > >> from disk. But once the method change (eg, recompilation) I have to > first detect, > >> that it happened, and second flush and refill this cache. I find this > tiresome. > > > > Do you flush your cache selectively? > > No, I can't for reasons :) > > > > > Scanning all source code for a given pattern takes less than a second > (~800 ms) on my machine. What's your performance goal? > > I have ~15.000 Methods that I have to compare line by line against each > other. > Doing that by going to the filesystem just kills it. > > > Best > -Tobias > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/be40e5c4/attachment.htm From Das.Linux at gmx.de Mon Jan 19 21:40:40 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 19 21:40:40 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: <9950DA27-88A9-4C82-8C59-0A589D9280EC@gmx.de> Hi, On 19.01.2015, at 22:31, Nicolas Cellier wrote: > Hi Tobias, > are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] > This is to workaround the readOnlyCopy used for thread safety which is the main killer of performance... > No, I was not aware. :) Thanks for that information. Best -Tobias > 2015-01-19 22:10 GMT+01:00 Tobias Pape : > > On 19.01.2015, at 21:51, Levente Uzonyi wrote: > > > On Mon, 19 Jan 2015, Tobias Pape wrote: > > > >> > >> On 19.01.2015, at 18:34, Chris Muller wrote: > >> > >>> On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape wrote: > >>> Hi all, > >>> > >>> > >>> We store method source _solely_ in files (.sources/.changes). > >>> Why? We have means to attach it to Compiled methods, in fact, more than one: > >>> > >>> > >>> CompiledMethod allInstances size. "57766." > >>> CompiledMethod allInstances count: [:m | m properties includesKey: #source]. "0." > >>> CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. "0." > >>> CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. "57700." > >>> > >>> > >>> " also interesting " > >>> (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) sortedCounts > >>> {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . 2->#TempsNamesZip} > >>> > >>> > >>> When doing some analysis on source code, it is a pain to _either_ > >>> always go to disk for the source _or_ cache the code myself (which may > >>> get out of sync sooon). > >>> > >>> If you're sending messages instead of viewing private innards, why is it a pain? > >> > >> What do you mean? > >> > >> Calling getSource on a CM goes 300km to disk instead of 1m to memory (metaphorically spoken) > >> and when I do analysis on source code I typically do stuff like that a lot. > >> And as developer I really dislike that I have to choose between either > >> > >> a) bad performance due to excessive IO (yes I want to access the source a lot) > >> b) caching things myself when already two ways of storing them are available. > > > > On today's machines you don't have to. Once you read the data from the disk, it'll be cached in memory. It would be faster to access the sources, if they were stored in a trailer, but that would bump the image size by about 15 MB (uncompressed), or 9 MB (compressed): > > > > I understand. But for a development image, I'd take that burden. > > > | size compressedSize | > > size := compressedSize := 0. > > CurrentReadOnlySourceFiles cacheDuring: [ > > SystemNavigation default allSelectorsAndMethodsDo: [ :behavior :selector :method | > > | string compressed | > > string := method getSource asString. > > compressed := string squeakToUtf8 zipped. > > size := size + string byteSize + ((string size > 255) asBit + 1 * 4). > > compressedSize := compressedSize + compressed byteSize + ((compressed size > 255) asBit + 1 * 4) ] ]. > > { size. compressedSize }. > > > > "==> #(15003880 9057408)" > > > What I am actually wondering about, > there are two completely different ways to _access_ source stored in the image > but no way to actually _store_ it there. > > > > >> > >>> > >>> Can't we just save the source code either via trailer or properties > >>> on first access? > >>> > >>> -1. Why do I want all of those String's in my image? > >> > >> To do stuff to them. > >> Like, analysing how many dots are in them, or how often someone crafts a Symbol. > >> Analysis stuff. > >> Currently, I have a separate structure that holds onto the code once retrieved > >> from disk. But once the method change (eg, recompilation) I have to first detect, > >> that it happened, and second flush and refill this cache. I find this tiresome. > > > > Do you flush your cache selectively? > > No, I can't for reasons :) > > > > > Scanning all source code for a given pattern takes less than a second (~800 ms) on my machine. What's your performance goal? > > I have ~15.000 Methods that I have to compare line by line against each other. > Doing that by going to the filesystem just kills it. > > > Best > -Tobias From leves at elte.hu Mon Jan 19 21:56:06 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon Jan 19 21:56:10 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: On Mon, 19 Jan 2015, Tobias Pape wrote: > > On 19.01.2015, at 21:51, Levente Uzonyi wrote: > >> On Mon, 19 Jan 2015, Tobias Pape wrote: >> >>> >>> On 19.01.2015, at 18:34, Chris Muller wrote: >>> >>>> On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape wrote: >>>> Hi all, >>>> >>>> >>>> We store method source _solely_ in files (.sources/.changes). >>>> Why? We have means to attach it to Compiled methods, in fact, more than one: >>>> >>>> >>>> CompiledMethod allInstances size. "57766." >>>> CompiledMethod allInstances count: [:m | m properties includesKey: #source]. "0." >>>> CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. "0." >>>> CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. "57700." >>>> >>>> >>>> " also interesting " >>>> (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) sortedCounts >>>> {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . 2->#TempsNamesZip} >>>> >>>> >>>> When doing some analysis on source code, it is a pain to _either_ >>>> always go to disk for the source _or_ cache the code myself (which may >>>> get out of sync sooon). >>>> >>>> If you're sending messages instead of viewing private innards, why is it a pain? >>> >>> What do you mean? >>> >>> Calling getSource on a CM goes 300km to disk instead of 1m to memory (metaphorically spoken) >>> and when I do analysis on source code I typically do stuff like that a lot. >>> And as developer I really dislike that I have to choose between either >>> >>> a) bad performance due to excessive IO (yes I want to access the source a lot) >>> b) caching things myself when already two ways of storing them are available. >> >> On today's machines you don't have to. Once you read the data from the disk, it'll be cached in memory. It would be faster to access the sources, if they were stored in a trailer, but that would bump the image size by about 15 MB (uncompressed), or 9 MB (compressed): >> > > I understand. But for a development image, I'd take that burden. > >> | size compressedSize | >> size := compressedSize := 0. >> CurrentReadOnlySourceFiles cacheDuring: [ >> SystemNavigation default allSelectorsAndMethodsDo: [ :behavior :selector :method | >> | string compressed | >> string := method getSource asString. >> compressed := string squeakToUtf8 zipped. >> size := size + string byteSize + ((string size > 255) asBit + 1 * 4). >> compressedSize := compressedSize + compressed byteSize + ((compressed size > 255) asBit + 1 * 4) ] ]. >> { size. compressedSize }. >> >> "==> #(15003880 9057408)" > > > What I am actually wondering about, > there are two completely different ways to _access_ source stored in the image > but no way to actually _store_ it there. You can use #dropSourcePointer to embed the source of a method in the image. For 15k methods you better swap the methods with custom code which converts them in a single batch. > >> >>> >>>> >>>> Can't we just save the source code either via trailer or properties >>>> on first access? >>>> >>>> -1. Why do I want all of those String's in my image? >>> >>> To do stuff to them. >>> Like, analysing how many dots are in them, or how often someone crafts a Symbol. >>> Analysis stuff. >>> Currently, I have a separate structure that holds onto the code once retrieved >>> from disk. But once the method change (eg, recompilation) I have to first detect, >>> that it happened, and second flush and refill this cache. I find this tiresome. >> >> Do you flush your cache selectively? > > No, I can't for reasons :) > >> >> Scanning all source code for a given pattern takes less than a second (~800 ms) on my machine. What's your performance goal? > > I have ~15.000 Methods that I have to compare line by line against each other. > Doing that by going to the filesystem just kills it. It's hard to tell much without knowing the exact problem. If you want to take a method and compare it with all previously processed methods line by line, then you can create a dictionary which maps lines to methods (or method-line number pairs). Levente > > > Best > -Tobias > > > From Das.Linux at gmx.de Mon Jan 19 21:56:51 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 19 21:56:52 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> Message-ID: On 19.01.2015, at 21:10, Chris Muller wrote: > I just downloaded Squeak4.5-13680.zip, unzipped it, and selected "Update Squeak". It updated to 13696 just fine; no errors. > > When are you seeing the empty mcz message? > There: https://imgur.com/a/IIOk1 > > On Mon, Jan 19, 2015 at 1:07 PM, Tobias Pape wrote: > Hi, > > On 19.01.2015, at 18:37, Chris Muller wrote: > >> More scary is when they would encounter a corrupted (empty) package. That message is intending to help us debug why that is happening.. >> > > We had this going on fore some while and I cannot > remember what the fix was in this case. Anyway, > an up-to-date Squeak 4.5 would surely help. > > Best > -Tobias > > > > >> On Mon, Jan 19, 2015 at 7:56 AM, Tobias Pape wrote: >> Hey, >> >> can somebody please copy a vanilla yet recent 4.5 to the >> ftp/files server? The current one we can get there still >> has this 'About to serialize empty package' weirdness and >> we sure do not want to scare away people who just >> hit the update button with such a message? >> >> Best >> -Tobias From leves at elte.hu Mon Jan 19 21:58:44 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon Jan 19 21:58:48 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: Yup, that makes a difference. Too bad it's still notification based, instead of being a process local variable. That would make it even faster. Levente On Mon, 19 Jan 2015, Nicolas Cellier wrote: > Hi Tobias, > are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] > This is to workaround the readOnlyCopy used for thread safety which is the main killer of performance... > > 2015-01-19 22:10 GMT+01:00 Tobias Pape : > > On 19.01.2015, at 21:51, Levente Uzonyi wrote: > > > On Mon, 19 Jan 2015, Tobias Pape wrote: > > > >> > >> On 19.01.2015, at 18:34, Chris Muller wrote: > >> > >>> On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape wrote: > >>> Hi all, > >>> > >>> > >>> We store method source _solely_ in files (.sources/.changes). > >>> Why? We have means to attach it to Compiled methods, in fact, more than one: > >>> > >>> > >>> CompiledMethod allInstances size. "57766." > >>> CompiledMethod allInstances count: [:m | m properties includesKey: #source].? "0." > >>> CompiledMethod allInstances count: [:m | m trailer sourceCode notNil]. "0." > >>> CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. "57700." > >>> > >>> > >>> " also interesting " > >>> (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) sortedCounts > >>> {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . 2->#TempsNamesZip} > >>> > >>> > >>> When doing some analysis on source code, it is a pain to _either_ > >>> always go to disk for the source _or_ cache the code myself (which may > >>> get out of sync sooon). > >>> > >>> If you're sending messages instead of viewing private innards, why is it a pain? > >> > >> What do you mean? > >> > >> Calling getSource on a CM goes 300km to disk instead of 1m to memory (metaphorically spoken) > >> and when I do analysis on source code I typically do stuff like that a lot. > >> And as developer I really dislike that I have to choose between either > >> > >> a) bad performance due to excessive IO (yes I want to access the source a lot) > >> b) caching things myself when already two ways of storing them are available. > > > > On today's machines you don't have to. Once you read the data from the disk, it'll be cached in memory. It would be faster to access the sources, if they were stored in a trailer, but that would > bump the image size by about 15 MB (uncompressed), or 9 MB (compressed): > > > > I understand. But for a development image, I'd take that burden. > > > | size compressedSize | > > size := compressedSize := 0. > > CurrentReadOnlySourceFiles cacheDuring: [ > >? ? ? ?SystemNavigation default allSelectorsAndMethodsDo: [ :behavior :selector :method | > >? ? ? ? ? ? ? ?| string compressed | > >? ? ? ? ? ? ? ?string := method getSource asString. > >? ? ? ? ? ? ? ?compressed := string squeakToUtf8 zipped. > >? ? ? ? ? ? ? ?size := size + string byteSize + ((string size > 255) asBit + 1 * 4). > >? ? ? ? ? ? ? ?compressedSize := compressedSize + compressed byteSize + ((compressed size > 255) asBit + 1 * 4) ] ]. > > { size. compressedSize }. > > > > "==> #(15003880 9057408)" > > > What I am actually wondering about, > there are two completely different ways to _access_ source stored in the image > but no way to actually _store_ it there. > > > > >> > >>> > >>>? Can't we just save the source code either via trailer or properties > >>> on first access? > >>> > >>> -1.? Why do I want all of those String's in my image? > >> > >> To do stuff to them. > >> Like, analysing how many dots are in them, or how often someone crafts a Symbol. > >> Analysis stuff. > >> Currently, I have a separate structure that holds onto the code once retrieved > >> from disk. But once the method change (eg, recompilation) I have to first detect, > >> that it happened, and second flush and refill this cache. I find this tiresome. > > > > Do you flush your cache selectively? > > No, I can't for reasons :) > > > > > Scanning all source code for a given pattern takes less than a second (~800 ms) on my machine. What's your performance goal? > > I have ~15.000 Methods that I have to compare line by line against each other. > Doing that by going to the filesystem just kills it. > > > Best > ? ? ? ? -Tobias > > > > > From Das.Linux at gmx.de Mon Jan 19 22:17:39 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 19 22:17:40 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: Hey On 19.01.2015, at 22:56, Levente Uzonyi wrote: > On Mon, 19 Jan 2015, Tobias Pape wrote: > >> >> On 19.01.2015, at 21:51, Levente Uzonyi wrote: >> >>> On Mon, 19 Jan 2015, Tobias Pape wrote: >>> >> [?] >> What I am actually wondering about, >> there are two completely different ways to _access_ source stored in the image >> but no way to actually _store_ it there. > > You can use #dropSourcePointer to embed the source of a method in the image. For 15k methods you better swap the methods with custom code which converts them in a single batch. ah. This goes into the trailer then? I think I actually misread some parts in CompiledMethod>>#sourceCode: and thought that code was dysfunctional. My bad. Thanks for resolving this mystery. The second one still remains: CompiledMethod>> getSourceFor: selector in: class "Retrieve or reconstruct the source code for this method." | trailer source | (self properties includesKey: #source) ifTrue: [^self properties at: #source]. trailer := self trailer. " ... " Judging from my image, this is never written, right? > >> >>> >>>> >>>>> >>>>> Can't we just save the source code either via trailer or properties >>>>> on first access? >>>>> >>>>> -1. Why do I want all of those String's in my image? >>>> >>>> To do stuff to them. >>>> Like, analysing how many dots are in them, or how often someone crafts a Symbol. >>>> Analysis stuff. >>>> Currently, I have a separate structure that holds onto the code once retrieved >>>> from disk. But once the method change (eg, recompilation) I have to first detect, >>>> that it happened, and second flush and refill this cache. I find this tiresome. >>> >>> Do you flush your cache selectively? >> >> No, I can't for reasons :) >> >>> >>> Scanning all source code for a given pattern takes less than a second (~800 ms) on my machine. What's your performance goal? >> >> I have ~15.000 Methods that I have to compare line by line against each other. >> Doing that by going to the filesystem just kills it. > > It's hard to tell much without knowing the exact problem. If you want to take a method and compare it with all previously processed methods line by line, then you can create a dictionary which maps lines to methods (or method-line number pairs). > Well what I did in the meantime (besides caching the source) was introducing an intermediate object that a) holds onto the string for a line of source code b) compares by identity and not its string's content and c) is interned via a Dictionary on the class side. (a bit like symbols but I didn't want to misuse them) That way, I can resort to identity based duplicate checking :) Best -Tobias > Levente > >> >> >> Best >> -Tobias From asqueaker at gmail.com Mon Jan 19 22:54:59 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon Jan 19 22:55:02 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> Message-ID: I deleted my package-cache and now I see it. It looks like this check was since moved higher where it would not get triggered unnecessarily. So its fixed in trunk. Unfortunate ofr the old version to be in 4.5 along with other issues too. Hopefully we'll find energy to make another 4.5 at least we know 4.6 won't have it. On Mon, Jan 19, 2015 at 3:56 PM, Tobias Pape wrote: > > On 19.01.2015, at 21:10, Chris Muller wrote: > > > I just downloaded Squeak4.5-13680.zip, unzipped it, and selected "Update > Squeak". It updated to 13696 just fine; no errors. > > > > When are you seeing the empty mcz message? > > > > There: > > https://imgur.com/a/IIOk1 > > > > > > On Mon, Jan 19, 2015 at 1:07 PM, Tobias Pape wrote: > > Hi, > > > > On 19.01.2015, at 18:37, Chris Muller wrote: > > > >> More scary is when they would encounter a corrupted (empty) package. > That message is intending to help us debug why that is happening.. > >> > > > > We had this going on fore some while and I cannot > > remember what the fix was in this case. Anyway, > > an up-to-date Squeak 4.5 would surely help. > > > > Best > > -Tobias > > > > > > > > > >> On Mon, Jan 19, 2015 at 7:56 AM, Tobias Pape wrote: > >> Hey, > >> > >> can somebody please copy a vanilla yet recent 4.5 to the > >> ftp/files server? The current one we can get there still > >> has this 'About to serialize empty package' weirdness and > >> we sure do not want to scare away people who just > >> hit the update button with such a message? > >> > >> Best > >> -Tobias > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/d7d41247/attachment.htm From Das.Linux at gmx.de Mon Jan 19 23:10:48 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon Jan 19 23:10:51 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> Message-ID: <37F57D76-72B0-4817-A52F-219838436498@gmx.de> On 19.01.2015, at 23:54, Chris Muller wrote: > I deleted my package-cache and now I see it. > > It looks like this check was since moved higher where it would not get triggered unnecessarily. So its fixed in trunk. Unfortunate ofr the old version to be in 4.5 along with other issues too. Hopefully we'll find energy to make another 4.5 at least we know 4.6 won't have it. What's necessary besides -update -cleanup (if even necessary) -upload? Best -Tobias From ma.chris.m at gmail.com Tue Jan 20 00:04:02 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Tue Jan 20 00:04:04 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: <37F57D76-72B0-4817-A52F-219838436498@gmx.de> References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> <37F57D76-72B0-4817-A52F-219838436498@gmx.de> Message-ID: - Backport all the fixes we need (this + the rename fix + ??) - Update the All-In-One. - Someone must sign All-In-One. - Test signed All-In-One (windows, Linux, Mac). - Upload All-In-One. - Upload plain image + changes. On Mon, Jan 19, 2015 at 5:10 PM, Tobias Pape wrote: > > On 19.01.2015, at 23:54, Chris Muller wrote: > >> I deleted my package-cache and now I see it. >> >> It looks like this check was since moved higher where it would not get triggered unnecessarily. So its fixed in trunk. Unfortunate ofr the old version to be in 4.5 along with other issues too. Hopefully we'll find energy to make another 4.5 at least we know 4.6 won't have it. > > What's necessary besides > -update > -cleanup (if even necessary) > -upload? > > Best > -Tobias > From Das.Linux at gmx.de Tue Jan 20 00:10:48 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue Jan 20 00:10:50 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> <37F57D76-72B0-4817-A52F-219838436498@gmx.de> Message-ID: <47D05015-792D-4337-9E13-C8E6DEA25954@gmx.de> On 20.01.2015, at 01:04, Chris Muller wrote: > - Backport all the fixes we need (this + the rename fix + ??) > - Update the All-In-One. > - Someone must sign All-In-One. > - Test signed All-In-One (windows, Linux, Mac). > - Upload All-In-One. > - Upload plain image + changes. > I understand. I just asked for an image where someone has hit the update button. But yes, somewhen? we definitely should do these things :) Bets -Tobias > > On Mon, Jan 19, 2015 at 5:10 PM, Tobias Pape wrote: >> >> On 19.01.2015, at 23:54, Chris Muller wrote: >> >>> I deleted my package-cache and now I see it. >>> >>> It looks like this check was since moved higher where it would not get triggered unnecessarily. So its fixed in trunk. Unfortunate ofr the old version to be in 4.5 along with other issues too. Hopefully we'll find energy to make another 4.5 at least we know 4.6 won't have it. >> >> What's necessary besides >> -update >> -cleanup (if even necessary) >> -upload? >> >> Best >> -Tobias From eliot.miranda at gmail.com Tue Jan 20 00:29:31 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 20 00:29:36 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> wrote: > Hi Tobias, > are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] > This is to workaround the readOnlyCopy used for thread safety which is the > main killer of performance... > IMO this is a bug. We should simply have a single read-only copy of each sources file and modify the debugger to either save and restore the state of a read-only copy around accessing source, or use its own read-only copy (except that the latter approach breaks when one debugs the debugger). The difference in performance between using CurrentReadOnlySourceFiles cacheDuring: [...] and not in anything that accesses source is huge. And CurrentReadOnlySourceFiles cacheDuring: [...] is a /lot/ of verbiage to type in doits, and a sign that something is wrong. > > 2015-01-19 22:10 GMT+01:00 Tobias Pape : > >> >> On 19.01.2015, at 21:51, Levente Uzonyi wrote: >> >> > On Mon, 19 Jan 2015, Tobias Pape wrote: >> > >> >> >> >> On 19.01.2015, at 18:34, Chris Muller wrote: >> >> >> >>> On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape >> wrote: >> >>> Hi all, >> >>> >> >>> >> >>> We store method source _solely_ in files (.sources/.changes). >> >>> Why? We have means to attach it to Compiled methods, in fact, more >> than one: >> >>> >> >>> >> >>> CompiledMethod allInstances size. "57766." >> >>> CompiledMethod allInstances count: [:m | m properties includesKey: >> #source]. "0." >> >>> CompiledMethod allInstances count: [:m | m trailer sourceCode >> notNil]. "0." >> >>> CompiledMethod allInstances count: [:m | m trailer hasSourcePointer]. >> "57700." >> >>> >> >>> >> >>> " also interesting " >> >>> (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) >> sortedCounts >> >>> {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . >> 2->#TempsNamesZip} >> >>> >> >>> >> >>> When doing some analysis on source code, it is a pain to _either_ >> >>> always go to disk for the source _or_ cache the code myself (which may >> >>> get out of sync sooon). >> >>> >> >>> If you're sending messages instead of viewing private innards, why is >> it a pain? >> >> >> >> What do you mean? >> >> >> >> Calling getSource on a CM goes 300km to disk instead of 1m to memory >> (metaphorically spoken) >> >> and when I do analysis on source code I typically do stuff like that a >> lot. >> >> And as developer I really dislike that I have to choose between either >> >> >> >> a) bad performance due to excessive IO (yes I want to access the >> source a lot) >> >> b) caching things myself when already two ways of storing them are >> available. >> > >> > On today's machines you don't have to. Once you read the data from the >> disk, it'll be cached in memory. It would be faster to access the sources, >> if they were stored in a trailer, but that would bump the image size by >> about 15 MB (uncompressed), or 9 MB (compressed): >> > >> >> I understand. But for a development image, I'd take that burden. >> >> > | size compressedSize | >> > size := compressedSize := 0. >> > CurrentReadOnlySourceFiles cacheDuring: [ >> > SystemNavigation default allSelectorsAndMethodsDo: [ :behavior >> :selector :method | >> > | string compressed | >> > string := method getSource asString. >> > compressed := string squeakToUtf8 zipped. >> > size := size + string byteSize + ((string size > 255) >> asBit + 1 * 4). >> > compressedSize := compressedSize + compressed byteSize + >> ((compressed size > 255) asBit + 1 * 4) ] ]. >> > { size. compressedSize }. >> > >> > "==> #(15003880 9057408)" >> >> >> What I am actually wondering about, >> there are two completely different ways to _access_ source stored in the >> image >> but no way to actually _store_ it there. >> >> > >> >> >> >>> >> >>> Can't we just save the source code either via trailer or properties >> >>> on first access? >> >>> >> >>> -1. Why do I want all of those String's in my image? >> >> >> >> To do stuff to them. >> >> Like, analysing how many dots are in them, or how often someone crafts >> a Symbol. >> >> Analysis stuff. >> >> Currently, I have a separate structure that holds onto the code once >> retrieved >> >> from disk. But once the method change (eg, recompilation) I have to >> first detect, >> >> that it happened, and second flush and refill this cache. I find this >> tiresome. >> > >> > Do you flush your cache selectively? >> >> No, I can't for reasons :) >> >> > >> > Scanning all source code for a given pattern takes less than a second >> (~800 ms) on my machine. What's your performance goal? >> >> I have ~15.000 Methods that I have to compare line by line against each >> other. >> Doing that by going to the filesystem just kills it. >> >> >> Best >> -Tobias > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/43f5fca8/attachment.htm From eliot.miranda at gmail.com Tue Jan 20 00:30:35 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 20 00:30:37 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: <47D05015-792D-4337-9E13-C8E6DEA25954@gmx.de> References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> <37F57D76-72B0-4817-A52F-219838436498@gmx.de> <47D05015-792D-4337-9E13-C8E6DEA25954@gmx.de> Message-ID: On Mon, Jan 19, 2015 at 4:10 PM, Tobias Pape wrote: > > On 20.01.2015, at 01:04, Chris Muller wrote: > > > - Backport all the fixes we need (this + the rename fix + ??) > > - Update the All-In-One. > > - Someone must sign All-In-One. > > - Test signed All-In-One (windows, Linux, Mac). > > - Upload All-In-One. > > - Upload plain image + changes. > > > > I understand. > I just asked for an image where someone has hit the update button. > But yes, somewhen? we definitely should do these things :) > ANy old 4.5 image or the release one? > > Bets > -Tobias > > > > > > On Mon, Jan 19, 2015 at 5:10 PM, Tobias Pape wrote: > >> > >> On 19.01.2015, at 23:54, Chris Muller wrote: > >> > >>> I deleted my package-cache and now I see it. > >>> > >>> It looks like this check was since moved higher where it would not get > triggered unnecessarily. So its fixed in trunk. Unfortunate ofr the old > version to be in 4.5 along with other issues too. Hopefully we'll find > energy to make another 4.5 at least we know 4.6 won't have it. > >> > >> What's necessary besides > >> -update > >> -cleanup (if even necessary) > >> -upload? > >> > >> Best > >> -Tobias > > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/703d7361/attachment-0001.htm From leves at elte.hu Tue Jan 20 01:09:21 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue Jan 20 01:09:25 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: On Mon, 19 Jan 2015, Eliot Miranda wrote: > > > On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier wrote: > Hi Tobias, > are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] > This is to workaround the readOnlyCopy used for thread safety which is the main killer of performance... > > > IMO this is a bug.? We should simply have a single read-only copy of each sources file and modify the debugger to either save and restore the state of a read-only copy around accessing source, or use its own > read-only copy (except that the latter approach breaks when one debugs the debugger).? The difference in performance between using CurrentReadOnlySourceFiles cacheDuring: [...] and not in anything that > accesses source is huge.? And CurrentReadOnlySourceFiles cacheDuring: [...] is a /lot/ of verbiage to type in doits, and a sign that something is wrong. How would using a single copy solve the concurrency issues? I think the real solution would be to use per process copies, which were initialized lazily, and were closed automatically after some time of inactivity. Levente From eliot.miranda at gmail.com Tue Jan 20 01:18:05 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 20 01:18:07 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: On Mon, Jan 19, 2015 at 5:09 PM, Levente Uzonyi wrote: > On Mon, 19 Jan 2015, Eliot Miranda wrote: > > >> >> On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier < >> nicolas.cellier.aka.nice@gmail.com> wrote: >> Hi Tobias, >> are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] >> This is to workaround the readOnlyCopy used for thread safety which is >> the main killer of performance... >> >> >> IMO this is a bug. We should simply have a single read-only copy of each >> sources file and modify the debugger to either save and restore the state >> of a read-only copy around accessing source, or use its own >> read-only copy (except that the latter approach breaks when one debugs >> the debugger). The difference in performance between using >> CurrentReadOnlySourceFiles cacheDuring: [...] and not in anything that >> accesses source is huge. And CurrentReadOnlySourceFiles cacheDuring: >> [...] is a /lot/ of verbiage to type in doits, and a sign that something is >> wrong. >> > > How would using a single copy solve the concurrency issues? > It wouldn't, but what issues are you seeing in concurrent source access? VW doesn't even have read-only copies and AFAICR we never had complaints about this. Is there really a thread-safety issue here? > > I think the real solution would be to use per process copies, which were > initialized lazily, and were closed automatically after some time of > inactivity. If concurrent access was really an issue then OK. But first I'd like some evidence that there's a real problem here. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150119/f7107990/attachment.htm From marcel.taeumel at student.hpi.uni-potsdam.de Tue Jan 20 06:53:20 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Tue Jan 20 06:56:38 2015 Subject: [squeak-dev] Re: The Inbox: Collections-ul.601.mcz In-Reply-To: References: Message-ID: <1421736800579-4800576.post@n4.nabble.com> Nice! :) Do you have any ideas about the array-to-order mapping to make removal O(1)? The array access seems quite hidden in Dictionary and not reachable via subclassing w/o much code duplication... Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-Collections-ul-601-mcz-tp4800473p4800576.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From florin.mateoc at gmail.com Tue Jan 20 07:25:48 2015 From: florin.mateoc at gmail.com (Florin Mateoc) Date: Tue Jan 20 07:25:32 2015 Subject: [squeak-dev] compiled squeakjs In-Reply-To: <54BD4707.70904@gmail.com> References: <54BBEE3E.8080208@gmail.com> <3FEB62EA-DEF5-4C6F-849A-7E65BE2B1F1F@freudenbergs.de> <54BD4707.70904@gmail.com> Message-ID: <54BE02FC.7040100@gmail.com> On 1/19/2015 1:03 PM, Florin Mateoc wrote: > The idea for become: goes something like this (I know that standard WeakMaps are not enumerable, but given that > Google/Caja were apparently able to write a WeakMap shim without native support, I hope that code can be used as > inspiration to give us enumerable ones - this would also address the more general requirement for weak > collections/allInstances): assignments, as well as the at:put: and instvarAt:put: primitives, add (if not already > there) to the right-hand side object a WeakMap property "owners". This happens only for non-primitive types. The keys > are the owners and the values are the indexes within the owner where the owned object lives. If there is already a > previous object within the owner at that index, the owner/index pair is removed from the previous object's owners. At > become: time, we iterate the owners and do the replacement And of course, if we did have enumerable WeakMaps, cleaning up of the previous owned object's owners does not need to happen, we can just check if what the owner has at the index is still valid at the time of executing become: or allReferences - this would move some pain to the right/less frequent place. Unfortunately, the shim that I mentioned is a dead end - they just store, as a hidden property, each weakMap value in the corresponding object used as its weakMap key, there is nothing stored in the weakMap itself to be iterated over. I think it's a pity that, for some obscure security scenario, they (ECMAScript) cripple an otherwise very useful feature. They could have offered a secure, non-enumerable version of weak collections in addition to an enumerable one for situations where it does not matter. Oh well, back to the drawing board (or to Bert's object layout :) ) Florin From commits at source.squeak.org Tue Jan 20 07:27:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 20 07:27:45 2015 Subject: [squeak-dev] The Trunk: Collections-mt.602.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.602.mcz ==================== Summary ==================== Name: Collections-mt.602 Author: mt Time: 20 January 2015, 8:27:19.919 am UUID: 96d6fefa-c902-7640-bd09-c17016199e81 Ancestors: Collections-ul.601 Merged improvements for OrderedDictionary from inbox (ul.601). Fixed problem in (mt.600 version) #copyFrom:to: with memory allocation. Preferred this over ul.601 because it is faster (8 per second vs. 12 per second). d := OrderedDictionary new. 1 to: 1000000 do: [:ea | d at: ea put: nil]. [d copyFrom: 250000 to: 750000] bench. =============== Diff against Collections-mt.600 =============== Item was added: + ----- Method: FloatCollection>>asFloatArray (in category 'adding') ----- + asFloatArray + "Optimized version" + + ^array copyFrom: firstIndex to: lastIndex! Item was changed: Dictionary subclass: #OrderedDictionary + instanceVariableNames: 'order' - instanceVariableNames: 'order lastIndex' classVariableNames: '' poolDictionaries: '' category: 'Collections-Sequenceable'! !OrderedDictionary commentStamp: 'mt 1/16/2015 10:42' prior: 0! I am an ordered dictionary. I have an additional index (called 'order') to keep track of the insertion order of my associations. The read access is not affected by the additional index. The index is updated in O(1) [time] when inserting new keys. For present keys, that insertion involves actions in O(n) to move the respective element to the end of the order. The growth operation compacts the index and takes O(n) additional time. NOTE: This is still no instance of SequenceableCollection. Having this, some protocols are missing and may require working on #associations, which is an Array and thus sequenceable.! Item was changed: ----- Method: OrderedDictionary>>associationsDo: (in category 'enumerating') ----- associationsDo: aBlock "Iterate over the order instead of the internal array." + order from: 1 to: tally do: aBlock! - lastIndex = 0 ifTrue: [^ self]. - 1 to: lastIndex do: [:index | - (order at: index) ifNotNil: [:element | - aBlock value: element]].! Item was changed: ----- Method: OrderedDictionary>>atIndex: (in category 'accessing') ----- atIndex: integer + integer > tally ifTrue: [ self error: 'indices are out of bounds' ]. + ^order at: integer! - ^ self atIndex: integer ifAbsent: [self errorOutOfBounds]! Item was changed: ----- Method: OrderedDictionary>>atIndex:ifAbsent: (in category 'accessing') ----- atIndex: integer ifAbsent: exceptionBlock "As we are sequenceable, provide index-based access." + integer > tally ifTrue: [ ^exceptionBlock value ]. + ^order at: integer ifAbsent: exceptionBlock! - | found | - found := 0. - self associationsDo: [:element | - (found := found + 1) = integer ifTrue: [ - ^ element]]. - - ^ exceptionBlock value! Item was changed: ----- Method: OrderedDictionary>>atNewIndex:put: (in category 'private') ----- atNewIndex: index put: anObject + super atNewIndex: index put: anObject. + order at: tally put: anObject + ! - lastIndex = order size ifTrue: [ - self fixEmptySlots]. - - lastIndex := lastIndex + 1. - order at: lastIndex put: anObject. - - super atNewIndex: index put: anObject.! Item was changed: ----- Method: OrderedDictionary>>copyFrom:to: (in category 'copying') ----- copyFrom: startIndex to: endIndex "Answer a copy of the receiver that contains elements from position startIndex to endIndex." - self fixEmptySlots. ^ self shallowCopy postCopyFrom: startIndex to: endIndex! Item was removed: - ----- Method: OrderedDictionary>>fillOrderFrom: (in category 'private') ----- - fillOrderFrom: anArray - - | arraySize | - arraySize := lastIndex. - lastIndex := 0. - 1 to: arraySize do: [:index | - (anArray at: index) ifNotNil: [:object | - lastIndex := lastIndex + 1. - order at: lastIndex put: object]].! Item was removed: - ----- Method: OrderedDictionary>>fixEmptySlots (in category 'private') ----- - fixEmptySlots - "Remove all nil slots in the order index to avoid overflow." - - lastIndex = tally ifTrue: [^ self]. - self fillOrderFrom: order.! Item was changed: ----- Method: OrderedDictionary>>growTo: (in category 'private') ----- growTo: anInteger | oldOrder | super growTo: anInteger. oldOrder := order. "Grow only to 75%. See #atNewIndex:put: in HashedCollection." + order := self class arrayType new: anInteger + 1 * 3 // 4. + order + replaceFrom: 1 + to: tally + with: oldOrder + startingAt: 1! - order := self class arrayType new: (anInteger * (3/4)) ceiling. - self fillOrderFrom: oldOrder.! Item was changed: ----- Method: OrderedDictionary>>initialize: (in category 'private') ----- initialize: n super initialize: n. + order := self class arrayType new: n + 1 * 3 // 4! - order := self class arrayType new: (n * (3/4)) ceiling. - lastIndex := 0.! Item was changed: ----- Method: OrderedDictionary>>isSorted (in category 'sorting') ----- isSorted + "Return true if the receiver is sorted by #<=." - "Return true if the receiver's keys are sorted by #<=." - self fixEmptySlots. ^ order isSortedBetween: 1 + and: tally! - and: lastIndex! Item was changed: ----- Method: OrderedDictionary>>postCopy (in category 'copying') ----- postCopy "We must not copy associations again but retrieve them from the array, which is already a copy. See super." super postCopy. + order := order copy. + 1 to: tally do: [ :index | + order at: index put: (array at: (self scanFor: (order at: index) key)) ]! - order := order collect: [:association | - association ifNotNil: [array at: (self scanFor: association key)]].! Item was changed: ----- Method: OrderedDictionary>>postCopyFrom:to: (in category 'copying') ----- postCopyFrom: startIndex to: endIndex "Adapted from SequenceableCollection and OrderedCollection." + | oldOrder | - | oldOrder newArraySize newOrderSize | - newArraySize := self class goodPrimeAtLeast: ((endIndex - startIndex + 1) * (5/4) "add 25%") ceiling. - newOrderSize := (newArraySize * (3/4)) ceiling. "remove 25%" - oldOrder := order. + array := self class arrayType + new: (self class goodPrimeAtLeast: endIndex - startIndex + 1 * 4 // 3). "fill 75% to 100%" + order := self class arrayType + new: array size * 3 // 4. "remove 25%" - order := self class arrayType new: newOrderSize. - array := self class arrayType new: newArraySize. startIndex to: endIndex do: [:index | | element | element := (oldOrder at: index) copy. order at: index - startIndex + 1 put: element. array at: (self scanFor: element key) put: element]. + tally := endIndex - startIndex + 1.! - lastIndex := endIndex - startIndex + 1. - tally := lastIndex. - - - ! Item was changed: ----- Method: OrderedDictionary>>removeKey:ifAbsent: (in category 'removing') ----- removeKey: key ifAbsent: aBlock + | result | + result := super removeKey: key ifAbsent: [ ^aBlock value ]. + (self scanOrderFor: key) ifNotNil: [ :index | + order + replaceFrom: index + to: tally + with: order + startingAt: index + 1 ]. + . order at: tally + 1 put: nil. + ^result! - (self scanOrderFor: key) ifNotNil: [:index | - order at: index put: nil]. - ^ super removeKey: key ifAbsent: aBlock! Item was changed: ----- Method: OrderedDictionary>>scanOrderFor: (in category 'private') ----- scanOrderFor: anObject + 1 to: tally do: [ :index | + (order at: index) key = anObject ifTrue: [ ^index ] ]. + ^nil! - 1 to: lastIndex do: [:index | - | element | - ((element := order at: index) notNil and: [anObject = element key]) - ifTrue: [^ index]]. - - ^ nil! Item was changed: ----- Method: OrderedDictionary>>sort (in category 'sorting') ----- sort + self sort: nil! - self sort: [:a1 :a2| a1 key <= a2 key].! Item was changed: ----- Method: OrderedDictionary>>sort: (in category 'sorting') ----- sort: aSortBlock "Like in OrderedCollection, sort the associations according to the sort block." + tally <= 1 ifTrue: [ ^self ]. + order + mergeSortFrom: 1 + to: tally + by: aSortBlock! - self ifNotEmpty: [ - self fixEmptySlots. - order - mergeSortFrom: 1 - to: lastIndex - by: aSortBlock].! From commits at source.squeak.org Tue Jan 20 07:28:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 20 07:28:28 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.235.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.235.mcz ==================== Summary ==================== Name: CollectionsTests-mt.235 Author: mt Time: 20 January 2015, 8:28:19.694 am UUID: 34359bef-b98b-214a-89b2-a1905c5bdca8 Ancestors: CollectionsTests-mt.234 Updated tests for OrderedDictionary. =============== Diff against CollectionsTests-mt.234 =============== Item was changed: ----- Method: OrderedDictionaryTest>>testCompact (in category 'tests') ----- testCompact + "Eager compacting on removal." + 1 to: 3 do: [:ea | sut at: ea put: nil]. - | oldCapacity | - 1 to: 3 do: [:ea | - sut at: ea put: nil]. - self assert: sut size equals: (sut instVarNamed: #lastIndex). - sut removeKey: 2. + self assert: 2 equals: ((sut instVarNamed: #order) count: [:ea | ea notNil]).! - self assert: sut size equals: (sut instVarNamed: #lastIndex) - 1. - - oldCapacity := sut capacity. - 4 to: 20 do: [:ea | - sut at: ea put: nil]. - self - assert: sut capacity > oldCapacity; - assert: sut size equals: (sut instVarNamed: #lastIndex). - ! From Das.Linux at gmx.de Tue Jan 20 08:10:16 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue Jan 20 08:10:19 2015 Subject: [squeak-dev] The Trunk: Collections-mt.602.mcz Message-ID: Hey, On 20.01.2015, at 07:27, commits@source.squeak.org wrote: > Marcel Taeumel uploaded a new version of Collections to project The Trunk: > http://source.squeak.org/trunk/Collections-mt.602.mcz > > ==================== Summary ==================== > > Name: Collections-mt.602 > Author: mt > Time: 20 January 2015, 8:27:19.919 am > UUID: 96d6fefa-c902-7640-bd09-c17016199e81 > Ancestors: Collections-ul.601 > > Merged improvements for OrderedDictionary from inbox (ul.601). > > Fixed problem in (mt.600 version) #copyFrom:to: with memory allocation. Preferred this over ul.601 because it is faster (8 per second vs. 12 per second). > > d := OrderedDictionary new. > 1 to: 1000000 do: [:ea | d at: ea put: nil]. > [d copyFrom: 250000 to: 750000] bench. > > =============== Diff against Collections-mt.600 =============== > Process question. Marcel just merged the changes from an inbox commit. Should Collections-ul.601 be a) moved to Trunk (for ancestry) or b) moved to the treated inbox or c) be delete or d) be left alone? Best -Tobias From Das.Linux at gmx.de Tue Jan 20 08:32:15 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue Jan 20 08:32:18 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> <37F57D76-72B0-4817-A52F-219838436498@gmx.de> <47D05015-792D-4337-9E13-C8E6DEA25954@gmx.de> Message-ID: On 20.01.2015, at 01:30, Eliot Miranda wrote: > On Mon, Jan 19, 2015 at 4:10 PM, Tobias Pape wrote: > > On 20.01.2015, at 01:04, Chris Muller wrote: > > > - Backport all the fixes we need (this + the rename fix + ??) > > - Update the All-In-One. > > - Someone must sign All-In-One. > > - Test signed All-In-One (windows, Linux, Mac). > > - Upload All-In-One. > > - Upload plain image + changes. > > > > I understand. > I just asked for an image where someone has hit the update button. > But yes, somewhen? we definitely should do these things :) > > ANy old 4.5 image or the release one? I don't understand the question. I would take the current release image on the file server and update it, and put it back with a new number. For the all-in-one, similar process. (But I would remove the update number from the image inside the all-in-one ) Best -Tobias > > > Bets > -Tobias > > > > > > On Mon, Jan 19, 2015 at 5:10 PM, Tobias Pape wrote: > >> > >> On 19.01.2015, at 23:54, Chris Muller wrote: > >> > >>> I deleted my package-cache and now I see it. > >>> > >>> It looks like this check was since moved higher where it would not get triggered unnecessarily. So its fixed in trunk. Unfortunate ofr the old version to be in 4.5 along with other issues too. Hopefully we'll find energy to make another 4.5 at least we know 4.6 won't have it. > >> > >> What's necessary besides > >> -update > >> -cleanup (if even necessary) > >> -upload? > >> > >> Best > >> -Tobias From commits at source.squeak.org Tue Jan 20 09:10:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 20 09:10:26 2015 Subject: [squeak-dev] The Trunk: Tests-topa.307.mcz Message-ID: Tobias Pape uploaded a new version of Tests to project The Trunk: http://source.squeak.org/trunk/Tests-topa.307.mcz ==================== Summary ==================== Name: Tests-topa.307 Author: topa Time: 20 January 2015, 10:10:13.719 am UUID: d5166f2b-dbec-49b7-ba75-87958543af4a Ancestors: Tests-dtl.306 Environments: Don't break user code expecting the Dictionary API =============== Diff against Tests-dtl.306 =============== Item was added: + ----- Method: EnvironmentTest>>testAssociationsDo (in category 'compatibility tests') ----- + testAssociationsDo + "For compatibility with legacy code, environments + should implement the dictionary protocol." + + env at: #Griffle put: value. + env at: #Plonk put: value. + env at: #Nurp put: value. + env associationsDo: [:assoc | + (#(Smalltalk Undeclared) includes: assoc key) + ifFalse: ["We're not interested in these default bindings" + self assert: (#(Griffle Plonk Nurp) includes: assoc key). + self assert: value equals: assoc value]]. + ! Item was added: + ----- Method: EnvironmentTest>>testKeysAndValuesDo (in category 'compatibility tests') ----- + testKeysAndValuesDo + "For compatibility with legacy code, environments + should implement the dictionary protocol." + + env at: #Griffle put: value. + env at: #Plonk put: value. + env at: #Nurp put: value. + env keysAndValuesDo: [:key :val | + (#(Smalltalk Undeclared) includes: key) + ifFalse: ["We're not interested in these default bindings" + self assert: (#(Griffle Plonk Nurp) includes: key). + self assert: value equals: val]].! Item was added: + ----- Method: EnvironmentTest>>testValuesDo (in category 'compatibility tests') ----- + testValuesDo + "For compatibility with legacy code, environments + should implement the dictionary protocol." + + | count | + env at: #Griffle put: value. + env at: #Plonk put: value. + env at: #Nurp put: value. + count := 0. + env valuesDo: [:val | count := count + 1]. + self assert: 3 + 2 equals: count description: '#valuesDo: should see all declared vallues plus the ones from Smalltalk and Undeclares' + ! From bert at freudenbergs.de Tue Jan 20 09:59:59 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue Jan 20 10:00:04 2015 Subject: [squeak-dev] About Inbox (was: The Trunk: Collections-mt.602.mcz) In-Reply-To: References: Message-ID: > On 20.01.2015, at 09:10, Tobias Pape wrote: > > Hey, > > On 20.01.2015, at 07:27, commits@source.squeak.org wrote: > >> Marcel Taeumel uploaded a new version of Collections to project The Trunk: >> http://source.squeak.org/trunk/Collections-mt.602.mcz >> >> ==================== Summary ==================== >> >> Name: Collections-mt.602 >> Author: mt >> Time: 20 January 2015, 8:27:19.919 am >> UUID: 96d6fefa-c902-7640-bd09-c17016199e81 >> Ancestors: Collections-ul.601 > > Process question. > Marcel just merged the changes from an inbox commit. > Should Collections-ul.601 be > d) be left alone? No way. We need to work on getting Inbox to zero ;) > c) be delete or Nope. We want to preserve all contributions. > b) moved to the treated inbox or That would be appropriate if this version isn't in the ancestry of Trunk. > a) moved to Trunk (for ancestry) Yep. Every direct ancestor should be in Trunk. Whether to include step-parent versions (from backporting/cherrypicking) in Trunk would be debatable. I would probably say having them in treated-inbox is enough, but keeping them in Trunk wouldn't hurt either. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/d26af775/smime.bin From nicolas.cellier.aka.nice at gmail.com Tue Jan 20 10:22:08 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Tue Jan 20 10:22:09 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: 2015-01-20 2:18 GMT+01:00 Eliot Miranda : > > > On Mon, Jan 19, 2015 at 5:09 PM, Levente Uzonyi wrote: > >> On Mon, 19 Jan 2015, Eliot Miranda wrote: >> >> >>> >>> On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier < >>> nicolas.cellier.aka.nice@gmail.com> wrote: >>> Hi Tobias, >>> are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] >>> This is to workaround the readOnlyCopy used for thread safety which is >>> the main killer of performance... >>> >>> >>> IMO this is a bug. We should simply have a single read-only copy of >>> each sources file and modify the debugger to either save and restore the >>> state of a read-only copy around accessing source, or use its own >>> read-only copy (except that the latter approach breaks when one debugs >>> the debugger). The difference in performance between using >>> CurrentReadOnlySourceFiles cacheDuring: [...] and not in anything that >>> accesses source is huge. And CurrentReadOnlySourceFiles cacheDuring: >>> [...] is a /lot/ of verbiage to type in doits, and a sign that something is >>> wrong. >>> >> >> How would using a single copy solve the concurrency issues? >> > > It wouldn't, but what issues are you seeing in concurrent source access? > VW doesn't even have read-only copies and AFAICR we never had complaints > about this. Is there really a thread-safety issue here? > > Couldn't there be a difference because VW properly handle read-append-stream for the underlying FILE? I have the feeling that such FILE is more robust to single write - multiple read concurrency, than a random-read-write FILE as used by Squeak... > >> I think the real solution would be to use per process copies, which were >> initialized lazily, and were closed automatically after some time of >> inactivity. > > > If concurrent access was really an issue then OK. But first I'd like some > evidence that there's a real problem here. > -- > best, > Eliot > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/d1e35777/attachment.htm From nicolas.cellier.aka.nice at gmail.com Tue Jan 20 10:28:12 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Tue Jan 20 10:28:16 2015 Subject: [squeak-dev] Why is source code always in files only? In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: 2015-01-20 1:29 GMT+01:00 Eliot Miranda : > > > On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier < > nicolas.cellier.aka.nice@gmail.com> wrote: > >> Hi Tobias, >> are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] >> This is to workaround the readOnlyCopy used for thread safety which is >> the main killer of performance... >> > > IMO this is a bug. We should simply have a single read-only copy of each > sources file and modify the debugger to either save and restore the state > of a read-only copy around accessing source, or use its own read-only copy > (except that the latter approach breaks when one debugs the debugger). The > difference in performance between using CurrentReadOnlySourceFiles > cacheDuring: [...] and not in anything that accesses source is huge. And > CurrentReadOnlySourceFiles cacheDuring: [...] is a /lot/ of verbiage to > type in doits, and a sign that something is wrong. > Yes it's smells... It's not our business, an encapsulation is missing. > > >> >> 2015-01-19 22:10 GMT+01:00 Tobias Pape : >> >>> >>> On 19.01.2015, at 21:51, Levente Uzonyi wrote: >>> >>> > On Mon, 19 Jan 2015, Tobias Pape wrote: >>> > >>> >> >>> >> On 19.01.2015, at 18:34, Chris Muller wrote: >>> >> >>> >>> On Mon, Jan 19, 2015 at 6:45 AM, Tobias Pape >>> wrote: >>> >>> Hi all, >>> >>> >>> >>> >>> >>> We store method source _solely_ in files (.sources/.changes). >>> >>> Why? We have means to attach it to Compiled methods, in fact, more >>> than one: >>> >>> >>> >>> >>> >>> CompiledMethod allInstances size. "57766." >>> >>> CompiledMethod allInstances count: [:m | m properties includesKey: >>> #source]. "0." >>> >>> CompiledMethod allInstances count: [:m | m trailer sourceCode >>> notNil]. "0." >>> >>> CompiledMethod allInstances count: [:m | m trailer >>> hasSourcePointer]. "57700." >>> >>> >>> >>> >>> >>> " also interesting " >>> >>> (CompiledMethod allInstances collect: [:m | m trailer kind] as: Bag) >>> sortedCounts >>> >>> {57701->#SourcePointer . 65->#NoTrailer . 14->#TempsNamesQCompress . >>> 2->#TempsNamesZip} >>> >>> >>> >>> >>> >>> When doing some analysis on source code, it is a pain to _either_ >>> >>> always go to disk for the source _or_ cache the code myself (which >>> may >>> >>> get out of sync sooon). >>> >>> >>> >>> If you're sending messages instead of viewing private innards, why >>> is it a pain? >>> >> >>> >> What do you mean? >>> >> >>> >> Calling getSource on a CM goes 300km to disk instead of 1m to memory >>> (metaphorically spoken) >>> >> and when I do analysis on source code I typically do stuff like that >>> a lot. >>> >> And as developer I really dislike that I have to choose between either >>> >> >>> >> a) bad performance due to excessive IO (yes I want to access the >>> source a lot) >>> >> b) caching things myself when already two ways of storing them are >>> available. >>> > >>> > On today's machines you don't have to. Once you read the data from the >>> disk, it'll be cached in memory. It would be faster to access the sources, >>> if they were stored in a trailer, but that would bump the image size by >>> about 15 MB (uncompressed), or 9 MB (compressed): >>> > >>> >>> I understand. But for a development image, I'd take that burden. >>> >>> > | size compressedSize | >>> > size := compressedSize := 0. >>> > CurrentReadOnlySourceFiles cacheDuring: [ >>> > SystemNavigation default allSelectorsAndMethodsDo: [ :behavior >>> :selector :method | >>> > | string compressed | >>> > string := method getSource asString. >>> > compressed := string squeakToUtf8 zipped. >>> > size := size + string byteSize + ((string size > 255) >>> asBit + 1 * 4). >>> > compressedSize := compressedSize + compressed byteSize + >>> ((compressed size > 255) asBit + 1 * 4) ] ]. >>> > { size. compressedSize }. >>> > >>> > "==> #(15003880 9057408)" >>> >>> >>> What I am actually wondering about, >>> there are two completely different ways to _access_ source stored in the >>> image >>> but no way to actually _store_ it there. >>> >>> > >>> >> >>> >>> >>> >>> Can't we just save the source code either via trailer or properties >>> >>> on first access? >>> >>> >>> >>> -1. Why do I want all of those String's in my image? >>> >> >>> >> To do stuff to them. >>> >> Like, analysing how many dots are in them, or how often someone >>> crafts a Symbol. >>> >> Analysis stuff. >>> >> Currently, I have a separate structure that holds onto the code once >>> retrieved >>> >> from disk. But once the method change (eg, recompilation) I have to >>> first detect, >>> >> that it happened, and second flush and refill this cache. I find this >>> tiresome. >>> > >>> > Do you flush your cache selectively? >>> >>> No, I can't for reasons :) >>> >>> > >>> > Scanning all source code for a given pattern takes less than a second >>> (~800 ms) on my machine. What's your performance goal? >>> >>> I have ~15.000 Methods that I have to compare line by line against each >>> other. >>> Doing that by going to the filesystem just kills it. >>> >>> >>> Best >>> -Tobias >> >> -- > best, > Eliot > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/8ed92863/attachment.htm From bert at freudenbergs.de Tue Jan 20 10:55:33 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue Jan 20 10:55:36 2015 Subject: [squeak-dev] Re: compiled squeakjs In-Reply-To: <54BE02FC.7040100@gmail.com> References: <54BBEE3E.8080208@gmail.com> <3FEB62EA-DEF5-4C6F-849A-7E65BE2B1F1F@freudenbergs.de> <54BD4707.70904@gmail.com> <54BE02FC.7040100@gmail.com> Message-ID: On 20.01.2015, at 08:25, Florin Mateoc wrote: > > On 1/19/2015 1:03 PM, Florin Mateoc wrote: >> The idea for become: goes something like this (I know that standard WeakMaps are not enumerable, but given that >> Google/Caja were apparently able to write a WeakMap shim without native support, I hope that code can be used as >> inspiration to give us enumerable ones - this would also address the more general requirement for weak >> collections/allInstances): assignments, as well as the at:put: and instvarAt:put: primitives, add (if not already >> there) to the right-hand side object a WeakMap property "owners". This happens only for non-primitive types. The keys >> are the owners and the values are the indexes within the owner where the owned object lives. If there is already a >> previous object within the owner at that index, the owner/index pair is removed from the previous object's owners. At >> become: time, we iterate the owners and do the replacement > > And of course, if we did have enumerable WeakMaps, cleaning up of the previous owned object's owners does not need to > happen, we can just check if what the owner has at the index is still valid at the time of executing become: or > allReferences - this would move some pain to the right/less frequent place. > > Unfortunately, the shim that I mentioned is a dead end - they just store, as a hidden property, each weakMap value in > the corresponding object used as its weakMap key, there is nothing stored in the weakMap itself to be iterated over. > I think it's a pity that, for some obscure security scenario, they (ECMAScript) cripple an otherwise very useful > feature. They could have offered a secure, non-enumerable version of weak collections in addition to an enumerable one > for situations where it does not matter. Oh well, back to the drawing board (or to Bert's object layout :) ) Yep. Working around the lack of weak collections in JavaScript was why I had to come up with my own memory model. I couldn't simply adopt Dan's, who used a Java weak array in JSqueak/Potato. I briefly got excited about the new WeakMap support in ES6, but as you discovered, without enumeration they are much weaker (pun intended) than what we have in Smalltalk. At first I thought they were completely useless, since the same could be achieved by adding a property to each object. But beyond that you can bulk-empty the WeakMap, being equivalent to removing that property from all those objects. So essentially WeakMaps are useful as caches that can easily be invalidated. I cannot think of another application. The *reason* for designing WeakMaps in such a limited way is that the ECMAScript committee thinks garbage collection should be unobservable. No expression in the language should depend on the state of the GC. This gives implementers of the language a lot more freedom in designing their VM. SqueakJS's "become" is pretty expensive, as is "allObjects". For "allInstances" it depends on whether there are instances in New Space, if not, it's much cheaper. My rationale for that is that these operations are expensive traditionally, so the class library has been designed to avoid them where possible (e.g. OrderedCollection delegating to an array instead of being an array). With Spur making "become" cheap, we may see this stuff sneak back in, and would have to re-evaluate the trade-offs. For your case, since you're mainly interested in porting a specific application, I think reference counting might work. This would make write-operations more expensive (but you already said that you're willing to pay that), but the cost would be spread over time. In contrast, SqueakJS does no checks at all on writing, making the general case be fast, but paying for that with a pause of a couple hundred milliseconds when it needs to walk the full object memory (e.g. for become). - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/536cd5a2/smime.bin From gettimothy at zoho.com Tue Jan 20 13:33:00 2015 From: gettimothy at zoho.com (gettimothy) Date: Tue Jan 20 13:33:05 2015 Subject: [squeak-dev] Request: new 4.5 artifact. In-Reply-To: References: <2D89D4A5-54FE-4610-8BBA-EF4ABF45B622@gmx.de> <37F57D76-72B0-4817-A52F-219838436498@gmx.de> Message-ID: <14b07881b95.ad3b992626550.7846459148598113502@zoho.com> For some reason, the packaging of the 4.5.zip file changed last summer/fall and an extra directory was introduced . This messed with existing scripts in Cog/image/*.sh cheers. tty. ---- On Mon, 19 Jan 2015 19:04:02 -0500 Chris Muller <ma.chris.m@gmail.com> wrote ---- - Backport all the fixes we need (this + the rename fix + ??) - Update the All-In-One. - Someone must sign All-In-One. - Test signed All-In-One (windows, Linux, Mac). - Upload All-In-One. - Upload plain image + changes. On Mon, Jan 19, 2015 at 5:10 PM, Tobias Pape <Das.Linux@gmx.de> wrote: > > On 19.01.2015, at 23:54, Chris Muller <asqueaker@gmail.com> wrote: > >> I deleted my package-cache and now I see it. >> >> It looks like this check was since moved higher where it would not get triggered unnecessarily. So its fixed in trunk. Unfortunate ofr the old version to be in 4.5 along with other issues too. Hopefully we'll find energy to make another 4.5 at least we know 4.6 won't have it. > > What's necessary besides > -update > -cleanup (if even necessary) > -upload? > > Best > -Tobias > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/97b9be3a/attachment.htm From florin.mateoc at gmail.com Tue Jan 20 14:17:38 2015 From: florin.mateoc at gmail.com (Florin Mateoc) Date: Tue Jan 20 14:17:21 2015 Subject: [squeak-dev] Re: compiled squeakjs In-Reply-To: References: <54BBEE3E.8080208@gmail.com> <3FEB62EA-DEF5-4C6F-849A-7E65BE2B1F1F@freudenbergs.de> <54BD4707.70904@gmail.com> <54BE02FC.7040100@gmail.com> Message-ID: <54BE6382.1090500@gmail.com> On 1/20/2015 5:55 AM, Bert Freudenberg wrote: > On 20.01.2015, at 08:25, Florin Mateoc wrote: >> On 1/19/2015 1:03 PM, Florin Mateoc wrote: >>> The idea for become: goes something like this (I know that standard WeakMaps are not enumerable, but given that >>> Google/Caja were apparently able to write a WeakMap shim without native support, I hope that code can be used as >>> inspiration to give us enumerable ones - this would also address the more general requirement for weak >>> collections/allInstances): assignments, as well as the at:put: and instvarAt:put: primitives, add (if not already >>> there) to the right-hand side object a WeakMap property "owners". This happens only for non-primitive types. The keys >>> are the owners and the values are the indexes within the owner where the owned object lives. If there is already a >>> previous object within the owner at that index, the owner/index pair is removed from the previous object's owners. At >>> become: time, we iterate the owners and do the replacement >> And of course, if we did have enumerable WeakMaps, cleaning up of the previous owned object's owners does not need to >> happen, we can just check if what the owner has at the index is still valid at the time of executing become: or >> allReferences - this would move some pain to the right/less frequent place. >> >> Unfortunately, the shim that I mentioned is a dead end - they just store, as a hidden property, each weakMap value in >> the corresponding object used as its weakMap key, there is nothing stored in the weakMap itself to be iterated over. >> I think it's a pity that, for some obscure security scenario, they (ECMAScript) cripple an otherwise very useful >> feature. They could have offered a secure, non-enumerable version of weak collections in addition to an enumerable one >> for situations where it does not matter. Oh well, back to the drawing board (or to Bert's object layout :) ) > Yep. Working around the lack of weak collections in JavaScript was why I had to come up with my own memory model. I couldn't simply adopt Dan's, who used a Java weak array in JSqueak/Potato. > > I briefly got excited about the new WeakMap support in ES6, but as you discovered, without enumeration they are much weaker (pun intended) than what we have in Smalltalk. At first I thought they were completely useless, since the same could be achieved by adding a property to each object. But beyond that you can bulk-empty the WeakMap, being equivalent to removing that property from all those objects. So essentially WeakMaps are useful as caches that can easily be invalidated. I cannot think of another application. Well, they also work as an "alreadySeen" collection for recursive operations. > The *reason* for designing WeakMaps in such a limited way is that the ECMAScript committee thinks garbage collection should be unobservable. No expression in the language should depend on the state of the GC. This gives implementers of the language a lot more freedom in designing their VM. I am not sure I understand this argument. Indeed, as they say, enumerating weak collections introduce some indeterminism. So what? Does that make Smalltalk or Java programs in general less deterministic than JavaScript ones? Obviously one has to take care and work around the possibility that something might or might not be there, but this is not such a unique situation in programming. As for the vm implementors, I wouldn't know, but did actually implementing weak references make the vms (various Smalltalk, Java, ActionScript...) take a hit in general performance or complexity? I think they only thing they "really" cared about was something about security (this is Mark Miller we are talking about :) ): "This is necessary to prevent attackers observing the internal behavior of other systems in the environment which share weakly-mapped objects. Should the number or names of items in the collection be discoverable from the API, even if the values aren't, WeakMap instances might create a side channel where one was previously not available." And I don't think this argument holds water, especially since, as I said, they could have offered both secure and unsecure versions. Florin -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/974ee952/attachment-0001.htm From commits at source.squeak.org Tue Jan 20 15:07:10 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 20 15:07:12 2015 Subject: [squeak-dev] The Trunk: Tests-topa.308.mcz Message-ID: Tobias Pape uploaded a new version of Tests to project The Trunk: http://source.squeak.org/trunk/Tests-topa.308.mcz ==================== Summary ==================== Name: Tests-topa.308 Author: topa Time: 20 January 2015, 4:06:59.651 pm UUID: 83f45eb7-b286-4b0d-b11b-8e973b6bb8b4 Ancestors: Tests-topa.307 Environments: The need for fresh bindings on class rename may be a good idea, we don't know yet. Need to talk to cwp, probably. =============== Diff against Tests-topa.307 =============== Item was added: + ----- Method: EnvironmentTest>>expectedFailures (in category 'as yet unclassified') ----- + expectedFailures + " The need for fresh bindings on class rename may be a good idea, + we don't know yet. Need to talk to cwp, probably" + + ^ #(testRenameCreatesNewBinding)! From commits at source.squeak.org Tue Jan 20 15:12:41 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 20 15:12:43 2015 Subject: [squeak-dev] The Trunk: Environments-topa.54.mcz Message-ID: Tobias Pape uploaded a new version of Environments to project The Trunk: http://source.squeak.org/trunk/Environments-topa.54.mcz ==================== Summary ==================== Name: Environments-topa.54 Author: topa Time: 20 January 2015, 4:12:36.674 pm UUID: b55bd16f-c2c0-4927-b170-4954383dd63f Ancestors: Environments-cmm.53 Update literal bindings in compiled methods when renaming a class. Restores working behavior of pre-Squeak4.5. =============== Diff against Environments-cmm.53 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. + binding := self declarationOf: oldName. - binding := self associationAt: oldName. declarations removeKey: oldName. + self binding: binding removedFrom: self. + undeclared removeKey: oldName. + + binding becomeForward: (newName => aClass). + declarations add: binding. + self binding: binding addedTo: self. - bindings removeKey: oldName. - " self binding: binding removedFrom: self." - binding key: newName. - declarations add: binding. - bindings add: binding. - " self binding: binding addedTo: self." - Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From asqueaker at gmail.com Tue Jan 20 15:51:08 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue Jan 20 15:51:11 2015 Subject: [squeak-dev] The Trunk: Collections-mt.602.mcz In-Reply-To: References: Message-ID: On Tue, Jan 20, 2015 at 2:10 AM, Tobias Pape wrote: > Hey, > > On 20.01.2015, at 07:27, commits@source.squeak.org wrote: > > > Marcel Taeumel uploaded a new version of Collections to project The > Trunk: > > http://source.squeak.org/trunk/Collections-mt.602.mcz > > > > ==================== Summary ==================== > > > > Name: Collections-mt.602 > > Author: mt > > Time: 20 January 2015, 8:27:19.919 am > > UUID: 96d6fefa-c902-7640-bd09-c17016199e81 > > Ancestors: Collections-ul.601 > > > > Merged improvements for OrderedDictionary from inbox (ul.601). > > > > Fixed problem in (mt.600 version) #copyFrom:to: with memory allocation. > Preferred this over ul.601 because it is faster (8 per second vs. 12 per > second). > > > > d := OrderedDictionary new. > > 1 to: 1000000 do: [:ea | d at: ea put: nil]. > > [d copyFrom: 250000 to: 750000] bench. > > > > =============== Diff against Collections-mt.600 =============== > > > > Process question. > Marcel just merged the changes from an inbox commit. > Should Collections-ul.601 be > a) moved to Trunk (for ancestry) or > b) moved to the treated inbox or > c) be delete or > d) be left alone? > > The MC model is a useful historical model only when backed by a repository with all ancestral versions. So, the answer is (a). -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/8b0083fb/attachment.htm From asqueaker at gmail.com Tue Jan 20 16:10:42 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue Jan 20 16:10:45 2015 Subject: [squeak-dev] The Trunk: Environments-topa.54.mcz In-Reply-To: <54be706e.c7588c0a.1163.4793SMTPIN_ADDED_MISSING@mx.google.com> References: <54be706e.c7588c0a.1163.4793SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: A more-proper fix that seems to work, thanks. On Tue, Jan 20, 2015 at 9:12 AM, wrote: > Tobias Pape uploaded a new version of Environments to project The Trunk: > http://source.squeak.org/trunk/Environments-topa.54.mcz > > ==================== Summary ==================== > > Name: Environments-topa.54 > Author: topa > Time: 20 January 2015, 4:12:36.674 pm > UUID: b55bd16f-c2c0-4927-b170-4954383dd63f > Ancestors: Environments-cmm.53 > > Update literal bindings in compiled methods when renaming a class. > > Restores working behavior of pre-Squeak4.5. > > =============== Diff against Environments-cmm.53 =============== > > Item was changed: > ----- Method: Environment>>renameClass:from:to: (in category 'classes > and traits') ----- > renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | binding category | > category := self organization categoryOfElement: oldName. > self organization classify: newName under: category > suppressIfDefault: true. > self organization removeElement: oldName. > > + binding := self declarationOf: oldName. > - binding := self associationAt: oldName. > declarations removeKey: oldName. > + self binding: binding removedFrom: self. > + undeclared removeKey: oldName. > + > + binding becomeForward: (newName => aClass). > + declarations add: binding. > + self binding: binding addedTo: self. > - bindings removeKey: oldName. > - " self binding: binding removedFrom: self." > > - binding key: newName. > - declarations add: binding. > - bindings add: binding. > - " self binding: binding addedTo: self." > - > Smalltalk renamedClass: aClass from: oldName to: newName. > SystemChangeNotifier uniqueInstance > classRenamed: aClass > from: oldName > to: newName > inCategory: category! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/a42447dd/attachment.htm From tim at rowledge.org Tue Jan 20 17:54:34 2015 From: tim at rowledge.org (tim Rowledge) Date: Tue Jan 20 17:54:40 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: <361D939E-C77B-4971-8807-0C3809EBBD19@rowledge.org> On 20-01-2015, at 2:22 AM, Nicolas Cellier wrote: > > > 2015-01-20 2:18 GMT+01:00 Eliot Miranda : > > > On Mon, Jan 19, 2015 at 5:09 PM, Levente Uzonyi wrote: > On Mon, 19 Jan 2015, Eliot Miranda wrote: > > > > On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier wrote: > Hi Tobias, > are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] > This is to workaround the readOnlyCopy used for thread safety which is the main killer of performance? > I?ve no idea if concurrency is the actual issue in your problem but the simple way to solve any issues with thread related access to files is to rewrite the damned FilePlugin to use a proper api. The separate set-pos & read-bytes + write-bytes is stupid. Use a read-bytes-from-this-pos type api. At least that way you have some confidence you?ll get the bytes you thought you wanted. Not to mention that -as has been discussed a gazillion times already - FilePlugin and the general file/dir handling in Squeak is extremely grungy. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: EFB: Emulate Five-volt Battery mode From eliot.miranda at gmail.com Tue Jan 20 19:27:31 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 20 19:27:34 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: On Tue, Jan 20, 2015 at 2:22 AM, Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> wrote: > > > 2015-01-20 2:18 GMT+01:00 Eliot Miranda : > >> >> >> On Mon, Jan 19, 2015 at 5:09 PM, Levente Uzonyi wrote: >> >>> On Mon, 19 Jan 2015, Eliot Miranda wrote: >>> >>> >>>> >>>> On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier < >>>> nicolas.cellier.aka.nice@gmail.com> wrote: >>>> Hi Tobias, >>>> are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] >>>> This is to workaround the readOnlyCopy used for thread safety which is >>>> the main killer of performance... >>>> >>>> >>>> IMO this is a bug. We should simply have a single read-only copy of >>>> each sources file and modify the debugger to either save and restore the >>>> state of a read-only copy around accessing source, or use its own >>>> read-only copy (except that the latter approach breaks when one debugs >>>> the debugger). The difference in performance between using >>>> CurrentReadOnlySourceFiles cacheDuring: [...] and not in anything that >>>> accesses source is huge. And CurrentReadOnlySourceFiles cacheDuring: >>>> [...] is a /lot/ of verbiage to type in doits, and a sign that something is >>>> wrong. >>>> >>> >>> How would using a single copy solve the concurrency issues? >>> >> >> It wouldn't, but what issues are you seeing in concurrent source access? >> VW doesn't even have read-only copies and AFAICR we never had complaints >> about this. Is there really a thread-safety issue here? >> >> > > Couldn't there be a difference because VW properly handle > read-append-stream for the underlying FILE? > I have the feeling that such FILE is more robust to single write - > multiple read concurrency, than a random-read-write FILE as used by > Squeak... > Maybe. And Tim's point about the file api is well0-taken, but its much more work at the Smalltalk level than at the VM level. However, I still want to see evidence of the potential thread-safety issues. Access to the source files for writing is not thread-safe anyway but no one complains about that. So I suspect we may be trying to fix a problem that doesn't really exist. IMO it is much more preferable to have fast access to source than thread-safety. If someone wants thread-safe access they can roll their own solution (e.g. install a wrapper hiding a mutex around the source files). The common case of accessing source should be fast. The difference between self systemNavigation allSelect: [:m| m getSourceFromFile asString includesSubString: 'not likely'] and CurrentReadOnlySourceFiles cacheDuring: [self systemNavigation allSelect: [:m| m getSourceFromFile asString includesSubString: 'not likely']] is 34 to 1 (!!), 28 seconds vs 0.8. :-( >>> I think the real solution would be to use per process copies, which were >>> initialized lazily, and were closed automatically after some time of >>> inactivity. >> >> >> If concurrent access was really an issue then OK. But first I'd like >> some evidence that there's a real problem here. >> -- >> best, >> Eliot >> >> >> >> > > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/5b654a92/attachment.htm From eliot.miranda at gmail.com Tue Jan 20 19:40:34 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 20 19:40:37 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz In-Reply-To: References: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Mon, Jan 19, 2015 at 1:59 AM, Frank Shearar wrote: > On 17 January 2015 at 18:35, Eliot Miranda > wrote: > > Hi Frank, > > > > On Jan 17, 2015, at 3:39 AM, Frank Shearar > wrote: > > > >> On 16 January 2015 at 21:44, wrote: > >>> Chris Muller uploaded a new version of System to project The Trunk: > >>> http://source.squeak.org/trunk/System-cmm.694.mcz > >>> > >>> ==================== Summary ==================== > >>> > >>> Name: System-cmm.694 > >>> Author: cmm > >>> Time: 16 January 2015, 3:44:19.079 pm > >>> UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 > >>> Ancestors: System-dtl.693 > >>> > >>> - #flush stdout and stderr after writing error information to them. > >>> - After that, if the exception is resumable (i.e. a Warning), resume > it. Except if its a MessageNotUnderstood -- that is not an error you want > to resume in a headless environment. > >> > >> Why? It's probably a rare use case for a #run: script to catch MNUs to > >> do something fancy, I guess? Maybe it's because #run: is usually > >> (always?) the top level of the program? > > > > One reason is that resuming an MNU simply resends from the > diesNotUnderstand: method, so resuming will result in infinite recursion. > I suppose the handler could allow one repeat but that seems arbitrary. > There's nothing to stop one including a resuming MNU handler in the > expression if one wants to override the default behaviour. > > > >> > >> Catching only MNUs seems very specific. Maybe there could be a #run: > >> version that says "and here's a function you can use to control which > >> exceptions are OK to resume, and which not"? > > > > Well there is Notification and Warning but (rightly) > MessageNotUnderstood is an Error. Reporting Notifications and Warnings to > the output and continuing, but aborting for other exceptions seems the > right thing to do, rather than basing it in resumability, yes? What am I > missing? > > > > Whether an exception is resumability or not is to do with whether one > can usefully provide a value with which to continue, not to do with the > severity of the error. > > Chris has already addressed the issue, but to continue the > conversation here, yes, an exception is resumable if e isResumable = > true. That's exactly as it should be. But seeing as an MNU is > resumable, you could write a handler that _did_ return a value. In > other words, the problem that I saw - and I think Chris and you agree? > - is that it looks weird to resume some resumable exceptions but not > others. > I think we all agree on this. There's no case for resuming anything other than Notification, Warning and subclasses. I agree with the point you make in a later mail, that #run: should > just bail noisily on a top-level exception. > > frank > > > For example, being able to resume with nil for a permissions violation > when opening a file or directory might make it really easy to implement a > find(1) like search over directories where some may be unreadable due to > permissions. Being able to resume doesn't make the permissions violation > any the less severe, but it dies give us a nice way if handling it, > certainly less complex than having to explicitly check for permissions > during the traversal. Likewise, being able to substitute a value for an > MNU allows all sorts of conveniences, eg see my code for disassembling > methods to bytecode messages. > > > > So IMO the system should be reporting Notifications and Warnings and > aborting for anything else. > > Yep. > > >> frank > > > > Eliot (phone) > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/9479194f/attachment.htm From eliot.miranda at gmail.com Tue Jan 20 20:26:07 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 20 20:26:09 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: Hi Chris, Hi Colin, On Thu, Jan 15, 2015 at 2:48 PM, Chris Muller wrote: > I did a minor class-hierarchy refactoring today which resulted in a an > invalid super pointer, resulting in a confusing image lock up due to > tight recursion. The script, below, demonstrates the issue in trunk: > > Object compile: 'test ^''Hello from Object'''. > (Object subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > 'test ^ super halt test, ''my super call lands on myself!'''. > (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass > instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' > category: 'Test'). > (Smalltalk classNamed: #MyNewAbstraction) new test > > But an existing method in the original MyClass had a call to super > which now lands in itself, resulting in a tight recursion. > > The same script without creating the new subclass results in an > instant VM crash (both interpreter 2357 and cog 3205): > > Object compile: 'test ^''Hello from Object'''. > (Object subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > 'test ^ super halt test, ''my super call lands on itself!'''. > (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > (Smalltalk classNamed: #MyNewAbstraction) new test > > I even tried recompiling my entire class hierarchy which was renamed, > but it didn't help. > > How can this be? I _KNOW_ I've used rename class many times in the > past... A regression? > This is indeed an Environments regression. The issue is where to fix the problem. One way to look at it is that Environment>>renameClass:from:to: does not update bindings in the renamed class's methods. Here's what the old code did: SystemDictionary>>renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | oldref category | category := SystemOrganization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. oldref := self associationAt: oldName. self removeKey: oldName. ** oldref key: newName. self add: oldref. "Old association preserves old refs" Smalltalk renamedClass: aClass from: oldName to: newName. self flushClassNameCache. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category The starred line changes the key on the old class's binding, meaning that all the methods whose methodClassAssociation is that binding get automatically updated (note that class methods have a methodClassAssociation that has no key and just points to the class object). The new code simply forgets to do this: Environment>>renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. binding := self declarationOf: oldName. declarations removeKey: oldName. self binding: binding removedFrom: self. binding := newName => aClass. declarations add: binding. self binding: binding addedTo: self. Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category But should the change go in Environment>>renameClass:from:to: or in the BindingPolicy? i.e. it could be implemented either in Environment>>renameClass:from:to:, or in Environment>>showBinding:. I guess the former, but I'm cc'ing Colin, because know it?, he wrote it! In any case there needs to be a test that checks that a method's methodClassAssociation is correctly updated after a rename. I bet Colin would have not made this slip had there been a test. Here's the code I used to test this: | mca1 mca2 | Object compile: 'test ^''Hello from Object'''. (Object subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test') compile: 'test ^ super halt test, ''my super call lands on itself!'''. mca1 := ((Smalltalk classNamed: #MyClass)>>#test) methodClassAssociation. (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. mca2 := ((Smalltalk classNamed: #MyNewAbstraction)>>#test) methodClassAssociation. { mca1. mca2. mca1 == mca2. mca1 == (Smalltalk bindingOf: #MyNewAbstraction). mca2 == (Smalltalk bindingOf: #MyNewAbstraction)} It answers { #MyClass=>nil . #MyClass=>nil . true . false . false} i.e. the binding isn't updated, but changes from #MyClass=>MyClass to #MyClass=>nil in binding:removedFrom:. -- HTH, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/972ff052/attachment.htm From eliot.miranda at gmail.com Tue Jan 20 20:33:42 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 20 20:33:46 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: On Tue, Jan 20, 2015 at 12:26 PM, Eliot Miranda wrote: > Hi Chris, Hi Colin, > > > On Thu, Jan 15, 2015 at 2:48 PM, Chris Muller > wrote: > >> I did a minor class-hierarchy refactoring today which resulted in a an >> invalid super pointer, resulting in a confusing image lock up due to >> tight recursion. The script, below, demonstrates the issue in trunk: >> >> Object compile: 'test ^''Hello from Object'''. >> (Object subclass: #MyClass instanceVariableNames: '' >> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >> 'test ^ super halt test, ''my super call lands on myself!'''. >> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass >> instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' >> category: 'Test'). >> (Smalltalk classNamed: #MyNewAbstraction) new test >> >> But an existing method in the original MyClass had a call to super >> which now lands in itself, resulting in a tight recursion. >> >> The same script without creating the new subclass results in an >> instant VM crash (both interpreter 2357 and cog 3205): >> >> Object compile: 'test ^''Hello from Object'''. >> (Object subclass: #MyClass instanceVariableNames: '' >> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >> 'test ^ super halt test, ''my super call lands on itself!'''. >> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> (Smalltalk classNamed: #MyNewAbstraction) new test >> >> I even tried recompiling my entire class hierarchy which was renamed, >> but it didn't help. >> >> How can this be? I _KNOW_ I've used rename class many times in the >> past... A regression? >> > > This is indeed an Environments regression. The issue is where to fix the > problem. One way to look at it is that Environment>>renameClass:from:to: > does not update bindings in the renamed class's methods. > > Here's what the old code did: > > SystemDictionary>>renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | oldref category | > category := SystemOrganization categoryOfElement: oldName. > self organization classify: newName under: category suppressIfDefault: > true. > self organization removeElement: oldName. > oldref := self associationAt: oldName. > self removeKey: oldName. > ** oldref key: newName. > self add: oldref. "Old association preserves old refs" > Smalltalk renamedClass: aClass from: oldName to: newName. > self flushClassNameCache. > SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: > newName inCategory: category > > The starred line changes the key on the old class's binding, meaning that > all the methods whose methodClassAssociation is that binding get > automatically updated (note that class methods have > a methodClassAssociation that has no key and just points to the class > object). > > The new code simply forgets to do this: > > Environment>>renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | binding category | > category := self organization categoryOfElement: oldName. > self organization classify: newName under: category suppressIfDefault: > true. > self organization removeElement: oldName. > binding := self declarationOf: oldName. > declarations removeKey: oldName. > self binding: binding removedFrom: self. > binding := newName => aClass. > declarations add: binding. > self binding: binding addedTo: self. > Smalltalk renamedClass: aClass from: oldName to: newName. > SystemChangeNotifier uniqueInstance > classRenamed: aClass > from: oldName > to: newName > inCategory: category > > > But should the change go in Environment>>renameClass:from:to: or in the > BindingPolicy? i.e. it could be implemented either in > Environment>>renameClass:from:to:, or in Environment>>showBinding:. I > guess the former, but I'm cc'ing Colin, because know it?, he wrote it! > and if the fix should indeed go in Environment>>renameClass:from:to: , it is as simple as Environment>>renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. binding := self declarationOf: oldName. declarations removeKey: oldName. self binding: binding removedFrom: self. binding := newName => aClass. declarations add: binding. self binding: binding addedTo: self. ** aClass updateMethodBindingsTo: binding. Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category I'll make this change and we can alter later if Colin thinks it's in the wrong place. > > In any case there needs to be a test that checks that a method's > methodClassAssociation is correctly updated after a rename. I bet Colin > would have not made this slip had there been a test. > > > Here's the code I used to test this: > > | mca1 mca2 | > Object compile: 'test ^''Hello from Object'''. > (Object > subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' > poolDictionaries: '' > category: 'Test') > compile: 'test ^ super halt test, ''my super call lands on itself!'''. > mca1 := ((Smalltalk classNamed: #MyClass)>>#test) methodClassAssociation. > (Smalltalk classNamed: #MyClass) > rename: 'MyNewAbstraction'. > mca2 := ((Smalltalk classNamed: #MyNewAbstraction)>>#test) > methodClassAssociation. > { mca1. mca2. mca1 == mca2. mca1 == (Smalltalk bindingOf: > #MyNewAbstraction). mca2 == (Smalltalk bindingOf: #MyNewAbstraction)} > > It answers { #MyClass=>nil . #MyClass=>nil . true . false . false} > i.e. the binding isn't updated, but changes from #MyClass=>MyClass to > #MyClass=>nil in binding:removedFrom:. > > > -- > HTH, > Eliot > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/767b0b1a/attachment.htm From Das.Linux at gmx.de Tue Jan 20 20:35:23 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue Jan 20 20:35:25 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: On 20.01.2015, at 21:33, Eliot Miranda wrote: > On Tue, Jan 20, 2015 at 12:26 PM, Eliot Miranda wrote: > Hi Chris, Hi Colin, > > > On Thu, Jan 15, 2015 at 2:48 PM, Chris Muller wrote: > I did a minor class-hierarchy refactoring today which resulted in a an > invalid super pointer, resulting in a confusing image lock up due to > tight recursion. The script, below, demonstrates the issue in trunk: > > Object compile: 'test ^''Hello from Object'''. > (Object subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > 'test ^ super halt test, ''my super call lands on myself!'''. > (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass > instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' > category: 'Test'). > (Smalltalk classNamed: #MyNewAbstraction) new test > > But an existing method in the original MyClass had a call to super > which now lands in itself, resulting in a tight recursion. > > The same script without creating the new subclass results in an > instant VM crash (both interpreter 2357 and cog 3205): > > Object compile: 'test ^''Hello from Object'''. > (Object subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > 'test ^ super halt test, ''my super call lands on itself!'''. > (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > (Smalltalk classNamed: #MyNewAbstraction) new test > > I even tried recompiling my entire class hierarchy which was renamed, > but it didn't help. > > How can this be? I _KNOW_ I've used rename class many times in the > past... A regression? > > This is indeed an Environments regression. The issue is where to fix the problem. One way to look at it is that Environment>>renameClass:from:to: does not update bindings in the renamed class's methods. > > Here's what the old code did: > > SystemDictionary>>renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | oldref category | > category := SystemOrganization categoryOfElement: oldName. > self organization classify: newName under: category suppressIfDefault: true. > self organization removeElement: oldName. > oldref := self associationAt: oldName. > self removeKey: oldName. > ** oldref key: newName. > self add: oldref. "Old association preserves old refs" > Smalltalk renamedClass: aClass from: oldName to: newName. > self flushClassNameCache. > SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category > > The starred line changes the key on the old class's binding, meaning that all the methods whose methodClassAssociation is that binding get automatically updated (note that class methods have a methodClassAssociation that has no key and just points to the class object). > > The new code simply forgets to do this: > > Environment>>renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | binding category | > category := self organization categoryOfElement: oldName. > self organization classify: newName under: category suppressIfDefault: true. > self organization removeElement: oldName. > > binding := self declarationOf: oldName. > declarations removeKey: oldName. > self binding: binding removedFrom: self. > > binding := newName => aClass. > declarations add: binding. > self binding: binding addedTo: self. > > Smalltalk renamedClass: aClass from: oldName to: newName. > SystemChangeNotifier uniqueInstance > classRenamed: aClass > from: oldName > to: newName > inCategory: category > > > But should the change go in Environment>>renameClass:from:to: or in the BindingPolicy? i.e. it could be implemented either in Environment>>renameClass:from:to:, or in Environment>>showBinding:. I guess the former, but I'm cc'ing Colin, because know it?, he wrote it! > > and if the fix should indeed go in Environment>>renameClass:from:to: , it is as simple as > > Environment>>renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | binding category | > category := self organization categoryOfElement: oldName. > self organization classify: newName under: category suppressIfDefault: true. > self organization removeElement: oldName. > > binding := self declarationOf: oldName. > declarations removeKey: oldName. > self binding: binding removedFrom: self. > > binding := newName => aClass. > declarations add: binding. > self binding: binding addedTo: self. > > ** aClass updateMethodBindingsTo: binding. > > Smalltalk renamedClass: aClass from: oldName to: newName. > SystemChangeNotifier uniqueInstance > classRenamed: aClass > from: oldName > to: newName > inCategory: category > > I'll make this change and we can alter later if Colin thinks it's in the wrong place. > > Eliot, be sure to check my changes before you do that. We try to fix the same problem! Best -Tobias > In any case there needs to be a test that checks that a method's methodClassAssociation is correctly updated after a rename. I bet Colin would have not made this slip had there been a test. > > > Here's the code I used to test this: > > | mca1 mca2 | > Object compile: 'test ^''Hello from Object'''. > (Object > subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' > poolDictionaries: '' > category: 'Test') > compile: 'test ^ super halt test, ''my super call lands on itself!'''. > mca1 := ((Smalltalk classNamed: #MyClass)>>#test) methodClassAssociation. > (Smalltalk classNamed: #MyClass) > rename: 'MyNewAbstraction'. > mca2 := ((Smalltalk classNamed: #MyNewAbstraction)>>#test) methodClassAssociation. > { mca1. mca2. mca1 == mca2. mca1 == (Smalltalk bindingOf: #MyNewAbstraction). mca2 == (Smalltalk bindingOf: #MyNewAbstraction)} > > It answers { #MyClass=>nil . #MyClass=>nil . true . false . false} > i.e. the binding isn't updated, but changes from #MyClass=>MyClass to #MyClass=>nil in binding:removedFrom:. From eliot.miranda at gmail.com Tue Jan 20 20:38:18 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 20 20:38:20 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: Ugh, I'm behind the times, Tobias you've already fixed it; thanks! Tobias, I like your use of becomeForward:; it is more robust. But I *think* the undeclared removal is misplaced. Don't you think that that code belongs in the BindingPolicy? On Tue, Jan 20, 2015 at 12:33 PM, Eliot Miranda wrote: > > > On Tue, Jan 20, 2015 at 12:26 PM, Eliot Miranda > wrote: > >> Hi Chris, Hi Colin, >> >> >> On Thu, Jan 15, 2015 at 2:48 PM, Chris Muller >> wrote: >> >>> I did a minor class-hierarchy refactoring today which resulted in a an >>> invalid super pointer, resulting in a confusing image lock up due to >>> tight recursion. The script, below, demonstrates the issue in trunk: >>> >>> Object compile: 'test ^''Hello from Object'''. >>> (Object subclass: #MyClass instanceVariableNames: '' >>> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >>> 'test ^ super halt test, ''my super call lands on myself!'''. >>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >>> ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass >>> instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' >>> category: 'Test'). >>> (Smalltalk classNamed: #MyNewAbstraction) new test >>> >>> But an existing method in the original MyClass had a call to super >>> which now lands in itself, resulting in a tight recursion. >>> >>> The same script without creating the new subclass results in an >>> instant VM crash (both interpreter 2357 and cog 3205): >>> >>> Object compile: 'test ^''Hello from Object'''. >>> (Object subclass: #MyClass instanceVariableNames: '' >>> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >>> 'test ^ super halt test, ''my super call lands on itself!'''. >>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >>> (Smalltalk classNamed: #MyNewAbstraction) new test >>> >>> I even tried recompiling my entire class hierarchy which was renamed, >>> but it didn't help. >>> >>> How can this be? I _KNOW_ I've used rename class many times in the >>> past... A regression? >>> >> >> This is indeed an Environments regression. The issue is where to fix the >> problem. One way to look at it is that Environment>>renameClass:from:to: >> does not update bindings in the renamed class's methods. >> >> Here's what the old code did: >> >> SystemDictionary>>renameClass: aClass from: oldName to: newName >> "Rename the class, aClass, to have the title newName." >> >> | oldref category | >> category := SystemOrganization categoryOfElement: oldName. >> self organization classify: newName under: category suppressIfDefault: >> true. >> self organization removeElement: oldName. >> oldref := self associationAt: oldName. >> self removeKey: oldName. >> ** oldref key: newName. >> self add: oldref. "Old association preserves old refs" >> Smalltalk renamedClass: aClass from: oldName to: newName. >> self flushClassNameCache. >> SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName >> to: newName inCategory: category >> >> The starred line changes the key on the old class's binding, meaning that >> all the methods whose methodClassAssociation is that binding get >> automatically updated (note that class methods have >> a methodClassAssociation that has no key and just points to the class >> object). >> >> The new code simply forgets to do this: >> >> Environment>>renameClass: aClass from: oldName to: newName >> "Rename the class, aClass, to have the title newName." >> >> | binding category | >> category := self organization categoryOfElement: oldName. >> self organization classify: newName under: category suppressIfDefault: >> true. >> self organization removeElement: oldName. >> binding := self declarationOf: oldName. >> declarations removeKey: oldName. >> self binding: binding removedFrom: self. >> binding := newName => aClass. >> declarations add: binding. >> self binding: binding addedTo: self. >> Smalltalk renamedClass: aClass from: oldName to: newName. >> SystemChangeNotifier uniqueInstance >> classRenamed: aClass >> from: oldName >> to: newName >> inCategory: category >> >> >> But should the change go in Environment>>renameClass:from:to: or in the >> BindingPolicy? i.e. it could be implemented either in >> Environment>>renameClass:from:to:, or in Environment>>showBinding:. I >> guess the former, but I'm cc'ing Colin, because know it?, he wrote it! >> > > and if the fix should indeed go in Environment>>renameClass:from:to: , it > is as simple as > > Environment>>renameClass: aClass from: oldName to: newName > "Rename the class, aClass, to have the title newName." > > | binding category | > category := self organization categoryOfElement: oldName. > self organization classify: newName under: category suppressIfDefault: > true. > self organization removeElement: oldName. > binding := self declarationOf: oldName. > declarations removeKey: oldName. > self binding: binding removedFrom: self. > binding := newName => aClass. > declarations add: binding. > self binding: binding addedTo: self. > > ** aClass updateMethodBindingsTo: binding. > Smalltalk renamedClass: aClass from: oldName to: newName. > SystemChangeNotifier uniqueInstance > classRenamed: aClass > from: oldName > to: newName > inCategory: category > > I'll make this change and we can alter later if Colin thinks it's in the > wrong place. > > >> >> In any case there needs to be a test that checks that a method's >> methodClassAssociation is correctly updated after a rename. I bet Colin >> would have not made this slip had there been a test. >> >> >> Here's the code I used to test this: >> >> | mca1 mca2 | >> Object compile: 'test ^''Hello from Object'''. >> (Object >> subclass: #MyClass instanceVariableNames: '' >> classVariableNames: '' >> poolDictionaries: '' >> category: 'Test') >> compile: 'test ^ super halt test, ''my super call lands on itself!'''. >> mca1 := ((Smalltalk classNamed: #MyClass)>>#test) methodClassAssociation. >> (Smalltalk classNamed: #MyClass) >> rename: 'MyNewAbstraction'. >> mca2 := ((Smalltalk classNamed: #MyNewAbstraction)>>#test) >> methodClassAssociation. >> { mca1. mca2. mca1 == mca2. mca1 == (Smalltalk bindingOf: >> #MyNewAbstraction). mca2 == (Smalltalk bindingOf: #MyNewAbstraction)} >> >> It answers { #MyClass=>nil . #MyClass=>nil . true . false . false} >> i.e. the binding isn't updated, but changes from #MyClass=>MyClass to >> #MyClass=>nil in binding:removedFrom:. >> >> >> -- >> HTH, >> Eliot >> > > > > -- > best, > Eliot > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/dd0cf827/attachment-0001.htm From Das.Linux at gmx.de Tue Jan 20 20:42:20 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue Jan 20 20:42:23 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: On 20.01.2015, at 21:38, Eliot Miranda wrote: > Ugh, I'm behind the times, Tobias you've already fixed it; thanks! Tobias, I like your use of becomeForward:; it is more robust. But I *think* the undeclared removal is misplaced. Don't you think that that code belongs in the BindingPolicy? Probably this is true, but then BindingPolicy has to have a notion of renaming, which it does not have to this point. The removal from the undeclared is only sensible in the renaming case. Best -Tobias PS: Other comments in the other mail. From Das.Linux at gmx.de Tue Jan 20 21:05:55 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue Jan 20 21:05:57 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: <3D39B2D4-26DE-4728-AD2B-D73EA3D11EA2@gmx.de> Hi, On 20.01.2015, at 21:33, Eliot Miranda wrote: > > ** aClass updateMethodBindingsTo: binding. While this will fix the home method problem, the effect is that other bindings are not updated. Probabl A) In 4.4, this works: | p | p := Object subclass: #Peter instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Unknown'. p compile: 'susi ^ Peter new'. " literals of #susi: {#Peter->Peter . #susi . #Peter->Peter} " p rename: #Anton. " literals of #susi: {#Anton->Anton . #susi . #Anton->Anton} " p new susi. "Works, returns an Anton, but source is out of sync" B) In 4.5: | p | p := Object subclass: #Peter instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Unknown'. p compile: 'susi ^ Peter new'. " literals of #susi: {#Peter=>Peter . #susi . #Peter=>Peter} " p rename: #Anton. " literals of #susi: {#Peter=>nil . #susi . #Peter=>nil} " p new susi. "Does not work, throws a DNU on nil, using #susi may crash the vm " C) In Trunk, after Environments-topa.54: | p | p := Object subclass: #Peter instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Unknown'. p compile: 'susi ^ Peter new'. " literals of #susi: {#Peter=>Peter . #susi . #Peter=>Peter} " p rename: #Anton. " literals of #susi: {#Anton=>Anton . #susi . #Anton=>Anton} " p new susi. "Works, returns an Anton, but source is out of sync" So, we got the 4.4 behavior back. However, Colin (cc) explicitly has a test that checks that a rename actually creates a new binding[1]. This mean, with Eliot's patch it would look like this: D) | p | p := Object subclass: #Peter instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Unknown'. p compile: 'susi ^ Peter new'. " literals of #susi: {#Peter=>Peter . #susi . #Peter=>Peter} " p rename: #Anton. " literals of #susi: {#Peter=>nil . #susi . #Anton=>Anton} " p new susi. "Does not work, throws a DNU on nil, would not crash the VM, Source is in sync, because Peter is now undeclared." After some discussion with Bert, we came to the conclusion that either of C) or D) can be desirable; the literal `Peter` is actually undeclared (as per D)) and probably running into an error is the right thing. Yet C) retains backwards compatibility. Ideas? Best -Tobias [1]: Colin, could you elaborate on that? From bert at freudenbergs.de Tue Jan 20 21:09:25 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue Jan 20 21:09:29 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: (got interrupted writing this, and now the discussion has progressed, but I'll send anyway) On 20.01.2015, at 21:26, Eliot Miranda wrote: > > This is indeed an Environments regression. The issue is where to fix the problem. One way to look at it is that Environment>>renameClass:from:to: does not update bindings in the renamed class's methods. I sat down with Tobias today, and a fix is in Trunk. It updates the bindings in method literals. > I bet Colin would have not made this slip had there been a test. It seemed to me as if Colin made a conscious decision to not keep the binding "alive". Instead, he changed the bindings in the compiled method to be #OldName->nil and puts it in Undeclared, and created a new binding in the environment as #NewName->aClass. There is even a test ensuring that oldBinding ~~ newBinding. I guess this is to ensure that what the method source says matches what the compiled method does. After renaming the class, the source code still uses OldName, but accepting it as-is would result in a binding like #OldName->nil to be created in Undeclared. Essentially, this way of doing it ensures that decompiling the method is not different from the actual source after a class rename, both use 'OldName'. However, I'd argue it's more important that the system keeps working while renaming a class. That's what the old scheme did - it simply stored the new class name as key of the binding, not disturbing execution at all. Our fix restores that behavior, albeit using #becomeForward: as did Colin's code, and we were not exactly sure, why. I still don't see why the become would be necessary. Note that we did not actually test this with multiple environments, aliases etc. One idea I had after this is that we perhaps could move the old binding to undeclared (keeping methods both working and decompilable) and additionally create a new binding under the new class name. Perhaps this is what Colin intended all along, and it was only the implementation that was buggy? If we knew exactly what we want, it seems like the environment code is reasonably simple to make it do that. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/720c43c1/smime.bin From leves at elte.hu Tue Jan 20 21:31:17 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue Jan 20 21:31:19 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: On Tue, 20 Jan 2015, Eliot Miranda wrote: > > > On Tue, Jan 20, 2015 at 2:22 AM, Nicolas Cellier wrote: > > > 2015-01-20 2:18 GMT+01:00 Eliot Miranda : > > > On Mon, Jan 19, 2015 at 5:09 PM, Levente Uzonyi wrote: > On Mon, 19 Jan 2015, Eliot Miranda wrote: > > > > On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier wrote: > ? ? ? Hi Tobias, > ? ? ? are you aware of CurrentReadOnlySourceFiles cacheDuring: [...] > This is to workaround the readOnlyCopy used for thread safety which is the main killer of performance... > > > IMO this is a bug.? We should simply have a single read-only copy of each sources file and modify the debugger to either save and restore the state of a > read-only copy around accessing source, or use its own > read-only copy (except that the latter approach breaks when one debugs the debugger).? The difference in performance between using CurrentReadOnlySourceFiles > cacheDuring: [...] and not in anything that > accesses source is huge.? And CurrentReadOnlySourceFiles cacheDuring: [...] is a /lot/ of verbiage to type in doits, and a sign that something is wrong. > > > How would using a single copy solve the concurrency issues? > > > It wouldn't, but what issues are you seeing in concurrent source access?? VW doesn't even have read-only copies and AFAICR we never had complaints about this.? Is there really a thread-safety > issue here? > ? > > > Couldn't there be a difference because VW properly handle read-append-stream for the underlying FILE? > I have the feeling that such FILE is more robust to single write - multiple read concurrency, than a random-read-write FILE as used by Squeak... > > > Maybe.? And Tim's point about the file api is well0-taken, but its much more work at the Smalltalk level than at the VM level. > > However, I still want to see evidence of the potential thread-safety issues.? Access to the source files for writing is not thread-safe anyway but no one complains about that.? So I suspect we may be trying > to fix a problem that doesn't really exist.? IMO it is much more preferable to have fast access to source than thread-safety.? If someone wants thread-safe access they can roll their own solution (e.g. > install a wrapper hiding a mutex around the source files).? The common case of accessing source should be fast.? The difference between I couldn't find out what the exact case was, but some tools (e.g. Slint) use background processes to examine a set of classes and their methods. > > ? ? self systemNavigation?allSelect: [:m| m getSourceFromFile asString includesSubString: 'not likely'] > > and > > ? ? CurrentReadOnlySourceFiles cacheDuring: [self systemNavigation allSelect: [:m| m getSourceFromFile asString includesSubString: 'not likely']] > > is 34 to 1 (!!), 28 seconds vs 0.8. I guess your numbers include the time it takes for the OS to read the data from the disk. This is added to the first test of the first run, but it's not added to the second test, because then the files are already cached. The numbers on my machine - ignoring the first run - are 3.215s and 0.685s, which means 4.7x speedup. Levente > > :-( > > > I think the real solution would be to use per process copies, which were initialized lazily, and were closed automatically after some time of inactivity. > > > If concurrent access was really an issue then OK.? But first I'd like some evidence that there's a real problem here. > -- > best,Eliot > > > > > > > > > > > -- > best,Eliot > > From nicolas.cellier.aka.nice at gmail.com Tue Jan 20 21:32:41 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Tue Jan 20 21:32:43 2015 Subject: [squeak-dev] The Trunk: System-cmm.694.mcz In-Reply-To: References: <54b98661.43318c0a.8f14.464eSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: 2015-01-20 20:40 GMT+01:00 Eliot Miranda : > > > On Mon, Jan 19, 2015 at 1:59 AM, Frank Shearar > wrote: > >> On 17 January 2015 at 18:35, Eliot Miranda >> wrote: >> > Hi Frank, >> > >> > On Jan 17, 2015, at 3:39 AM, Frank Shearar >> wrote: >> > >> >> On 16 January 2015 at 21:44, wrote: >> >>> Chris Muller uploaded a new version of System to project The Trunk: >> >>> http://source.squeak.org/trunk/System-cmm.694.mcz >> >>> >> >>> ==================== Summary ==================== >> >>> >> >>> Name: System-cmm.694 >> >>> Author: cmm >> >>> Time: 16 January 2015, 3:44:19.079 pm >> >>> UUID: e79a2347-2f40-4fec-8f00-f67ecad68491 >> >>> Ancestors: System-dtl.693 >> >>> >> >>> - #flush stdout and stderr after writing error information to them. >> >>> - After that, if the exception is resumable (i.e. a Warning), resume >> it. Except if its a MessageNotUnderstood -- that is not an error you want >> to resume in a headless environment. >> >> >> >> Why? It's probably a rare use case for a #run: script to catch MNUs to >> >> do something fancy, I guess? Maybe it's because #run: is usually >> >> (always?) the top level of the program? >> > >> > One reason is that resuming an MNU simply resends from the >> diesNotUnderstand: method, so resuming will result in infinite recursion. >> I suppose the handler could allow one repeat but that seems arbitrary. >> There's nothing to stop one including a resuming MNU handler in the >> expression if one wants to override the default behaviour. >> > >> >> >> >> Catching only MNUs seems very specific. Maybe there could be a #run: >> >> version that says "and here's a function you can use to control which >> >> exceptions are OK to resume, and which not"? >> > >> > Well there is Notification and Warning but (rightly) >> MessageNotUnderstood is an Error. Reporting Notifications and Warnings to >> the output and continuing, but aborting for other exceptions seems the >> right thing to do, rather than basing it in resumability, yes? What am I >> missing? >> > >> > Whether an exception is resumability or not is to do with whether one >> can usefully provide a value with which to continue, not to do with the >> severity of the error. >> >> Chris has already addressed the issue, but to continue the >> conversation here, yes, an exception is resumable if e isResumable = >> true. That's exactly as it should be. But seeing as an MNU is >> resumable, you could write a handler that _did_ return a value. In >> other words, the problem that I saw - and I think Chris and you agree? >> - is that it looks weird to resume some resumable exceptions but not >> others. >> > > I think we all agree on this. There's no case for resuming anything other > than Notification, Warning and subclasses. > > +1, see also http://stackoverflow.com/questions/27679183/why-zerodivide-is-resumable It explains why some exceptions are resumable... And why it's not allways a good idea to resume an exception just because it is resumable. Nicolas > I agree with the point you make in a later mail, that #run: should >> just bail noisily on a top-level exception. >> >> frank >> >> > For example, being able to resume with nil for a permissions violation >> when opening a file or directory might make it really easy to implement a >> find(1) like search over directories where some may be unreadable due to >> permissions. Being able to resume doesn't make the permissions violation >> any the less severe, but it dies give us a nice way if handling it, >> certainly less complex than having to explicitly check for permissions >> during the traversal. Likewise, being able to substitute a value for an >> MNU allows all sorts of conveniences, eg see my code for disassembling >> methods to bytecode messages. >> > >> > So IMO the system should be reporting Notifications and Warnings and >> aborting for anything else. >> >> Yep. >> >> >> frank >> > >> > Eliot (phone) >> >> > > > -- > best, > Eliot > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/c4683ea2/attachment.htm From asqueaker at gmail.com Tue Jan 20 22:56:46 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue Jan 20 22:56:49 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: Hi Eliot, there were TWO problems, Bert and Tobias have fixed one of them. The second one is still unfixed in trunk. When you run this script and arrive at the debugger, step INTO: Object compile: 'test ^''Hello from Object'''. (Object subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test') compile: 'test ^ super halt test, ''my super call lands on itself!'''. (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. (Smalltalk classNamed: #MyNewAbstraction) new test then be sure to step INTO the super call to #test. See how it lands you in teh same method? THAT bug exists back at least as far back as 4.2, so I don't think its Environments related. I took a look at it and presented my findings in the other email thread with subject "The Inbox: Environments-cmm.52.mcz", -- that screenshot showing that the bytecodes are teh same and the literal binding looks correct. So I have no idea why its not calling super correctly... On Tue, Jan 20, 2015 at 2:38 PM, Eliot Miranda wrote: > > Ugh, I'm behind the times, Tobias you've already fixed it; thanks! Tobias, I like your use of becomeForward:; it is more robust. But I *think* the undeclared removal is misplaced. Don't you think that that code belongs in the BindingPolicy? > > On Tue, Jan 20, 2015 at 12:33 PM, Eliot Miranda wrote: >> >> >> >> On Tue, Jan 20, 2015 at 12:26 PM, Eliot Miranda wrote: >>> >>> Hi Chris, Hi Colin, >>> >>> >>> On Thu, Jan 15, 2015 at 2:48 PM, Chris Muller wrote: >>>> >>>> I did a minor class-hierarchy refactoring today which resulted in a an >>>> invalid super pointer, resulting in a confusing image lock up due to >>>> tight recursion. The script, below, demonstrates the issue in trunk: >>>> >>>> Object compile: 'test ^''Hello from Object'''. >>>> (Object subclass: #MyClass instanceVariableNames: '' >>>> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >>>> 'test ^ super halt test, ''my super call lands on myself!'''. >>>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >>>> ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass >>>> instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' >>>> category: 'Test'). >>>> (Smalltalk classNamed: #MyNewAbstraction) new test >>>> >>>> But an existing method in the original MyClass had a call to super >>>> which now lands in itself, resulting in a tight recursion. >>>> >>>> The same script without creating the new subclass results in an >>>> instant VM crash (both interpreter 2357 and cog 3205): >>>> >>>> Object compile: 'test ^''Hello from Object'''. >>>> (Object subclass: #MyClass instanceVariableNames: '' >>>> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >>>> 'test ^ super halt test, ''my super call lands on itself!'''. >>>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >>>> (Smalltalk classNamed: #MyNewAbstraction) new test >>>> >>>> I even tried recompiling my entire class hierarchy which was renamed, >>>> but it didn't help. >>>> >>>> How can this be? I _KNOW_ I've used rename class many times in the >>>> past... A regression? >>> >>> >>> This is indeed an Environments regression. The issue is where to fix the problem. One way to look at it is that Environment>>renameClass:from:to: does not update bindings in the renamed class's methods. >>> >>> Here's what the old code did: >>> >>> SystemDictionary>>renameClass: aClass from: oldName to: newName >>> "Rename the class, aClass, to have the title newName." >>> >>> | oldref category | >>> category := SystemOrganization categoryOfElement: oldName. >>> self organization classify: newName under: category suppressIfDefault: true. >>> self organization removeElement: oldName. >>> oldref := self associationAt: oldName. >>> self removeKey: oldName. >>> ** oldref key: newName. >>> self add: oldref. "Old association preserves old refs" >>> Smalltalk renamedClass: aClass from: oldName to: newName. >>> self flushClassNameCache. >>> SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category >>> >>> The starred line changes the key on the old class's binding, meaning that all the methods whose methodClassAssociation is that binding get automatically updated (note that class methods have a methodClassAssociation that has no key and just points to the class object). >>> >>> The new code simply forgets to do this: >>> >>> Environment>>renameClass: aClass from: oldName to: newName >>> "Rename the class, aClass, to have the title newName." >>> >>> | binding category | >>> category := self organization categoryOfElement: oldName. >>> self organization classify: newName under: category suppressIfDefault: true. >>> self organization removeElement: oldName. >>> binding := self declarationOf: oldName. >>> declarations removeKey: oldName. >>> self binding: binding removedFrom: self. >>> binding := newName => aClass. >>> declarations add: binding. >>> self binding: binding addedTo: self. >>> Smalltalk renamedClass: aClass from: oldName to: newName. >>> SystemChangeNotifier uniqueInstance >>> classRenamed: aClass >>> from: oldName >>> to: newName >>> inCategory: category >>> >>> >>> But should the change go in Environment>>renameClass:from:to: or in the BindingPolicy? i.e. it could be implemented either in Environment>>renameClass:from:to:, or in Environment>>showBinding:. I guess the former, but I'm cc'ing Colin, because know it?, he wrote it! >> >> >> and if the fix should indeed go in Environment>>renameClass:from:to: , it is as simple as >> >> Environment>>renameClass: aClass from: oldName to: newName >> "Rename the class, aClass, to have the title newName." >> >> | binding category | >> category := self organization categoryOfElement: oldName. >> self organization classify: newName under: category suppressIfDefault: true. >> self organization removeElement: oldName. >> binding := self declarationOf: oldName. >> declarations removeKey: oldName. >> self binding: binding removedFrom: self. >> binding := newName => aClass. >> declarations add: binding. >> self binding: binding addedTo: self. >> >> ** aClass updateMethodBindingsTo: binding. >> Smalltalk renamedClass: aClass from: oldName to: newName. >> SystemChangeNotifier uniqueInstance >> classRenamed: aClass >> from: oldName >> to: newName >> inCategory: category >> >> I'll make this change and we can alter later if Colin thinks it's in the wrong place. >> >>> >>> >>> In any case there needs to be a test that checks that a method's methodClassAssociation is correctly updated after a rename. I bet Colin would have not made this slip had there been a test. >>> >>> >>> Here's the code I used to test this: >>> >>> | mca1 mca2 | >>> Object compile: 'test ^''Hello from Object'''. >>> (Object >>> subclass: #MyClass instanceVariableNames: '' >>> classVariableNames: '' >>> poolDictionaries: '' >>> category: 'Test') >>> compile: 'test ^ super halt test, ''my super call lands on itself!'''. >>> mca1 := ((Smalltalk classNamed: #MyClass)>>#test) methodClassAssociation. >>> (Smalltalk classNamed: #MyClass) >>> rename: 'MyNewAbstraction'. >>> mca2 := ((Smalltalk classNamed: #MyNewAbstraction)>>#test) methodClassAssociation. >>> { mca1. mca2. mca1 == mca2. mca1 == (Smalltalk bindingOf: #MyNewAbstraction). mca2 == (Smalltalk bindingOf: #MyNewAbstraction)} >>> >>> It answers { #MyClass=>nil . #MyClass=>nil . true . false . false} >>> i.e. the binding isn't updated, but changes from #MyClass=>MyClass to #MyClass=>nil in binding:removedFrom:. >>> >>> >>> -- >>> HTH, >>> Eliot >> >> >> >> >> -- >> best, >> Eliot > > > > > -- > best, > Eliot > > > From eliot.miranda at gmail.com Tue Jan 20 23:01:32 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 20 23:01:34 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: Hi Levente, On Tue, Jan 20, 2015 at 1:31 PM, Levente Uzonyi wrote: > On Tue, 20 Jan 2015, Eliot Miranda wrote: > > >> >> On Tue, Jan 20, 2015 at 2:22 AM, Nicolas Cellier < >> nicolas.cellier.aka.nice@gmail.com> wrote: >> >> >> 2015-01-20 2:18 GMT+01:00 Eliot Miranda : >> >> >> On Mon, Jan 19, 2015 at 5:09 PM, Levente Uzonyi < >> leves@elte.hu> wrote: >> On Mon, 19 Jan 2015, Eliot Miranda wrote: >> >> >> >> On Mon, Jan 19, 2015 at 1:31 PM, Nicolas Cellier < >> nicolas.cellier.aka.nice@gmail.com> wrote: >> Hi Tobias, >> are you aware of CurrentReadOnlySourceFiles >> cacheDuring: [...] >> This is to workaround the readOnlyCopy used for >> thread safety which is the main killer of performance... >> >> >> IMO this is a bug. We should simply have a >> single read-only copy of each sources file and modify the debugger to >> either save and restore the state of a >> read-only copy around accessing source, or use >> its own >> read-only copy (except that the latter approach >> breaks when one debugs the debugger). The difference in performance >> between using CurrentReadOnlySourceFiles >> cacheDuring: [...] and not in anything that >> accesses source is huge. And >> CurrentReadOnlySourceFiles cacheDuring: [...] is a /lot/ of verbiage to >> type in doits, and a sign that something is wrong. >> >> >> How would using a single copy solve the concurrency >> issues? >> >> >> It wouldn't, but what issues are you seeing in concurrent source access? >> VW doesn't even have read-only copies and AFAICR we never had complaints >> about this. Is there really a thread-safety >> issue here? >> >> >> >> Couldn't there be a difference because VW properly handle >> read-append-stream for the underlying FILE? >> I have the feeling that such FILE is more robust to single write - >> multiple read concurrency, than a random-read-write FILE as used by >> Squeak... >> >> >> Maybe. And Tim's point about the file api is well0-taken, but its much >> more work at the Smalltalk level than at the VM level. >> >> However, I still want to see evidence of the potential thread-safety >> issues. Access to the source files for writing is not thread-safe anyway >> but no one complains about that. So I suspect we may be trying >> to fix a problem that doesn't really exist. IMO it is much more >> preferable to have fast access to source than thread-safety. If someone >> wants thread-safe access they can roll their own solution (e.g. >> install a wrapper hiding a mutex around the source files). The common >> case of accessing source should be fast. The difference between >> > > I couldn't find out what the exact case was, but some tools (e.g. Slint) > use background processes to examine a set of classes and their methods. > > >> self systemNavigation allSelect: [:m| m getSourceFromFile asString >> includesSubString: 'not likely'] >> >> and >> >> CurrentReadOnlySourceFiles cacheDuring: [self systemNavigation >> allSelect: [:m| m getSourceFromFile asString includesSubString: 'not >> likely']] >> >> is 34 to 1 (!!), 28 seconds vs 0.8. >> > > I guess your numbers include the time it takes for the OS to read the data > from the disk. This is added to the first test of the first run, but it's > not added to the second test, because then the files are already cached. > > The numbers on my machine - ignoring the first run - are 3.215s and > 0.685s, which means 4.7x speedup. Good point. When I run the cacheing version first my times are 640ms vs 6589ms, 10.3 to 1. That's still very large. > > > Levente > > > >> :-( >> >> >> I think the real solution would be to use per process >> copies, which were initialized lazily, and were closed automatically after >> some time of inactivity. >> >> >> If concurrent access was really an issue then OK. But first I'd like >> some evidence that there's a real problem here. >> -- >> best,Eliot >> >> >> >> >> >> >> >> >> >> >> -- >> best,Eliot >> >> > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/2c53d543/attachment.htm From nicolas.cellier.aka.nice at gmail.com Wed Jan 21 00:05:37 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 21 00:05:39 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: 2015-01-20 23:56 GMT+01:00 Chris Muller : > Hi Eliot, there were TWO problems, Bert and Tobias have fixed one of > them. The second one is still unfixed in trunk. When you run this > script and arrive at the debugger, step INTO: > > Object compile: 'test ^''Hello from Object'''. > (Object subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > 'test ^ super halt test, ''my super call lands on itself!'''. > (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > (Smalltalk classNamed: #MyNewAbstraction) new test > > But it behaves as it should... You first send halt to super. If you resume it just answer self. Then you send test to self (it's not a super send and never been) > then be sure to step INTO the super call to #test. See how it lands > you in teh same method? THAT bug exists back at least as far back as > 4.2, so I don't think its Environments related. > > I took a look at it and presented my findings in the other email > thread with subject "The Inbox: Environments-cmm.52.mcz", -- that > screenshot showing that the bytecodes are teh same and the literal > binding looks correct. > > So I have no idea why its not calling super correctly... > > > On Tue, Jan 20, 2015 at 2:38 PM, Eliot Miranda > wrote: > > > > Ugh, I'm behind the times, Tobias you've already fixed it; thanks! > Tobias, I like your use of becomeForward:; it is more robust. But I > *think* the undeclared removal is misplaced. Don't you think that that > code belongs in the BindingPolicy? > > > > On Tue, Jan 20, 2015 at 12:33 PM, Eliot Miranda > wrote: > >> > >> > >> > >> On Tue, Jan 20, 2015 at 12:26 PM, Eliot Miranda < > eliot.miranda@gmail.com> wrote: > >>> > >>> Hi Chris, Hi Colin, > >>> > >>> > >>> On Thu, Jan 15, 2015 at 2:48 PM, Chris Muller > wrote: > >>>> > >>>> I did a minor class-hierarchy refactoring today which resulted in a an > >>>> invalid super pointer, resulting in a confusing image lock up due to > >>>> tight recursion. The script, below, demonstrates the issue in trunk: > >>>> > >>>> Object compile: 'test ^''Hello from Object'''. > >>>> (Object subclass: #MyClass instanceVariableNames: '' > >>>> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > >>>> 'test ^ super halt test, ''my super call lands on myself!'''. > >>>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > >>>> ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass > >>>> instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' > >>>> category: 'Test'). > >>>> (Smalltalk classNamed: #MyNewAbstraction) new test > >>>> > >>>> But an existing method in the original MyClass had a call to super > >>>> which now lands in itself, resulting in a tight recursion. > >>>> > >>>> The same script without creating the new subclass results in an > >>>> instant VM crash (both interpreter 2357 and cog 3205): > >>>> > >>>> Object compile: 'test ^''Hello from Object'''. > >>>> (Object subclass: #MyClass instanceVariableNames: '' > >>>> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > >>>> 'test ^ super halt test, ''my super call lands on itself!'''. > >>>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > >>>> (Smalltalk classNamed: #MyNewAbstraction) new test > >>>> > >>>> I even tried recompiling my entire class hierarchy which was renamed, > >>>> but it didn't help. > >>>> > >>>> How can this be? I _KNOW_ I've used rename class many times in the > >>>> past... A regression? > >>> > >>> > >>> This is indeed an Environments regression. The issue is where to fix > the problem. One way to look at it is that > Environment>>renameClass:from:to: does not update bindings in the renamed > class's methods. > >>> > >>> Here's what the old code did: > >>> > >>> SystemDictionary>>renameClass: aClass from: oldName to: newName > >>> "Rename the class, aClass, to have the title newName." > >>> > >>> | oldref category | > >>> category := SystemOrganization categoryOfElement: oldName. > >>> self organization classify: newName under: category suppressIfDefault: > true. > >>> self organization removeElement: oldName. > >>> oldref := self associationAt: oldName. > >>> self removeKey: oldName. > >>> ** oldref key: newName. > >>> self add: oldref. "Old association preserves old refs" > >>> Smalltalk renamedClass: aClass from: oldName to: newName. > >>> self flushClassNameCache. > >>> SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName > to: newName inCategory: category > >>> > >>> The starred line changes the key on the old class's binding, meaning > that all the methods whose methodClassAssociation is that binding get > automatically updated (note that class methods have a > methodClassAssociation that has no key and just points to the class object). > >>> > >>> The new code simply forgets to do this: > >>> > >>> Environment>>renameClass: aClass from: oldName to: newName > >>> "Rename the class, aClass, to have the title newName." > >>> > >>> | binding category | > >>> category := self organization categoryOfElement: oldName. > >>> self organization classify: newName under: category suppressIfDefault: > true. > >>> self organization removeElement: oldName. > >>> binding := self declarationOf: oldName. > >>> declarations removeKey: oldName. > >>> self binding: binding removedFrom: self. > >>> binding := newName => aClass. > >>> declarations add: binding. > >>> self binding: binding addedTo: self. > >>> Smalltalk renamedClass: aClass from: oldName to: newName. > >>> SystemChangeNotifier uniqueInstance > >>> classRenamed: aClass > >>> from: oldName > >>> to: newName > >>> inCategory: category > >>> > >>> > >>> But should the change go in Environment>>renameClass:from:to: or in > the BindingPolicy? i.e. it could be implemented either in > Environment>>renameClass:from:to:, or in Environment>>showBinding:. I > guess the former, but I'm cc'ing Colin, because know it?, he wrote it! > >> > >> > >> and if the fix should indeed go in Environment>>renameClass:from:to: , > it is as simple as > >> > >> Environment>>renameClass: aClass from: oldName to: newName > >> "Rename the class, aClass, to have the title newName." > >> > >> | binding category | > >> category := self organization categoryOfElement: oldName. > >> self organization classify: newName under: category suppressIfDefault: > true. > >> self organization removeElement: oldName. > >> binding := self declarationOf: oldName. > >> declarations removeKey: oldName. > >> self binding: binding removedFrom: self. > >> binding := newName => aClass. > >> declarations add: binding. > >> self binding: binding addedTo: self. > >> > >> ** aClass updateMethodBindingsTo: binding. > >> Smalltalk renamedClass: aClass from: oldName to: newName. > >> SystemChangeNotifier uniqueInstance > >> classRenamed: aClass > >> from: oldName > >> to: newName > >> inCategory: category > >> > >> I'll make this change and we can alter later if Colin thinks it's in > the wrong place. > >> > >>> > >>> > >>> In any case there needs to be a test that checks that a method's > methodClassAssociation is correctly updated after a rename. I bet Colin > would have not made this slip had there been a test. > >>> > >>> > >>> Here's the code I used to test this: > >>> > >>> | mca1 mca2 | > >>> Object compile: 'test ^''Hello from Object'''. > >>> (Object > >>> subclass: #MyClass instanceVariableNames: '' > >>> classVariableNames: '' > >>> poolDictionaries: '' > >>> category: 'Test') > >>> compile: 'test ^ super halt test, ''my super call lands on itself!'''. > >>> mca1 := ((Smalltalk classNamed: #MyClass)>>#test) > methodClassAssociation. > >>> (Smalltalk classNamed: #MyClass) > >>> rename: 'MyNewAbstraction'. > >>> mca2 := ((Smalltalk classNamed: #MyNewAbstraction)>>#test) > methodClassAssociation. > >>> { mca1. mca2. mca1 == mca2. mca1 == (Smalltalk bindingOf: > #MyNewAbstraction). mca2 == (Smalltalk bindingOf: #MyNewAbstraction)} > >>> > >>> It answers { #MyClass=>nil . #MyClass=>nil . true . false . false} > >>> i.e. the binding isn't updated, but changes from #MyClass=>MyClass to > #MyClass=>nil in binding:removedFrom:. > >>> > >>> > >>> -- > >>> HTH, > >>> Eliot > >> > >> > >> > >> > >> -- > >> best, > >> Eliot > > > > > > > > > > -- > > best, > > Eliot > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150121/4864fc2f/attachment.htm From tim at rowledge.org Wed Jan 21 00:12:45 2015 From: tim at rowledge.org (tim Rowledge) Date: Wed Jan 21 00:12:49 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> Message-ID: <1A95090F-20BD-4167-999F-D196DE1C1AD5@rowledge.org> On 20-01-2015, at 3:01 PM, Eliot Miranda wrote: > > I couldn't find out what the exact case was, but some tools (e.g. Slint) use background processes to examine a set of classes and their methods. Doesn?t Shout read the sources when colouring them? tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim "Bother!" said Pooh, searching for the $10m winning lottery ticket. From nicolas.cellier.aka.nice at gmail.com Wed Jan 21 00:25:03 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 21 00:25:04 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: <1A95090F-20BD-4167-999F-D196DE1C1AD5@rowledge.org> References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> <1A95090F-20BD-4167-999F-D196DE1C1AD5@rowledge.org> Message-ID: 2015-01-21 1:12 GMT+01:00 tim Rowledge : > > On 20-01-2015, at 3:01 PM, Eliot Miranda wrote: > > > > I couldn't find out what the exact case was, but some tools (e.g. Slint) > use background processes to examine a set of classes and their methods. > > > Doesn?t Shout read the sources when colouring them? > > Bingo! styler styleInBackgroundProcess: textMorph contents Since the position of a ReadWriteStream is for both reading and writing, the read and write are going to fight each other... In which case a read-append-stream would be superior, it would not write to the read-position, but allways append... ReadWriteStream really is a complex beast. > tim > -- > tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim > "Bother!" said Pooh, searching for the $10m winning lottery ticket. > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150121/f0db09ce/attachment.htm From nicolas.cellier.aka.nice at gmail.com Wed Jan 21 00:29:23 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 21 00:29:26 2015 Subject: Read-only source files (was: Re: [squeak-dev] Why is source code always in files only?) In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> <1A95090F-20BD-4167-999F-D196DE1C1AD5@rowledge.org> Message-ID: 2015-01-21 1:25 GMT+01:00 Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com>: > > > 2015-01-21 1:12 GMT+01:00 tim Rowledge : > >> >> On 20-01-2015, at 3:01 PM, Eliot Miranda wrote: >> > >> > I couldn't find out what the exact case was, but some tools (e.g. >> Slint) use background processes to examine a set of classes and their >> methods. >> >> >> Doesn?t Shout read the sources when colouring them? >> >> > Bingo! > styler styleInBackgroundProcess: textMorph contents > > Oops, answered too fast, textMorph contents indicates that the source were already fetched in foreground process... > Since the position of a ReadWriteStream is for both reading and writing, > the read and write are going to fight each other... > In which case a read-append-stream would be superior, it would not write > to the read-position, but allways append... > > ReadWriteStream really is a complex beast. > > >> tim >> -- >> tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim >> "Bother!" said Pooh, searching for the $10m winning lottery ticket. >> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150121/930311af/attachment-0001.htm From craig at netjam.org Wed Jan 21 01:31:26 2015 From: craig at netjam.org (Craig Latta) Date: Wed Jan 21 01:31:39 2015 Subject: [squeak-dev] re: Read-only source files In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> <1A95090F-20BD-4167-999F-D196DE1C1AD5@rowledge.org> Message-ID: > ReadWriteStream really is a complex beast. Now *that* is certain. The traditional Stream implementation is significantly bogus. I've never had a need for a write-only stream, so all streams can be readable by default; any exceptional circumstances can use... exceptions. Then ReadStream, WriteStream and ReadWriteStream go away, instead there's a WritableStream subclass of PositionableStream. Lots of discussion about multiple inheritance and traits also goes away, which is pleasant. ;) I suspect this is how They would have done it in the first place back in the day, if they had had exceptions. -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From nicolas.cellier.aka.nice at gmail.com Wed Jan 21 01:39:06 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 21 01:39:10 2015 Subject: [squeak-dev] re: Context status 2015-01-16 In-Reply-To: <54BD178F.8090501@netjam.org> References: <54B9A0D9.5000707@netjam.org> <54BD178F.8090501@netjam.org> Message-ID: 2015-01-19 15:41 GMT+01:00 Craig Latta : > > Okay, I'll add both of the execution-driven imprinters to the > repository. They're called "active" and "passive" imprinting. > > Active imprinting is directed by the system that initially has the > desired code. An ActiveImprintingServer has clients in the systems which > will receive the code. Every time the server system runs a method in a > certain process, it imprints that method onto each of the clients. One > use case for this is giving the code of a demo to an audience as you run > it. > > Passive imprinting is directed by the system that wants the code. > The target system makes a remote-messaging connection to a system which > has the code, and runs an expression which will use the code. Every time > a method is missing from the target system (in any process), the target > system requests the missing method from the provider system, installs > it, and retries running that method. > > I have imprinted the exception-handling system, the compiler, and > the class builder with both approaches. > > > In this scheme, something is striking me. Some images share some code (classes, compiledMethods) But what about code mutations/updates? Without such mutations, is it still Smalltalk? Without active imprinting, such mutations might not be obvious to propagate (for example a subclass now overrides a message of super) And since you import class builder and compiler in the target, on what purpose? Is the target going to change a class locally? What if it then imports incompatible methods from provider? Or is the goal to just replicate some mutations from the provider? Maybe the scheme is more interesting for deployment of static code, but I'm curious to know if ever live updates would still be possible... > thanks, > > -C > > -- > Craig Latta > netjam.org > +31 6 2757 7177 (SMS ok) > + 1 415 287 3547 (no SMS) > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150121/980d11ae/attachment.htm From nicolas.cellier.aka.nice at gmail.com Wed Jan 21 01:58:29 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed Jan 21 01:58:31 2015 Subject: [squeak-dev] re: Read-only source files In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> <1A95090F-20BD-4167-999F-D196DE1C1AD5@rowledge.org> Message-ID: 2015-01-21 2:31 GMT+01:00 Craig Latta : > > > ReadWriteStream really is a complex beast. > > Now *that* is certain. The traditional Stream implementation is > significantly bogus. I've never had a need for a write-only stream, so > all streams can be readable by default; any exceptional circumstances > can use... exceptions. Then ReadStream, WriteStream and ReadWriteStream > go away, instead there's a WritableStream subclass of > PositionableStream. Lots of discussion about multiple inheritance and > traits also goes away, which is pleasant. ;) > > Interesting POV. Following the Xtreams principles, I went the opposite way, rewriting every usage of ReadWriteStream into either ReadStream or WriteStream. I did only published some in trunk, but have more unfinished/untested... I never had to intermix read and write randomly in a stream, this should be reserved to very specific things like sharing state as in a database. Streams make sense for sequential processings, less for random access. Indeed, most usage of ReadWriteStream in Squeak is just for chaining several processings (like a unix pipe). So if I write into a collection thru a WriteStream, then read the contents with a ReadStream, I'm done. No complex multi-purpose objects with complex capabilities and exceptions, just simple objects with simple capabilities, composition and delegation. Nicolas I suspect this is how They would have done it in the first place > back in the day, if they had had exceptions. > > > -C > > -- > Craig Latta > netjam.org > +31 6 2757 7177 (SMS ok) > + 1 415 287 3547 (no SMS) > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150121/589dd312/attachment.htm From asqueaker at gmail.com Wed Jan 21 03:24:50 2015 From: asqueaker at gmail.com (Chris Muller) Date: Wed Jan 21 03:24:53 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: OMG.... :$ LOL!! I'm sooo embarassed..! I never write "super someMethodOtherThanTheOneImIn" but I sure did that with "super halt" didn't I? Duh. Now I'm wondering what my recursion was that locked up because it didn't have a halt in the loop.. Ugg, sorry, if I find this bug again I'll take better care to recreate it. :) On Tue, Jan 20, 2015 at 6:05 PM, Nicolas Cellier wrote: > > > 2015-01-20 23:56 GMT+01:00 Chris Muller : >> >> Hi Eliot, there were TWO problems, Bert and Tobias have fixed one of >> them. The second one is still unfixed in trunk. When you run this >> script and arrive at the debugger, step INTO: >> >> Object compile: 'test ^''Hello from Object'''. >> (Object subclass: #MyClass instanceVariableNames: '' >> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >> 'test ^ super halt test, ''my super call lands on itself!'''. >> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> (Smalltalk classNamed: #MyNewAbstraction) new test >> > > But it behaves as it should... > You first send halt to super. > If you resume it just answer self. > > Then you send test to self (it's not a super send and never been) > > >> >> then be sure to step INTO the super call to #test. See how it lands >> you in teh same method? THAT bug exists back at least as far back as >> 4.2, so I don't think its Environments related. >> >> I took a look at it and presented my findings in the other email >> thread with subject "The Inbox: Environments-cmm.52.mcz", -- that >> screenshot showing that the bytecodes are teh same and the literal >> binding looks correct. >> >> So I have no idea why its not calling super correctly... >> >> >> On Tue, Jan 20, 2015 at 2:38 PM, Eliot Miranda >> wrote: >> > >> > Ugh, I'm behind the times, Tobias you've already fixed it; thanks! >> > Tobias, I like your use of becomeForward:; it is more robust. But I *think* >> > the undeclared removal is misplaced. Don't you think that that code belongs >> > in the BindingPolicy? >> > >> > On Tue, Jan 20, 2015 at 12:33 PM, Eliot Miranda >> > wrote: >> >> >> >> >> >> >> >> On Tue, Jan 20, 2015 at 12:26 PM, Eliot Miranda >> >> wrote: >> >>> >> >>> Hi Chris, Hi Colin, >> >>> >> >>> >> >>> On Thu, Jan 15, 2015 at 2:48 PM, Chris Muller >> >>> wrote: >> >>>> >> >>>> I did a minor class-hierarchy refactoring today which resulted in a >> >>>> an >> >>>> invalid super pointer, resulting in a confusing image lock up due to >> >>>> tight recursion. The script, below, demonstrates the issue in trunk: >> >>>> >> >>>> Object compile: 'test ^''Hello from Object'''. >> >>>> (Object subclass: #MyClass instanceVariableNames: '' >> >>>> classVariableNames: '' poolDictionaries: '' category: 'Test') >> >>>> compile: >> >>>> 'test ^ super halt test, ''my super call lands on myself!'''. >> >>>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> >>>> ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass >> >>>> instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' >> >>>> category: 'Test'). >> >>>> (Smalltalk classNamed: #MyNewAbstraction) new test >> >>>> >> >>>> But an existing method in the original MyClass had a call to super >> >>>> which now lands in itself, resulting in a tight recursion. >> >>>> >> >>>> The same script without creating the new subclass results in an >> >>>> instant VM crash (both interpreter 2357 and cog 3205): >> >>>> >> >>>> Object compile: 'test ^''Hello from Object'''. >> >>>> (Object subclass: #MyClass instanceVariableNames: '' >> >>>> classVariableNames: '' poolDictionaries: '' category: 'Test') >> >>>> compile: >> >>>> 'test ^ super halt test, ''my super call lands on itself!'''. >> >>>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> >>>> (Smalltalk classNamed: #MyNewAbstraction) new test >> >>>> >> >>>> I even tried recompiling my entire class hierarchy which was renamed, >> >>>> but it didn't help. >> >>>> >> >>>> How can this be? I _KNOW_ I've used rename class many times in the >> >>>> past... A regression? >> >>> >> >>> >> >>> This is indeed an Environments regression. The issue is where to fix >> >>> the problem. One way to look at it is that >> >>> Environment>>renameClass:from:to: does not update bindings in the renamed >> >>> class's methods. >> >>> >> >>> Here's what the old code did: >> >>> >> >>> SystemDictionary>>renameClass: aClass from: oldName to: newName >> >>> "Rename the class, aClass, to have the title newName." >> >>> >> >>> | oldref category | >> >>> category := SystemOrganization categoryOfElement: oldName. >> >>> self organization classify: newName under: category suppressIfDefault: >> >>> true. >> >>> self organization removeElement: oldName. >> >>> oldref := self associationAt: oldName. >> >>> self removeKey: oldName. >> >>> ** oldref key: newName. >> >>> self add: oldref. "Old association preserves old refs" >> >>> Smalltalk renamedClass: aClass from: oldName to: newName. >> >>> self flushClassNameCache. >> >>> SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName >> >>> to: newName inCategory: category >> >>> >> >>> The starred line changes the key on the old class's binding, meaning >> >>> that all the methods whose methodClassAssociation is that binding get >> >>> automatically updated (note that class methods have a methodClassAssociation >> >>> that has no key and just points to the class object). >> >>> >> >>> The new code simply forgets to do this: >> >>> >> >>> Environment>>renameClass: aClass from: oldName to: newName >> >>> "Rename the class, aClass, to have the title newName." >> >>> >> >>> | binding category | >> >>> category := self organization categoryOfElement: oldName. >> >>> self organization classify: newName under: category suppressIfDefault: >> >>> true. >> >>> self organization removeElement: oldName. >> >>> binding := self declarationOf: oldName. >> >>> declarations removeKey: oldName. >> >>> self binding: binding removedFrom: self. >> >>> binding := newName => aClass. >> >>> declarations add: binding. >> >>> self binding: binding addedTo: self. >> >>> Smalltalk renamedClass: aClass from: oldName to: newName. >> >>> SystemChangeNotifier uniqueInstance >> >>> classRenamed: aClass >> >>> from: oldName >> >>> to: newName >> >>> inCategory: category >> >>> >> >>> >> >>> But should the change go in Environment>>renameClass:from:to: or in >> >>> the BindingPolicy? i.e. it could be implemented either in >> >>> Environment>>renameClass:from:to:, or in Environment>>showBinding:. I guess >> >>> the former, but I'm cc'ing Colin, because know it?, he wrote it! >> >> >> >> >> >> and if the fix should indeed go in Environment>>renameClass:from:to: , >> >> it is as simple as >> >> >> >> Environment>>renameClass: aClass from: oldName to: newName >> >> "Rename the class, aClass, to have the title newName." >> >> >> >> | binding category | >> >> category := self organization categoryOfElement: oldName. >> >> self organization classify: newName under: category suppressIfDefault: >> >> true. >> >> self organization removeElement: oldName. >> >> binding := self declarationOf: oldName. >> >> declarations removeKey: oldName. >> >> self binding: binding removedFrom: self. >> >> binding := newName => aClass. >> >> declarations add: binding. >> >> self binding: binding addedTo: self. >> >> >> >> ** aClass updateMethodBindingsTo: binding. >> >> Smalltalk renamedClass: aClass from: oldName to: newName. >> >> SystemChangeNotifier uniqueInstance >> >> classRenamed: aClass >> >> from: oldName >> >> to: newName >> >> inCategory: category >> >> >> >> I'll make this change and we can alter later if Colin thinks it's in >> >> the wrong place. >> >> >> >>> >> >>> >> >>> In any case there needs to be a test that checks that a method's >> >>> methodClassAssociation is correctly updated after a rename. I bet Colin >> >>> would have not made this slip had there been a test. >> >>> >> >>> >> >>> Here's the code I used to test this: >> >>> >> >>> | mca1 mca2 | >> >>> Object compile: 'test ^''Hello from Object'''. >> >>> (Object >> >>> subclass: #MyClass instanceVariableNames: '' >> >>> classVariableNames: '' >> >>> poolDictionaries: '' >> >>> category: 'Test') >> >>> compile: 'test ^ super halt test, ''my super call lands on >> >>> itself!'''. >> >>> mca1 := ((Smalltalk classNamed: #MyClass)>>#test) >> >>> methodClassAssociation. >> >>> (Smalltalk classNamed: #MyClass) >> >>> rename: 'MyNewAbstraction'. >> >>> mca2 := ((Smalltalk classNamed: #MyNewAbstraction)>>#test) >> >>> methodClassAssociation. >> >>> { mca1. mca2. mca1 == mca2. mca1 == (Smalltalk bindingOf: >> >>> #MyNewAbstraction). mca2 == (Smalltalk bindingOf: #MyNewAbstraction)} >> >>> >> >>> It answers { #MyClass=>nil . #MyClass=>nil . true . false . false} >> >>> i.e. the binding isn't updated, but changes from #MyClass=>MyClass to >> >>> #MyClass=>nil in binding:removedFrom:. >> >>> >> >>> >> >>> -- >> >>> HTH, >> >>> Eliot >> >> >> >> >> >> >> >> >> >> -- >> >> best, >> >> Eliot >> > >> > >> > >> > >> > -- >> > best, >> > Eliot >> > >> > >> > >> > > > > From casey.obrien.r at gmail.com Wed Jan 21 05:34:35 2015 From: casey.obrien.r at gmail.com (Casey Ransberger) Date: Wed Jan 21 05:34:37 2015 Subject: [squeak-dev] Squeak on a mouse? Message-ID: Ran across this. Kind of a cool idea. The whole computer is in the mouse. My first thought was, I want to put a VM on that:) as it would be convenient for users of e.g. EToys and Scratch. Then it occurred to me: Squeak, running on a *mouse.* You know _that's_ right! Couldn't help sharing the thought... http://mybroadband.co.za/news/gadgets/117096-your-entire-pc-in-a-mouse.html -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150120/269fdeda/attachment.htm From leves at elte.hu Wed Jan 21 07:46:27 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed Jan 21 07:46:32 2015 Subject: [squeak-dev] Re: The Inbox: Collections-ul.601.mcz In-Reply-To: <1421736800579-4800576.post@n4.nabble.com> References: <1421736800579-4800576.post@n4.nabble.com> Message-ID: I think the only way to do it is to duplicate the code. But going that way would have other tradeoffs. What is more important? To have O(1) time removal, or to have O(1) time access by index? Looking at the Python docs, I think that dictionary is implemented by using a linked list, because it doesn't look like it supports access by index, but it can remove both the first and the last pair[1]. Levente [1] https://docs.python.org/2/library/collections.html#collections.OrderedDict On Mon, 19 Jan 2015, Marcel Taeumel wrote: > Nice! :) > > Do you have any ideas about the array-to-order mapping to make removal O(1)? > The array access seems quite hidden in Dictionary and not reachable via > subclassing w/o much code duplication... > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Inbox-Collections-ul-601-mcz-tp4800473p4800576.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From edgardec2005 at gmail.com Wed Jan 21 08:46:44 2015 From: edgardec2005 at gmail.com (Edgar De Cleene) Date: Wed Jan 21 08:46:50 2015 Subject: [squeak-dev] Squeak on a mouse? In-Reply-To: References: Message-ID: <6DBAF77A4934409A8BF73B9AAEE851A7@gmail.com> On Wednesday, January 21, 2015 at 2:34 AM, Casey Ransberger wrote: > Ran across this. Kind of a cool idea. The whole computer is in the mouse. My first thought was, I want to put a VM on that:) as it would be convenient for users of e.g. EToys and Scratch. > > Then it occurred to me: Squeak, running on a *mouse.* You know _that's_ right! > > Couldn't help sharing the thought... > > http://mybroadband.co.za/news/gadgets/117096-your-entire-pc-in-a-mouse.html Sounds as a good place for put my Cuis fork. http://squeakros.org/CuiSantafesino.2.zip. Try and see what you could do with the smaller Morphic Smalltalk -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150121/3421f95d/attachment.htm From commits at source.squeak.org Wed Jan 21 09:35:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 21 09:35:29 2015 Subject: [squeak-dev] The Trunk: Tests-topa.309.mcz Message-ID: Tobias Pape uploaded a new version of Tests to project The Trunk: http://source.squeak.org/trunk/Tests-topa.309.mcz ==================== Summary ==================== Name: Tests-topa.309 Author: topa Time: 21 January 2015, 10:35:14.311 am UUID: 351b14f2-b099-430e-bd63-0cee8756f68f Ancestors: Tests-topa.308 Reinstall the 'new binding' condition in class renames. Also test that literals still work after renaming. =============== Diff against Tests-topa.308 =============== Item was removed: - ----- Method: EnvironmentTest>>expectedFailures (in category 'as yet unclassified') ----- - expectedFailures - " The need for fresh bindings on class rename may be a good idea, - we don't know yet. Need to talk to cwp, probably" - - ^ #(testRenameCreatesNewBinding)! Item was added: + ----- Method: EnvironmentTest>>testRenameContinuity (in category 'class tests') ----- + testRenameContinuity + "When we rename a class, literal references to it + from method bytecode should still work even though + they are now undeclared." + + | class | + env importSelf. + class := self createClass: #Griffle. + class compileSilently: 'foo ^ Griffle new' classified: ''. + self shouldnt: [class new foo] raise: Error. + self assert: class equals: class new foo class description: ''. + + class rename: #Plonk. + self shouldnt: [class new foo] raise: Error. + self + assert: class + equals: class new foo class + description: 'The value of the binding should still be intact after a class rename'. + ! Item was changed: ----- Method: EnvironmentTest>>testRenameCreatesNewBinding (in category 'class tests') ----- testRenameCreatesNewBinding "When we rename a class, a completely new binding should be created for the new name. + The old binding is moved to undeclared." - The old binding is moved to undeclared, and - given a null value." | class newBinding oldBinding | env importSelf. class := self createClass: #Griffle. oldBinding := env bindingOf: #Griffle. class rename: #Plonk. newBinding := env bindingOf: #Plonk. self deny: newBinding == oldBinding. + self assert: class identical: oldBinding value. - self assert: nil identical: oldBinding value. self assert: #Griffle equals: oldBinding key. self assert: #Plonk equals: newBinding key. self assert: class identical: newBinding value. ! From commits at source.squeak.org Wed Jan 21 10:15:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 21 10:15:45 2015 Subject: [squeak-dev] The Trunk: Environments-topa.55.mcz Message-ID: Tobias Pape uploaded a new version of Environments to project The Trunk: http://source.squeak.org/trunk/Environments-topa.55.mcz ==================== Summary ==================== Name: Environments-topa.55 Author: topa Time: 21 January 2015, 11:15:37.19 am UUID: ac4cd9b0-1628-4881-a2c2-f6d1e1a6f089 Ancestors: Environments-topa.54 3rd attempt at class-rename fixes. This version a) avoids #becomeForward: b) fixes method homes after rename c) moves the obsolete binding to undeclared but keeps it working. Effectively, this is the outcome: | p | p := Object subclass: #A instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Unknown'. p compile: 'foo ^ A new'. " literals of #foo {#A=>A . #foo . #A=>A}" p rename: #B. " literals of #foo {#A=>B . #foo . #B=>B}" p new foo class == p. =============== Diff against Environments-topa.54 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." + | oldBinding newBinding category | - | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. + oldBinding := self declarationOf: oldName. - binding := self declarationOf: oldName. declarations removeKey: oldName. + self binding: oldBinding removedFrom: self. + " re-route now undeclared oldBinding " + oldBinding value: aClass. - self binding: binding removedFrom: self. - undeclared removeKey: oldName. + newBinding := newName => aClass. + aClass updateMethodBindingsTo: newBinding. + declarations add: newBinding. + self binding: newBinding addedTo: self. - binding becomeForward: (newName => aClass). - declarations add: binding. - self binding: binding addedTo: self. Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From commits at source.squeak.org Wed Jan 21 10:17:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 21 10:17:07 2015 Subject: [squeak-dev] The Trunk: Tools-topa.533.mcz Message-ID: Tobias Pape uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-topa.533.mcz ==================== Summary ==================== Name: Tools-topa.533 Author: topa Time: 21 January 2015, 11:16:47.425 am UUID: ff38a625-c34d-462c-a7f4-366d031f3127 Ancestors: Tools-ul.532 Fix notification about obsolete class references after a class rename =============== Diff against Tools-ul.532 =============== Item was changed: ----- Method: Browser>>renameClass (in category 'class functions') ----- renameClass + | oldName newName obs oldBinding | - | oldName newName obs | self hasClassSelected ifFalse: [^ self]. self okToChange ifFalse: [^ self]. oldName := self selectedClass name. newName := self request: 'Please type new class name' initialAnswer: oldName. newName = '' ifTrue: [^ self]. "Cancel returns ''" newName := newName asSymbol. newName = oldName ifTrue: [^ self]. (self selectedClass environment includesKey: newName) ifTrue: [^ self error: newName , ' already exists']. + oldBinding := self selectedClass environment declarationOf: oldName. self selectedClass rename: newName. selectedClassName := newName. self changed: #classList. + obs := self systemNavigation allCallsOn: oldBinding. - obs := self systemNavigation - allCallsOn: (self selectedClass environment associationAt: newName). obs isEmpty ifFalse: [self systemNavigation browseMessageList: obs name: 'Obsolete References to ' , oldName autoSelect: oldName]. self selectClassNamed: newName.! From craig at netjam.org Wed Jan 21 10:44:03 2015 From: craig at netjam.org (Craig Latta) Date: Wed Jan 21 10:44:15 2015 Subject: [squeak-dev] re: execution-driven imprinting (was "Context status 2015-01-16") In-Reply-To: References: <54B9A0D9.5000707@netjam.org> <54BD178F.8090501@netjam.org> Message-ID: Hi Nicolas-- > In this scheme, something is striking me. Some images share some code > (classes, compiledMethods). But what about code mutations/updates? That's doable. A target system can record what it has received, and from where. Through a continuous or periodic remote-messaging connection to a providing system (not necessarily the original one), or by subscribing to update broadcasts from a repository that a providing system updates, the target system can stay up to date. > Without such mutations, is it still Smalltalk? I think it would be, but we don't have to give them up so it's only a philosophical point. > With active imprinting, such mutations might not be obvious to > propagate (for example a subclass now overrides a message of super) I think a target system could arrange to receive notifications about absolutely every change which might effect the code it has, and discard the ones it deems irrelevant. > ...you import class builder and compiler in the target; for what > purpose? Is the target going to change a class locally? No, those were just examples of rather complex and interconnected frameworks which are tricky to transfer via source code recompilation. They made good demonstrations of the execution-driven imprinting technique. One big feature is that the person doing the transfer doesn't need to understand anything about the code being transferred, and the technique works without modification no matter what the code is. > What if it then imports incompatible methods from the provider? The imprinting mechanism doesn't transfer incompatible methods. It supports a negotiation between the systems involved, though, to make the targets compatible before transferring a method, if the person operating the system approves. > Maybe the scheme is more interesting for deployment of static code, > but I'm curious to know if live updates would ever still be > possible... Yes indeed! I wouldn't be as interested in it if they weren't. This is meant to bring a fully-functional livecoding system, like we're all used to having, to distributed situations. thanks, -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From craig at netjam.org Wed Jan 21 10:47:53 2015 From: craig at netjam.org (Craig Latta) Date: Wed Jan 21 10:50:09 2015 Subject: [squeak-dev] re: Stream factoring (was "Read-only source files") In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> <1A95090F-20BD-4167-999F-D196DE1C1AD5@rowledge.org> Message-ID: > [a Stream factoring which does not conflate reading and writing via > class inheritance] > > No complex multi-purpose objects with complex capabilities and > exceptions, just simple objects with simple capabilities, composition > and delegation. Yes, although I think the situation is even simpler with the no-write-only factoring I described. And some exceptions will always crop up when you're dealing with external resources, internal collection exhaustion, etc. -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From frank.shearar at gmail.com Wed Jan 21 11:48:07 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Wed Jan 21 11:48:09 2015 Subject: [squeak-dev] re: Read-only source files In-Reply-To: References: <431AA114-AEB9-4AA7-8AF3-6CF9839A5585@gmx.de> <1A95090F-20BD-4167-999F-D196DE1C1AD5@rowledge.org> Message-ID: On 21 January 2015 at 01:58, Nicolas Cellier wrote: > > > 2015-01-21 2:31 GMT+01:00 Craig Latta : >> >> >> > ReadWriteStream really is a complex beast. >> >> Now *that* is certain. The traditional Stream implementation is >> significantly bogus. I've never had a need for a write-only stream, so >> all streams can be readable by default; any exceptional circumstances >> can use... exceptions. Then ReadStream, WriteStream and ReadWriteStream >> go away, instead there's a WritableStream subclass of >> PositionableStream. Lots of discussion about multiple inheritance and >> traits also goes away, which is pleasant. ;) >> > > Interesting POV. > Following the Xtreams principles, I went the opposite way, rewriting every > usage of ReadWriteStream into either ReadStream or WriteStream. I did only > published some in trunk, but have more unfinished/untested... > I never had to intermix read and write randomly in a stream, this should be > reserved to very specific things like sharing state as in a database. > Streams make sense for sequential processings, less for random access. > Indeed, most usage of ReadWriteStream in Squeak is just for chaining several > processings (like a unix pipe). > So if I write into a collection thru a WriteStream, then read the contents > with a ReadStream, I'm done. > > No complex multi-purpose objects with complex capabilities and exceptions, > just simple objects with simple capabilities, composition and delegation. We have talked from time to time about moving to Xtream. It's a very nice library. frank > Nicolas > > >> I suspect this is how They would have done it in the first place >> back in the day, if they had had exceptions. >> >> >> -C >> >> -- >> Craig Latta >> netjam.org >> +31 6 2757 7177 (SMS ok) >> + 1 415 287 3547 (no SMS) >> >> > > > > From bert at freudenbergs.de Wed Jan 21 14:39:02 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Wed Jan 21 14:39:05 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: On 20.01.2015, at 21:33, Eliot Miranda wrote: > > ** aClass updateMethodBindingsTo: binding. We committed a version that incorporates this, as well as keeping the binding working during class renames (Environments-topa.54, Tests-topa.309). Another fix ensures that the warning about obsolete references still pops up after renaming (Tools-topa.533). - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150121/58c16934/smime.bin From marcel.taeumel at student.hpi.uni-potsdam.de Wed Jan 21 15:50:33 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Wed Jan 21 15:54:01 2015 Subject: [squeak-dev] Layout policy ignored for morphs w/o submorphs... ? Message-ID: <1421855433451-4800819.post@n4.nabble.com> Hi! :) There is something strange going on in Morphic land considering layout policies and their rights. :D Consider this excerpt from Morph >> #doLayoutIn: ... submorphs isEmpty ifTrue: [^fullBounds := priorBounds]. ... Okay, the policy has no chance because this is not called then: ... layout := self layoutPolicy. layout ifNotNil: [layout layout: self in: layoutBounds]. ... Furthermore, Morph >> #layoutBounds dares to preprocess #layoutInset (which will be stored in an instance of TableProperties ... ?!) like this: | inset box | inset := self layoutInset. box := self innerBounds. inset isZero ifTrue:[^box]. ^ box insetBy: inset Phew. Obviously, the TableLayoutPolicy should access a morph's layout inset during actual layout (i.e., #layout:in:). My questions: - Why should a morph keep its prior extent by default when having no submorphs? - Can we (I^^) give layout policies more control about whether to layout even w/o submorphs? - Can we (I^^) move #layoutInset processing to TableLayout? - Can we (I^^) move code about proportional layouting from Morph to ProportionalLayout? Best, Marcel -- View this message in context: http://forum.world.st/Layout-policy-ignored-for-morphs-w-o-submorphs-tp4800819.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Wed Jan 21 16:12:44 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Wed Jan 21 16:16:11 2015 Subject: [squeak-dev] Re: Layout policy ignored for morphs w/o submorphs... ? In-Reply-To: <1421855433451-4800819.post@n4.nabble.com> References: <1421855433451-4800819.post@n4.nabble.com> Message-ID: <1421856764001-4800821.post@n4.nabble.com> After a small discussion with Bert, I realized that you normally do layouting *only* for your submorphs. This is fine for #rigid and #spaceFill behavior because you need your owner's data to layout. However, #shrinkWrap, as it is currently implemented in a similar way, has nothing to do with your owner. I vote for being able to implement #shrinkWrap behavior in your own layout policy: | shrinkWrappedMorph | shrinkWrappedMorph := Morph new layoutPolicy: ShrinkWrapLayout new. shrinkWrappedMorph addMorph: Morph new. shrinkWrappedMorph addMorph: Morph new. shrinkWrappedMorph addMorph: Morph new. self assert: shrinkWrappedMorph fullBounds = shrinkWrappedMorph submorphBounds. As for now, this would be against the concept of layout policies and how they are implemented in Morph. We should anticipate such behavior and thus allow policies to work -- even w/o any submorph present. As I look through TableLayout >> #layoutTopToBottom:in:, this is already happening: | shrinkWrappedMorph | shrinkWrappedMorph := Morph new layoutPolicy: TableLayout new. shrinkWrappedMorph vResizing: #shrinkWrap; hResizing: #shrinkWrap. shrinkWrappedMorph addMorph: Morph new. shrinkWrappedMorph addMorph: Morph new. shrinkWrappedMorph addMorph: Morph new. self assert: shrinkWrappedMorph fullBounds = shrinkWrappedMorph submorphBounds. You don't need a parent with a layout policy that realizes your shrinkWrap-behavior. Thus, there is no reason for a morph to prevent a policy from working when there is no submorph present. Best, Marcel -- View this message in context: http://forum.world.st/Layout-policy-ignored-for-morphs-w-o-submorphs-tp4800819p4800821.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From jecel at merlintec.com Wed Jan 21 17:24:10 2015 From: jecel at merlintec.com (Jecel Assumpcao Jr.) Date: Wed Jan 21 16:24:23 2015 Subject: [squeak-dev] Squeak on a mouse? In-Reply-To: References: Message-ID: Casey, > http://mybroadband.co.za/news/gadgets/117096-your-entire-pc-in-a-mouse.html That is a nice idea, but just to remind people of older implementations I would like to point out the late Jef Fox's computer in a mouse from 2000: http://www.ultratechnology.com/scope.htm The F21 processor was created from Jef by Chuck Moore and ran Forth natively. In this demo, the whole computer was inside the mouse and the cable coming out of it was the video cable you connected to a monitor. -- Jecel From asqueaker at gmail.com Wed Jan 21 16:39:37 2015 From: asqueaker at gmail.com (Chris Muller) Date: Wed Jan 21 16:39:40 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: Okay, I found the invalid super-pointer behavior. It's a lot better with Bert & Tobias' fix, but still there to a smaller degree.. Object compile: 'test ^''Hello from Object'''. (Object subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test') compile: 'test self halt. ^ super test, ''my super call lands on myself!'''. (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test'). (Smalltalk classNamed: #MyClass) new test Do-it on the above. When the debugger appears, simply highlight the code "super test" in the debugger and press "Print It". I expected to see 'Hello from Object' but it seems to be calculating super from the receiver class rather than the method's home class... WITHOUT Bert and Tobias' fix, the above results in the super call truly landing on itself, and if you take the halt out, the tight-recursion I mentioned from teh first paragraph of this thread. WITH their fix, the problem only manifests in the debugger as demonstrated. See, I'm not crazy! :) On Tue, Jan 20, 2015 at 6:05 PM, Nicolas Cellier wrote: > > > 2015-01-20 23:56 GMT+01:00 Chris Muller : >> >> Hi Eliot, there were TWO problems, Bert and Tobias have fixed one of >> them. The second one is still unfixed in trunk. When you run this >> script and arrive at the debugger, step INTO: >> >> Object compile: 'test ^''Hello from Object'''. >> (Object subclass: #MyClass instanceVariableNames: '' >> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >> 'test ^ super halt test, ''my super call lands on itself!'''. >> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> (Smalltalk classNamed: #MyNewAbstraction) new test >> > > But it behaves as it should... > You first send halt to super. > If you resume it just answer self. > > Then you send test to self (it's not a super send and never been) > > >> >> then be sure to step INTO the super call to #test. See how it lands >> you in teh same method? THAT bug exists back at least as far back as >> 4.2, so I don't think its Environments related. >> >> I took a look at it and presented my findings in the other email >> thread with subject "The Inbox: Environments-cmm.52.mcz", -- that >> screenshot showing that the bytecodes are teh same and the literal >> binding looks correct. >> >> So I have no idea why its not calling super correctly... >> >> >> On Tue, Jan 20, 2015 at 2:38 PM, Eliot Miranda >> wrote: >> > >> > Ugh, I'm behind the times, Tobias you've already fixed it; thanks! >> > Tobias, I like your use of becomeForward:; it is more robust. But I *think* >> > the undeclared removal is misplaced. Don't you think that that code belongs >> > in the BindingPolicy? >> > >> > On Tue, Jan 20, 2015 at 12:33 PM, Eliot Miranda >> > wrote: >> >> >> >> >> >> >> >> On Tue, Jan 20, 2015 at 12:26 PM, Eliot Miranda >> >> wrote: >> >>> >> >>> Hi Chris, Hi Colin, >> >>> >> >>> >> >>> On Thu, Jan 15, 2015 at 2:48 PM, Chris Muller >> >>> wrote: >> >>>> >> >>>> I did a minor class-hierarchy refactoring today which resulted in a >> >>>> an >> >>>> invalid super pointer, resulting in a confusing image lock up due to >> >>>> tight recursion. The script, below, demonstrates the issue in trunk: >> >>>> >> >>>> Object compile: 'test ^''Hello from Object'''. >> >>>> (Object subclass: #MyClass instanceVariableNames: '' >> >>>> classVariableNames: '' poolDictionaries: '' category: 'Test') >> >>>> compile: >> >>>> 'test ^ super halt test, ''my super call lands on myself!'''. >> >>>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> >>>> ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass >> >>>> instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' >> >>>> category: 'Test'). >> >>>> (Smalltalk classNamed: #MyNewAbstraction) new test >> >>>> >> >>>> But an existing method in the original MyClass had a call to super >> >>>> which now lands in itself, resulting in a tight recursion. >> >>>> >> >>>> The same script without creating the new subclass results in an >> >>>> instant VM crash (both interpreter 2357 and cog 3205): >> >>>> >> >>>> Object compile: 'test ^''Hello from Object'''. >> >>>> (Object subclass: #MyClass instanceVariableNames: '' >> >>>> classVariableNames: '' poolDictionaries: '' category: 'Test') >> >>>> compile: >> >>>> 'test ^ super halt test, ''my super call lands on itself!'''. >> >>>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> >>>> (Smalltalk classNamed: #MyNewAbstraction) new test >> >>>> >> >>>> I even tried recompiling my entire class hierarchy which was renamed, >> >>>> but it didn't help. >> >>>> >> >>>> How can this be? I _KNOW_ I've used rename class many times in the >> >>>> past... A regression? >> >>> >> >>> >> >>> This is indeed an Environments regression. The issue is where to fix >> >>> the problem. One way to look at it is that >> >>> Environment>>renameClass:from:to: does not update bindings in the renamed >> >>> class's methods. >> >>> >> >>> Here's what the old code did: >> >>> >> >>> SystemDictionary>>renameClass: aClass from: oldName to: newName >> >>> "Rename the class, aClass, to have the title newName." >> >>> >> >>> | oldref category | >> >>> category := SystemOrganization categoryOfElement: oldName. >> >>> self organization classify: newName under: category suppressIfDefault: >> >>> true. >> >>> self organization removeElement: oldName. >> >>> oldref := self associationAt: oldName. >> >>> self removeKey: oldName. >> >>> ** oldref key: newName. >> >>> self add: oldref. "Old association preserves old refs" >> >>> Smalltalk renamedClass: aClass from: oldName to: newName. >> >>> self flushClassNameCache. >> >>> SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName >> >>> to: newName inCategory: category >> >>> >> >>> The starred line changes the key on the old class's binding, meaning >> >>> that all the methods whose methodClassAssociation is that binding get >> >>> automatically updated (note that class methods have a methodClassAssociation >> >>> that has no key and just points to the class object). >> >>> >> >>> The new code simply forgets to do this: >> >>> >> >>> Environment>>renameClass: aClass from: oldName to: newName >> >>> "Rename the class, aClass, to have the title newName." >> >>> >> >>> | binding category | >> >>> category := self organization categoryOfElement: oldName. >> >>> self organization classify: newName under: category suppressIfDefault: >> >>> true. >> >>> self organization removeElement: oldName. >> >>> binding := self declarationOf: oldName. >> >>> declarations removeKey: oldName. >> >>> self binding: binding removedFrom: self. >> >>> binding := newName => aClass. >> >>> declarations add: binding. >> >>> self binding: binding addedTo: self. >> >>> Smalltalk renamedClass: aClass from: oldName to: newName. >> >>> SystemChangeNotifier uniqueInstance >> >>> classRenamed: aClass >> >>> from: oldName >> >>> to: newName >> >>> inCategory: category >> >>> >> >>> >> >>> But should the change go in Environment>>renameClass:from:to: or in >> >>> the BindingPolicy? i.e. it could be implemented either in >> >>> Environment>>renameClass:from:to:, or in Environment>>showBinding:. I guess >> >>> the former, but I'm cc'ing Colin, because know it?, he wrote it! >> >> >> >> >> >> and if the fix should indeed go in Environment>>renameClass:from:to: , >> >> it is as simple as >> >> >> >> Environment>>renameClass: aClass from: oldName to: newName >> >> "Rename the class, aClass, to have the title newName." >> >> >> >> | binding category | >> >> category := self organization categoryOfElement: oldName. >> >> self organization classify: newName under: category suppressIfDefault: >> >> true. >> >> self organization removeElement: oldName. >> >> binding := self declarationOf: oldName. >> >> declarations removeKey: oldName. >> >> self binding: binding removedFrom: self. >> >> binding := newName => aClass. >> >> declarations add: binding. >> >> self binding: binding addedTo: self. >> >> >> >> ** aClass updateMethodBindingsTo: binding. >> >> Smalltalk renamedClass: aClass from: oldName to: newName. >> >> SystemChangeNotifier uniqueInstance >> >> classRenamed: aClass >> >> from: oldName >> >> to: newName >> >> inCategory: category >> >> >> >> I'll make this change and we can alter later if Colin thinks it's in >> >> the wrong place. >> >> >> >>> >> >>> >> >>> In any case there needs to be a test that checks that a method's >> >>> methodClassAssociation is correctly updated after a rename. I bet Colin >> >>> would have not made this slip had there been a test. >> >>> >> >>> >> >>> Here's the code I used to test this: >> >>> >> >>> | mca1 mca2 | >> >>> Object compile: 'test ^''Hello from Object'''. >> >>> (Object >> >>> subclass: #MyClass instanceVariableNames: '' >> >>> classVariableNames: '' >> >>> poolDictionaries: '' >> >>> category: 'Test') >> >>> compile: 'test ^ super halt test, ''my super call lands on >> >>> itself!'''. >> >>> mca1 := ((Smalltalk classNamed: #MyClass)>>#test) >> >>> methodClassAssociation. >> >>> (Smalltalk classNamed: #MyClass) >> >>> rename: 'MyNewAbstraction'. >> >>> mca2 := ((Smalltalk classNamed: #MyNewAbstraction)>>#test) >> >>> methodClassAssociation. >> >>> { mca1. mca2. mca1 == mca2. mca1 == (Smalltalk bindingOf: >> >>> #MyNewAbstraction). mca2 == (Smalltalk bindingOf: #MyNewAbstraction)} >> >>> >> >>> It answers { #MyClass=>nil . #MyClass=>nil . true . false . false} >> >>> i.e. the binding isn't updated, but changes from #MyClass=>MyClass to >> >>> #MyClass=>nil in binding:removedFrom:. >> >>> >> >>> >> >>> -- >> >>> HTH, >> >>> Eliot >> >> >> >> >> >> >> >> >> >> -- >> >> best, >> >> Eliot >> > >> > >> > >> > >> > -- >> > best, >> > Eliot >> > >> > >> > >> > > > > From Das.Linux at gmx.de Wed Jan 21 18:24:40 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed Jan 21 18:24:49 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: Hi Chris On 21.01.2015, at 17:39, Chris Muller wrote: > Okay, I found the invalid super-pointer behavior. > > It's a lot better with Bert & Tobias' fix, but still there to a smaller degree.. > > Object compile: 'test ^''Hello from Object'''. > (Object subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > 'test self halt. ^ super test, ''my super call lands on myself!'''. > (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass > instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' > category: 'Test'). > (Smalltalk classNamed: #MyClass) new test > > Do-it on the above. When the debugger appears, simply highlight the > code "super test" in the debugger and press "Print It". > > I expected to see 'Hello from Object' but it seems to be calculating > super from the receiver class rather than the method's home class... > > WITHOUT Bert and Tobias' fix, the above results in the super call > truly landing on itself, and if you take the halt out, the > tight-recursion I mentioned from teh first paragraph of this thread. > WITH their fix, the problem only manifests in the debugger as > demonstrated. If you hit step-into, you actually end up in the Superclass. _Only_ if you select 'super test' and PrintIt (or DoIt), the apparent ?recursion? is triggered. This is due to the way DoIt work, they compile an anonymous class that are ?homed? in the receivers class, in this case MyClass. Hence, super ends up in MyNewAbstraction[1]. Yes, this is a bit surprising, but I don't know whether it is wrong. Compiler>>evaluate:in:to:notifying:ifFail:logged: calculates the home class of the DoIt via this: | theClass | theClass := ((aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class). that is, the _Receiver_ of the context, not the home class of the context's method. @Bert, Eliot: Which one do you think would be correct? the Stack is down below[1]. Best -Tobias [1]: Compiler>>evaluateCue:ifFail: Receiver: a Compiler Arguments and temporary variables: aCue: a CompilationCue failBlock: [closure] in Compiler>>evaluateCue:ifFail:logged: methodNode: DoItIn: ThisContext ^ super test method: (MyClass>>#DoItIn: "a CompiledMethod(374)") value: nil Receiver's instance variables: parser: a Parser cue: a CompilationCue Compiler>>evaluateCue:ifFail:logged: Receiver: a Compiler Arguments and temporary variables: aCue: a CompilationCue failBlock: [closure] in [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAnd...etc... logFlag: true value: nil Receiver's instance variables: parser: a Parser cue: a CompilationCue Compiler>>evaluate:in:to:notifying:ifFail:logged: Receiver: a Compiler Arguments and temporary variables: textOrStream: a ReadStream aContext: MyClass(MyNewAbstraction)>>test receiver: a MyClass aRequestor: a SmalltalkEditor failBlock: [closure] in [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAnd...etc... logFlag: true theClass: MyClass Receiver's instance variables: parser: a Parser cue: a CompilationCue [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: Receiver: a SmalltalkEditor Arguments and temporary variables: < Receiver's instance variables: morph: a TextMorphForEditView(3464) selectionShowing: false model: a Debugger paragraph: a NewParagraph markBlock: a CharacterBlock with index 21 and character $s and rectangle 110@0 ...etc... pointBlock: a CharacterBlock with index 31 and character $, and rectangle 174@0...etc... beginTypeInIndex: nil emphasisHere: {a TextColor code: (Color r: 0.0 g: 0.0 b: 0.5)} lastParenLocation: nil otherInterval: (20 to: 19) oldInterval: (20 to: 19) typeAhead: nil styler: nil BlockClosure>>on:do: Receiver: [closure] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: Arguments and temporary variables: exception: OutOfScopeNotification handlerAction: [closure] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo...etc... handlerActive: true Receiver's instance variables: outerContext: SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: startpc: 97 numArgs: 0 SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: Receiver: a SmalltalkEditor Arguments and temporary variables: aBlock: [closure] in [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt result: nil rcvr: a MyClass ctxt: MyClass(MyNewAbstraction)>>test Receiver's instance variables: morph: a TextMorphForEditView(3464) selectionShowing: false model: a Debugger paragraph: a NewParagraph markBlock: a CharacterBlock with index 21 and character $s and rectangle 110@0 ...etc... pointBlock: a CharacterBlock with index 31 and character $, and rectangle 174@0...etc... beginTypeInIndex: nil emphasisHere: {a TextColor code: (Color r: 0.0 g: 0.0 b: 0.5)} lastParenLocation: nil otherInterval: (20 to: 19) oldInterval: (20 to: 19) typeAhead: nil styler: nil [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt Receiver: a PluggableTextMorphPlus(473) Arguments and temporary variables: oldEditor: {a SmalltalkEditor} Receiver's instance variables: bounds: 36@380 corner: 740@592 owner: a PluggablePanelMorph(3130) submorphs: {a ScrollBar(1013) . a TransformMorph(3047)} fullBounds: 36@380 corner: 740@592 color: Color white extension: a MorphExtension (3891) [other: (layoutFrame -> a LayoutFrame) (vSc...etc... borderWidth: 1 borderColor: Color lightGray model: a Debugger slotName: nil open: false scrollBar: a ScrollBar(1013) scroller: a TransformMorph(3047) retractableScrollBar: false scrollBarOnLeft: false getMenuSelector: #codePaneMenu:shifted: getMenuTitleSelector: nil scrollBarHidden: nil hasFocus: false hScrollBar: a ScrollBar(2030) textMorph: a TextMorphForEditView(3464) getTextSelector: #contents setTextSelector: #contents:notifying: getSelectionSelector: #contentsSelection hasUnacceptedEdits: false askBeforeDiscardingEdits: true selectionInterval: (21 to: 30) hasEditingConflicts: false getColorSelector: nil acceptAction: nil unstyledAcceptText: nil styler: a SHTextStylerST80 TextMorphForEditView(TextMorph)>>handleEdit: Receiver: a TextMorphForEditView(3464) Arguments and temporary variables: editBlock: [closure] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt result: nil Receiver's instance variables: bounds: 0@0 corner: 683@18 owner: a TransformMorph(3047) submorphs: #() fullBounds: 0@0 corner: 683@18 color: Color black extension: a MorphExtension (3814) [other: (blinkStart -> 1091554)] borderWidth: 0 borderColor: Color black textStyle: a TextStyle Bitmap DejaVu Sans 9 text: a Text for 'test self halt. ^ super test, ''my super call lands on myse...etc... wrapFlag: true paragraph: a NewParagraph editor: a SmalltalkEditor container: nil predecessor: nil successor: nil backgroundColor: nil margins: nil editHistory: nil editView: a PluggableTextMorphPlus(473) acceptOnCR: false PluggableTextMorphPlus(PluggableTextMorph)>>printIt Receiver: a PluggableTextMorphPlus(473) Arguments and temporary variables: oldEditor: {a SmalltalkEditor} Receiver's instance variables: bounds: 36@380 corner: 740@592 owner: a PluggablePanelMorph(3130) submorphs: {a ScrollBar(1013) . a TransformMorph(3047)} fullBounds: 36@380 corner: 740@592 color: Color white extension: a MorphExtension (3891) [other: (layoutFrame -> a LayoutFrame) (vSc...etc... borderWidth: 1 borderColor: Color lightGray model: a Debugger slotName: nil open: false scrollBar: a ScrollBar(1013) scroller: a TransformMorph(3047) retractableScrollBar: false scrollBarOnLeft: false getMenuSelector: #codePaneMenu:shifted: getMenuTitleSelector: nil scrollBarHidden: nil hasFocus: false hScrollBar: a ScrollBar(2030) textMorph: a TextMorphForEditView(3464) getTextSelector: #contents setTextSelector: #contents:notifying: getSelectionSelector: #contentsSelection hasUnacceptedEdits: false askBeforeDiscardingEdits: true selectionInterval: (21 to: 30) hasEditingConflicts: false getColorSelector: nil acceptAction: nil unstyledAcceptText: nil styler: a SHTextStylerST80 Debugger(StringHolder)>>perform:orSendTo: Receiver: a Debugger Arguments and temporary variables: selector: #printIt otherTarget: a PluggableTextMorphPlus(473) Receiver's instance variables: dependents: a DependentsArray(a PluggableSystemWindow(1857) a PluggableListMorp...etc... contents: a Text for 'test self halt. ^ super test, ''my super call lands on ...etc... currentCompiledMethod: nil contentsSymbol: #source multiWindowState: nil interruptedProcess: a Process in Debugger class>>morphicOpenOn:context:label:co...etc... interruptedController: nil contextStack: an OrderedCollection(MyClass(Object)>>halt MyClass(MyNewAbstracti...etc... contextStackIndex: 2 contextStackList: an OrderedCollection('MyClass(Object)>>halt' 'MyClass(MyNewAb...etc... receiverInspector: an Inspector contextVariablesInspector: a ContextVariablesInspector externalInterrupt: false proceedValue: nil selectingPC: true savedCursor: ((CursorWithMask extent: 16@16 depth: 1 fromArray: #( 2r0 2...etc... isolationHead: nil failedProject: nil errorWasInUIProcess: true labelString: nil message: nil untilExpression: nil Debugger>>perform:orSendTo: Receiver: a Debugger Arguments and temporary variables: selector: #printIt otherTarget: a PluggableTextMorphPlus(473) result: nil Receiver's instance variables: dependents: a DependentsArray(a PluggableSystemWindow(1857) a PluggableListMorp...etc... contents: a Text for 'test self halt. ^ super test, ''my super call lands on ...etc... currentCompiledMethod: nil contentsSymbol: #source multiWindowState: nil interruptedProcess: a Process in Debugger class>>morphicOpenOn:context:label:co...etc... interruptedController: nil contextStack: an OrderedCollection(MyClass(Object)>>halt MyClass(MyNewAbstracti...etc... contextStackIndex: 2 contextStackList: an OrderedCollection('MyClass(Object)>>halt' 'MyClass(MyNewAb...etc... receiverInspector: an Inspector contextVariablesInspector: a ContextVariablesInspector externalInterrupt: false proceedValue: nil selectingPC: true savedCursor: ((CursorWithMask extent: 16@16 depth: 1 fromArray: #( 2r0 2...etc... isolationHead: nil failedProject: nil errorWasInUIProcess: true labelString: nil message: nil untilExpression: nil MenuItemMorph>>DoIt Receiver: a MenuItemMorph(77)'print it (p)' Arguments and temporary variables: Receiver's instance variables: bounds: 216@558 corner: 359@576 owner: a MenuMorph(2209) submorphs: #() fullBounds: 216@558 corner: 359@576 color: Color black extension: a MorphExtension (264) [other: (layoutProperties -> a LayoutPropert...etc... font: a StrikeFont(Bitmap DejaVu Sans 9 14) emphasis: 0 contents: 'print it (p)' hasFocus: false isEnabled: true subMenu: nil isSelected: false target: a Debugger selector: #perform:orSendTo: arguments: {#printIt . a PluggableTextMorphPlus(473)} icon: Form(16x16x32) lastMousePosition: nil CompiledMethod>>valueWithReceiver:arguments: Receiver: (MenuItemMorph>>#DoIt "a CompiledMethod(1420)") Arguments and temporary variables: aReceiver: a MenuItemMorph(77)'print it (p)' anArray: #() Receiver's instance variables: (MenuItemMorph>>#DoIt "a CompiledMethod(1420)") [] in SmalltalkEditor(TextEditor)>>debug:receiver:in: Receiver: a SmalltalkEditor Arguments and temporary variables: < Receiver's instance variables: morph: a TextMorphForEditView(4064) selectionShowing: false model: an ObjectExplorer paragraph: a NewParagraph markBlock: a CharacterBlock with index 1 and character $s and rectangle 0@0 cor...etc... pointBlock: a CharacterBlock with index 62 and rectangle 366@0 corner: 366@16 ...etc... beginTypeInIndex: nil emphasisHere: {a TextFontChange font: 2} lastParenLocation: nil otherInterval: (61 to: 61) oldInterval: (55 to: 54) typeAhead: a WriteStream styler: nil [] in BlockClosure>>newProcess Receiver: [closure] in SmalltalkEditor(TextEditor)>>debug:receiver:in: Arguments and temporary variables: Receiver's instance variables: outerContext: SmalltalkEditor(TextEditor)>>debug:receiver:in: startpc: 112 numArgs: 0 --- The full stack --- Compiler>>evaluateCue:ifFail: Compiler>>evaluateCue:ifFail:logged: Compiler>>evaluate:in:to:notifying:ifFail:logged: [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: BlockClosure>>on:do: SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt TextMorphForEditView(TextMorph)>>handleEdit: PluggableTextMorphPlus(PluggableTextMorph)>>printIt Debugger(StringHolder)>>perform:orSendTo: Debugger>>perform:orSendTo: MenuItemMorph>>DoIt CompiledMethod>>valueWithReceiver:arguments: [] in SmalltalkEditor(TextEditor)>>debug:receiver:in: [] in BlockClosure>>newProcess -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 1625 bytes Desc: Message signed with OpenPGP using GPGMail Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150121/38cb7961/signature-0001.pgp From tim at rowledge.org Wed Jan 21 18:24:46 2015 From: tim at rowledge.org (tim Rowledge) Date: Wed Jan 21 18:24:55 2015 Subject: [squeak-dev] Squeak on a mouse? In-Reply-To: <6DBAF77A4934409A8BF73B9AAEE851A7@gmail.com> References: <6DBAF77A4934409A8BF73B9AAEE851A7@gmail.com> Message-ID: <3470FE4B-65AE-4CF0-A2F5-767390DD413D@rowledge.org> On 21-01-2015, at 12:46 AM, Edgar De Cleene wrote: >> >> http://mybroadband.co.za/news/gadgets/117096-your-entire-pc-in-a-mouse.html I wish I could resist seeing the comments on that (and indeed so much of the internet) - ?duh, ARM means android?. What a pillock. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Dukedom: aristocratic birth control From tim at rowledge.org Wed Jan 21 18:26:56 2015 From: tim at rowledge.org (tim Rowledge) Date: Wed Jan 21 18:26:59 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: On 21-01-2015, at 8:39 AM, Chris Muller wrote: > See, I'm not crazy! :) Let?s not get ahead of ourselves here. Clearly, you *are* crazy, but in this case you?re not wrong. There?s an important difference. After all, being wrong is a bad thing. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Useful random insult:- One clown short of a circus. From eliot.miranda at gmail.com Wed Jan 21 19:07:28 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed Jan 21 19:07:31 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: Hi Tobias, On Wed, Jan 21, 2015 at 10:24 AM, Tobias Pape wrote: > Hi Chris > > On 21.01.2015, at 17:39, Chris Muller wrote: > > > Okay, I found the invalid super-pointer behavior. > > > > It's a lot better with Bert & Tobias' fix, but still there to a smaller > degree.. > > > > Object compile: 'test ^''Hello from Object'''. > > (Object subclass: #MyClass instanceVariableNames: '' > > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > > 'test self halt. ^ super test, ''my super call lands on myself!'''. > > (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. > > ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass > > instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' > > category: 'Test'). > > (Smalltalk classNamed: #MyClass) new test > > > > Do-it on the above. When the debugger appears, simply highlight the > > code "super test" in the debugger and press "Print It". > > > > I expected to see 'Hello from Object' but it seems to be calculating > > super from the receiver class rather than the method's home class... > > > > WITHOUT Bert and Tobias' fix, the above results in the super call > > truly landing on itself, and if you take the halt out, the > > tight-recursion I mentioned from teh first paragraph of this thread. > > WITH their fix, the problem only manifests in the debugger as > > demonstrated. > > If you hit step-into, you actually end up in the Superclass. > _Only_ if you select 'super test' and PrintIt (or DoIt), the > apparent ?recursion? is triggered. > This is due to the way DoIt work, they compile an anonymous class > that are ?homed? in the receivers class, in this case MyClass. Hence, > super ends up in MyNewAbstraction[1]. > Yes, this is a bit surprising, but I don't know whether it is wrong. > > > Compiler>>evaluate:in:to:notifying:ifFail:logged: > > calculates the home class of the DoIt via this: > > | theClass | > theClass := ((aContext == nil ifTrue: [receiver] ifFalse: > [aContext receiver]) class). > > that is, the _Receiver_ of the context, not the home class of the > context's method. > Yes, well found. Whereas if we used | theClass | theClass := aContext ifNil: [receiver class] ifFalse: [aContext methodClass] we would get the behaviour Chris is (rightly) expecting. > > @Bert, Eliot: Which one do you think would be correct? the Stack is down > below[1]. > So neither :-). I think the correct code is as I wrote above, the receiver's class if no context, otherwise the context's methodClass (which of course is derived from the context's method). > > > > Best > -Tobias > > > [1]: > > Compiler>>evaluateCue:ifFail: > Receiver: a Compiler > Arguments and temporary variables: > aCue: a CompilationCue > failBlock: [closure] in > Compiler>>evaluateCue:ifFail:logged: > methodNode: DoItIn: ThisContext > ^ super test > method: (MyClass>>#DoItIn: "a CompiledMethod(374)") > value: nil > Receiver's instance variables: > parser: a Parser > cue: a CompilationCue > > Compiler>>evaluateCue:ifFail:logged: > Receiver: a Compiler > Arguments and temporary variables: > aCue: a CompilationCue > failBlock: [closure] in [] in > SmalltalkEditor(TextEditor)>>evaluateSelectionAnd...etc... > logFlag: true > value: nil > Receiver's instance variables: > parser: a Parser > cue: a CompilationCue > > Compiler>>evaluate:in:to:notifying:ifFail:logged: > Receiver: a Compiler > Arguments and temporary variables: > textOrStream: a ReadStream > aContext: MyClass(MyNewAbstraction)>>test > receiver: a MyClass > aRequestor: a SmalltalkEditor > failBlock: [closure] in [] in > SmalltalkEditor(TextEditor)>>evaluateSelectionAnd...etc... > logFlag: true > theClass: MyClass > Receiver's instance variables: > parser: a Parser > cue: a CompilationCue > > [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > Receiver: a SmalltalkEditor > Arguments and temporary variables: > < > Receiver's instance variables: > morph: a TextMorphForEditView(3464) > selectionShowing: false > model: a Debugger > paragraph: a NewParagraph > markBlock: a CharacterBlock with index 21 and > character $s and rectangle 110@0 ...etc... > pointBlock: a CharacterBlock with index 31 and > character $, and rectangle 174@0...etc... > beginTypeInIndex: nil > emphasisHere: {a TextColor code: (Color r: 0.0 g: 0.0 b: > 0.5)} > lastParenLocation: nil > otherInterval: (20 to: 19) > oldInterval: (20 to: 19) > typeAhead: nil > styler: nil > > BlockClosure>>on:do: > Receiver: [closure] in > SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > Arguments and temporary variables: > exception: OutOfScopeNotification > handlerAction: [closure] in > SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo...etc... > handlerActive: true > Receiver's instance variables: > outerContext: > SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > startpc: 97 > numArgs: 0 > > SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > Receiver: a SmalltalkEditor > Arguments and temporary variables: > aBlock: [closure] in [] in > PluggableTextMorphPlus(PluggableTextMorph)>>printIt > result: nil > rcvr: a MyClass > ctxt: MyClass(MyNewAbstraction)>>test > Receiver's instance variables: > morph: a TextMorphForEditView(3464) > selectionShowing: false > model: a Debugger > paragraph: a NewParagraph > markBlock: a CharacterBlock with index 21 and > character $s and rectangle 110@0 ...etc... > pointBlock: a CharacterBlock with index 31 and > character $, and rectangle 174@0...etc... > beginTypeInIndex: nil > emphasisHere: {a TextColor code: (Color r: 0.0 g: 0.0 b: > 0.5)} > lastParenLocation: nil > otherInterval: (20 to: 19) > oldInterval: (20 to: 19) > typeAhead: nil > styler: nil > > [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt > Receiver: a PluggableTextMorphPlus(473) > Arguments and temporary variables: > oldEditor: {a SmalltalkEditor} > Receiver's instance variables: > bounds: 36@380 corner: 740@592 > owner: a PluggablePanelMorph(3130) > submorphs: {a ScrollBar(1013) . a > TransformMorph(3047)} > fullBounds: 36@380 corner: 740@592 > color: Color white > extension: a MorphExtension (3891) [other: > (layoutFrame -> a LayoutFrame) (vSc...etc... > borderWidth: 1 > borderColor: Color lightGray > model: a Debugger > slotName: nil > open: false > scrollBar: a ScrollBar(1013) > scroller: a TransformMorph(3047) > retractableScrollBar: false > scrollBarOnLeft: false > getMenuSelector: #codePaneMenu:shifted: > getMenuTitleSelector: nil > scrollBarHidden: nil > hasFocus: false > hScrollBar: a ScrollBar(2030) > textMorph: a TextMorphForEditView(3464) > getTextSelector: #contents > setTextSelector: #contents:notifying: > getSelectionSelector: #contentsSelection > hasUnacceptedEdits: false > askBeforeDiscardingEdits: true > selectionInterval: (21 to: 30) > hasEditingConflicts: false > getColorSelector: nil > acceptAction: nil > unstyledAcceptText: nil > styler: a SHTextStylerST80 > > TextMorphForEditView(TextMorph)>>handleEdit: > Receiver: a TextMorphForEditView(3464) > Arguments and temporary variables: > editBlock: [closure] in > PluggableTextMorphPlus(PluggableTextMorph)>>printIt > result: nil > Receiver's instance variables: > bounds: 0@0 corner: 683@18 > owner: a TransformMorph(3047) > submorphs: #() > fullBounds: 0@0 corner: 683@18 > color: Color black > extension: a MorphExtension (3814) [other: > (blinkStart -> 1091554)] > borderWidth: 0 > borderColor: Color black > textStyle: a TextStyle Bitmap DejaVu Sans 9 > text: a Text for 'test self halt. ^ super test, ''my > super call lands on myse...etc... > wrapFlag: true > paragraph: a NewParagraph > editor: a SmalltalkEditor > container: nil > predecessor: nil > successor: nil > backgroundColor: nil > margins: nil > editHistory: nil > editView: a PluggableTextMorphPlus(473) > acceptOnCR: false > > PluggableTextMorphPlus(PluggableTextMorph)>>printIt > Receiver: a PluggableTextMorphPlus(473) > Arguments and temporary variables: > oldEditor: {a SmalltalkEditor} > Receiver's instance variables: > bounds: 36@380 corner: 740@592 > owner: a PluggablePanelMorph(3130) > submorphs: {a ScrollBar(1013) . a > TransformMorph(3047)} > fullBounds: 36@380 corner: 740@592 > color: Color white > extension: a MorphExtension (3891) [other: > (layoutFrame -> a LayoutFrame) (vSc...etc... > borderWidth: 1 > borderColor: Color lightGray > model: a Debugger > slotName: nil > open: false > scrollBar: a ScrollBar(1013) > scroller: a TransformMorph(3047) > retractableScrollBar: false > scrollBarOnLeft: false > getMenuSelector: #codePaneMenu:shifted: > getMenuTitleSelector: nil > scrollBarHidden: nil > hasFocus: false > hScrollBar: a ScrollBar(2030) > textMorph: a TextMorphForEditView(3464) > getTextSelector: #contents > setTextSelector: #contents:notifying: > getSelectionSelector: #contentsSelection > hasUnacceptedEdits: false > askBeforeDiscardingEdits: true > selectionInterval: (21 to: 30) > hasEditingConflicts: false > getColorSelector: nil > acceptAction: nil > unstyledAcceptText: nil > styler: a SHTextStylerST80 > > Debugger(StringHolder)>>perform:orSendTo: > Receiver: a Debugger > Arguments and temporary variables: > selector: #printIt > otherTarget: a PluggableTextMorphPlus(473) > Receiver's instance variables: > dependents: a DependentsArray(a > PluggableSystemWindow(1857) a PluggableListMorp...etc... > contents: a Text for 'test self halt. ^ super > test, ''my super call lands on ...etc... > currentCompiledMethod: nil > contentsSymbol: #source > multiWindowState: nil > interruptedProcess: a Process in Debugger > class>>morphicOpenOn:context:label:co...etc... > interruptedController: nil > contextStack: an OrderedCollection(MyClass(Object)>>halt > MyClass(MyNewAbstracti...etc... > contextStackIndex: 2 > contextStackList: an > OrderedCollection('MyClass(Object)>>halt' 'MyClass(MyNewAb...etc... > receiverInspector: an Inspector > contextVariablesInspector: a ContextVariablesInspector > externalInterrupt: false > proceedValue: nil > selectingPC: true > savedCursor: ((CursorWithMask > extent: 16@16 > depth: 1 > fromArray: #( > 2r0 > 2...etc... > isolationHead: nil > failedProject: nil > errorWasInUIProcess: true > labelString: nil > message: nil > untilExpression: nil > > Debugger>>perform:orSendTo: > Receiver: a Debugger > Arguments and temporary variables: > selector: #printIt > otherTarget: a PluggableTextMorphPlus(473) > result: nil > Receiver's instance variables: > dependents: a DependentsArray(a > PluggableSystemWindow(1857) a PluggableListMorp...etc... > contents: a Text for 'test self halt. ^ super > test, ''my super call lands on ...etc... > currentCompiledMethod: nil > contentsSymbol: #source > multiWindowState: nil > interruptedProcess: a Process in Debugger > class>>morphicOpenOn:context:label:co...etc... > interruptedController: nil > contextStack: an OrderedCollection(MyClass(Object)>>halt > MyClass(MyNewAbstracti...etc... > contextStackIndex: 2 > contextStackList: an > OrderedCollection('MyClass(Object)>>halt' 'MyClass(MyNewAb...etc... > receiverInspector: an Inspector > contextVariablesInspector: a ContextVariablesInspector > externalInterrupt: false > proceedValue: nil > selectingPC: true > savedCursor: ((CursorWithMask > extent: 16@16 > depth: 1 > fromArray: #( > 2r0 > 2...etc... > isolationHead: nil > failedProject: nil > errorWasInUIProcess: true > labelString: nil > message: nil > untilExpression: nil > > MenuItemMorph>>DoIt > Receiver: a MenuItemMorph(77)'print it (p)' > Arguments and temporary variables: > > Receiver's instance variables: > bounds: 216@558 corner: 359@576 > owner: a MenuMorph(2209) > submorphs: #() > fullBounds: 216@558 corner: 359@576 > color: Color black > extension: a MorphExtension (264) [other: > (layoutProperties -> a LayoutPropert...etc... > font: a StrikeFont(Bitmap DejaVu Sans 9 14) > emphasis: 0 > contents: 'print it (p)' > hasFocus: false > isEnabled: true > subMenu: nil > isSelected: false > target: a Debugger > selector: #perform:orSendTo: > arguments: {#printIt . a PluggableTextMorphPlus(473)} > icon: Form(16x16x32) > lastMousePosition: nil > > CompiledMethod>>valueWithReceiver:arguments: > Receiver: (MenuItemMorph>>#DoIt "a CompiledMethod(1420)") > Arguments and temporary variables: > aReceiver: a MenuItemMorph(77)'print it (p)' > anArray: #() > Receiver's instance variables: > (MenuItemMorph>>#DoIt "a CompiledMethod(1420)") > > [] in SmalltalkEditor(TextEditor)>>debug:receiver:in: > Receiver: a SmalltalkEditor > Arguments and temporary variables: > < > Receiver's instance variables: > morph: a TextMorphForEditView(4064) > selectionShowing: false > model: an ObjectExplorer > paragraph: a NewParagraph > markBlock: a CharacterBlock with index 1 and > character $s and rectangle 0@0 cor...etc... > pointBlock: a CharacterBlock with index 62 and > rectangle 366@0 corner: 366@16 > ...etc... > beginTypeInIndex: nil > emphasisHere: {a TextFontChange font: 2} > lastParenLocation: nil > otherInterval: (61 to: 61) > oldInterval: (55 to: 54) > typeAhead: a WriteStream > styler: nil > > [] in BlockClosure>>newProcess > Receiver: [closure] in > SmalltalkEditor(TextEditor)>>debug:receiver:in: > Arguments and temporary variables: > > Receiver's instance variables: > outerContext: > SmalltalkEditor(TextEditor)>>debug:receiver:in: > startpc: 112 > numArgs: 0 > > > --- The full stack --- > Compiler>>evaluateCue:ifFail: > Compiler>>evaluateCue:ifFail:logged: > Compiler>>evaluate:in:to:notifying:ifFail:logged: > [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > BlockClosure>>on:do: > SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt > TextMorphForEditView(TextMorph)>>handleEdit: > PluggableTextMorphPlus(PluggableTextMorph)>>printIt > Debugger(StringHolder)>>perform:orSendTo: > Debugger>>perform:orSendTo: > MenuItemMorph>>DoIt > CompiledMethod>>valueWithReceiver:arguments: > [] in SmalltalkEditor(TextEditor)>>debug:receiver:in: > [] in BlockClosure>>newProcess > > > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150121/d89f0675/attachment.htm From asqueaker at gmail.com Wed Jan 21 19:20:52 2015 From: asqueaker at gmail.com (Chris Muller) Date: Wed Jan 21 19:20:54 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: On Wed, Jan 21, 2015 at 12:24 PM, Tobias Pape wrote: > Hi Chris > > On 21.01.2015, at 17:39, Chris Muller wrote: > >> Okay, I found the invalid super-pointer behavior. >> >> It's a lot better with Bert & Tobias' fix, but still there to a smaller degree.. >> >> Object compile: 'test ^''Hello from Object'''. >> (Object subclass: #MyClass instanceVariableNames: '' >> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >> 'test self halt. ^ super test, ''my super call lands on myself!'''. >> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >> ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass >> instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' >> category: 'Test'). >> (Smalltalk classNamed: #MyClass) new test >> >> Do-it on the above. When the debugger appears, simply highlight the >> code "super test" in the debugger and press "Print It". >> >> I expected to see 'Hello from Object' but it seems to be calculating >> super from the receiver class rather than the method's home class... >> >> WITHOUT Bert and Tobias' fix, the above results in the super call >> truly landing on itself, and if you take the halt out, the >> tight-recursion I mentioned from teh first paragraph of this thread. >> WITH their fix, the problem only manifests in the debugger as >> demonstrated. > > If you hit step-into, you actually end up in the Superclass. > _Only_ if you select 'super test' and PrintIt (or DoIt), the > apparent ?recursion? is triggered. > This is due to the way DoIt work, they compile an anonymous class > that are ?homed? in the receivers class, in this case MyClass. Hence, > super ends up in MyNewAbstraction[1]. > Yes, this is a bit surprising, but I don't know whether it is wrong. It is inconsistent than if you did not do the rename: Object compile: 'test ^''Hello from Object'''. (Object subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test') compile: 'test self halt. ^ super test, ''my super call lands on myself!'''. (Smalltalk classNamed: #MyClass) new test This time, inside the debugger, "super test" reports the expected 'Hello from Object'. So, _something_ must be different in the renamed class..? > > > Compiler>>evaluate:in:to:notifying:ifFail:logged: > > calculates the home class of the DoIt via this: > > | theClass | > theClass := ((aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class). > > that is, the _Receiver_ of the context, not the home class of the context's method. > > @Bert, Eliot: Which one do you think would be correct? the Stack is down below[1]. > > > > Best > -Tobias > > > [1]: > > Compiler>>evaluateCue:ifFail: > Receiver: a Compiler > Arguments and temporary variables: > aCue: a CompilationCue > failBlock: [closure] in Compiler>>evaluateCue:ifFail:logged: > methodNode: DoItIn: ThisContext > ^ super test > method: (MyClass>>#DoItIn: "a CompiledMethod(374)") > value: nil > Receiver's instance variables: > parser: a Parser > cue: a CompilationCue > > Compiler>>evaluateCue:ifFail:logged: > Receiver: a Compiler > Arguments and temporary variables: > aCue: a CompilationCue > failBlock: [closure] in [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAnd...etc... > logFlag: true > value: nil > Receiver's instance variables: > parser: a Parser > cue: a CompilationCue > > Compiler>>evaluate:in:to:notifying:ifFail:logged: > Receiver: a Compiler > Arguments and temporary variables: > textOrStream: a ReadStream > aContext: MyClass(MyNewAbstraction)>>test > receiver: a MyClass > aRequestor: a SmalltalkEditor > failBlock: [closure] in [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAnd...etc... > logFlag: true > theClass: MyClass > Receiver's instance variables: > parser: a Parser > cue: a CompilationCue > > [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > Receiver: a SmalltalkEditor > Arguments and temporary variables: > < > Receiver's instance variables: > morph: a TextMorphForEditView(3464) > selectionShowing: false > model: a Debugger > paragraph: a NewParagraph > markBlock: a CharacterBlock with index 21 and character $s and rectangle 110@0 ...etc... > pointBlock: a CharacterBlock with index 31 and character $, and rectangle 174@0...etc... > beginTypeInIndex: nil > emphasisHere: {a TextColor code: (Color r: 0.0 g: 0.0 b: 0.5)} > lastParenLocation: nil > otherInterval: (20 to: 19) > oldInterval: (20 to: 19) > typeAhead: nil > styler: nil > > BlockClosure>>on:do: > Receiver: [closure] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > Arguments and temporary variables: > exception: OutOfScopeNotification > handlerAction: [closure] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo...etc... > handlerActive: true > Receiver's instance variables: > outerContext: SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > startpc: 97 > numArgs: 0 > > SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > Receiver: a SmalltalkEditor > Arguments and temporary variables: > aBlock: [closure] in [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt > result: nil > rcvr: a MyClass > ctxt: MyClass(MyNewAbstraction)>>test > Receiver's instance variables: > morph: a TextMorphForEditView(3464) > selectionShowing: false > model: a Debugger > paragraph: a NewParagraph > markBlock: a CharacterBlock with index 21 and character $s and rectangle 110@0 ...etc... > pointBlock: a CharacterBlock with index 31 and character $, and rectangle 174@0...etc... > beginTypeInIndex: nil > emphasisHere: {a TextColor code: (Color r: 0.0 g: 0.0 b: 0.5)} > lastParenLocation: nil > otherInterval: (20 to: 19) > oldInterval: (20 to: 19) > typeAhead: nil > styler: nil > > [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt > Receiver: a PluggableTextMorphPlus(473) > Arguments and temporary variables: > oldEditor: {a SmalltalkEditor} > Receiver's instance variables: > bounds: 36@380 corner: 740@592 > owner: a PluggablePanelMorph(3130) > submorphs: {a ScrollBar(1013) . a TransformMorph(3047)} > fullBounds: 36@380 corner: 740@592 > color: Color white > extension: a MorphExtension (3891) [other: (layoutFrame -> a LayoutFrame) (vSc...etc... > borderWidth: 1 > borderColor: Color lightGray > model: a Debugger > slotName: nil > open: false > scrollBar: a ScrollBar(1013) > scroller: a TransformMorph(3047) > retractableScrollBar: false > scrollBarOnLeft: false > getMenuSelector: #codePaneMenu:shifted: > getMenuTitleSelector: nil > scrollBarHidden: nil > hasFocus: false > hScrollBar: a ScrollBar(2030) > textMorph: a TextMorphForEditView(3464) > getTextSelector: #contents > setTextSelector: #contents:notifying: > getSelectionSelector: #contentsSelection > hasUnacceptedEdits: false > askBeforeDiscardingEdits: true > selectionInterval: (21 to: 30) > hasEditingConflicts: false > getColorSelector: nil > acceptAction: nil > unstyledAcceptText: nil > styler: a SHTextStylerST80 > > TextMorphForEditView(TextMorph)>>handleEdit: > Receiver: a TextMorphForEditView(3464) > Arguments and temporary variables: > editBlock: [closure] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt > result: nil > Receiver's instance variables: > bounds: 0@0 corner: 683@18 > owner: a TransformMorph(3047) > submorphs: #() > fullBounds: 0@0 corner: 683@18 > color: Color black > extension: a MorphExtension (3814) [other: (blinkStart -> 1091554)] > borderWidth: 0 > borderColor: Color black > textStyle: a TextStyle Bitmap DejaVu Sans 9 > text: a Text for 'test self halt. ^ super test, ''my super call lands on myse...etc... > wrapFlag: true > paragraph: a NewParagraph > editor: a SmalltalkEditor > container: nil > predecessor: nil > successor: nil > backgroundColor: nil > margins: nil > editHistory: nil > editView: a PluggableTextMorphPlus(473) > acceptOnCR: false > > PluggableTextMorphPlus(PluggableTextMorph)>>printIt > Receiver: a PluggableTextMorphPlus(473) > Arguments and temporary variables: > oldEditor: {a SmalltalkEditor} > Receiver's instance variables: > bounds: 36@380 corner: 740@592 > owner: a PluggablePanelMorph(3130) > submorphs: {a ScrollBar(1013) . a TransformMorph(3047)} > fullBounds: 36@380 corner: 740@592 > color: Color white > extension: a MorphExtension (3891) [other: (layoutFrame -> a LayoutFrame) (vSc...etc... > borderWidth: 1 > borderColor: Color lightGray > model: a Debugger > slotName: nil > open: false > scrollBar: a ScrollBar(1013) > scroller: a TransformMorph(3047) > retractableScrollBar: false > scrollBarOnLeft: false > getMenuSelector: #codePaneMenu:shifted: > getMenuTitleSelector: nil > scrollBarHidden: nil > hasFocus: false > hScrollBar: a ScrollBar(2030) > textMorph: a TextMorphForEditView(3464) > getTextSelector: #contents > setTextSelector: #contents:notifying: > getSelectionSelector: #contentsSelection > hasUnacceptedEdits: false > askBeforeDiscardingEdits: true > selectionInterval: (21 to: 30) > hasEditingConflicts: false > getColorSelector: nil > acceptAction: nil > unstyledAcceptText: nil > styler: a SHTextStylerST80 > > Debugger(StringHolder)>>perform:orSendTo: > Receiver: a Debugger > Arguments and temporary variables: > selector: #printIt > otherTarget: a PluggableTextMorphPlus(473) > Receiver's instance variables: > dependents: a DependentsArray(a PluggableSystemWindow(1857) a PluggableListMorp...etc... > contents: a Text for 'test self halt. ^ super test, ''my super call lands on ...etc... > currentCompiledMethod: nil > contentsSymbol: #source > multiWindowState: nil > interruptedProcess: a Process in Debugger class>>morphicOpenOn:context:label:co...etc... > interruptedController: nil > contextStack: an OrderedCollection(MyClass(Object)>>halt MyClass(MyNewAbstracti...etc... > contextStackIndex: 2 > contextStackList: an OrderedCollection('MyClass(Object)>>halt' 'MyClass(MyNewAb...etc... > receiverInspector: an Inspector > contextVariablesInspector: a ContextVariablesInspector > externalInterrupt: false > proceedValue: nil > selectingPC: true > savedCursor: ((CursorWithMask > extent: 16@16 > depth: 1 > fromArray: #( > 2r0 > 2...etc... > isolationHead: nil > failedProject: nil > errorWasInUIProcess: true > labelString: nil > message: nil > untilExpression: nil > > Debugger>>perform:orSendTo: > Receiver: a Debugger > Arguments and temporary variables: > selector: #printIt > otherTarget: a PluggableTextMorphPlus(473) > result: nil > Receiver's instance variables: > dependents: a DependentsArray(a PluggableSystemWindow(1857) a PluggableListMorp...etc... > contents: a Text for 'test self halt. ^ super test, ''my super call lands on ...etc... > currentCompiledMethod: nil > contentsSymbol: #source > multiWindowState: nil > interruptedProcess: a Process in Debugger class>>morphicOpenOn:context:label:co...etc... > interruptedController: nil > contextStack: an OrderedCollection(MyClass(Object)>>halt MyClass(MyNewAbstracti...etc... > contextStackIndex: 2 > contextStackList: an OrderedCollection('MyClass(Object)>>halt' 'MyClass(MyNewAb...etc... > receiverInspector: an Inspector > contextVariablesInspector: a ContextVariablesInspector > externalInterrupt: false > proceedValue: nil > selectingPC: true > savedCursor: ((CursorWithMask > extent: 16@16 > depth: 1 > fromArray: #( > 2r0 > 2...etc... > isolationHead: nil > failedProject: nil > errorWasInUIProcess: true > labelString: nil > message: nil > untilExpression: nil > > MenuItemMorph>>DoIt > Receiver: a MenuItemMorph(77)'print it (p)' > Arguments and temporary variables: > > Receiver's instance variables: > bounds: 216@558 corner: 359@576 > owner: a MenuMorph(2209) > submorphs: #() > fullBounds: 216@558 corner: 359@576 > color: Color black > extension: a MorphExtension (264) [other: (layoutProperties -> a LayoutPropert...etc... > font: a StrikeFont(Bitmap DejaVu Sans 9 14) > emphasis: 0 > contents: 'print it (p)' > hasFocus: false > isEnabled: true > subMenu: nil > isSelected: false > target: a Debugger > selector: #perform:orSendTo: > arguments: {#printIt . a PluggableTextMorphPlus(473)} > icon: Form(16x16x32) > lastMousePosition: nil > > CompiledMethod>>valueWithReceiver:arguments: > Receiver: (MenuItemMorph>>#DoIt "a CompiledMethod(1420)") > Arguments and temporary variables: > aReceiver: a MenuItemMorph(77)'print it (p)' > anArray: #() > Receiver's instance variables: > (MenuItemMorph>>#DoIt "a CompiledMethod(1420)") > > [] in SmalltalkEditor(TextEditor)>>debug:receiver:in: > Receiver: a SmalltalkEditor > Arguments and temporary variables: > < > Receiver's instance variables: > morph: a TextMorphForEditView(4064) > selectionShowing: false > model: an ObjectExplorer > paragraph: a NewParagraph > markBlock: a CharacterBlock with index 1 and character $s and rectangle 0@0 cor...etc... > pointBlock: a CharacterBlock with index 62 and rectangle 366@0 corner: 366@16 > ...etc... > beginTypeInIndex: nil > emphasisHere: {a TextFontChange font: 2} > lastParenLocation: nil > otherInterval: (61 to: 61) > oldInterval: (55 to: 54) > typeAhead: a WriteStream > styler: nil > > [] in BlockClosure>>newProcess > Receiver: [closure] in SmalltalkEditor(TextEditor)>>debug:receiver:in: > Arguments and temporary variables: > > Receiver's instance variables: > outerContext: SmalltalkEditor(TextEditor)>>debug:receiver:in: > startpc: 112 > numArgs: 0 > > > --- The full stack --- > Compiler>>evaluateCue:ifFail: > Compiler>>evaluateCue:ifFail:logged: > Compiler>>evaluate:in:to:notifying:ifFail:logged: > [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > BlockClosure>>on:do: > SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: > [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt > TextMorphForEditView(TextMorph)>>handleEdit: > PluggableTextMorphPlus(PluggableTextMorph)>>printIt > Debugger(StringHolder)>>perform:orSendTo: > Debugger>>perform:orSendTo: > MenuItemMorph>>DoIt > CompiledMethod>>valueWithReceiver:arguments: > [] in SmalltalkEditor(TextEditor)>>debug:receiver:in: > [] in BlockClosure>>newProcess > > > > From asqueaker at gmail.com Wed Jan 21 19:34:36 2015 From: asqueaker at gmail.com (Chris Muller) Date: Wed Jan 21 19:34:39 2015 Subject: [squeak-dev] renaming a class causes invalid super pointer CompiledMethod..! In-Reply-To: References: Message-ID: Okay, I got it. It's not the rename, the reason it worked was because it was not an instance of a further subclass. As demonstrated by [1]. DoIt processing calculates "super" of the receiver's class, not the methodHome's class. Just what you said. As far as everyday debugging, I've never noticed this behavior in 21 years of Smalltalking. When I was debugging yesterday and the code of my superclass method was one-line "^true" and I got false back --- it was surreal. Well found indeed, thanks for fixing. [1] -- Same script but instantiate MySubclass (under MyClass) instead. Object compile: 'test ^''Hello from Object'''. (Object subclass: #MyClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test') compile: 'test self halt. ^ super test, ''my super call lands on myself!'''. ((Smalltalk classNamed: #MyClass) subclass: #MySubclass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Test'). (Smalltalk classNamed: #MySubclass) new test On Wed, Jan 21, 2015 at 1:20 PM, Chris Muller wrote: > On Wed, Jan 21, 2015 at 12:24 PM, Tobias Pape wrote: >> Hi Chris >> >> On 21.01.2015, at 17:39, Chris Muller wrote: >> >>> Okay, I found the invalid super-pointer behavior. >>> >>> It's a lot better with Bert & Tobias' fix, but still there to a smaller degree.. >>> >>> Object compile: 'test ^''Hello from Object'''. >>> (Object subclass: #MyClass instanceVariableNames: '' >>> classVariableNames: '' poolDictionaries: '' category: 'Test') compile: >>> 'test self halt. ^ super test, ''my super call lands on myself!'''. >>> (Smalltalk classNamed: #MyClass) rename: 'MyNewAbstraction'. >>> ((Smalltalk classNamed: #MyNewAbstraction) subclass: #MyClass >>> instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' >>> category: 'Test'). >>> (Smalltalk classNamed: #MyClass) new test >>> >>> Do-it on the above. When the debugger appears, simply highlight the >>> code "super test" in the debugger and press "Print It". >>> >>> I expected to see 'Hello from Object' but it seems to be calculating >>> super from the receiver class rather than the method's home class... >>> >>> WITHOUT Bert and Tobias' fix, the above results in the super call >>> truly landing on itself, and if you take the halt out, the >>> tight-recursion I mentioned from teh first paragraph of this thread. >>> WITH their fix, the problem only manifests in the debugger as >>> demonstrated. >> >> If you hit step-into, you actually end up in the Superclass. >> _Only_ if you select 'super test' and PrintIt (or DoIt), the >> apparent ?recursion? is triggered. >> This is due to the way DoIt work, they compile an anonymous class >> that are ?homed? in the receivers class, in this case MyClass. Hence, >> super ends up in MyNewAbstraction[1]. >> Yes, this is a bit surprising, but I don't know whether it is wrong. > > It is inconsistent than if you did not do the rename: > > Object compile: 'test ^''Hello from Object'''. > (Object subclass: #MyClass instanceVariableNames: '' > classVariableNames: '' poolDictionaries: '' category: 'Test') compile: > 'test self halt. ^ super test, ''my super call lands on myself!'''. > (Smalltalk classNamed: #MyClass) new test > > This time, inside the debugger, "super test" reports the expected > 'Hello from Object'. > > So, _something_ must be different in the renamed class..? > > > >> >> >> Compiler>>evaluate:in:to:notifying:ifFail:logged: >> >> calculates the home class of the DoIt via this: >> >> | theClass | >> theClass := ((aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class). >> >> that is, the _Receiver_ of the context, not the home class of the context's method. >> >> @Bert, Eliot: Which one do you think would be correct? the Stack is down below[1]. >> >> >> >> Best >> -Tobias >> >> >> [1]: >> >> Compiler>>evaluateCue:ifFail: >> Receiver: a Compiler >> Arguments and temporary variables: >> aCue: a CompilationCue >> failBlock: [closure] in Compiler>>evaluateCue:ifFail:logged: >> methodNode: DoItIn: ThisContext >> ^ super test >> method: (MyClass>>#DoItIn: "a CompiledMethod(374)") >> value: nil >> Receiver's instance variables: >> parser: a Parser >> cue: a CompilationCue >> >> Compiler>>evaluateCue:ifFail:logged: >> Receiver: a Compiler >> Arguments and temporary variables: >> aCue: a CompilationCue >> failBlock: [closure] in [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAnd...etc... >> logFlag: true >> value: nil >> Receiver's instance variables: >> parser: a Parser >> cue: a CompilationCue >> >> Compiler>>evaluate:in:to:notifying:ifFail:logged: >> Receiver: a Compiler >> Arguments and temporary variables: >> textOrStream: a ReadStream >> aContext: MyClass(MyNewAbstraction)>>test >> receiver: a MyClass >> aRequestor: a SmalltalkEditor >> failBlock: [closure] in [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAnd...etc... >> logFlag: true >> theClass: MyClass >> Receiver's instance variables: >> parser: a Parser >> cue: a CompilationCue >> >> [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: >> Receiver: a SmalltalkEditor >> Arguments and temporary variables: >> < >> Receiver's instance variables: >> morph: a TextMorphForEditView(3464) >> selectionShowing: false >> model: a Debugger >> paragraph: a NewParagraph >> markBlock: a CharacterBlock with index 21 and character $s and rectangle 110@0 ...etc... >> pointBlock: a CharacterBlock with index 31 and character $, and rectangle 174@0...etc... >> beginTypeInIndex: nil >> emphasisHere: {a TextColor code: (Color r: 0.0 g: 0.0 b: 0.5)} >> lastParenLocation: nil >> otherInterval: (20 to: 19) >> oldInterval: (20 to: 19) >> typeAhead: nil >> styler: nil >> >> BlockClosure>>on:do: >> Receiver: [closure] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: >> Arguments and temporary variables: >> exception: OutOfScopeNotification >> handlerAction: [closure] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo...etc... >> handlerActive: true >> Receiver's instance variables: >> outerContext: SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: >> startpc: 97 >> numArgs: 0 >> >> SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: >> Receiver: a SmalltalkEditor >> Arguments and temporary variables: >> aBlock: [closure] in [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt >> result: nil >> rcvr: a MyClass >> ctxt: MyClass(MyNewAbstraction)>>test >> Receiver's instance variables: >> morph: a TextMorphForEditView(3464) >> selectionShowing: false >> model: a Debugger >> paragraph: a NewParagraph >> markBlock: a CharacterBlock with index 21 and character $s and rectangle 110@0 ...etc... >> pointBlock: a CharacterBlock with index 31 and character $, and rectangle 174@0...etc... >> beginTypeInIndex: nil >> emphasisHere: {a TextColor code: (Color r: 0.0 g: 0.0 b: 0.5)} >> lastParenLocation: nil >> otherInterval: (20 to: 19) >> oldInterval: (20 to: 19) >> typeAhead: nil >> styler: nil >> >> [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt >> Receiver: a PluggableTextMorphPlus(473) >> Arguments and temporary variables: >> oldEditor: {a SmalltalkEditor} >> Receiver's instance variables: >> bounds: 36@380 corner: 740@592 >> owner: a PluggablePanelMorph(3130) >> submorphs: {a ScrollBar(1013) . a TransformMorph(3047)} >> fullBounds: 36@380 corner: 740@592 >> color: Color white >> extension: a MorphExtension (3891) [other: (layoutFrame -> a LayoutFrame) (vSc...etc... >> borderWidth: 1 >> borderColor: Color lightGray >> model: a Debugger >> slotName: nil >> open: false >> scrollBar: a ScrollBar(1013) >> scroller: a TransformMorph(3047) >> retractableScrollBar: false >> scrollBarOnLeft: false >> getMenuSelector: #codePaneMenu:shifted: >> getMenuTitleSelector: nil >> scrollBarHidden: nil >> hasFocus: false >> hScrollBar: a ScrollBar(2030) >> textMorph: a TextMorphForEditView(3464) >> getTextSelector: #contents >> setTextSelector: #contents:notifying: >> getSelectionSelector: #contentsSelection >> hasUnacceptedEdits: false >> askBeforeDiscardingEdits: true >> selectionInterval: (21 to: 30) >> hasEditingConflicts: false >> getColorSelector: nil >> acceptAction: nil >> unstyledAcceptText: nil >> styler: a SHTextStylerST80 >> >> TextMorphForEditView(TextMorph)>>handleEdit: >> Receiver: a TextMorphForEditView(3464) >> Arguments and temporary variables: >> editBlock: [closure] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt >> result: nil >> Receiver's instance variables: >> bounds: 0@0 corner: 683@18 >> owner: a TransformMorph(3047) >> submorphs: #() >> fullBounds: 0@0 corner: 683@18 >> color: Color black >> extension: a MorphExtension (3814) [other: (blinkStart -> 1091554)] >> borderWidth: 0 >> borderColor: Color black >> textStyle: a TextStyle Bitmap DejaVu Sans 9 >> text: a Text for 'test self halt. ^ super test, ''my super call lands on myse...etc... >> wrapFlag: true >> paragraph: a NewParagraph >> editor: a SmalltalkEditor >> container: nil >> predecessor: nil >> successor: nil >> backgroundColor: nil >> margins: nil >> editHistory: nil >> editView: a PluggableTextMorphPlus(473) >> acceptOnCR: false >> >> PluggableTextMorphPlus(PluggableTextMorph)>>printIt >> Receiver: a PluggableTextMorphPlus(473) >> Arguments and temporary variables: >> oldEditor: {a SmalltalkEditor} >> Receiver's instance variables: >> bounds: 36@380 corner: 740@592 >> owner: a PluggablePanelMorph(3130) >> submorphs: {a ScrollBar(1013) . a TransformMorph(3047)} >> fullBounds: 36@380 corner: 740@592 >> color: Color white >> extension: a MorphExtension (3891) [other: (layoutFrame -> a LayoutFrame) (vSc...etc... >> borderWidth: 1 >> borderColor: Color lightGray >> model: a Debugger >> slotName: nil >> open: false >> scrollBar: a ScrollBar(1013) >> scroller: a TransformMorph(3047) >> retractableScrollBar: false >> scrollBarOnLeft: false >> getMenuSelector: #codePaneMenu:shifted: >> getMenuTitleSelector: nil >> scrollBarHidden: nil >> hasFocus: false >> hScrollBar: a ScrollBar(2030) >> textMorph: a TextMorphForEditView(3464) >> getTextSelector: #contents >> setTextSelector: #contents:notifying: >> getSelectionSelector: #contentsSelection >> hasUnacceptedEdits: false >> askBeforeDiscardingEdits: true >> selectionInterval: (21 to: 30) >> hasEditingConflicts: false >> getColorSelector: nil >> acceptAction: nil >> unstyledAcceptText: nil >> styler: a SHTextStylerST80 >> >> Debugger(StringHolder)>>perform:orSendTo: >> Receiver: a Debugger >> Arguments and temporary variables: >> selector: #printIt >> otherTarget: a PluggableTextMorphPlus(473) >> Receiver's instance variables: >> dependents: a DependentsArray(a PluggableSystemWindow(1857) a PluggableListMorp...etc... >> contents: a Text for 'test self halt. ^ super test, ''my super call lands on ...etc... >> currentCompiledMethod: nil >> contentsSymbol: #source >> multiWindowState: nil >> interruptedProcess: a Process in Debugger class>>morphicOpenOn:context:label:co...etc... >> interruptedController: nil >> contextStack: an OrderedCollection(MyClass(Object)>>halt MyClass(MyNewAbstracti...etc... >> contextStackIndex: 2 >> contextStackList: an OrderedCollection('MyClass(Object)>>halt' 'MyClass(MyNewAb...etc... >> receiverInspector: an Inspector >> contextVariablesInspector: a ContextVariablesInspector >> externalInterrupt: false >> proceedValue: nil >> selectingPC: true >> savedCursor: ((CursorWithMask >> extent: 16@16 >> depth: 1 >> fromArray: #( >> 2r0 >> 2...etc... >> isolationHead: nil >> failedProject: nil >> errorWasInUIProcess: true >> labelString: nil >> message: nil >> untilExpression: nil >> >> Debugger>>perform:orSendTo: >> Receiver: a Debugger >> Arguments and temporary variables: >> selector: #printIt >> otherTarget: a PluggableTextMorphPlus(473) >> result: nil >> Receiver's instance variables: >> dependents: a DependentsArray(a PluggableSystemWindow(1857) a PluggableListMorp...etc... >> contents: a Text for 'test self halt. ^ super test, ''my super call lands on ...etc... >> currentCompiledMethod: nil >> contentsSymbol: #source >> multiWindowState: nil >> interruptedProcess: a Process in Debugger class>>morphicOpenOn:context:label:co...etc... >> interruptedController: nil >> contextStack: an OrderedCollection(MyClass(Object)>>halt MyClass(MyNewAbstracti...etc... >> contextStackIndex: 2 >> contextStackList: an OrderedCollection('MyClass(Object)>>halt' 'MyClass(MyNewAb...etc... >> receiverInspector: an Inspector >> contextVariablesInspector: a ContextVariablesInspector >> externalInterrupt: false >> proceedValue: nil >> selectingPC: true >> savedCursor: ((CursorWithMask >> extent: 16@16 >> depth: 1 >> fromArray: #( >> 2r0 >> 2...etc... >> isolationHead: nil >> failedProject: nil >> errorWasInUIProcess: true >> labelString: nil >> message: nil >> untilExpression: nil >> >> MenuItemMorph>>DoIt >> Receiver: a MenuItemMorph(77)'print it (p)' >> Arguments and temporary variables: >> >> Receiver's instance variables: >> bounds: 216@558 corner: 359@576 >> owner: a MenuMorph(2209) >> submorphs: #() >> fullBounds: 216@558 corner: 359@576 >> color: Color black >> extension: a MorphExtension (264) [other: (layoutProperties -> a LayoutPropert...etc... >> font: a StrikeFont(Bitmap DejaVu Sans 9 14) >> emphasis: 0 >> contents: 'print it (p)' >> hasFocus: false >> isEnabled: true >> subMenu: nil >> isSelected: false >> target: a Debugger >> selector: #perform:orSendTo: >> arguments: {#printIt . a PluggableTextMorphPlus(473)} >> icon: Form(16x16x32) >> lastMousePosition: nil >> >> CompiledMethod>>valueWithReceiver:arguments: >> Receiver: (MenuItemMorph>>#DoIt "a CompiledMethod(1420)") >> Arguments and temporary variables: >> aReceiver: a MenuItemMorph(77)'print it (p)' >> anArray: #() >> Receiver's instance variables: >> (MenuItemMorph>>#DoIt "a CompiledMethod(1420)") >> >> [] in SmalltalkEditor(TextEditor)>>debug:receiver:in: >> Receiver: a SmalltalkEditor >> Arguments and temporary variables: >> < >> Receiver's instance variables: >> morph: a TextMorphForEditView(4064) >> selectionShowing: false >> model: an ObjectExplorer >> paragraph: a NewParagraph >> markBlock: a CharacterBlock with index 1 and character $s and rectangle 0@0 cor...etc... >> pointBlock: a CharacterBlock with index 62 and rectangle 366@0 corner: 366@16 >> ...etc... >> beginTypeInIndex: nil >> emphasisHere: {a TextFontChange font: 2} >> lastParenLocation: nil >> otherInterval: (61 to: 61) >> oldInterval: (55 to: 54) >> typeAhead: a WriteStream >> styler: nil >> >> [] in BlockClosure>>newProcess >> Receiver: [closure] in SmalltalkEditor(TextEditor)>>debug:receiver:in: >> Arguments and temporary variables: >> >> Receiver's instance variables: >> outerContext: SmalltalkEditor(TextEditor)>>debug:receiver:in: >> startpc: 112 >> numArgs: 0 >> >> >> --- The full stack --- >> Compiler>>evaluateCue:ifFail: >> Compiler>>evaluateCue:ifFail:logged: >> Compiler>>evaluate:in:to:notifying:ifFail:logged: >> [] in SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: >> BlockClosure>>on:do: >> SmalltalkEditor(TextEditor)>>evaluateSelectionAndDo: >> [] in PluggableTextMorphPlus(PluggableTextMorph)>>printIt >> TextMorphForEditView(TextMorph)>>handleEdit: >> PluggableTextMorphPlus(PluggableTextMorph)>>printIt >> Debugger(StringHolder)>>perform:orSendTo: >> Debugger>>perform:orSendTo: >> MenuItemMorph>>DoIt >> CompiledMethod>>valueWithReceiver:arguments: >> [] in SmalltalkEditor(TextEditor)>>debug:receiver:in: >> [] in BlockClosure>>newProcess >> >> >> >> From asqueaker at gmail.com Wed Jan 21 23:05:09 2015 From: asqueaker at gmail.com (Chris Muller) Date: Wed Jan 21 23:05:14 2015 Subject: [Pharo-dev] [squeak-dev] re: Context status 2015-01-16 In-Reply-To: References: <54B9A0D9.5000707@netjam.org> <54BD178F.8090501@netjam.org> Message-ID: On Tue, Jan 20, 2015 at 7:39 PM, Nicolas Cellier wrote: > > > 2015-01-19 15:41 GMT+01:00 Craig Latta : >> >> >> Okay, I'll add both of the execution-driven imprinters to the >> repository. They're called "active" and "passive" imprinting. >> >> Active imprinting is directed by the system that initially has the >> desired code. An ActiveImprintingServer has clients in the systems which >> will receive the code. Every time the server system runs a method in a >> certain process, it imprints that method onto each of the clients. One >> use case for this is giving the code of a demo to an audience as you run >> it. >> >> Passive imprinting is directed by the system that wants the code. >> The target system makes a remote-messaging connection to a system which >> has the code, and runs an expression which will use the code. Every time >> a method is missing from the target system (in any process), the target >> system requests the missing method from the provider system, installs >> it, and retries running that method. >> >> I have imprinted the exception-handling system, the compiler, and >> the class builder with both approaches. >> >> > > In this scheme, something is striking me. > Some images share some code (classes, compiledMethods) > But what about code mutations/updates? > > Without such mutations, is it still Smalltalk? > > Without active imprinting, such mutations might not be obvious to propagate > (for example a subclass now overrides a message of super) > > And since you import class builder and compiler in the target, on what > purpose? Is the target going to change a class locally? What if it then > imports incompatible methods from provider? Or is the goal to just replicate > some mutations from the provider? > > Maybe the scheme is more interesting for deployment of static code, but I'm > curious to know if ever live updates would still be possible... The particular scenario I was dreaming of would never have changes made to the imprinted images. At worst, the source Caddilac image might be have a patch applied in production, in which case it would need some way to invalidate the updated methods in all clients... From commits at source.squeak.org Wed Jan 21 23:48:35 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 21 23:48:37 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz Message-ID: Tobias Pape uploaded a new version of Environments to project The Trunk: http://source.squeak.org/trunk/Environments-topa.56.mcz ==================== Summary ==================== Name: Environments-topa.56 Author: topa Time: 22 January 2015, 12:48:30.677 am UUID: e5cad590-2869-4f02-84ac-482952779d06 Ancestors: Environments-topa.55 Provide more Dictionary protocol for exisiting users of Smalltalk globals. =============== Diff against Environments-topa.55 =============== Item was added: + ----- Method: Environment>>associationsDo: (in category 'emulating') ----- + associationsDo: aBlock + "Evaluate aBlock for each of the receiver's elements (key/value associations)." + + declarations associationsDo: aBlock! Item was changed: ----- Method: Environment>>do: (in category 'emulating') ----- do: aBlock "Evaluate aBlock for each of the receiver's values." + self valuesDo: aBlock! - declarations valuesDo: aBlock! Item was added: + ----- Method: Environment>>keysAndValuesDo: (in category 'emulating') ----- + keysAndValuesDo: aBlock + ^self associationsDo: [:assoc | + aBlock value: assoc key value: assoc value].! Item was added: + ----- Method: Environment>>valuesDo: (in category 'emulating') ----- + valuesDo: aBlock + "Evaluate aBlock for each of the receiver's values." + + declarations valuesDo: aBlock! From casey.obrien.r at gmail.com Thu Jan 22 03:20:49 2015 From: casey.obrien.r at gmail.com (Casey Ransberger) Date: Thu Jan 22 03:27:06 2015 Subject: [squeak-dev] Squeak on a mouse? In-Reply-To: <54bfd2bd.89ace00a.1bb5.fffffe14SMTPIN_ADDED_MISSING@mx.google.com> References: <54bfd2bd.89ace00a.1bb5.fffffe14SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Thanks for the link, Jecel. I'm particularly impressed that it's a few hundred words of Forth (I'm assuming he must mean word definitions. 600 actual total words seems unlikely to me; it would be cool to get clarification.) Still though, that's not a lot for a functioning GUI. > On Jan 21, 2015, at 9:24 AM, "Jecel Assumpcao Jr." wrote: > > Casey, > >> http://mybroadband.co.za/news/gadgets/117096-your-entire-pc-in-a-mouse.html > > That is a nice idea, but just to remind people of older implementations > I would like to point out the late Jef Fox's computer in a mouse from > 2000: > > http://www.ultratechnology.com/scope.htm > > The F21 processor was created from Jef by Chuck Moore and ran Forth > natively. In this demo, the whole computer was inside the mouse and the > cable coming out of it was the video cable you connected to a monitor. > > -- Jecel > > From jgr.asselin at me.com Thu Jan 22 04:52:57 2015 From: jgr.asselin at me.com (Raymond Asselin) Date: Thu Jan 22 04:53:01 2015 Subject: [squeak-dev] Squeak on a mouse? In-Reply-To: References: <54bfd2bd.89ace00a.1bb5.fffffe14SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <88F61456-3BA0-40E7-BC56-E3725C126C43@me.com> IIRC, a word In Forth is more like a method in Smalltalk Envoy? de mon iPhone > Le 2015-01-21 ? 22:20, Casey Ransberger a ?crit : > > Thanks for the link, Jecel. I'm particularly impressed that it's a few hundred words of Forth (I'm assuming he must mean word definitions. 600 actual total words seems unlikely to me; it would be cool to get clarification.) Still though, that's not a lot for a functioning GUI. > >> On Jan 21, 2015, at 9:24 AM, "Jecel Assumpcao Jr." wrote: >> >> Casey, >> >>> http://mybroadband.co.za/news/gadgets/117096-your-entire-pc-in-a-mouse.html >> >> That is a nice idea, but just to remind people of older implementations >> I would like to point out the late Jef Fox's computer in a mouse from >> 2000: >> >> http://www.ultratechnology.com/scope.htm >> >> The F21 processor was created from Jef by Chuck Moore and ran Forth >> natively. In this demo, the whole computer was inside the mouse and the >> cable coming out of it was the video cable you connected to a monitor. >> >> -- Jecel > From frank.shearar at gmail.com Thu Jan 22 08:22:37 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Thu Jan 22 08:22:39 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz In-Reply-To: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 21 January 2015 at 23:48, wrote: > Tobias Pape uploaded a new version of Environments to project The Trunk: > http://source.squeak.org/trunk/Environments-topa.56.mcz > > ==================== Summary ==================== > > Name: Environments-topa.56 > Author: topa > Time: 22 January 2015, 12:48:30.677 am > UUID: e5cad590-2869-4f02-84ac-482952779d06 > Ancestors: Environments-topa.55 > > Provide more Dictionary protocol for exisiting users of Smalltalk globals. If it addresses, in an expedient way, existing problems, then fine. But the Environments work was explicitly trying to move _away_ from the Dictionary protocols. Hence why the existing Dictionary-like methods are in the "emulating" category. frank From Das.Linux at gmx.de Thu Jan 22 08:25:59 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu Jan 22 08:26:03 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 22.01.2015, at 09:22, Frank Shearar wrote: > On 21 January 2015 at 23:48, wrote: >> Tobias Pape uploaded a new version of Environments to project The Trunk: >> http://source.squeak.org/trunk/Environments-topa.56.mcz >> >> ==================== Summary ==================== >> >> Name: Environments-topa.56 >> Author: topa >> Time: 22 January 2015, 12:48:30.677 am >> UUID: e5cad590-2869-4f02-84ac-482952779d06 >> Ancestors: Environments-topa.55 >> >> Provide more Dictionary protocol for exisiting users of Smalltalk globals. > > If it addresses, in an expedient way, existing problems, then fine. > But the Environments work was explicitly trying to move _away_ from > the Dictionary protocols. Hence why the existing Dictionary-like > methods are in the "emulating" category. Refactoring-Core is using this API. Best -Tobias From frank.shearar at gmail.com Thu Jan 22 08:30:02 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Thu Jan 22 08:30:04 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 22 January 2015 at 08:25, Tobias Pape wrote: > > On 22.01.2015, at 09:22, Frank Shearar wrote: > >> On 21 January 2015 at 23:48, wrote: >>> Tobias Pape uploaded a new version of Environments to project The Trunk: >>> http://source.squeak.org/trunk/Environments-topa.56.mcz >>> >>> ==================== Summary ==================== >>> >>> Name: Environments-topa.56 >>> Author: topa >>> Time: 22 January 2015, 12:48:30.677 am >>> UUID: e5cad590-2869-4f02-84ac-482952779d06 >>> Ancestors: Environments-topa.55 >>> >>> Provide more Dictionary protocol for exisiting users of Smalltalk globals. >> >> If it addresses, in an expedient way, existing problems, then fine. >> But the Environments work was explicitly trying to move _away_ from >> the Dictionary protocols. Hence why the existing Dictionary-like >> methods are in the "emulating" category. > > Refactoring-Core is using this API. Obviously making the rest of the world move to the Environments API is the _right_ thing to do, if it's manipulating environmental stuff, but in the meantime, +1 to this addition :) frank > Best > -Tobias > From trygver at ifi.uio.no Thu Jan 22 14:59:46 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Thu Jan 22 14:59:53 2015 Subject: [squeak-dev] BabyIDE now works in Squeak 4.5 In-Reply-To: <20150118162405.GA99283@shell.msen.com> References: <54B6830F.5080009@ifi.uio.no> <20150118162405.GA99283@shell.msen.com> Message-ID: <54C11062.2090701@ifi.uio.no> Hi Dave, Thank you for taking the time to look at BabyIDE. You spotted its most novel part, the graphical interaction diagram. Alan coined the term object orientation: "/Thus its semantics are a bit like having thousands and thousands of computers all hooked together by a very fast network./". The interaction diagram shows such a network where objects have been mustered to play their roles in the performance of a task or use case. The behavior of the objects is coded in methods attached to the roles. General questions and ideas about DCI can best be placed on object-composition@googlegroups.com which represents several years of DCI knowledge and experience with implementations in languages such as C++, C#, Marvin, Ruby, Scala, Erlang, Javascript, Haxe, PHP, and Python. Smalltalk is not in this list. This is surprising since Smalltalk has the most sophisticated IDE for DCI and is its natural home. --Trygve On 18.01.2015 17:24, David T. Lewis wrote: > On Wed, Jan 14, 2015 at 03:54:07PM +0100, Trygve Reenskaug wrote: >> Hi all, >> >> DCI is a programming paradigm with strong separation of concerns >> * Classes are used for coding system state - what the system *is*. >> * DCI Contexts are used for coding system behavior - what the system >> *does*. >> The DCI separation of concerns enhances code readability, supports >> testing, and simplifies system extension. >> BabyIDE is an IDE that supports the DCI separation of concerns by >> viewing the code in practically independent projections. >> ++++ > I just installed BabyIdeAllInOne in my working trunk image. I have only > just started to look at it, but I have to say right away that the browser > is really interesting. It has a context view that provides an conventional > browser view, and you can switch to an interaction view that shows a graphical > interaction diagram. The objects in the diagram are live, and selecting one > displays its methods and their implementation. > > Dave > > > -- The essence of object orientation is that objects collaborateto achieve a goal. --- Trygve Reenskaug mailto: trygver@ifi.uio.no Morgedalsvn. 5A http://folk.uio.no/trygver/ N-0378 Oslo http://fullOO.info Norway Tel: (+47) 22 49 57 27 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150122/175b67f7/attachment.htm From nicolas.cellier.aka.nice at gmail.com Thu Jan 22 17:32:42 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Thu Jan 22 17:32:44 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: 2015-01-22 9:30 GMT+01:00 Frank Shearar : > On 22 January 2015 at 08:25, Tobias Pape wrote: > > > > On 22.01.2015, at 09:22, Frank Shearar wrote: > > > >> On 21 January 2015 at 23:48, wrote: > >>> Tobias Pape uploaded a new version of Environments to project The > Trunk: > >>> http://source.squeak.org/trunk/Environments-topa.56.mcz > >>> > >>> ==================== Summary ==================== > >>> > >>> Name: Environments-topa.56 > >>> Author: topa > >>> Time: 22 January 2015, 12:48:30.677 am > >>> UUID: e5cad590-2869-4f02-84ac-482952779d06 > >>> Ancestors: Environments-topa.55 > >>> > >>> Provide more Dictionary protocol for exisiting users of Smalltalk > globals. > >> > >> If it addresses, in an expedient way, existing problems, then fine. > >> But the Environments work was explicitly trying to move _away_ from > >> the Dictionary protocols. Hence why the existing Dictionary-like > >> methods are in the "emulating" category. > > > > Refactoring-Core is using this API. > > Obviously making the rest of the world move to the Environments API is > the _right_ thing to do, if it's manipulating environmental stuff, but > in the meantime, +1 to this addition :) > > frank > > We can use the #deprecated: in the meantime so as to not forget - that we should change senders - that we should not use this API in new code > > Best > > -Tobias > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150122/0b9ce2c1/attachment.htm From Das.Linux at gmx.de Thu Jan 22 17:46:42 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu Jan 22 17:46:46 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 22.01.2015, at 18:32, Nicolas Cellier wrote: > > > 2015-01-22 9:30 GMT+01:00 Frank Shearar : > On 22 January 2015 at 08:25, Tobias Pape wrote: > > > > On 22.01.2015, at 09:22, Frank Shearar wrote: > > > >> On 21 January 2015 at 23:48, wrote: > >>> Tobias Pape uploaded a new version of Environments to project The Trunk: > >>> http://source.squeak.org/trunk/Environments-topa.56.mcz > >>> > >>> ==================== Summary ==================== > >>> > >>> Name: Environments-topa.56 > >>> Author: topa > >>> Time: 22 January 2015, 12:48:30.677 am > >>> UUID: e5cad590-2869-4f02-84ac-482952779d06 > >>> Ancestors: Environments-topa.55 > >>> > >>> Provide more Dictionary protocol for exisiting users of Smalltalk globals. > >> > >> If it addresses, in an expedient way, existing problems, then fine. > >> But the Environments work was explicitly trying to move _away_ from > >> the Dictionary protocols. Hence why the existing Dictionary-like > >> methods are in the "emulating" category. > > > > Refactoring-Core is using this API. > > Obviously making the rest of the world move to the Environments API is > the _right_ thing to do, if it's manipulating environmental stuff, but > in the meantime, +1 to this addition :) > > frank > > > We can use the #deprecated: in the meantime so as to not forget > - that we should change senders > - that we should not use this API in new code I'm unsure. I _really_ like the idea of treating a namespace as a dictionary. But this is just gut feeling. Best -Tobias From bert at freudenbergs.de Thu Jan 22 18:06:01 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Thu Jan 22 18:06:03 2015 Subject: [squeak-dev] Tools for Environments (was Re: The Trunk: Environments-topa.56.mcz) In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <7683E78D-C6A5-4FFA-B427-ECE7E47167FA@freudenbergs.de> On 22.01.2015, at 18:46, Tobias Pape wrote: > > On 22.01.2015, at 18:32, Nicolas Cellier wrote: >> >> We can use the #deprecated: in the meantime so as to not forget >> - that we should change senders >> - that we should not use this API in new code > > I'm unsure. > I _really_ like the idea of treating a namespace as a dictionary. > But this is just gut feeling. Once we actually use multiple environments, won't we have to modify the tools anyway? It would be a pity if you could only use e.g. the Refactoring tools on the global environment. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150122/7df6834a/smime.bin From tim.oesterreich at student.hpi.de Thu Jan 22 20:22:25 2015 From: tim.oesterreich at student.hpi.de (Tim Oesterreich) Date: Thu Jan 22 20:22:20 2015 Subject: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows Message-ID: <000001d03681$23831a60$6a894f20$@student.hpi.de> Hello all, |package folder| "Name of the Monticello-package that should be archived" package := 'SWAProject'. "Name of the resources folder in Contents/Resources/" folder := 'SWA-Resources'. zip := ZipArchive new. mczStream := RWBinaryOrTextStream on: (String new: 10000). workingCopy := MCWorkingCopy forPackage: (MCPackage new name: package). version := workingCopy newVersion fileOutOn: mczStream. (zip addString: mczStream contents as: package, '.mcz') desiredCompressionLevel: 0. zip addTree: Smalltalk imagePath match: [:e | e fullName startsWith: Smalltalk imagePath , FileDirectory slash , folder]. zip addString: 'self fileInMonticelloZipVersionNamed: ''' , package, '.mcz''. (self membersMatching: ''' , folder , FileDirectory slash , '*.*'') do: [ :f | self extractMember: f].' as: 'install/preamble'. zip writeToFileNamed: package , '.sar'. This code should create a SAR-Archive from a Monticello-Package including all resources in the specified folder However it throws the error "File not in Directory: SWA-Resources#" on a Windows-System, while working fine on a Mac. It seems like there is an issue with the handling of platform-dependent directory seperators (\ on Windows, / on UNIX). Best -Tim -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150122/2aa9e5f7/attachment.htm From asqueaker at gmail.com Thu Jan 22 20:26:48 2015 From: asqueaker at gmail.com (Chris Muller) Date: Thu Jan 22 20:26:51 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Thu, Jan 22, 2015 at 11:46 AM, Tobias Pape wrote: > > On 22.01.2015, at 18:32, Nicolas Cellier wrote: > >> >> >> 2015-01-22 9:30 GMT+01:00 Frank Shearar : >> On 22 January 2015 at 08:25, Tobias Pape wrote: >> > >> > On 22.01.2015, at 09:22, Frank Shearar wrote: >> > >> >> On 21 January 2015 at 23:48, wrote: >> >>> Tobias Pape uploaded a new version of Environments to project The Trunk: >> >>> http://source.squeak.org/trunk/Environments-topa.56.mcz >> >>> >> >>> ==================== Summary ==================== >> >>> >> >>> Name: Environments-topa.56 >> >>> Author: topa >> >>> Time: 22 January 2015, 12:48:30.677 am >> >>> UUID: e5cad590-2869-4f02-84ac-482952779d06 >> >>> Ancestors: Environments-topa.55 >> >>> >> >>> Provide more Dictionary protocol for exisiting users of Smalltalk globals. >> >> >> >> If it addresses, in an expedient way, existing problems, then fine. >> >> But the Environments work was explicitly trying to move _away_ from >> >> the Dictionary protocols. Hence why the existing Dictionary-like >> >> methods are in the "emulating" category. >> > >> > Refactoring-Core is using this API. >> >> Obviously making the rest of the world move to the Environments API is >> the _right_ thing to do, if it's manipulating environmental stuff, but >> in the meantime, +1 to this addition :) >> >> frank >> >> >> We can use the #deprecated: in the meantime so as to not forget >> - that we should change senders >> - that we should not use this API in new code > > I'm unsure. > I _really_ like the idea of treating a namespace as a dictionary. > But this is just gut feeling. My first reaction was similar to Frank's, but then I remembered that this is Tobias who, I think, has worked on some of the HP's projects like Code Talk and other cool IDE and development tools. That made me more empathetic to Tobias' gut feeling -- because by being able to have an API consistent with a general collection, it may have facilitated the implementation of some of these tools. So I concluded the "detractor" is not it _having_ Dictionary API, but by _using_ its Dictionary API from other places that could and should use higher-level Environments API. We could simply not do that. From asqueaker at gmail.com Thu Jan 22 20:30:19 2015 From: asqueaker at gmail.com (Chris Muller) Date: Thu Jan 22 20:30:21 2015 Subject: [squeak-dev] Tools for Environments (was Re: The Trunk: Environments-topa.56.mcz) In-Reply-To: <7683E78D-C6A5-4FFA-B427-ECE7E47167FA@freudenbergs.de> References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> <7683E78D-C6A5-4FFA-B427-ECE7E47167FA@freudenbergs.de> Message-ID: On Thu, Jan 22, 2015 at 12:06 PM, Bert Freudenberg wrote: > On 22.01.2015, at 18:46, Tobias Pape wrote: >> >> On 22.01.2015, at 18:32, Nicolas Cellier wrote: >>> >>> We can use the #deprecated: in the meantime so as to not forget >>> - that we should change senders >>> - that we should not use this API in new code >> >> I'm unsure. >> I _really_ like the idea of treating a namespace as a dictionary. >> But this is just gut feeling. > > Once we actually use multiple environments, won't we have to modify the tools anyway? It would be a pity if you could only use e.g. the Refactoring tools on the global environment. Why would including the Dictionary API in Smalltalk mean one could "only" use the Refactoring tools? It is no impediment to developing new tools.. From gettimothy at zoho.com Thu Jan 22 22:23:29 2015 From: gettimothy at zoho.com (gettimothy) Date: Thu Jan 22 22:23:32 2015 Subject: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows In-Reply-To: <000001d03681$23831a60$6a894f20$@student.hpi.de> References: <000001d03681$23831a60$6a894f20$@student.hpi.de> Message-ID: <14b13be3c8a.ad3986f5102304.7932731850340882217@zoho.com> W/o testing it, I noticed that you have a forward slash in FileDirectory slash , '*.*'') do: [ :f | self extractMember: f].' as: 'install/preamble'. <---------------------should this be FileDirectory slash? cheers ---- On Thu, 22 Jan 2015 15:22:25 -0500 Tim Oesterreich <tim.oesterreich@student.hpi.de> wrote ---- Hello all, |package folder| ?Name of the Monticello-package that should be archived? package := 'SWAProject'. ?Name of the resources folder in Contents/Resources/? folder := 'SWA-Resources'. zip := ZipArchive new. mczStream := RWBinaryOrTextStream on: (String new: 10000). workingCopy := MCWorkingCopy forPackage: (MCPackage new name: package). version := workingCopy newVersion fileOutOn: mczStream. (zip addString: mczStream contents as: package, '.mcz') desiredCompressionLevel: 0. zip addTree: Smalltalk imagePath match: [:e | e fullName startsWith: Smalltalk imagePath , FileDirectory slash , folder]. zip addString: 'self fileInMonticelloZipVersionNamed: ''' , package, '.mcz''. (self membersMatching: ''' , folder , FileDirectory slash , '*.*'') do: [ :f | self extractMember: f].' as: 'install/preamble'. zip writeToFileNamed: package , '.sar'. This code should create a SAR-Archive from a Monticello-Package including all resources in the specified folder However it throws the error ?File not in Directory: SWA-Resources#? on a Windows-System, while working fine on a Mac. It seems like there is an issue with the handling of platform-dependent directory seperators (\ on Windows, / on UNIX). Best -Tim -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150122/ec42b12c/attachment-0001.htm From tim.oesterreich at student.hpi.de Thu Jan 22 23:02:30 2015 From: tim.oesterreich at student.hpi.de (Tim Oesterreich) Date: Thu Jan 22 23:02:25 2015 Subject: AW: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows In-Reply-To: <14b13be3c8a.ad3986f5102304.7932731850340882217@zoho.com> References: <000001d03681$23831a60$6a894f20$@student.hpi.de> <14b13be3c8a.ad3986f5102304.7932731850340882217@zoho.com> Message-ID: <001f01d03697$8092cb90$81b862b0$@student.hpi.de> No that?s not it. The error occurs at ?zip addTree:match:? Von: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] Im Auftrag von gettimothy Gesendet: Thursday, 22 January, 2015 23:23 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows W/o testing it, I noticed that you have a forward slash in FileDirectory slash , '*.*'') do: [ :f | self extractMember: f].' as: 'install/preamble'. <---------------------should this be FileDirectory slash? cheers ---- On Thu, 22 Jan 2015 15:22:25 -0500 Tim Oesterreich < tim.oesterreich@student.hpi.de> wrote ---- Hello all, |package folder| ?Name of the Monticello-package that should be archived? package := 'SWAProject'. ?Name of the resources folder in Contents/Resources/? folder := 'SWA-Resources'. zip := ZipArchive new. mczStream := RWBinaryOrTextStream on: (String new: 10000). workingCopy := MCWorkingCopy forPackage: (MCPackage new name: package). version := workingCopy newVersion fileOutOn: mczStream. (zip addString: mczStream contents as: package, '.mcz') desiredCompressionLevel: 0. zip addTree: Smalltalk imagePath match: [:e | e fullName startsWith: Smalltalk imagePath , FileDirectory slash , folder]. zip addString: 'self fileInMonticelloZipVersionNamed: ''' , package, '.mcz''. (self membersMatching: ''' , folder , FileDirectory slash , '*.*'') do: [ :f | self extractMember: f].' as: 'install/preamble'. zip writeToFileNamed: package , '.sar'. This code should create a SAR-Archive from a Monticello-Package including all resources in the specified folder However it throws the error ?File not in Directory: SWA-Resources#? on a Windows-System, while working fine on a Mac. It seems like there is an issue with the handling of platform-dependent directory seperators (\ on Windows, / on UNIX). Best -Tim -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150123/4e98a93b/attachment.htm From bert at freudenbergs.de Thu Jan 22 23:10:53 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Thu Jan 22 23:10:57 2015 Subject: [squeak-dev] Tools for Environments (was Re: The Trunk: Environments-topa.56.mcz) In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> <7683E78D-C6A5-4FFA-B427-ECE7E47167FA@freudenbergs.de> Message-ID: <29BE90AD-A7D7-4648-BD07-8B6093F6971C@freudenbergs.de> > On 22.01.2015, at 21:30, Chris Muller wrote: > > On Thu, Jan 22, 2015 at 12:06 PM, Bert Freudenberg wrote: >> On 22.01.2015, at 18:46, Tobias Pape wrote: >>> >>> On 22.01.2015, at 18:32, Nicolas Cellier wrote: >>>> >>>> We can use the #deprecated: in the meantime so as to not forget >>>> - that we should change senders >>>> - that we should not use this API in new code >>> >>> I'm unsure. >>> I _really_ like the idea of treating a namespace as a dictionary. >>> But this is just gut feeling. >> >> Once we actually use multiple environments, won't we have to modify the tools anyway? It would be a pity if you could only use e.g. the Refactoring tools on the global environment. > > Why would including the Dictionary API in Smalltalk mean one could > "only" use the Refactoring tools? It is no impediment to developing > new tools.. Grammar slip. I meant to write "you could use e.g. the Refactoring tools only on the global environment." An old tool will not know that there is more than one environment. If it has to be made aware of environments anyway, then at the same time it can be made to use the proper API, so we may not need to add the dictionary protocol. OTOH I like polymorphism. I see no good reason to not make the environment expose a dictionary-like protocol, since it clearly associates keys with values, which sounds a lot like a dictionary. But I presume Colin had good reasons to not make this obvious addition, so it may well be that I'm missing something. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150123/a9617ca3/smime.bin From Das.Linux at gmx.de Thu Jan 22 23:29:16 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu Jan 22 23:29:28 2015 Subject: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows In-Reply-To: <001f01d03697$8092cb90$81b862b0$@student.hpi.de> References: <000001d03681$23831a60$6a894f20$@student.hpi.de> <14b13be3c8a.ad3986f5102304.7932731850340882217@zoho.com> <001f01d03697$8092cb90$81b862b0$@student.hpi.de> Message-ID: <4D92A0D6-B9D4-4E3B-B27D-7A7FD00DE24F@gmx.de> Hi previously today I debugged the error together with Tim. The culprit seems to be in ZipDirectoryMember>>localFileName: aString 1 | dir entry parent | 2 super localFileName: aString. 3 fileName last = $/ ifFalse: [ fileName := fileName, '/' ]. 4 parent := FileDirectory default. 5 (parent directoryExists: fileName) ifTrue: [ 6 dir := FileDirectory on: (parent fullNameFor: fileName). 7 entry := dir directoryEntry. 8 self setLastModFileDateTimeFrom: entry modificationTime 9 ] the problematic messages are #directoryExists: (5) and #fullNameFor: (6), because on Windows, `parent` is a DosFileDirectory (w/ pathDelemiter == $\) but line 3 and super (2, ArchiveMember>>#localFileName: (super of ZipDirectoryMember) force $/ at the end of the string. ArchiveMember>>localFileName: aString "Set my internal filename. Returns the (possibly new) filename. aString will be translated from local FS format into Unix format." ^fileName := aString copyReplaceAll: FileDirectory slash with: '/'. so, if `aString` above is 'Resources', it is forced to be 'Resources/', which DosFileDirectory ?sanitizes? to 'Resources#', which does not exists... Best -Tobias On 23.01.2015, at 00:02, Tim Oesterreich wrote: > No that?s not it. > The error occurs at > ?zip addTree:match:? > > Von: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] Im Auftrag vongettimothy > Gesendet: Thursday, 22 January, 2015 23:23 > An: The general-purpose Squeak developers list > Betreff: Re: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows > > W/o testing it, I noticed that you have a forward slash in > > > FileDirectory slash , '*.*'') do: [ :f | self > > extractMember: f].' as: 'install/preamble'. <---------------------should this be FileDirectory slash? > > cheers > > > ---- On Thu, 22 Jan 2015 15:22:25 -0500 Tim Oesterreich wrote ---- > Hello all, > > > > |package folder| > > > > ?Name of the Monticello-package that should be archived? > > package := 'SWAProject'. > > ?Name of the resources folder in Contents/Resources/? > > folder := 'SWA-Resources'. > > > > zip := ZipArchive new. > > mczStream := RWBinaryOrTextStream on: (String new: 10000). > > workingCopy := MCWorkingCopy forPackage: (MCPackage new name: package). > > version := workingCopy newVersion fileOutOn: mczStream. > > (zip addString: mczStream contents as: package, '.mcz') desiredCompressionLevel: 0. > > zip addTree: Smalltalk imagePath match: [:e | e fullName startsWith: > > Smalltalk imagePath , FileDirectory slash , folder]. > > zip addString: 'self fileInMonticelloZipVersionNamed: ''' , package, '.mcz''. > > (self membersMatching: ''' , folder , FileDirectory slash , '*.*'') do: [ :f | self > > extractMember: f].' as: 'install/preamble'. > > zip writeToFileNamed: package , '.sar'. > > > > This code should create a SAR-Archive from a Monticello-Package including all resources in the specified folder > > However it throws the error ?File not in Directory: SWA-Resources#? on a Windows-System, while working fine on a Mac. > > It seems like there is an issue with the handling of platform-dependent directory seperators (\ on Windows, / on UNIX). > > > > Best > > -Tim -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 1625 bytes Desc: Message signed with OpenPGP using GPGMail Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150123/4beb93be/signature.pgp From lewis at mail.msen.com Fri Jan 23 01:47:09 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri Jan 23 01:47:11 2015 Subject: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows In-Reply-To: <4D92A0D6-B9D4-4E3B-B27D-7A7FD00DE24F@gmx.de> References: <000001d03681$23831a60$6a894f20$@student.hpi.de> <14b13be3c8a.ad3986f5102304.7932731850340882217@zoho.com> <001f01d03697$8092cb90$81b862b0$@student.hpi.de> <4D92A0D6-B9D4-4E3B-B27D-7A7FD00DE24F@gmx.de> Message-ID: <20150123014709.GA5601@shell.msen.com> I do not have a Windows machine handy to check this, but it sounds to me like you and Tim are closing in on the problem. If I remember right, the zip archive uses '/' internally as a path separator, regardless of the conventions of the local file system. A DosFileDirectory would quite rightly use the path separator conventions for a DOS (Windows) file system, so the path separator would be '\'. It would not be right to mix the two conventions. >From your description below, it looks like ZipDirectoryMemory>>localFileName: is trying to mix up the zip path separator conventions with the host file system conventions. That is wrong, but apparently it works by accident on Unix based systems. If you can fix this so that it works properly on Windows, then it will probably also work on Unix (and OS X) based systems. Most likely it will be necessary to figure out two different path strings, one for the path name on the local (DOS/Windows) file system, and another to represent that same path name using the zip member conventions (which happen to be based on Unix file system path names). I think that this illustrates the importance of testing Squeak on a variety of platforms :-) Dave I guess that the "parent fullNameFor: localFileSystemPath" should be using a localFileSystemPath with the loc On Fri, Jan 23, 2015 at 12:29:16AM +0100, Tobias Pape wrote: > Hi > > previously today I debugged the error together with Tim. > The culprit seems to be in > > ZipDirectoryMember>>localFileName: aString > 1 | dir entry parent | > 2 super localFileName: aString. > 3 fileName last = $/ ifFalse: [ fileName := fileName, '/' ]. > 4 parent := FileDirectory default. > 5 (parent directoryExists: fileName) ifTrue: [ > 6 dir := FileDirectory on: (parent fullNameFor: fileName). > 7 entry := dir directoryEntry. > 8 self setLastModFileDateTimeFrom: entry modificationTime > 9 ] > > the problematic messages are #directoryExists: (5) and #fullNameFor: (6), > because on Windows, `parent` is a DosFileDirectory (w/ pathDelemiter == $\) > but line 3 and super (2, ArchiveMember>>#localFileName: (super of ZipDirectoryMember) > force $/ at the end of the string. > > ArchiveMember>>localFileName: aString > "Set my internal filename. > Returns the (possibly new) filename. > aString will be translated from local FS format into Unix format." > > ^fileName := aString copyReplaceAll: FileDirectory slash with: '/'. > > so, if `aString` above is 'Resources', it is forced to be > > 'Resources/', which DosFileDirectory ?sanitizes? to 'Resources#', which does > not exists... > > Best > -Tobias > > > > On 23.01.2015, at 00:02, Tim Oesterreich wrote: > > > No that?s not it. > > The error occurs at > > ?zip addTree:match:? > > > > Von: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] Im Auftrag vongettimothy > > Gesendet: Thursday, 22 January, 2015 23:23 > > An: The general-purpose Squeak developers list > > Betreff: Re: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows > > > > W/o testing it, I noticed that you have a forward slash in > > > > > > FileDirectory slash , '*.*'') do: [ :f | self > > > > extractMember: f].' as: 'install/preamble'. <---------------------should this be FileDirectory slash? > > > > cheers > > > > > > ---- On Thu, 22 Jan 2015 15:22:25 -0500 Tim Oesterreich wrote ---- > > Hello all, > > > > > > > > |package folder| > > > > > > > > ?Name of the Monticello-package that should be archived? > > > > package := 'SWAProject'. > > > > ?Name of the resources folder in Contents/Resources/? > > > > folder := 'SWA-Resources'. > > > > > > > > zip := ZipArchive new. > > > > mczStream := RWBinaryOrTextStream on: (String new: 10000). > > > > workingCopy := MCWorkingCopy forPackage: (MCPackage new name: package). > > > > version := workingCopy newVersion fileOutOn: mczStream. > > > > (zip addString: mczStream contents as: package, '.mcz') desiredCompressionLevel: 0. > > > > zip addTree: Smalltalk imagePath match: [:e | e fullName startsWith: > > > > Smalltalk imagePath , FileDirectory slash , folder]. > > > > zip addString: 'self fileInMonticelloZipVersionNamed: ''' , package, '.mcz''. > > > > (self membersMatching: ''' , folder , FileDirectory slash , '*.*'') do: [ :f | self > > > > extractMember: f].' as: 'install/preamble'. > > > > zip writeToFileNamed: package , '.sar'. > > > > > > > > This code should create a SAR-Archive from a Monticello-Package including all resources in the specified folder > > > > However it throws the error ?File not in Directory: SWA-Resources#? on a Windows-System, while working fine on a Mac. > > > > It seems like there is an issue with the handling of platform-dependent directory seperators (\ on Windows, / on UNIX). > > > > > > > > Best > > > > -Tim > > > From marcel.taeumel at student.hpi.uni-potsdam.de Fri Jan 23 09:28:32 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri Jan 23 09:32:12 2015 Subject: [squeak-dev] Manual shrink-wrapping to submorphs Message-ID: <1422005312629-4801162.post@n4.nabble.com> Hi, there! As this does not work because the quasi-global coordinate system interferes: self bounds: self submorphBounds. How about adding a new method #shrinkWrap to morphs: shrinkWrap "Change bounds to match submorphBounds." self submorphBounds in: [:newBounds | | deltaPosition | deltaPosition := newBounds topLeft - self topLeft. self submorphsDo: [:morph | morph topLeft: morph topLeft - deltaPosition]. self topLeft: self topLeft + deltaPosition; extent: newBounds extent]. Best, Marcel -- View this message in context: http://forum.world.st/Manual-shrink-wrapping-to-submorphs-tp4801162.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From frank.shearar at gmail.com Fri Jan 23 09:57:16 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Fri Jan 23 09:57:18 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 22 January 2015 at 20:26, Chris Muller wrote: > On Thu, Jan 22, 2015 at 11:46 AM, Tobias Pape wrote: >> >> On 22.01.2015, at 18:32, Nicolas Cellier wrote: >> >>> >>> >>> 2015-01-22 9:30 GMT+01:00 Frank Shearar : >>> On 22 January 2015 at 08:25, Tobias Pape wrote: >>> > >>> > On 22.01.2015, at 09:22, Frank Shearar wrote: >>> > >>> >> On 21 January 2015 at 23:48, wrote: >>> >>> Tobias Pape uploaded a new version of Environments to project The Trunk: >>> >>> http://source.squeak.org/trunk/Environments-topa.56.mcz >>> >>> >>> >>> ==================== Summary ==================== >>> >>> >>> >>> Name: Environments-topa.56 >>> >>> Author: topa >>> >>> Time: 22 January 2015, 12:48:30.677 am >>> >>> UUID: e5cad590-2869-4f02-84ac-482952779d06 >>> >>> Ancestors: Environments-topa.55 >>> >>> >>> >>> Provide more Dictionary protocol for exisiting users of Smalltalk globals. >>> >> >>> >> If it addresses, in an expedient way, existing problems, then fine. >>> >> But the Environments work was explicitly trying to move _away_ from >>> >> the Dictionary protocols. Hence why the existing Dictionary-like >>> >> methods are in the "emulating" category. >>> > >>> > Refactoring-Core is using this API. >>> >>> Obviously making the rest of the world move to the Environments API is >>> the _right_ thing to do, if it's manipulating environmental stuff, but >>> in the meantime, +1 to this addition :) >>> >>> frank >>> >>> >>> We can use the #deprecated: in the meantime so as to not forget >>> - that we should change senders >>> - that we should not use this API in new code >> >> I'm unsure. >> I _really_ like the idea of treating a namespace as a dictionary. >> But this is just gut feeling. > > My first reaction was similar to Frank's, but then I remembered that > this is Tobias who, I think, has worked on some of the HP's projects > like Code Talk and other cool IDE and development tools. > > That made me more empathetic to Tobias' gut feeling -- because by > being able to have an API consistent with a general collection, it may > have facilitated the implementation of some of these tools. > > So I concluded the "detractor" is not it _having_ Dictionary API, but > by _using_ its Dictionary API from other places that could and should > use higher-level Environments API. We could simply not do that. Yes, exactly. frank From commits at source.squeak.org Sat Jan 24 00:31:45 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 00:31:46 2015 Subject: [squeak-dev] The Inbox: Compression-dtl.47.mcz Message-ID: David T. Lewis uploaded a new version of Compression to project The Inbox: http://source.squeak.org/inbox/Compression-dtl.47.mcz ==================== Summary ==================== Name: Compression-dtl.47 Author: dtl Time: 23 January 2015, 7:31:41.423 pm UUID: 4694513c-b90e-4953-accc-31b7d6c09432 Ancestors: Compression-bf.46 ZipDirectoryMember>>localFileName should use host file system semantics to test for file directory path, it should not assume that unix conventions apply. This hopefully fixes the problem identified by Tim Oesterreich on squeak-dev: [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows =============== Diff against Compression-bf.46 =============== Item was changed: ----- Method: ZipDirectoryMember>>localFileName: (in category 'accessing') ----- localFileName: aString + | dir entry parent fsPath | - | dir entry parent | super localFileName: aString. fileName last = $/ ifFalse: [ fileName := fileName, '/' ]. parent := FileDirectory default. + aString last = parent pathNameDelimiter + ifTrue: [fsPath := parent fullNameFor: aString] + ifFalse: [fsPath := parent fullNameFor: aString, parent slash]. + (parent directoryExists: fsPath) ifTrue: [ + dir := FileDirectory on: fsPath. - (parent directoryExists: fileName) ifTrue: [ - dir := FileDirectory on: (parent fullNameFor: fileName). entry := dir directoryEntry. self setLastModFileDateTimeFrom: entry modificationTime ] ! From lewis at mail.msen.com Sat Jan 24 00:42:35 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat Jan 24 00:42:37 2015 Subject: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows In-Reply-To: <000001d03681$23831a60$6a894f20$@student.hpi.de> References: <000001d03681$23831a60$6a894f20$@student.hpi.de> Message-ID: <20150124004235.GA36459@shell.msen.com> Hi Tim and Tobias, I put a proposed fix for this in the inbox. The update is: ZipDirectoryMember>>localFileName: aString | dir entry parent fsPath | super localFileName: aString. fileName last = $/ ifFalse: [ fileName := fileName, '/' ]. parent := FileDirectory default. aString last = parent pathNameDelimiter ifTrue: [fsPath := parent fullNameFor: aString] ifFalse: [fsPath := parent fullNameFor: aString, parent slash]. (parent directoryExists: fsPath) ifTrue: [ dir := FileDirectory on: fsPath. entry := dir directoryEntry. self setLastModFileDateTimeFrom: entry modificationTime ] This separates the host file system test (Windows in the case) from the path naming in the zip archive. It also expands the path name to be fully qualified ("C:\foo\bar" not just "bar") because this is important on Windows and also should work on Unix. Please give this a try and see if it solves the problem for you. If nobody complains, I'll move it to trunk in a day or so. Dave On Thu, Jan 22, 2015 at 09:22:25PM +0100, Tim Oesterreich wrote: > Hello all, > > > > |package folder| > > > > "Name of the Monticello-package that should be archived" > > package := 'SWAProject'. > > "Name of the resources folder in Contents/Resources/" > > folder := 'SWA-Resources'. > > > > zip := ZipArchive new. > > mczStream := RWBinaryOrTextStream on: (String new: 10000). > > workingCopy := MCWorkingCopy forPackage: (MCPackage new name: package). > > version := workingCopy newVersion fileOutOn: mczStream. > > (zip addString: mczStream contents as: package, '.mcz') > desiredCompressionLevel: 0. > > zip addTree: Smalltalk imagePath match: [:e | e fullName startsWith: > > Smalltalk imagePath , FileDirectory slash , folder]. > > zip addString: 'self fileInMonticelloZipVersionNamed: ''' , package, > '.mcz''. > > (self membersMatching: ''' , folder , FileDirectory slash , '*.*'') do: [ :f > | self > > extractMember: f].' as: 'install/preamble'. > > zip writeToFileNamed: package , '.sar'. > > > > This code should create a SAR-Archive from a Monticello-Package including > all resources in the specified folder > > However it throws the error "File not in Directory: SWA-Resources#" on a > Windows-System, while working fine on a Mac. > > It seems like there is an issue with the handling of platform-dependent > directory seperators (\ on Windows, / on UNIX). > > > > Best > > -Tim > > > > From tim.oesterreich at student.hpi.de Sat Jan 24 01:53:20 2015 From: tim.oesterreich at student.hpi.de (Tim Oesterreich) Date: Sat Jan 24 01:53:13 2015 Subject: AW: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows In-Reply-To: <20150124004235.GA36459@shell.msen.com> References: <000001d03681$23831a60$6a894f20$@student.hpi.de> <20150124004235.GA36459@shell.msen.com> Message-ID: <000001d03778$87fafb00$97f0f100$@student.hpi.de> Hi Dave, this did fix the problem. (Tested on Windows. I'm assuming it doesn't suddenly crash on Unix now ;) ) Thank you! Tim -----Urspr?ngliche Nachricht----- Von: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] Im Auftrag von David T. Lewis Gesendet: Saturday, 24 January, 2015 1:43 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows Hi Tim and Tobias, I put a proposed fix for this in the inbox. The update is: ZipDirectoryMember>>localFileName: aString | dir entry parent fsPath | super localFileName: aString. fileName last = $/ ifFalse: [ fileName := fileName, '/' ]. parent := FileDirectory default. aString last = parent pathNameDelimiter ifTrue: [fsPath := parent fullNameFor: aString] ifFalse: [fsPath := parent fullNameFor: aString, parent slash]. (parent directoryExists: fsPath) ifTrue: [ dir := FileDirectory on: fsPath. entry := dir directoryEntry. self setLastModFileDateTimeFrom: entry modificationTime ] This separates the host file system test (Windows in the case) from the path naming in the zip archive. It also expands the path name to be fully qualified ("C:\foo\bar" not just "bar") because this is important on Windows and also should work on Unix. Please give this a try and see if it solves the problem for you. If nobody complains, I'll move it to trunk in a day or so. Dave On Thu, Jan 22, 2015 at 09:22:25PM +0100, Tim Oesterreich wrote: > Hello all, > > > > |package folder| > > > > "Name of the Monticello-package that should be archived" > > package := 'SWAProject'. > > "Name of the resources folder in Contents/Resources/" > > folder := 'SWA-Resources'. > > > > zip := ZipArchive new. > > mczStream := RWBinaryOrTextStream on: (String new: 10000). > > workingCopy := MCWorkingCopy forPackage: (MCPackage new name: package). > > version := workingCopy newVersion fileOutOn: mczStream. > > (zip addString: mczStream contents as: package, '.mcz') > desiredCompressionLevel: 0. > > zip addTree: Smalltalk imagePath match: [:e | e fullName startsWith: > > Smalltalk imagePath , FileDirectory slash , folder]. > > zip addString: 'self fileInMonticelloZipVersionNamed: ''' , package, > '.mcz''. > > (self membersMatching: ''' , folder , FileDirectory slash , '*.*'') > do: [ :f > | self > > extractMember: f].' as: 'install/preamble'. > > zip writeToFileNamed: package , '.sar'. > > > > This code should create a SAR-Archive from a Monticello-Package > including all resources in the specified folder > > However it throws the error "File not in Directory: SWA-Resources#" on > a Windows-System, while working fine on a Mac. > > It seems like there is an issue with the handling of > platform-dependent directory seperators (\ on Windows, / on UNIX). > > > > Best > > -Tim > > > > From lewis at mail.msen.com Sat Jan 24 02:00:52 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat Jan 24 02:00:55 2015 Subject: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows In-Reply-To: <000001d03778$87fafb00$97f0f100$@student.hpi.de> References: <000001d03681$23831a60$6a894f20$@student.hpi.de> <20150124004235.GA36459@shell.msen.com> <000001d03778$87fafb00$97f0f100$@student.hpi.de> Message-ID: <20150124020052.GA49324@shell.msen.com> OK good. I tried it on Unix with your original example code, and that works also. I will move the update from inbox to trunk. Thanks, Dave On Sat, Jan 24, 2015 at 02:53:20AM +0100, Tim Oesterreich wrote: > Hi Dave, > > this did fix the problem. (Tested on Windows. I'm assuming it doesn't > suddenly crash on Unix now ;) ) > > Thank you! > > Tim > > -----Urspr?ngliche Nachricht----- > Von: squeak-dev-bounces@lists.squeakfoundation.org > [mailto:squeak-dev-bounces@lists.squeakfoundation.org] Im Auftrag von David > T. Lewis > Gesendet: Saturday, 24 January, 2015 1:43 > An: The general-purpose Squeak developers list > Betreff: Re: [squeak-dev] [BUG] ERROR: File not in Directory: [...] while > trying to create a SAR-archive on Windows > > Hi Tim and Tobias, > > I put a proposed fix for this in the inbox. > > The update is: > > ZipDirectoryMember>>localFileName: aString > | dir entry parent fsPath | > super localFileName: aString. > fileName last = $/ ifFalse: [ fileName := fileName, '/' ]. > parent := FileDirectory default. > aString last = parent pathNameDelimiter > ifTrue: [fsPath := parent fullNameFor: aString] > ifFalse: [fsPath := parent fullNameFor: aString, parent > slash]. > (parent directoryExists: fsPath) ifTrue: [ > dir := FileDirectory on: fsPath. > entry := dir directoryEntry. > self setLastModFileDateTimeFrom: entry modificationTime > ] > > > This separates the host file system test (Windows in the case) from the path > naming in the zip archive. It also expands the path name to be fully > qualified ("C:\foo\bar" not just "bar") because this is important on Windows > and also should work on Unix. > > Please give this a try and see if it solves the problem for you. If nobody > complains, I'll move it to trunk in a day or so. > > Dave > > > > On Thu, Jan 22, 2015 at 09:22:25PM +0100, Tim Oesterreich wrote: > > Hello all, > > > > > > > > |package folder| > > > > > > > > "Name of the Monticello-package that should be archived" > > > > package := 'SWAProject'. > > > > "Name of the resources folder in Contents/Resources/" > > > > folder := 'SWA-Resources'. > > > > > > > > zip := ZipArchive new. > > > > mczStream := RWBinaryOrTextStream on: (String new: 10000). > > > > workingCopy := MCWorkingCopy forPackage: (MCPackage new name: package). > > > > version := workingCopy newVersion fileOutOn: mczStream. > > > > (zip addString: mczStream contents as: package, '.mcz') > > desiredCompressionLevel: 0. > > > > zip addTree: Smalltalk imagePath match: [:e | e fullName startsWith: > > > > Smalltalk imagePath , FileDirectory slash , folder]. > > > > zip addString: 'self fileInMonticelloZipVersionNamed: ''' , package, > > '.mcz''. > > > > (self membersMatching: ''' , folder , FileDirectory slash , '*.*'') > > do: [ :f > > | self > > > > extractMember: f].' as: 'install/preamble'. > > > > zip writeToFileNamed: package , '.sar'. > > > > > > > > This code should create a SAR-Archive from a Monticello-Package > > including all resources in the specified folder > > > > However it throws the error "File not in Directory: SWA-Resources#" on > > a Windows-System, while working fine on a Mac. > > > > It seems like there is an issue with the handling of > > platform-dependent directory seperators (\ on Windows, / on UNIX). > > > > > > > > Best > > > > -Tim > > > > > > > > > > > > From commits at source.squeak.org Sat Jan 24 02:02:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 02:02:26 2015 Subject: [squeak-dev] The Trunk: Compression-dtl.47.mcz Message-ID: David T. Lewis uploaded a new version of Compression to project The Trunk: http://source.squeak.org/trunk/Compression-dtl.47.mcz ==================== Summary ==================== Name: Compression-dtl.47 Author: dtl Time: 23 January 2015, 7:31:41.423 pm UUID: 4694513c-b90e-4953-accc-31b7d6c09432 Ancestors: Compression-bf.46 ZipDirectoryMember>>localFileName should use host file system semantics to test for file directory path, it should not assume that unix conventions apply. This hopefully fixes the problem identified by Tim Oesterreich on squeak-dev: [BUG] ERROR: File not in Directory: [...] while trying to create a SAR-archive on Windows =============== Diff against Compression-bf.46 =============== Item was changed: ----- Method: ZipDirectoryMember>>localFileName: (in category 'accessing') ----- localFileName: aString + | dir entry parent fsPath | - | dir entry parent | super localFileName: aString. fileName last = $/ ifFalse: [ fileName := fileName, '/' ]. parent := FileDirectory default. + aString last = parent pathNameDelimiter + ifTrue: [fsPath := parent fullNameFor: aString] + ifFalse: [fsPath := parent fullNameFor: aString, parent slash]. + (parent directoryExists: fsPath) ifTrue: [ + dir := FileDirectory on: fsPath. - (parent directoryExists: fileName) ifTrue: [ - dir := FileDirectory on: (parent fullNameFor: fileName). entry := dir directoryEntry. self setLastModFileDateTimeFrom: entry modificationTime ] ! From commits at source.squeak.org Sat Jan 24 14:21:13 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 14:21:14 2015 Subject: [squeak-dev] The Trunk: Compiler-topa.292.mcz Message-ID: Tobias Pape uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-topa.292.mcz ==================== Summary ==================== Name: Compiler-topa.292 Author: topa Time: 24 January 2015, 3:21:01.295 pm UUID: 96d2c928-fd32-4327-b74a-55e09df39549 Ancestors: Compiler-eem.291 Fix super-send DoIts in the debugger. =============== Diff against Compiler-eem.291 =============== Item was changed: ----- Method: Compiler>>evaluate:in:to:notifying:ifFail: (in category 'public access') ----- evaluate: textOrStream in: aContext to: receiver notifying: aRequestor ifFail: failBlock "Compiles the sourceStream into a parse tree, then generates code into a method. If aContext is not nil, the text can refer to temporaries in that context (the Debugger uses this). If aRequestor is not nil, then it will receive a notify:at: message before the attempt to evaluate is aborted. Finally, the compiled method is invoked from here via withArgs:executeMethod:, hence the system no longer creates Doit method litter on errors." | theClass | + theClass := aContext ifNil: [receiver class] ifNotNil: [:ctx | ctx methodClass]. - theClass := ((aContext == nil ifTrue: [receiver] ifFalse: [aContext receiver]) class). ^self evaluateCue: (CompilationCue source: textOrStream context: aContext receiver: receiver class: theClass environment: theClass environment requestor: aRequestor) ifFail: failBlock! From commits at source.squeak.org Sat Jan 24 14:31:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 14:31:26 2015 Subject: [squeak-dev] Squeak 4.5: Environments-nice.47.mcz Message-ID: Tobias Pape uploaded a new version of Environments to project Squeak 4.5: http://source.squeak.org/squeak45/Environments-nice.47.mcz ==================== Summary ==================== Name: Environments-nice.47 Author: nice Time: 25 May 2014, 12:22:16.232 am UUID: 83f41a4a-d652-4246-8c98-587bf994a91a Ancestors: Environments-ul.46 Rename EnvironmentRequest to CurrentEnvironment and use it to implement Environment class>>current. Or more exactly, replace with rather than rename (and don't remove EnvironmentRequest yet, otherwise the update-stream which is using EnvironmentRequest via Monticello will fail) =============== Diff against Environments-ul.46 =============== Item was added: + Notification subclass: #CurrentEnvironment + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'Environments-Loading'! Item was added: + ----- Method: Environment class>>current (in category 'accessing') ----- + current + ^ CurrentEnvironment signal ifNil: [self default]! Item was changed: ----- Method: EnvironmentLoader>>evaluate: (in category 'as yet unclassified') ----- evaluate: chunk ^ [Compiler evaluate: chunk environment: environment] + on: CurrentEnvironment - on: EnvironmentRequest do: [:req | req resume: environment]! Item was changed: ----- Method: EnvironmentLoader>>evaluate:logged: (in category 'as yet unclassified') ----- evaluate: chunk logged: aBoolean ^ [Compiler evaluate: chunk environment: environment logged: aBoolean] + on: CurrentEnvironment - on: EnvironmentRequest do: [:req | req resume: environment]! From commits at source.squeak.org Sat Jan 24 14:31:35 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 14:31:36 2015 Subject: [squeak-dev] Squeak 4.5: Environments-cmm.52.mcz Message-ID: Tobias Pape uploaded a new version of Environments to project Squeak 4.5: http://source.squeak.org/squeak45/Environments-cmm.52.mcz ==================== Summary ==================== Name: Environments-cmm.52 Author: cmm Time: 16 January 2015, 2:40:52.666 pm UUID: 3da327fd-f1d6-49e1-ac81-0207b9264153 Ancestors: Environments-cmm.51, Environments-nice.47 - Roll back cwp.50 because creating a new binding leaves the CM-literal bindings in their old state. - Don't signal #binding:removedFrom: because it's becoming the literal in CM's to a newly created Undeclared literal with the old name. - So since we no longer signal removed: don't signal #binding:addedTo: either. Renaming is a updating of a binding, not a removing or adding. =============== Diff against Environments-cmm.51 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. + binding := self associationAt: oldName. - binding := self declarationOf: oldName. declarations removeKey: oldName. + " self binding: binding removedFrom: self." - self binding: binding removedFrom: self. + binding key: newName. - binding := newName => aClass. declarations add: binding. + " self binding: binding addedTo: self." - self binding: binding addedTo: self. Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From commits at source.squeak.org Sat Jan 24 14:32:14 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 14:32:15 2015 Subject: [squeak-dev] Squeak 4.5: Environments-cmm.53.mcz Message-ID: Tobias Pape uploaded a new version of Environments to project Squeak 4.5: http://source.squeak.org/squeak45/Environments-cmm.53.mcz ==================== Summary ==================== Name: Environments-cmm.53 Author: cmm Time: 16 January 2015, 2:54:24.767 pm UUID: 69b32fc7-98f1-4c19-9976-a38106a9ee63 Ancestors: Environments-cmm.52 - Only change key when it is NOT in the 'bindings' Dictionary, otherwise it would be in a state inconsistent with its new hash. =============== Diff against Environments-cmm.52 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. binding := self associationAt: oldName. declarations removeKey: oldName. + bindings removeKey: oldName. " self binding: binding removedFrom: self." binding key: newName. + declarations add: binding. + bindings add: binding. - declarations add: binding. " self binding: binding addedTo: self." Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From commits at source.squeak.org Sat Jan 24 14:32:22 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 14:32:22 2015 Subject: [squeak-dev] Squeak 4.5: Environments-topa.54.mcz Message-ID: Tobias Pape uploaded a new version of Environments to project Squeak 4.5: http://source.squeak.org/squeak45/Environments-topa.54.mcz ==================== Summary ==================== Name: Environments-topa.54 Author: topa Time: 20 January 2015, 4:12:36.674 pm UUID: b55bd16f-c2c0-4927-b170-4954383dd63f Ancestors: Environments-cmm.53 Update literal bindings in compiled methods when renaming a class. Restores working behavior of pre-Squeak4.5. =============== Diff against Environments-cmm.53 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. + binding := self declarationOf: oldName. - binding := self associationAt: oldName. declarations removeKey: oldName. + self binding: binding removedFrom: self. + undeclared removeKey: oldName. + + binding becomeForward: (newName => aClass). + declarations add: binding. + self binding: binding addedTo: self. - bindings removeKey: oldName. - " self binding: binding removedFrom: self." - binding key: newName. - declarations add: binding. - bindings add: binding. - " self binding: binding addedTo: self." - Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From commits at source.squeak.org Sat Jan 24 14:32:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 14:32:27 2015 Subject: [squeak-dev] Squeak 4.5: Environments-topa.55.mcz Message-ID: Tobias Pape uploaded a new version of Environments to project Squeak 4.5: http://source.squeak.org/squeak45/Environments-topa.55.mcz ==================== Summary ==================== Name: Environments-topa.55 Author: topa Time: 21 January 2015, 11:15:37.19 am UUID: ac4cd9b0-1628-4881-a2c2-f6d1e1a6f089 Ancestors: Environments-topa.54 3rd attempt at class-rename fixes. This version a) avoids #becomeForward: b) fixes method homes after rename c) moves the obsolete binding to undeclared but keeps it working. Effectively, this is the outcome: | p | p := Object subclass: #A instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Unknown'. p compile: 'foo ^ A new'. " literals of #foo {#A=>A . #foo . #A=>A}" p rename: #B. " literals of #foo {#A=>B . #foo . #B=>B}" p new foo class == p. =============== Diff against Environments-topa.54 =============== Item was changed: ----- Method: Environment>>renameClass:from:to: (in category 'classes and traits') ----- renameClass: aClass from: oldName to: newName "Rename the class, aClass, to have the title newName." + | oldBinding newBinding category | - | binding category | category := self organization categoryOfElement: oldName. self organization classify: newName under: category suppressIfDefault: true. self organization removeElement: oldName. + oldBinding := self declarationOf: oldName. - binding := self declarationOf: oldName. declarations removeKey: oldName. + self binding: oldBinding removedFrom: self. + " re-route now undeclared oldBinding " + oldBinding value: aClass. - self binding: binding removedFrom: self. - undeclared removeKey: oldName. + newBinding := newName => aClass. + aClass updateMethodBindingsTo: newBinding. + declarations add: newBinding. + self binding: newBinding addedTo: self. - binding becomeForward: (newName => aClass). - declarations add: binding. - self binding: binding addedTo: self. Smalltalk renamedClass: aClass from: oldName to: newName. SystemChangeNotifier uniqueInstance classRenamed: aClass from: oldName to: newName inCategory: category! From commits at source.squeak.org Sat Jan 24 14:32:34 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 14:32:35 2015 Subject: [squeak-dev] Squeak 4.5: Environments-topa.56.mcz Message-ID: Tobias Pape uploaded a new version of Environments to project Squeak 4.5: http://source.squeak.org/squeak45/Environments-topa.56.mcz ==================== Summary ==================== Name: Environments-topa.56 Author: topa Time: 22 January 2015, 12:48:30.677 am UUID: e5cad590-2869-4f02-84ac-482952779d06 Ancestors: Environments-topa.55 Provide more Dictionary protocol for exisiting users of Smalltalk globals. =============== Diff against Environments-topa.55 =============== Item was added: + ----- Method: Environment>>associationsDo: (in category 'emulating') ----- + associationsDo: aBlock + "Evaluate aBlock for each of the receiver's elements (key/value associations)." + + declarations associationsDo: aBlock! Item was changed: ----- Method: Environment>>do: (in category 'emulating') ----- do: aBlock "Evaluate aBlock for each of the receiver's values." + self valuesDo: aBlock! - declarations valuesDo: aBlock! Item was added: + ----- Method: Environment>>keysAndValuesDo: (in category 'emulating') ----- + keysAndValuesDo: aBlock + ^self associationsDo: [:assoc | + aBlock value: assoc key value: assoc value].! Item was added: + ----- Method: Environment>>valuesDo: (in category 'emulating') ----- + valuesDo: aBlock + "Evaluate aBlock for each of the receiver's values." + + declarations valuesDo: aBlock! From commits at source.squeak.org Sat Jan 24 14:33:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 24 14:33:57 2015 Subject: [squeak-dev] Squeak 4.5: Tools-topa.520.mcz Message-ID: Tobias Pape uploaded a new version of Tools to project Squeak 4.5: http://source.squeak.org/squeak45/Tools-topa.520.mcz ==================== Summary ==================== Name: Tools-topa.520 Author: topa Time: 24 January 2015, 3:33:41.564 pm UUID: b3b4946b-2a81-4d72-b665-2879d4cfd54a Ancestors: Tools-cmm.519 Cherry-picked from Trunk (Tools-topa.533): Fix notification about obsolete class references after a class rename =============== Diff against Tools-cmm.519 =============== Item was changed: ----- Method: Browser>>renameClass (in category 'class functions') ----- renameClass + | oldName newName obs oldBinding | - | oldName newName obs | self hasClassSelected ifFalse: [^ self]. self okToChange ifFalse: [^ self]. oldName := self selectedClass name. newName := self request: 'Please type new class name' initialAnswer: oldName. newName = '' ifTrue: [^ self]. "Cancel returns ''" newName := newName asSymbol. newName = oldName ifTrue: [^ self]. (self selectedClass environment includesKey: newName) ifTrue: [^ self error: newName , ' already exists']. + oldBinding := self selectedClass environment declarationOf: oldName. self selectedClass rename: newName. selectedClassName := newName. self changed: #classList. + obs := self systemNavigation allCallsOn: oldBinding. - obs := self systemNavigation - allCallsOn: (self selectedClass environment associationAt: newName). obs isEmpty ifFalse: [self systemNavigation browseMessageList: obs name: 'Obsolete References to ' , oldName autoSelect: oldName]. self selectClassNamed: newName.! From lewis at mail.msen.com Sun Jan 25 15:47:43 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sun Jan 25 15:47:50 2015 Subject: [squeak-dev] Re: [Newbies] material design for squeak! In-Reply-To: <4e6a32aae0e385987d4b95ac08e6d84d@kathe.in> References: <4e6a32aae0e385987d4b95ac08e6d84d@kathe.in> Message-ID: <20150125154743.GA88140@shell.msen.com> On Sun, Jan 25, 2015 at 09:02:35PM +0530, Mayuresh Kathe wrote: > considering the *great* graphics and animation support available under > squeak, would it be difficult to mould the squeak 'ui' to adhere to > material design guidelines [1] from google? > > 1. http://www.google.com/design/spec/material-design/introduction.html > > ~mayuresh > Designing and implementing user interfaces tends to be a lot of work, but aside from that I so no reason that it could not be done. One of the nice aspects of Squeak (often overlooked) is that it provides a concept of "projects" in which different types of user interface environments can be implemented. You can open a Morphic project or an MVC project, and the system will look and feel quite different depending which kind of project you are currently using. The concept can be extended to other kinds of UI implementation, such as the one you are suggesting here. I am cross-posting to the squeak-dev list, which is probably a better place to continue the discussion. Dave From mayuresh at kathe.in Sun Jan 25 16:01:49 2015 From: mayuresh at kathe.in (Mayuresh Kathe) Date: Sun Jan 25 16:02:00 2015 Subject: [squeak-dev] Re: [Newbies] material design for squeak! In-Reply-To: <20150125154743.GA88140@shell.msen.com> References: <4e6a32aae0e385987d4b95ac08e6d84d@kathe.in> <20150125154743.GA88140@shell.msen.com> Message-ID: <20150125160147.GA1332@aio.kathe.in> On Sun, Jan 25, 2015 at 10:47:43AM -0500, David T. Lewis wrote: > On Sun, Jan 25, 2015 at 09:02:35PM +0530, Mayuresh Kathe wrote: > > considering the *great* graphics and animation support available under > > squeak, would it be difficult to mould the squeak 'ui' to adhere to > > material design guidelines [1] from google? > > > > 1. http://www.google.com/design/spec/material-design/introduction.html > > > > ~mayuresh > > > > Designing and implementing user interfaces tends to be a lot of work, but > aside from that I so no reason that it could not be done. > > One of the nice aspects of Squeak (often overlooked) is that it provides > a concept of "projects" in which different types of user interface > environments can be implemented. You can open a Morphic project or an > MVC project, and the system will look and feel quite different depending > which kind of project you are currently using. The concept can be extended > to other kinds of UI implementation, such as the one you are suggesting > here. > > I am cross-posting to the squeak-dev list, which is probably a better > place to continue the discussion. > > Dave okay, since i am still self-training for smalltalk and all stuff squeak, would like to know if the preferred approach be to create my own project and do what i want with it without crippling the rest of my system image? ~mayuresh From lewis at mail.msen.com Sun Jan 25 17:16:55 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sun Jan 25 17:16:58 2015 Subject: [squeak-dev] Re: [Newbies] material design for squeak! In-Reply-To: <20150125160147.GA1332@aio.kathe.in> References: <4e6a32aae0e385987d4b95ac08e6d84d@kathe.in> <20150125154743.GA88140@shell.msen.com> <20150125160147.GA1332@aio.kathe.in> Message-ID: <20150125171655.GA97022@shell.msen.com> On Sun, Jan 25, 2015 at 09:31:49PM +0530, Mayuresh Kathe wrote: > On Sun, Jan 25, 2015 at 10:47:43AM -0500, David T. Lewis wrote: > > On Sun, Jan 25, 2015 at 09:02:35PM +0530, Mayuresh Kathe wrote: > > > considering the *great* graphics and animation support available under > > > squeak, would it be difficult to mould the squeak 'ui' to adhere to > > > material design guidelines [1] from google? > > > > > > 1. http://www.google.com/design/spec/material-design/introduction.html > > > > > > ~mayuresh > > > > > > > Designing and implementing user interfaces tends to be a lot of work, but > > aside from that I so no reason that it could not be done. > > > > One of the nice aspects of Squeak (often overlooked) is that it provides > > a concept of "projects" in which different types of user interface > > environments can be implemented. You can open a Morphic project or an > > MVC project, and the system will look and feel quite different depending > > which kind of project you are currently using. The concept can be extended > > to other kinds of UI implementation, such as the one you are suggesting > > here. > > > > I am cross-posting to the squeak-dev list, which is probably a better > > place to continue the discussion. > > > > Dave > > okay, since i am still self-training for smalltalk and all stuff squeak, > would like to know if the preferred approach be to create my own project > and do what i want with it without crippling the rest of my system > image? Hi Mayuresh, Start by doing this: Project current explore This will give you an explorer on your current project. This corresponds to everything that you are interacting with on your Squeak display right now. If you have created other projects, they will be linked together though the nextProject, previousProject, and parentProject that you see in the explorer. You will also see a uiManager in your explorer. Your current project is probably an instance of MorphicProject, and the UI manager will be an instance of MorphicUIManager. The two cooperate to manage the Morphic user interface. If you were in an MVC project (try it) you would have an MVCProject that has an MVCUIManager. If you browse the class hierarchy for both Project and UIManager, you will see that these are abstract classes that have subclasses to represent the Morphic and MVC user interfaces. There is also a related ToolBuilder hierarchy that is used for creating the the Morphic or MVC tools (browsers, debuggers, and so forth). To create a different kind of user interface, you would want to create new kinds of Project and UIManager, and maybe also ToolBuilder. One way to get started would be to subclass the existing MorphicProject and MorphicUIManager, and start changing those subclasses a little bit at a time until you achieve the behavior you want. Your new kind of Project would be activated through the Squeak menus. I will not try to explain that now, but if you look at the toolbar at the top of the Squeak window, you will see: Project -> New Project -> New MVCProject -> New MorphicProject So you would add your new kind of project into the menus: Project -> New Project -> New MVCProject -> New MorphicProject -> New MaterialDesignProject And more generally, we might hope some day to see a few other kinds of projects: Project -> New Project -> New MVCProject -> New MorphicProject -> New MaterialDesignProject -> New ScratchProject -> New EtoysProject -> New Morphic3Project -> New SeasideProject Dave From mayuresh at kathe.in Sun Jan 25 17:57:27 2015 From: mayuresh at kathe.in (Mayuresh Kathe) Date: Sun Jan 25 17:57:35 2015 Subject: [squeak-dev] Re: [Newbies] material design for squeak! In-Reply-To: <20150125171655.GA97022@shell.msen.com> References: <4e6a32aae0e385987d4b95ac08e6d84d@kathe.in> <20150125154743.GA88140@shell.msen.com> <20150125160147.GA1332@aio.kathe.in> <20150125171655.GA97022@shell.msen.com> Message-ID: <20150125175726.GA1349@aio.kathe.in> On Sun, Jan 25, 2015 at 12:16:55PM -0500, David T. Lewis wrote: > On Sun, Jan 25, 2015 at 09:31:49PM +0530, Mayuresh Kathe wrote: > > On Sun, Jan 25, 2015 at 10:47:43AM -0500, David T. Lewis wrote: > > > On Sun, Jan 25, 2015 at 09:02:35PM +0530, Mayuresh Kathe wrote: > > > > considering the *great* graphics and animation support available under > > > > squeak, would it be difficult to mould the squeak 'ui' to adhere to > > > > material design guidelines [1] from google? > > > > > > > > 1. http://www.google.com/design/spec/material-design/introduction.html > > > > > > > > ~mayuresh > > > > > > > > > > Designing and implementing user interfaces tends to be a lot of work, but > > > aside from that I so no reason that it could not be done. > > > > > > One of the nice aspects of Squeak (often overlooked) is that it provides > > > a concept of "projects" in which different types of user interface > > > environments can be implemented. You can open a Morphic project or an > > > MVC project, and the system will look and feel quite different depending > > > which kind of project you are currently using. The concept can be extended > > > to other kinds of UI implementation, such as the one you are suggesting > > > here. > > > > > > I am cross-posting to the squeak-dev list, which is probably a better > > > place to continue the discussion. > > > > > > Dave > > > > okay, since i am still self-training for smalltalk and all stuff squeak, > > would like to know if the preferred approach be to create my own project > > and do what i want with it without crippling the rest of my system > > image? > > Hi Mayuresh, > > Start by doing this: > > Project current explore > > This will give you an explorer on your current project. This corresponds > to everything that you are interacting with on your Squeak display right > now. > > If you have created other projects, they will be linked together though > the nextProject, previousProject, and parentProject that you see in the > explorer. > > You will also see a uiManager in your explorer. Your current project is > probably an instance of MorphicProject, and the UI manager will be an > instance of MorphicUIManager. The two cooperate to manage the Morphic > user interface. If you were in an MVC project (try it) you would have an > MVCProject that has an MVCUIManager. > > If you browse the class hierarchy for both Project and UIManager, you > will see that these are abstract classes that have subclasses to represent > the Morphic and MVC user interfaces. There is also a related ToolBuilder > hierarchy that is used for creating the the Morphic or MVC tools (browsers, > debuggers, and so forth). > > To create a different kind of user interface, you would want to create > new kinds of Project and UIManager, and maybe also ToolBuilder. One way > to get started would be to subclass the existing MorphicProject and > MorphicUIManager, and start changing those subclasses a little bit at > a time until you achieve the behavior you want. > > Your new kind of Project would be activated through the Squeak menus. I > will not try to explain that now, but if you look at the toolbar at the > top of the Squeak window, you will see: > > Project > -> New Project > -> New MVCProject > -> New MorphicProject > > So you would add your new kind of project into the menus: > > Project > -> New Project > -> New MVCProject > -> New MorphicProject > -> New MaterialDesignProject > > And more generally, we might hope some day to see a few other kinds > of projects: > > Project > -> New Project > -> New MVCProject > -> New MorphicProject > -> New MaterialDesignProject > -> New ScratchProject > -> New EtoysProject > -> New Morphic3Project > -> New SeasideProject > > Dave hello dave, "Project current explore" is definitely cool, i did not know about it. as i'd mentioned, i am still quite some time away from completing my self-training in smalltalk using squeak, post which i would need to spend a considerable amount of time gaining experience, and i guess that's when i would be ready to dive in to work on creating my own user interface. i am quite impressed with the work done on "thirdway", an extension of the 'mvc' project world, and i hope to become atleast as good as the creator of that project. thanks for your detailed response, it was quite nice of you. ~mayuresh From lewis at mail.msen.com Sun Jan 25 18:11:08 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sun Jan 25 18:11:10 2015 Subject: [squeak-dev] Re: [Newbies] material design for squeak! In-Reply-To: <20150125175726.GA1349@aio.kathe.in> References: <4e6a32aae0e385987d4b95ac08e6d84d@kathe.in> <20150125154743.GA88140@shell.msen.com> <20150125160147.GA1332@aio.kathe.in> <20150125171655.GA97022@shell.msen.com> <20150125175726.GA1349@aio.kathe.in> Message-ID: <20150125181108.GA10600@shell.msen.com> On Sun, Jan 25, 2015 at 11:27:27PM +0530, Mayuresh Kathe wrote: > On Sun, Jan 25, 2015 at 12:16:55PM -0500, David T. Lewis wrote: > > On Sun, Jan 25, 2015 at 09:31:49PM +0530, Mayuresh Kathe wrote: > > > On Sun, Jan 25, 2015 at 10:47:43AM -0500, David T. Lewis wrote: > > > > On Sun, Jan 25, 2015 at 09:02:35PM +0530, Mayuresh Kathe wrote: > > > > > considering the *great* graphics and animation support available under > > > > > squeak, would it be difficult to mould the squeak 'ui' to adhere to > > > > > material design guidelines [1] from google? > > > > > > > > > > 1. http://www.google.com/design/spec/material-design/introduction.html > > > > > > > > > > ~mayuresh > > > > > > > > > > > > > Designing and implementing user interfaces tends to be a lot of work, but > > > > aside from that I so no reason that it could not be done. > > > > > > > > One of the nice aspects of Squeak (often overlooked) is that it provides > > > > a concept of "projects" in which different types of user interface > > > > environments can be implemented. You can open a Morphic project or an > > > > MVC project, and the system will look and feel quite different depending > > > > which kind of project you are currently using. The concept can be extended > > > > to other kinds of UI implementation, such as the one you are suggesting > > > > here. > > > > > > > > I am cross-posting to the squeak-dev list, which is probably a better > > > > place to continue the discussion. > > > > > > > > Dave > > > > > > okay, since i am still self-training for smalltalk and all stuff squeak, > > > would like to know if the preferred approach be to create my own project > > > and do what i want with it without crippling the rest of my system > > > image? > > > > Hi Mayuresh, > > > > Start by doing this: > > > > Project current explore > > > > This will give you an explorer on your current project. This corresponds > > to everything that you are interacting with on your Squeak display right > > now. > > > > If you have created other projects, they will be linked together though > > the nextProject, previousProject, and parentProject that you see in the > > explorer. > > > > You will also see a uiManager in your explorer. Your current project is > > probably an instance of MorphicProject, and the UI manager will be an > > instance of MorphicUIManager. The two cooperate to manage the Morphic > > user interface. If you were in an MVC project (try it) you would have an > > MVCProject that has an MVCUIManager. > > > > If you browse the class hierarchy for both Project and UIManager, you > > will see that these are abstract classes that have subclasses to represent > > the Morphic and MVC user interfaces. There is also a related ToolBuilder > > hierarchy that is used for creating the the Morphic or MVC tools (browsers, > > debuggers, and so forth). > > > > To create a different kind of user interface, you would want to create > > new kinds of Project and UIManager, and maybe also ToolBuilder. One way > > to get started would be to subclass the existing MorphicProject and > > MorphicUIManager, and start changing those subclasses a little bit at > > a time until you achieve the behavior you want. > > > > Your new kind of Project would be activated through the Squeak menus. I > > will not try to explain that now, but if you look at the toolbar at the > > top of the Squeak window, you will see: > > > > Project > > -> New Project > > -> New MVCProject > > -> New MorphicProject > > > > So you would add your new kind of project into the menus: > > > > Project > > -> New Project > > -> New MVCProject > > -> New MorphicProject > > -> New MaterialDesignProject > > > > And more generally, we might hope some day to see a few other kinds > > of projects: > > > > Project > > -> New Project > > -> New MVCProject > > -> New MorphicProject > > -> New MaterialDesignProject > > -> New ScratchProject > > -> New EtoysProject > > -> New Morphic3Project > > -> New SeasideProject > > > > Dave > > hello dave, > > "Project current explore" is definitely cool, i did not know about it. > > as i'd mentioned, i am still quite some time away from completing my > self-training in smalltalk using squeak, post which i would need to > spend a considerable amount of time gaining experience, and i guess > that's when i would be ready to dive in to work on creating my own > user interface. > > i am quite impressed with the work done on "thirdway", an extension of > the 'mvc' project world, and i hope to become atleast as good as the > creator of that project. I think you mean this project by Boris Gaertner: http://bgaertner.gmxhome.de/twinfo.html http://wiki.squeak.org/squeak/1829 It looks very interesting, although I do not know if the code is still available. > > thanks for your detailed response, it was quite nice of you. > Good luck with your self-training. That is how I learned Smalltalk and Squeak also. Keep asking questions :-) Dave From asqueaker at gmail.com Sun Jan 25 20:19:27 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sun Jan 25 20:19:29 2015 Subject: [squeak-dev] something happened to trunk? Message-ID: After updating Eliot's trunk46-spur image (2014-12-01) to latest Trunk code, I can no longer load my base "Ma-Installer" package. If I don't update Eliots image with Trunk, then I have no problems whatsoever. What broke? Error: Metaclasses can only have one instance 25 January 2015 2:12:26.263 pm VM: unix - Smalltalk Image: Squeak4.5 [latest update: #14078] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/cmm/Chris/dev/Squeak Trusted Dir /home/cmm/Chris/dev/Squeak/secure Untrusted Dir /home/cmm/Chris/dev/Squeak/My Squeak Metaclass(Object)>>error: Receiver: MaInstaller class Arguments and temporary variables: aString: 'Metaclasses can only have one instance' Receiver's instance variables: superclass: Installer class methodDict: a MethodDictionary() format: 65548 instanceVariables: #('localRepository') organization: ('as yet unclassified') thisClass: MaInstaller Metaclass(ClassDescription)>>updateInstances:from:isMeta: Receiver: MaInstaller class Arguments and temporary variables: oldInstances: {MaInstaller} oldClass: MaInstaller class isMeta: true map: nil variable: nil instSize: nil newInstances: nil i: nil iLimiT: nil Receiver's instance variables: superclass: Installer class methodDict: a MethodDictionary() format: 65548 instanceVariables: #('localRepository') organization: ('as yet unclassified') thisClass: MaInstaller Metaclass(ClassDescription)>>updateInstancesFrom: Receiver: MaInstaller class Arguments and temporary variables: oldClass: MaInstaller class Receiver's instance variables: superclass: Installer class methodDict: a MethodDictionary() format: 65548 instanceVariables: #('localRepository') organization: ('as yet unclassified') thisClass: MaInstaller [] in ClassBuilder>>update:to: Receiver: a ClassBuilder Arguments and temporary variables: oldClass: MaInstaller class newClass: MaInstaller class meta: true Receiver's instance variables: environ: Smalltalk classMap: nil instVarMap: an IdentityDictionary() progress: [closure] in SystemProgressMorph>>position:label:min:max: maxClassIndex: 1 currentClassIndex: 1 BlockClosure>>ensure: Receiver: [closure] in ClassBuilder>>update:to: Arguments and temporary variables: aBlock: [closure] in BlockClosure>>valueUnpreemptively complete: nil returnValue: nil Receiver's instance variables: outerContext: ClassBuilder>>update:to: startpc: 75 numArgs: 0 BlockClosure>>valueUnpreemptively Receiver: [closure] in ClassBuilder>>update:to: Arguments and temporary variables: activeProcess: a Process in nil oldPriority: 40 result: nil Receiver's instance variables: outerContext: ClassBuilder>>update:to: startpc: 75 numArgs: 0 ClassBuilder>>update:to: Receiver: a ClassBuilder Arguments and temporary variables: oldClass: MaInstaller class newClass: MaInstaller class meta: true Receiver's instance variables: environ: Smalltalk classMap: nil instVarMap: an IdentityDictionary() progress: [closure] in SystemProgressMorph>>position:label:min:max: maxClassIndex: 1 currentClassIndex: 1 ClassBuilder>>mutate:to: Receiver: a ClassBuilder Arguments and temporary variables: oldClass: MaInstaller class newClass: MaInstaller class Receiver's instance variables: environ: Smalltalk classMap: nil instVarMap: an IdentityDictionary() progress: [closure] in SystemProgressMorph>>position:label:min:max: maxClassIndex: 1 currentClassIndex: 1 [] in [] in ClassBuilder>>recompile:from:to:mutate: Receiver: a ClassBuilder Arguments and temporary variables: < Receiver's instance variables: environ: Smalltalk classMap: nil instVarMap: an IdentityDictionary() progress: [closure] in SystemProgressMorph>>position:label:min:max: maxClassIndex: 1 currentClassIndex: 1 BlockClosure>>on:do: Receiver: [closure] in [] in ClassBuilder>>recompile:from:to:mutate: Arguments and temporary variables: exception: CurrentReadOnlySourceFiles handlerAction: [closure] in CurrentReadOnlySourceFiles class>>cacheDuring: handlerActive: true Receiver's instance variables: outerContext: [] in ClassBuilder>>recompile:from:to:mutate: startpc: 161 numArgs: 0 CurrentReadOnlySourceFiles class>>cacheDuring: Receiver: CurrentReadOnlySourceFiles Arguments and temporary variables: aBlock: [closure] in [] in ClassBuilder>>recompile:from:to:mutate: currentReadOnlySouceFiles: {an ExpandedSourceFileArray(MultiByteFileStream: '/u...etc... Receiver's instance variables: superclass: Exception methodDict: a MethodDictionary(#defaultAction->(CurrentReadOnlySourceFiles>>#de...etc... format: 65541 instanceVariables: nil organization: ('handling' defaultAction) subclasses: nil name: #CurrentReadOnlySourceFiles classPool: nil sharedPools: nil environment: Smalltalk category: #'Files-System' [] in ClassBuilder>>recompile:from:to:mutate: Receiver: a ClassBuilder Arguments and temporary variables: < Receiver's instance variables: environ: Smalltalk classMap: nil instVarMap: an IdentityDictionary() progress: [closure] in SystemProgressMorph>>position:label:min:max: maxClassIndex: 1 currentClassIndex: 1 [] in ClassBuilder>>informUserDuring: Receiver: a ClassBuilder Arguments and temporary variables: aBlock: [closure] in SystemProgressMorph>>position:label:min:max: bar: [closure] in ClassBuilder>>recompile:from:to:mutate: Receiver's instance variables: environ: Smalltalk classMap: nil instVarMap: an IdentityDictionary() progress: [closure] in SystemProgressMorph>>position:label:min:max: maxClassIndex: 1 currentClassIndex: 1 [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: Receiver: a MorphicUIManager Arguments and temporary variables: < Receiver's instance variables: toolBuilder: nil BlockClosure>>on:do: Receiver: [closure] in [] in MorphicUIManager>>displayProgress:at:from:to:during: Arguments and temporary variables: exception: ProgressNotification handlerAction: [closure] in [] in MorphicUIManager>>displayProgress:at:from:to:...etc... handlerActive: true Receiver's instance variables: outerContext: [] in MorphicUIManager>>displayProgress:at:from:to:during: startpc: 86 numArgs: 0 [] in MorphicUIManager>>displayProgress:at:from:to:during: Receiver: a MorphicUIManager Arguments and temporary variables: < Receiver's instance variables: toolBuilder: nil BlockClosure>>ensure: Receiver: [closure] in MorphicUIManager>>displayProgress:at:from:to:during: Arguments and temporary variables: aBlock: [closure] in MorphicUIManager>>displayProgress:at:from:to:during: complete: nil returnValue: nil Receiver's instance variables: outerContext: MorphicUIManager>>displayProgress:at:from:to:during: startpc: 79 numArgs: 0 MorphicUIManager>>displayProgress:at:from:to:during: Receiver: a MorphicUIManager Arguments and temporary variables: titleString: ' ' aPoint: 400@300 minVal: 0 maxVal: 0 workBlock: [closure] in ClassBuilder>>informUserDuring: progress: [closure] in SystemProgressMorph>>position:label:min:max: result: #(nil) Receiver's instance variables: toolBuilder: nil ProgressInitiationException>>defaultResumeValue Receiver: ProgressInitiationException: Arguments and temporary variables: Receiver's instance variables: messageText: nil tag: nil signalContext: ProgressInitiationException(Exception)>>signal handlerContext: nil outerContext: nil workBlock: [closure] in ClassBuilder>>informUserDuring: maxVal: 0 minVal: 0 aPoint: 400@300 progressTitle: ' ' --- The full stack --- Metaclass(Object)>>error: Metaclass(ClassDescription)>>updateInstances:from:isMeta: Metaclass(ClassDescription)>>updateInstancesFrom: [] in ClassBuilder>>update:to: BlockClosure>>ensure: BlockClosure>>valueUnpreemptively ClassBuilder>>update:to: ClassBuilder>>mutate:to: [] in [] in ClassBuilder>>recompile:from:to:mutate: BlockClosure>>on:do: CurrentReadOnlySourceFiles class>>cacheDuring: [] in ClassBuilder>>recompile:from:to:mutate: [] in ClassBuilder>>informUserDuring: [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: BlockClosure>>on:do: [] in MorphicUIManager>>displayProgress:at:from:to:during: BlockClosure>>ensure: MorphicUIManager>>displayProgress:at:from:to:during: ProgressInitiationException>>defaultResumeValue - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ProgressInitiationException(Exception)>>resume ProgressInitiationException>>defaultAction UndefinedObject>>handleSignal: MethodContext(ContextPart)>>handleSignal: MethodContext(ContextPart)>>handleSignal: MethodContext(ContextPart)>>handleSignal: MethodContext(ContextPart)>>handleSignal: ProgressInitiationException(Exception)>>signal ProgressInitiationException>>display:at:from:to:during: ProgressInitiationException class>>display:at:from:to:during: SystemProgressMorph class>>informUserAt:during: MorphicUIManager>>informUserDuring: ClassBuilder>>informUserDuring: ClassBuilder>>recompile:from:to:mutate: ClassBuilder>>class:instanceVariableNames:unsafe: ClassBuilder>>class:instanceVariableNames: Metaclass>>instanceVariableNames: MCClassDefinition>>load [] in [] in [] in [] in [] in MCPackageLoader>>basicLoad [] in [] in OrderedCollection(Collection)>>do:displayingProgress:every: OrderedCollection>>do: [] in OrderedCollection(Collection)>>do:displayingProgress:every: [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: BlockClosure>>on:do: [] in MorphicUIManager>>displayProgress:at:from:to:during: BlockClosure>>ensure: MorphicUIManager>>displayProgress:at:from:to:during: ProgressInitiationException>>defaultResumeValue ProgressInitiationException(Exception)>>resume ProgressInitiationException>>defaultAction UndefinedObject>>handleSignal: MethodContext(ContextPart)>>handleSignal: MethodContext(ContextPart)>>handleSignal: MethodContext(ContextPart)>>handleSignal: ProgressInitiationException(Exception)>>signal ProgressInitiationException>>display:at:from:to:during: ProgressInitiationException class>>display:at:from:to:during: ByteString(String)>>displayProgressAt:from:to:during: ByteString(String)>>displayProgressFrom:to:during: OrderedCollection(Collection)>>do:displayingProgress:every: OrderedCollection(Collection)>>do:displayingProgress: [] in [] in [] in [] in MCPackageLoader>>basicLoad -- and more not shown -- From Das.Linux at gmx.de Sun Jan 25 20:38:07 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Sun Jan 25 20:38:12 2015 Subject: [squeak-dev] something happened to trunk? In-Reply-To: References: Message-ID: <7CB4A9D3-F319-4D3E-850A-D62341DC0D87@gmx.de> On 25.01.2015, at 21:19, Chris Muller wrote: > After updating Eliot's trunk46-spur image (2014-12-01) to latest Trunk > code, I can no longer load my base "Ma-Installer" package. If I don't > update Eliots image with Trunk, then I have no problems whatsoever. > > What broke? Judging from your stack trace, Metaclass(ClassDescription)>>updateInstances:from:isMeta: gets called with oldInstances: {MaInstaller}. There's a check oldInstances size = 1 ifFalse:[^self error:'Metaclasses can only have one instance']. So apparently, {MaInstaller} size ~= 1, which is puzzling, What do you get if you PrintIt? Best -Tobias > > Error: Metaclasses can only have one instance > 25 January 2015 2:12:26.263 pm > > VM: unix - Smalltalk > Image: Squeak4.5 [latest update: #14078] > > SecurityManager state: > Restricted: false > FileAccess: true > SocketAccess: true > Working Dir /home/cmm/Chris/dev/Squeak > Trusted Dir /home/cmm/Chris/dev/Squeak/secure > Untrusted Dir /home/cmm/Chris/dev/Squeak/My Squeak > > Metaclass(Object)>>error: > Receiver: MaInstaller class > Arguments and temporary variables: > aString: 'Metaclasses can only have one instance' > Receiver's instance variables: > superclass: Installer class > methodDict: a MethodDictionary() > format: 65548 > instanceVariables: #('localRepository') > organization: ('as yet unclassified') > > thisClass: MaInstaller > > Metaclass(ClassDescription)>>updateInstances:from:isMeta: > Receiver: MaInstaller class > Arguments and temporary variables: > oldInstances: {MaInstaller} > oldClass: MaInstaller class > isMeta: true > map: nil > variable: nil > instSize: nil > newInstances: nil > i: nil > iLimiT: nil > Receiver's instance variables: > superclass: Installer class > methodDict: a MethodDictionary() > format: 65548 > instanceVariables: #('localRepository') > organization: ('as yet unclassified') > > thisClass: MaInstaller > > Metaclass(ClassDescription)>>updateInstancesFrom: > Receiver: MaInstaller class > Arguments and temporary variables: > oldClass: MaInstaller class > Receiver's instance variables: > superclass: Installer class > methodDict: a MethodDictionary() > format: 65548 > instanceVariables: #('localRepository') > organization: ('as yet unclassified') > > thisClass: MaInstaller > > [] in ClassBuilder>>update:to: > Receiver: a ClassBuilder > Arguments and temporary variables: > oldClass: MaInstaller class > newClass: MaInstaller class > meta: true > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > BlockClosure>>ensure: > Receiver: [closure] in ClassBuilder>>update:to: > Arguments and temporary variables: > aBlock: [closure] in BlockClosure>>valueUnpreemptively > complete: nil > returnValue: nil > Receiver's instance variables: > outerContext: ClassBuilder>>update:to: > startpc: 75 > numArgs: 0 > > BlockClosure>>valueUnpreemptively > Receiver: [closure] in ClassBuilder>>update:to: > Arguments and temporary variables: > activeProcess: a Process in nil > oldPriority: 40 > result: nil > Receiver's instance variables: > outerContext: ClassBuilder>>update:to: > startpc: 75 > numArgs: 0 > > ClassBuilder>>update:to: > Receiver: a ClassBuilder > Arguments and temporary variables: > oldClass: MaInstaller class > newClass: MaInstaller class > meta: true > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > ClassBuilder>>mutate:to: > Receiver: a ClassBuilder > Arguments and temporary variables: > oldClass: MaInstaller class > newClass: MaInstaller class > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > [] in [] in ClassBuilder>>recompile:from:to:mutate: > Receiver: a ClassBuilder > Arguments and temporary variables: > < > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > BlockClosure>>on:do: > Receiver: [closure] in [] in ClassBuilder>>recompile:from:to:mutate: > Arguments and temporary variables: > exception: CurrentReadOnlySourceFiles > handlerAction: [closure] in CurrentReadOnlySourceFiles class>>cacheDuring: > handlerActive: true > Receiver's instance variables: > outerContext: [] in ClassBuilder>>recompile:from:to:mutate: > startpc: 161 > numArgs: 0 > > CurrentReadOnlySourceFiles class>>cacheDuring: > Receiver: CurrentReadOnlySourceFiles > Arguments and temporary variables: > aBlock: [closure] in [] in ClassBuilder>>recompile:from:to:mutate: > currentReadOnlySouceFiles: {an > ExpandedSourceFileArray(MultiByteFileStream: '/u...etc... > Receiver's instance variables: > superclass: Exception > methodDict: a MethodDictionary(#defaultAction->(CurrentReadOnlySourceFiles>>#de...etc... > format: 65541 > instanceVariables: nil > organization: ('handling' defaultAction) > > subclasses: nil > name: #CurrentReadOnlySourceFiles > classPool: nil > sharedPools: nil > environment: Smalltalk > category: #'Files-System' > > [] in ClassBuilder>>recompile:from:to:mutate: > Receiver: a ClassBuilder > Arguments and temporary variables: > < > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > [] in ClassBuilder>>informUserDuring: > Receiver: a ClassBuilder > Arguments and temporary variables: > aBlock: [closure] in SystemProgressMorph>>position:label:min:max: > bar: [closure] in ClassBuilder>>recompile:from:to:mutate: > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: > Receiver: a MorphicUIManager > Arguments and temporary variables: > < > Receiver's instance variables: > toolBuilder: nil > > BlockClosure>>on:do: > Receiver: [closure] in [] in > MorphicUIManager>>displayProgress:at:from:to:during: > Arguments and temporary variables: > exception: ProgressNotification > handlerAction: [closure] in [] in > MorphicUIManager>>displayProgress:at:from:to:...etc... > handlerActive: true > Receiver's instance variables: > outerContext: [] in MorphicUIManager>>displayProgress:at:from:to:during: > startpc: 86 > numArgs: 0 > > [] in MorphicUIManager>>displayProgress:at:from:to:during: > Receiver: a MorphicUIManager > Arguments and temporary variables: > < > Receiver's instance variables: > toolBuilder: nil > > BlockClosure>>ensure: > Receiver: [closure] in MorphicUIManager>>displayProgress:at:from:to:during: > Arguments and temporary variables: > aBlock: [closure] in MorphicUIManager>>displayProgress:at:from:to:during: > complete: nil > returnValue: nil > Receiver's instance variables: > outerContext: MorphicUIManager>>displayProgress:at:from:to:during: > startpc: 79 > numArgs: 0 > > MorphicUIManager>>displayProgress:at:from:to:during: > Receiver: a MorphicUIManager > Arguments and temporary variables: > titleString: ' ' > aPoint: 400@300 > minVal: 0 > maxVal: 0 > workBlock: [closure] in ClassBuilder>>informUserDuring: > progress: [closure] in SystemProgressMorph>>position:label:min:max: > result: #(nil) > Receiver's instance variables: > toolBuilder: nil > > ProgressInitiationException>>defaultResumeValue > Receiver: ProgressInitiationException: > Arguments and temporary variables: > > Receiver's instance variables: > messageText: nil > tag: nil > signalContext: ProgressInitiationException(Exception)>>signal > handlerContext: nil > outerContext: nil > workBlock: [closure] in ClassBuilder>>informUserDuring: > maxVal: 0 > minVal: 0 > aPoint: 400@300 > progressTitle: ' ' From eliot.miranda at gmail.com Sun Jan 25 22:17:00 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun Jan 25 22:17:06 2015 Subject: [squeak-dev] something happened to trunk? In-Reply-To: References: Message-ID: Hi Chris, On Jan 25, 2015, at 12:19 PM, Chris Muller wrote: > After updating Eliot's trunk46-spur image (2014-12-01) to latest Trunk > code, I can no longer load my base "Ma-Installer" package. If I don't > update Eliots image with Trunk, then I have no problems whatsoever. > > What broke? > > Error: Metaclasses can only have one instance It could be a become bug with class table management. Can you let me have the image and instructions to try and reproduce the bug? > 25 January 2015 2:12:26.263 pm > > VM: unix - Smalltalk > Image: Squeak4.5 [latest update: #14078] > > SecurityManager state: > Restricted: false > FileAccess: true > SocketAccess: true > Working Dir /home/cmm/Chris/dev/Squeak > Trusted Dir /home/cmm/Chris/dev/Squeak/secure > Untrusted Dir /home/cmm/Chris/dev/Squeak/My Squeak > > Metaclass(Object)>>error: > Receiver: MaInstaller class > Arguments and temporary variables: > aString: 'Metaclasses can only have one instance' > Receiver's instance variables: > superclass: Installer class > methodDict: a MethodDictionary() > format: 65548 > instanceVariables: #('localRepository') > organization: ('as yet unclassified') > > thisClass: MaInstaller > > Metaclass(ClassDescription)>>updateInstances:from:isMeta: > Receiver: MaInstaller class > Arguments and temporary variables: > oldInstances: {MaInstaller} > oldClass: MaInstaller class > isMeta: true > map: nil > variable: nil > instSize: nil > newInstances: nil > i: nil > iLimiT: nil > Receiver's instance variables: > superclass: Installer class > methodDict: a MethodDictionary() > format: 65548 > instanceVariables: #('localRepository') > organization: ('as yet unclassified') > > thisClass: MaInstaller > > Metaclass(ClassDescription)>>updateInstancesFrom: > Receiver: MaInstaller class > Arguments and temporary variables: > oldClass: MaInstaller class > Receiver's instance variables: > superclass: Installer class > methodDict: a MethodDictionary() > format: 65548 > instanceVariables: #('localRepository') > organization: ('as yet unclassified') > > thisClass: MaInstaller > > [] in ClassBuilder>>update:to: > Receiver: a ClassBuilder > Arguments and temporary variables: > oldClass: MaInstaller class > newClass: MaInstaller class > meta: true > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > BlockClosure>>ensure: > Receiver: [closure] in ClassBuilder>>update:to: > Arguments and temporary variables: > aBlock: [closure] in BlockClosure>>valueUnpreemptively > complete: nil > returnValue: nil > Receiver's instance variables: > outerContext: ClassBuilder>>update:to: > startpc: 75 > numArgs: 0 > > BlockClosure>>valueUnpreemptively > Receiver: [closure] in ClassBuilder>>update:to: > Arguments and temporary variables: > activeProcess: a Process in nil > oldPriority: 40 > result: nil > Receiver's instance variables: > outerContext: ClassBuilder>>update:to: > startpc: 75 > numArgs: 0 > > ClassBuilder>>update:to: > Receiver: a ClassBuilder > Arguments and temporary variables: > oldClass: MaInstaller class > newClass: MaInstaller class > meta: true > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > ClassBuilder>>mutate:to: > Receiver: a ClassBuilder > Arguments and temporary variables: > oldClass: MaInstaller class > newClass: MaInstaller class > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > [] in [] in ClassBuilder>>recompile:from:to:mutate: > Receiver: a ClassBuilder > Arguments and temporary variables: > < > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > BlockClosure>>on:do: > Receiver: [closure] in [] in ClassBuilder>>recompile:from:to:mutate: > Arguments and temporary variables: > exception: CurrentReadOnlySourceFiles > handlerAction: [closure] in CurrentReadOnlySourceFiles class>>cacheDuring: > handlerActive: true > Receiver's instance variables: > outerContext: [] in ClassBuilder>>recompile:from:to:mutate: > startpc: 161 > numArgs: 0 > > CurrentReadOnlySourceFiles class>>cacheDuring: > Receiver: CurrentReadOnlySourceFiles > Arguments and temporary variables: > aBlock: [closure] in [] in ClassBuilder>>recompile:from:to:mutate: > currentReadOnlySouceFiles: {an > ExpandedSourceFileArray(MultiByteFileStream: '/u...etc... > Receiver's instance variables: > superclass: Exception > methodDict: a MethodDictionary(#defaultAction->(CurrentReadOnlySourceFiles>>#de...etc... > format: 65541 > instanceVariables: nil > organization: ('handling' defaultAction) > > subclasses: nil > name: #CurrentReadOnlySourceFiles > classPool: nil > sharedPools: nil > environment: Smalltalk > category: #'Files-System' > > [] in ClassBuilder>>recompile:from:to:mutate: > Receiver: a ClassBuilder > Arguments and temporary variables: > < > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > [] in ClassBuilder>>informUserDuring: > Receiver: a ClassBuilder > Arguments and temporary variables: > aBlock: [closure] in SystemProgressMorph>>position:label:min:max: > bar: [closure] in ClassBuilder>>recompile:from:to:mutate: > Receiver's instance variables: > environ: Smalltalk > classMap: nil > instVarMap: an IdentityDictionary() > progress: [closure] in SystemProgressMorph>>position:label:min:max: > maxClassIndex: 1 > currentClassIndex: 1 > > [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: > Receiver: a MorphicUIManager > Arguments and temporary variables: > < > Receiver's instance variables: > toolBuilder: nil > > BlockClosure>>on:do: > Receiver: [closure] in [] in > MorphicUIManager>>displayProgress:at:from:to:during: > Arguments and temporary variables: > exception: ProgressNotification > handlerAction: [closure] in [] in > MorphicUIManager>>displayProgress:at:from:to:...etc... > handlerActive: true > Receiver's instance variables: > outerContext: [] in MorphicUIManager>>displayProgress:at:from:to:during: > startpc: 86 > numArgs: 0 > > [] in MorphicUIManager>>displayProgress:at:from:to:during: > Receiver: a MorphicUIManager > Arguments and temporary variables: > < > Receiver's instance variables: > toolBuilder: nil > > BlockClosure>>ensure: > Receiver: [closure] in MorphicUIManager>>displayProgress:at:from:to:during: > Arguments and temporary variables: > aBlock: [closure] in MorphicUIManager>>displayProgress:at:from:to:during: > complete: nil > returnValue: nil > Receiver's instance variables: > outerContext: MorphicUIManager>>displayProgress:at:from:to:during: > startpc: 79 > numArgs: 0 > > MorphicUIManager>>displayProgress:at:from:to:during: > Receiver: a MorphicUIManager > Arguments and temporary variables: > titleString: ' ' > aPoint: 400@300 > minVal: 0 > maxVal: 0 > workBlock: [closure] in ClassBuilder>>informUserDuring: > progress: [closure] in SystemProgressMorph>>position:label:min:max: > result: #(nil) > Receiver's instance variables: > toolBuilder: nil > > ProgressInitiationException>>defaultResumeValue > Receiver: ProgressInitiationException: > Arguments and temporary variables: > > Receiver's instance variables: > messageText: nil > tag: nil > signalContext: ProgressInitiationException(Exception)>>signal > handlerContext: nil > outerContext: nil > workBlock: [closure] in ClassBuilder>>informUserDuring: > maxVal: 0 > minVal: 0 > aPoint: 400@300 > progressTitle: ' ' > > > --- The full stack --- > Metaclass(Object)>>error: > Metaclass(ClassDescription)>>updateInstances:from:isMeta: > Metaclass(ClassDescription)>>updateInstancesFrom: > [] in ClassBuilder>>update:to: > BlockClosure>>ensure: > BlockClosure>>valueUnpreemptively > ClassBuilder>>update:to: > ClassBuilder>>mutate:to: > [] in [] in ClassBuilder>>recompile:from:to:mutate: > BlockClosure>>on:do: > CurrentReadOnlySourceFiles class>>cacheDuring: > [] in ClassBuilder>>recompile:from:to:mutate: > [] in ClassBuilder>>informUserDuring: > [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: > BlockClosure>>on:do: > [] in MorphicUIManager>>displayProgress:at:from:to:during: > BlockClosure>>ensure: > MorphicUIManager>>displayProgress:at:from:to:during: > ProgressInitiationException>>defaultResumeValue > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > ProgressInitiationException(Exception)>>resume > ProgressInitiationException>>defaultAction > UndefinedObject>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > ProgressInitiationException(Exception)>>signal > ProgressInitiationException>>display:at:from:to:during: > ProgressInitiationException class>>display:at:from:to:during: > SystemProgressMorph class>>informUserAt:during: > MorphicUIManager>>informUserDuring: > ClassBuilder>>informUserDuring: > ClassBuilder>>recompile:from:to:mutate: > ClassBuilder>>class:instanceVariableNames:unsafe: > ClassBuilder>>class:instanceVariableNames: > Metaclass>>instanceVariableNames: > MCClassDefinition>>load > [] in [] in [] in [] in [] in MCPackageLoader>>basicLoad > [] in [] in OrderedCollection(Collection)>>do:displayingProgress:every: > OrderedCollection>>do: > [] in OrderedCollection(Collection)>>do:displayingProgress:every: > [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: > BlockClosure>>on:do: > [] in MorphicUIManager>>displayProgress:at:from:to:during: > BlockClosure>>ensure: > MorphicUIManager>>displayProgress:at:from:to:during: > ProgressInitiationException>>defaultResumeValue > ProgressInitiationException(Exception)>>resume > ProgressInitiationException>>defaultAction > UndefinedObject>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > ProgressInitiationException(Exception)>>signal > ProgressInitiationException>>display:at:from:to:during: > ProgressInitiationException class>>display:at:from:to:during: > ByteString(String)>>displayProgressAt:from:to:during: > ByteString(String)>>displayProgressFrom:to:during: > OrderedCollection(Collection)>>do:displayingProgress:every: > OrderedCollection(Collection)>>do:displayingProgress: > [] in [] in [] in [] in MCPackageLoader>>basicLoad > -- and more not shown -- > From ma.chris.m at gmail.com Sun Jan 25 23:32:28 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Sun Jan 25 23:32:30 2015 Subject: [squeak-dev] something happened to trunk? In-Reply-To: References: Message-ID: Eliot, I sent you a link to the Spur image with instructions to recreate the problem. Thank you! PS -- I've been working on an image which can reproduce the zombie eviction too. I'll send you another link if I can.. On Sun, Jan 25, 2015 at 4:17 PM, Eliot Miranda wrote: > Hi Chris, > > On Jan 25, 2015, at 12:19 PM, Chris Muller wrote: > >> After updating Eliot's trunk46-spur image (2014-12-01) to latest Trunk >> code, I can no longer load my base "Ma-Installer" package. If I don't >> update Eliots image with Trunk, then I have no problems whatsoever. >> >> What broke? >> >> Error: Metaclasses can only have one instance > > It could be a become bug with class table management. Can you let me have the image and instructions to try and reproduce the bug? > > >> 25 January 2015 2:12:26.263 pm >> >> VM: unix - Smalltalk >> Image: Squeak4.5 [latest update: #14078] >> >> SecurityManager state: >> Restricted: false >> FileAccess: true >> SocketAccess: true >> Working Dir /home/cmm/Chris/dev/Squeak >> Trusted Dir /home/cmm/Chris/dev/Squeak/secure >> Untrusted Dir /home/cmm/Chris/dev/Squeak/My Squeak >> >> Metaclass(Object)>>error: >> Receiver: MaInstaller class >> Arguments and temporary variables: >> aString: 'Metaclasses can only have one instance' >> Receiver's instance variables: >> superclass: Installer class >> methodDict: a MethodDictionary() >> format: 65548 >> instanceVariables: #('localRepository') >> organization: ('as yet unclassified') >> >> thisClass: MaInstaller >> >> Metaclass(ClassDescription)>>updateInstances:from:isMeta: >> Receiver: MaInstaller class >> Arguments and temporary variables: >> oldInstances: {MaInstaller} >> oldClass: MaInstaller class >> isMeta: true >> map: nil >> variable: nil >> instSize: nil >> newInstances: nil >> i: nil >> iLimiT: nil >> Receiver's instance variables: >> superclass: Installer class >> methodDict: a MethodDictionary() >> format: 65548 >> instanceVariables: #('localRepository') >> organization: ('as yet unclassified') >> >> thisClass: MaInstaller >> >> Metaclass(ClassDescription)>>updateInstancesFrom: >> Receiver: MaInstaller class >> Arguments and temporary variables: >> oldClass: MaInstaller class >> Receiver's instance variables: >> superclass: Installer class >> methodDict: a MethodDictionary() >> format: 65548 >> instanceVariables: #('localRepository') >> organization: ('as yet unclassified') >> >> thisClass: MaInstaller >> >> [] in ClassBuilder>>update:to: >> Receiver: a ClassBuilder >> Arguments and temporary variables: >> oldClass: MaInstaller class >> newClass: MaInstaller class >> meta: true >> Receiver's instance variables: >> environ: Smalltalk >> classMap: nil >> instVarMap: an IdentityDictionary() >> progress: [closure] in SystemProgressMorph>>position:label:min:max: >> maxClassIndex: 1 >> currentClassIndex: 1 >> >> BlockClosure>>ensure: >> Receiver: [closure] in ClassBuilder>>update:to: >> Arguments and temporary variables: >> aBlock: [closure] in BlockClosure>>valueUnpreemptively >> complete: nil >> returnValue: nil >> Receiver's instance variables: >> outerContext: ClassBuilder>>update:to: >> startpc: 75 >> numArgs: 0 >> >> BlockClosure>>valueUnpreemptively >> Receiver: [closure] in ClassBuilder>>update:to: >> Arguments and temporary variables: >> activeProcess: a Process in nil >> oldPriority: 40 >> result: nil >> Receiver's instance variables: >> outerContext: ClassBuilder>>update:to: >> startpc: 75 >> numArgs: 0 >> >> ClassBuilder>>update:to: >> Receiver: a ClassBuilder >> Arguments and temporary variables: >> oldClass: MaInstaller class >> newClass: MaInstaller class >> meta: true >> Receiver's instance variables: >> environ: Smalltalk >> classMap: nil >> instVarMap: an IdentityDictionary() >> progress: [closure] in SystemProgressMorph>>position:label:min:max: >> maxClassIndex: 1 >> currentClassIndex: 1 >> >> ClassBuilder>>mutate:to: >> Receiver: a ClassBuilder >> Arguments and temporary variables: >> oldClass: MaInstaller class >> newClass: MaInstaller class >> Receiver's instance variables: >> environ: Smalltalk >> classMap: nil >> instVarMap: an IdentityDictionary() >> progress: [closure] in SystemProgressMorph>>position:label:min:max: >> maxClassIndex: 1 >> currentClassIndex: 1 >> >> [] in [] in ClassBuilder>>recompile:from:to:mutate: >> Receiver: a ClassBuilder >> Arguments and temporary variables: >> < >> Receiver's instance variables: >> environ: Smalltalk >> classMap: nil >> instVarMap: an IdentityDictionary() >> progress: [closure] in SystemProgressMorph>>position:label:min:max: >> maxClassIndex: 1 >> currentClassIndex: 1 >> >> BlockClosure>>on:do: >> Receiver: [closure] in [] in ClassBuilder>>recompile:from:to:mutate: >> Arguments and temporary variables: >> exception: CurrentReadOnlySourceFiles >> handlerAction: [closure] in CurrentReadOnlySourceFiles class>>cacheDuring: >> handlerActive: true >> Receiver's instance variables: >> outerContext: [] in ClassBuilder>>recompile:from:to:mutate: >> startpc: 161 >> numArgs: 0 >> >> CurrentReadOnlySourceFiles class>>cacheDuring: >> Receiver: CurrentReadOnlySourceFiles >> Arguments and temporary variables: >> aBlock: [closure] in [] in ClassBuilder>>recompile:from:to:mutate: >> currentReadOnlySouceFiles: {an >> ExpandedSourceFileArray(MultiByteFileStream: '/u...etc... >> Receiver's instance variables: >> superclass: Exception >> methodDict: a MethodDictionary(#defaultAction->(CurrentReadOnlySourceFiles>>#de...etc... >> format: 65541 >> instanceVariables: nil >> organization: ('handling' defaultAction) >> >> subclasses: nil >> name: #CurrentReadOnlySourceFiles >> classPool: nil >> sharedPools: nil >> environment: Smalltalk >> category: #'Files-System' >> >> [] in ClassBuilder>>recompile:from:to:mutate: >> Receiver: a ClassBuilder >> Arguments and temporary variables: >> < >> Receiver's instance variables: >> environ: Smalltalk >> classMap: nil >> instVarMap: an IdentityDictionary() >> progress: [closure] in SystemProgressMorph>>position:label:min:max: >> maxClassIndex: 1 >> currentClassIndex: 1 >> >> [] in ClassBuilder>>informUserDuring: >> Receiver: a ClassBuilder >> Arguments and temporary variables: >> aBlock: [closure] in SystemProgressMorph>>position:label:min:max: >> bar: [closure] in ClassBuilder>>recompile:from:to:mutate: >> Receiver's instance variables: >> environ: Smalltalk >> classMap: nil >> instVarMap: an IdentityDictionary() >> progress: [closure] in SystemProgressMorph>>position:label:min:max: >> maxClassIndex: 1 >> currentClassIndex: 1 >> >> [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: >> Receiver: a MorphicUIManager >> Arguments and temporary variables: >> < >> Receiver's instance variables: >> toolBuilder: nil >> >> BlockClosure>>on:do: >> Receiver: [closure] in [] in >> MorphicUIManager>>displayProgress:at:from:to:during: >> Arguments and temporary variables: >> exception: ProgressNotification >> handlerAction: [closure] in [] in >> MorphicUIManager>>displayProgress:at:from:to:...etc... >> handlerActive: true >> Receiver's instance variables: >> outerContext: [] in MorphicUIManager>>displayProgress:at:from:to:during: >> startpc: 86 >> numArgs: 0 >> >> [] in MorphicUIManager>>displayProgress:at:from:to:during: >> Receiver: a MorphicUIManager >> Arguments and temporary variables: >> < >> Receiver's instance variables: >> toolBuilder: nil >> >> BlockClosure>>ensure: >> Receiver: [closure] in MorphicUIManager>>displayProgress:at:from:to:during: >> Arguments and temporary variables: >> aBlock: [closure] in MorphicUIManager>>displayProgress:at:from:to:during: >> complete: nil >> returnValue: nil >> Receiver's instance variables: >> outerContext: MorphicUIManager>>displayProgress:at:from:to:during: >> startpc: 79 >> numArgs: 0 >> >> MorphicUIManager>>displayProgress:at:from:to:during: >> Receiver: a MorphicUIManager >> Arguments and temporary variables: >> titleString: ' ' >> aPoint: 400@300 >> minVal: 0 >> maxVal: 0 >> workBlock: [closure] in ClassBuilder>>informUserDuring: >> progress: [closure] in SystemProgressMorph>>position:label:min:max: >> result: #(nil) >> Receiver's instance variables: >> toolBuilder: nil >> >> ProgressInitiationException>>defaultResumeValue >> Receiver: ProgressInitiationException: >> Arguments and temporary variables: >> >> Receiver's instance variables: >> messageText: nil >> tag: nil >> signalContext: ProgressInitiationException(Exception)>>signal >> handlerContext: nil >> outerContext: nil >> workBlock: [closure] in ClassBuilder>>informUserDuring: >> maxVal: 0 >> minVal: 0 >> aPoint: 400@300 >> progressTitle: ' ' >> >> >> --- The full stack --- >> Metaclass(Object)>>error: >> Metaclass(ClassDescription)>>updateInstances:from:isMeta: >> Metaclass(ClassDescription)>>updateInstancesFrom: >> [] in ClassBuilder>>update:to: >> BlockClosure>>ensure: >> BlockClosure>>valueUnpreemptively >> ClassBuilder>>update:to: >> ClassBuilder>>mutate:to: >> [] in [] in ClassBuilder>>recompile:from:to:mutate: >> BlockClosure>>on:do: >> CurrentReadOnlySourceFiles class>>cacheDuring: >> [] in ClassBuilder>>recompile:from:to:mutate: >> [] in ClassBuilder>>informUserDuring: >> [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: >> BlockClosure>>on:do: >> [] in MorphicUIManager>>displayProgress:at:from:to:during: >> BlockClosure>>ensure: >> MorphicUIManager>>displayProgress:at:from:to:during: >> ProgressInitiationException>>defaultResumeValue >> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >> ProgressInitiationException(Exception)>>resume >> ProgressInitiationException>>defaultAction >> UndefinedObject>>handleSignal: >> MethodContext(ContextPart)>>handleSignal: >> MethodContext(ContextPart)>>handleSignal: >> MethodContext(ContextPart)>>handleSignal: >> MethodContext(ContextPart)>>handleSignal: >> ProgressInitiationException(Exception)>>signal >> ProgressInitiationException>>display:at:from:to:during: >> ProgressInitiationException class>>display:at:from:to:during: >> SystemProgressMorph class>>informUserAt:during: >> MorphicUIManager>>informUserDuring: >> ClassBuilder>>informUserDuring: >> ClassBuilder>>recompile:from:to:mutate: >> ClassBuilder>>class:instanceVariableNames:unsafe: >> ClassBuilder>>class:instanceVariableNames: >> Metaclass>>instanceVariableNames: >> MCClassDefinition>>load >> [] in [] in [] in [] in [] in MCPackageLoader>>basicLoad >> [] in [] in OrderedCollection(Collection)>>do:displayingProgress:every: >> OrderedCollection>>do: >> [] in OrderedCollection(Collection)>>do:displayingProgress:every: >> [] in [] in MorphicUIManager>>displayProgress:at:from:to:during: >> BlockClosure>>on:do: >> [] in MorphicUIManager>>displayProgress:at:from:to:during: >> BlockClosure>>ensure: >> MorphicUIManager>>displayProgress:at:from:to:during: >> ProgressInitiationException>>defaultResumeValue >> ProgressInitiationException(Exception)>>resume >> ProgressInitiationException>>defaultAction >> UndefinedObject>>handleSignal: >> MethodContext(ContextPart)>>handleSignal: >> MethodContext(ContextPart)>>handleSignal: >> MethodContext(ContextPart)>>handleSignal: >> ProgressInitiationException(Exception)>>signal >> ProgressInitiationException>>display:at:from:to:during: >> ProgressInitiationException class>>display:at:from:to:during: >> ByteString(String)>>displayProgressAt:from:to:during: >> ByteString(String)>>displayProgressFrom:to:during: >> OrderedCollection(Collection)>>do:displayingProgress:every: >> OrderedCollection(Collection)>>do:displayingProgress: >> [] in [] in [] in [] in MCPackageLoader>>basicLoad >> -- and more not shown -- >> From commits at source.squeak.org Mon Jan 26 14:34:23 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon Jan 26 14:34:24 2015 Subject: [squeak-dev] The Inbox: Morphic-mt.755.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Inbox: http://source.squeak.org/inbox/Morphic-mt.755.mcz ==================== Summary ==================== Name: Morphic-mt.755 Author: mt Time: 26 January 2015, 3:33:59.723 pm UUID: 2d4a39f5-5d85-d84e-bb0a-0d82257dd6c7 Ancestors: Morphic-mt.754 A keyboard event handler that supports multiple repeated key event processing. Normal #keyStroke: does not repeat if more than one key is pressed. Scenario: Multi-player Tetris. ^__^ The class comment includes instructions. =============== Diff against Morphic-mt.754 =============== Item was added: + Object subclass: #KeyboardEventHandler + instanceVariableNames: 'mutex pressedKeys longDelay shortDelay keyMap loop' + classVariableNames: '' + poolDictionaries: '' + category: 'Morphic-Events'! + + !KeyboardEventHandler commentStamp: 'mt 1/26/2015 15:30' prior: 0! + I allow for simulating repetition behavior of multiple "key strokes" because normal Squeak/OS cannot do that. + + HOW TO USE + --- + + 1) Subclass a morph, create an instance of me, give me a #keyMap, and call #startLoop, e.g. in #intoWorld:. + 2) Overwrite #handleKeyDown: and #handleKeyUp: and pass the events to me via #keyDown: resp. #keyUp:. + 2a) Call #value on the return value of #keyDown: if not nil to process the first call back immediately. + 3) Don't forget to call #stopLoop in, e.g., #outOfWorld: of your morph. + + You can play around with #delay: and #rate: .! Item was added: + ----- Method: KeyboardEventHandler>>delay (in category 'accessing') ----- + delay + + ^ longDelay! Item was added: + ----- Method: KeyboardEventHandler>>delay: (in category 'accessing') ----- + delay: milliseconds + "Time between first stroke and repetition." + + mutex critical: [longDelay := milliseconds].! Item was added: + ----- Method: KeyboardEventHandler>>fire: (in category 'running') ----- + fire: keyValue + + (keyMap at: keyValue ifAbsent: []) + ifNotNil: [:callback | WorldState addDeferredUIMessage: callback].! Item was added: + ----- Method: KeyboardEventHandler>>initialize (in category 'initialization') ----- + initialize + + super initialize. + + mutex := Mutex new. + pressedKeys := IdentityDictionary new. + longDelay := 200. "ms" + shortDelay := 20. "ms"! Item was added: + ----- Method: KeyboardEventHandler>>keyDown: (in category 'event handling') ----- + keyDown: evt + "Returns the callback if any. Caller has to ensure immediate fire!!" + + | result | + result := nil. + + mutex critical: [ + pressedKeys at: evt keyValue ifAbsentPut: [ + result := keyMap at: evt keyValue ifAbsent: []. + Time millisecondClockValue + longDelay]]. + + ^ result! Item was added: + ----- Method: KeyboardEventHandler>>keyMap (in category 'accessing') ----- + keyMap + + ^ keyMap! Item was added: + ----- Method: KeyboardEventHandler>>keyMap: (in category 'accessing') ----- + keyMap: aKeyMap + "Maps actual key values to callbacks." + + mutex critical: [keyMap := aKeyMap copy].! Item was added: + ----- Method: KeyboardEventHandler>>keyUp: (in category 'event handling') ----- + keyUp: evt + + mutex critical: [ + pressedKeys removeKey: evt keyValue ifAbsent: [] ].! Item was added: + ----- Method: KeyboardEventHandler>>process (in category 'running') ----- + process + "Look for callbacks to fire." + + mutex critical: [ + Time millisecondClockValue in: [:ms | + pressedKeys associationsDo: [:assoc | + ms >= assoc value ifTrue: [ + self fire: assoc key. + assoc value: ms + shortDelay]]]].! Item was added: + ----- Method: KeyboardEventHandler>>rate (in category 'accessing') ----- + rate + + ^ 1000 // shortDelay! Item was added: + ----- Method: KeyboardEventHandler>>rate: (in category 'accessing') ----- + rate: strokesPerSecond + + mutex critical: [shortDelay := 1000 // strokesPerSecond].! Item was added: + ----- Method: KeyboardEventHandler>>startLoop (in category 'running') ----- + startLoop + + self stopLoop. + + loop := [ + | delay | + delay := Delay forMilliseconds: 8. + [ self process. delay wait ] repeat ] fork.! Item was added: + ----- Method: KeyboardEventHandler>>stopLoop (in category 'running') ----- + stopLoop + + loop ifNotNil: #terminate. + loop := nil.! From eliot.miranda at gmail.com Mon Jan 26 18:44:06 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon Jan 26 18:44:09 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.599.mcz In-Reply-To: References: <1421655586903-4800301.post@n4.nabble.com> <1421659350139-4800312.post@n4.nabble.com> <1421660290104-4800317.post@n4.nabble.com> Message-ID: On Mon, Jan 19, 2015 at 11:32 AM, Levente Uzonyi wrote: > I never said it was easy. > Another way to do it is to compact eagerly on removal (as it's done in > Pharo). This gives better mass removal performance, and some of the code > becomes significantly simpler. This results in further performance boost. > > Removal still takes O(n) time, which means mass removal is in O(n^2), but > with a significantly smaller constant (~1/10), which improves the > usability of the collection quite a bit: > > | n random array | > n := 10000. > random := Random seed: 36rSQUEAK. > array := Array new: n streamContents: [ :stream | > n timesRepeat: [ stream nextPut: (random nextInt: 1073741823) -> 1 > ] ]. > { OrderedDictionary. LinkedDictionary } collect: [ :class | > Smalltalk garbageCollect. > [ > | instance | > instance := class new. > instance addAll: array. > array do: [ :each | instance removeKey: each key ] ] timeToRun ]. > "==> #(78 10)" > > (If n is 100k, then the result is still pretty bad: #(7055 136).) > > You can find these changes in the Inbox. > In Spur, self become: self copyEmpty should be cheap. This takes about 18 usecs on my 2.2GHz i7. So at some point the become will be cheaper for removeAll. Levente > > On Mon, 19 Jan 2015, Marcel Taeumel wrote: > > Woah, managing such a lookup index between "array" and "order" is quite >> complicated with the current implementation of Dictionary. :D >> >> Best, >> Marcel >> >> >> >> -- >> View this message in context: http://forum.world.st/The- >> Trunk-Collections-mt-599-mcz-tp4800299p4800317.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> >> >> > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150126/a1fe6433/attachment.htm From eliot.miranda at gmail.com Mon Jan 26 18:49:53 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon Jan 26 18:49:56 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Thu, Jan 22, 2015 at 9:46 AM, Tobias Pape wrote: > > On 22.01.2015, at 18:32, Nicolas Cellier < > nicolas.cellier.aka.nice@gmail.com> wrote: > > > > > > > 2015-01-22 9:30 GMT+01:00 Frank Shearar : > > On 22 January 2015 at 08:25, Tobias Pape wrote: > > > > > > On 22.01.2015, at 09:22, Frank Shearar > wrote: > > > > > >> On 21 January 2015 at 23:48, wrote: > > >>> Tobias Pape uploaded a new version of Environments to project The > Trunk: > > >>> http://source.squeak.org/trunk/Environments-topa.56.mcz > > >>> > > >>> ==================== Summary ==================== > > >>> > > >>> Name: Environments-topa.56 > > >>> Author: topa > > >>> Time: 22 January 2015, 12:48:30.677 am > > >>> UUID: e5cad590-2869-4f02-84ac-482952779d06 > > >>> Ancestors: Environments-topa.55 > > >>> > > >>> Provide more Dictionary protocol for exisiting users of Smalltalk > globals. > > >> > > >> If it addresses, in an expedient way, existing problems, then fine. > > >> But the Environments work was explicitly trying to move _away_ from > > >> the Dictionary protocols. Hence why the existing Dictionary-like > > >> methods are in the "emulating" category. > > > > > > Refactoring-Core is using this API. > > > > Obviously making the rest of the world move to the Environments API is > > the _right_ thing to do, if it's manipulating environmental stuff, but > > in the meantime, +1 to this addition :) > > > > frank > > > > > > We can use the #deprecated: in the meantime so as to not forget > > - that we should change senders > > - that we should not use this API in new code > > I'm unsure. > I _really_ like the idea of treating a namespace as a dictionary. > To be pedantic, +0.5. I like being able to use the read-only part of the Dictionary protocol on Environments. It is the destructive update-in-place part at:put: et al that shouldn't be supported. Modification is something that Environment needs to control carefgully to maintain system integrity. But this is just gut feeling. > > Best > -Tobias > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150126/7c2aba53/attachment.htm From commits at source.squeak.org Tue Jan 27 00:47:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:47:29 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.592.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.592.mcz ==================== Summary ==================== Name: Collections.spur-mt.592 Author: eem Time: 26 January 2015, 4:46:21.925 pm UUID: 218ea410-7389-42f1-a15e-21218969f4b7 Ancestors: Collections-mt.592, Collections.spur-mt.591 Collections-mt.592 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 Some nil checks replaced with #notNil because ProtoObject knows it and it is faster (about 15%) =============== Diff against Collections-mt.592 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:47:09.8 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:47:59 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:48:00 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.593.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.593.mcz ==================== Summary ==================== Name: Collections.spur-mt.593 Author: eem Time: 26 January 2015, 4:46:23.624 pm UUID: 933a6a8d-b44d-44bd-bb6c-26d2ac6f6517 Ancestors: Collections-mt.593, Collections.spur-mt.592 Collections-mt.593 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 New ordered dictionary added, which keeps track of the insertion order. =============== Diff against Collections-mt.593 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:47:52.014 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:47:59 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:48:05 2015 Subject: [squeak-dev] The Trunk: Collections.spur-topa.594.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-topa.594.mcz ==================== Summary ==================== Name: Collections.spur-topa.594 Author: eem Time: 26 January 2015, 4:46:33.479 pm UUID: ebdac0eb-7170-4d06-a079-d636aa2d425e Ancestors: Collections-topa.594, Collections.spur-mt.593 Collections-topa.594 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 Add #flattened as alias for #flatten. The former makes it more clear a copy will be returned (cf. #reversed), the latter is more in line with ANSI names (cf. #reverse) and other languages. =============== Diff against Collections-topa.594 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:47:54.206 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:48:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:48:08 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.595.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.595.mcz ==================== Summary ==================== Name: Collections.spur-mt.595 Author: eem Time: 26 January 2015, 4:46:24.89 pm UUID: 5c70bb94-3622-44a7-9172-352bb33d11e3 Ancestors: Collections-mt.595 Collections-mt.595 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 Some fixes to the OrderedDictionary implementation and its class comment was updated. =============== Diff against Collections-mt.595 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:47:58.581 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:49:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:49:28 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.596.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.596.mcz ==================== Summary ==================== Name: Collections.spur-mt.596 Author: eem Time: 26 January 2015, 4:46:26.334 pm UUID: bae3ffe2-66dd-4879-b636-e0935924e495 Ancestors: Collections-mt.596, Collections.spur-mt.595 Collections-mt.596 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 some fixes to OrderedDictionary including copy; small part of the protocol of OrderedCollection adopted (#sort, #first, ...). =============== Diff against Collections-mt.596 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:49:13.6 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:49:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:49:32 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.597.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.597.mcz ==================== Summary ==================== Name: Collections.spur-mt.597 Author: eem Time: 26 January 2015, 4:46:27.947 pm UUID: 660536f9-8581-4dd2-9c48-ccfd0ac4e1d5 Ancestors: Collections-mt.597, Collections.spur-mt.596 Collections-mt.597 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 Removed non-working #first: from OrderedDictionary. Was committed by accident. ^__^ =============== Diff against Collections-mt.597 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:49:13.746 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:49:30 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:49:37 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.598.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.598.mcz ==================== Summary ==================== Name: Collections.spur-ul.598 Author: eem Time: 26 January 2015, 4:46:34.806 pm UUID: 4205a362-bbd6-443f-b8b9-79cf8bc27ad8 Ancestors: Collections-ul.598 Collections-ul.598 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 - Fix: OrderedCollection >> #asArray returns an Array instead of an instance of the class returned by the class side #arrayType method. - Slightly more efficient OrderedCollection >> #sort:. - Merged Collections-ul.589: - Deprecated Collection class >> #randomForPicking. - Replaced all accesses to RandomForPicking with ThreadSafeRandom value. - WeakKeyDictionary >> associationsDo: ignores associations with GC'd keys. This affects all enumerator methods, and makes overriding #keysDo: unnecessary. - Added a new method SequenceableCollection #>> groupsDo:, which works like #groupsOf:atATimeDo:, but uses the block's argument count as the group size. Depends on Kernel-ul.893 =============== Diff against Collections-ul.598 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:49:13.845 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:49:33 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:49:40 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.599.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.599.mcz ==================== Summary ==================== Name: Collections.spur-mt.599 Author: eem Time: 26 January 2015, 4:46:29.055 pm UUID: eb4c5dca-0ace-492d-8ebc-09b533fa9593 Ancestors: Collections-mt.599 Collections-mt.599 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 Implemented "First wins"-strategy wrt. to the order of associations. Allowed for simplifying the code. Order array does only grow to 75% to mitigate the greediness of the Dictionary. =============== Diff against Collections-mt.599 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:49:17.983 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:49:57 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:49:59 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.600.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.600.mcz ==================== Summary ==================== Name: Collections.spur-mt.600 Author: eem Time: 26 January 2015, 4:46:30.669 pm UUID: a3d0c487-cbb8-4b8f-ade6-f3ba895f52d4 Ancestors: Collections-mt.600, Collections.spur-mt.599 Collections-mt.600 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 Copy ranges of elements in OrderedDictionary. =============== Diff against Collections-mt.600 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:49:56.629 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:50:46 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:50:48 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-topa.292.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-topa.292.mcz ==================== Summary ==================== Name: Compiler.spur-topa.292 Author: eem Time: 26 January 2015, 4:46:39.423 pm UUID: 709398b3-252c-40ad-9201-ee475535a3a0 Ancestors: Compiler-topa.292, Compiler.spur-eem.291 Compiler-topa.292 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 Fix super-send DoIts in the debugger. =============== Diff against Compiler-topa.292 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Tue Jan 27 00:50:53 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:50:57 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.602.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.602.mcz ==================== Summary ==================== Name: Collections.spur-mt.602 Author: eem Time: 26 January 2015, 4:46:31.779 pm UUID: fdb430a8-7f4e-4b6d-b998-8563215804de Ancestors: Collections-mt.602 Collections-mt.602 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 Merged improvements for OrderedDictionary from inbox (ul.601). Fixed problem in (mt.600 version) #copyFrom:to: with memory allocation. Preferred this over ul.601 because it is faster (8 per second vs. 12 per second). d := OrderedDictionary new. 1 to: 1000000 do: [:ea | d at: ea put: nil]. [d copyFrom: 250000 to: 750000] bench. =============== Diff against Collections-mt.602 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 27 January 2015 12:50:43.975 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Tue Jan 27 00:51:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 00:51:40 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.696.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.696.mcz ==================== Summary ==================== Name: System.spur-cmm.696 Author: eem Time: 26 January 2015, 4:46:44.707 pm UUID: 2ebcf616-d328-4201-ba34-87ff39d540bf Ancestors: System-cmm.696, System.spur-kfr.695 System-cmm.696 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.236 - Remove the crazy check for MessageNotUnderstood in Smalltalk #run:.. Headless mode should always exit on any Error. - In fact, even when not in headless mode, we don't need to halt but simply #pass the Error to the default handler for Errors do what it does, whether that's popping a debugger which could be resumed (if the Error isResumable) or something else. =============== Diff against System-cmm.696 =============== Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From leves at elte.hu Tue Jan 27 07:12:13 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue Jan 27 07:12:18 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.599.mcz In-Reply-To: References: <1421655586903-4800301.post@n4.nabble.com> <1421659350139-4800312.post@n4.nabble.com> <1421660290104-4800317.post@n4.nabble.com> Message-ID: On Mon, 26 Jan 2015, Eliot Miranda wrote: > > > On Mon, Jan 19, 2015 at 11:32 AM, Levente Uzonyi wrote: > I never said it was easy. > Another way to do it is to compact eagerly on removal (as it's done in > Pharo). This gives better mass removal performance, and some of the code > becomes significantly simpler. This results in further performance boost. > > Removal still takes O(n) time, which means mass removal is in O(n^2), but with a significantly smaller constant (~1/10), which improves the > usability of the collection quite a bit: > > | n random array | > n := 10000. > random := Random seed: 36rSQUEAK. > array := Array new: n streamContents: [ :stream | > ? ? ? ? n timesRepeat: [ stream nextPut: (random nextInt: 1073741823) -> 1 ] ]. > { OrderedDictionary. LinkedDictionary } collect: [ :class | > ? ? Smalltalk garbageCollect. > ? ? [ > ? ? ? ? | instance | > ? ? ? ? instance := class new. > ? ? ? ? instance addAll: array. > ? ? ? ? array do: [ :each | instance removeKey: each key ] ] timeToRun ]. > "==> #(78 10)" > > (If n is 100k, then the result is still pretty bad: #(7055 136).) > > You can find these changes in the Inbox. > > > In Spur, self become: self copyEmpty should be cheap.? This takes about 18 usecs on my 2.2GHz i7.? So at some point the become will be cheaper for removeAll. This benchmark shows that it takes O(n) time to remove a single element using random access, while it takes O(1) time with the linked implementation. For #removeAll, if we want to go to the direction where we allocate new arrays (instead of replacing all the elements with nil - as it is done now), then I think assigning them to the instance variables will always be faster than #become:. 0.018ms sounds great for #become:. Levente > > Levente > > On Mon, 19 Jan 2015, Marcel Taeumel wrote: > > Woah, managing such a lookup index between "array" and "order" is quite > complicated with the current implementation of Dictionary. :D > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Collections-mt-599-mcz-tp4800299p4800317.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > > > > > > -- > best,Eliot > > From lecteur at zogotounga.net Tue Jan 27 07:33:39 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Tue Jan 27 07:33:32 2015 Subject: [squeak-dev] The Trunk: Environments-topa.56.mcz In-Reply-To: References: <54c03ad8.c7588c0a.573d.ffffb1ffSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <54C73F53.7020804@zogotounga.net> > I'm unsure. > I _really_ like the idea of treating a namespace as a dictionary. > > > To be pedantic, +0.5. I like being able to use the read-only part of > the Dictionary protocol on Environments. It is the destructive > update-in-place part at:put: et al that shouldn't be supported. > Modification is something that Environment needs to control carefgully > to maintain system integrity. Isn't it the tradition of Smalltalk to be able to completely mess the system up by redefining a few methods, or using dangerous ones ? Stef From marcel.taeumel at student.hpi.uni-potsdam.de Tue Jan 27 07:41:55 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Tue Jan 27 07:46:02 2015 Subject: [squeak-dev] Re: The Trunk: Environments-topa.56.mcz In-Reply-To: References: Message-ID: <1422344515670-4801863.post@n4.nabble.com> If it looks -- e.g. in an object explorer -- like a dictionary, you should be able to talk to it like one. If #at:put: offers no meaningful implementation, throw a descriptive exception. Raising a generic DNU/MNU in such a case may confuse the tool/application developer and hence may repeat such a discussion over and over again. :) If, some day, we will find a meaningful/safe implementation/semantic for #at:put:, just provide it and stop raising and exception. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Environments-topa-56-mcz-tp4800863p4801863.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Tue Jan 27 07:44:19 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Tue Jan 27 07:48:26 2015 Subject: [squeak-dev] Re: The Trunk: Environments-topa.56.mcz In-Reply-To: <1422344515670-4801863.post@n4.nabble.com> References: <1422344515670-4801863.post@n4.nabble.com> Message-ID: <1422344659309-4801864.post@n4.nabble.com> Isn't there even a way to raise an exception and keep on calling that method? [env at: #foo put: #bar] on: UnsafeInterfaceException do: [:ex | ex resume]. Should be fine for development tools? So you could provide some implementation and still raise an exception. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Environments-topa-56-mcz-tp4800863p4801864.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Tue Jan 27 16:53:51 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue Jan 27 16:53:53 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz Message-ID: Marcel Taeumel uploaded a new version of System to project The Inbox: http://source.squeak.org/inbox/System-mt.697.mcz ==================== Summary ==================== Name: System-mt.697 Author: mt Time: 27 January 2015, 5:53:38.431 pm UUID: 9296f429-477d-0745-a878-6e11e7de5edd Ancestors: System-cmm.696 Let message tally ignore #home but just use #sender to handle block closures correctly. =============== Diff against System-cmm.696 =============== Item was changed: ----- Method: MessageTally>>tally:by: (in category 'tallying') ----- tally: context by: count "Explicitly tally the specified context and its stack." | sender | "Add to this node if appropriate" context method == method ifTrue: [^self bumpBy: count]. "No sender? Add new branch to the tree." + (sender := context sender) ifNil: [ - (sender := context home sender)ifNil: [ ^ (self bumpBy: count) tallyPath: context by: count]. "Find the node for the sending context (or add it if necessary)" ^ (self tally: sender by: count) tallyPath: context by: count! Item was changed: ----- Method: MessageTally>>tally:in:by: (in category 'tallying') ----- tally: context in: aProcess by: count "Explicitly tally the specified context and its stack." | sender | "Add to this node if appropriate" context method == method ifTrue: [^self bumpBy: count]. "No sender? Add new branch to the tree." + (sender := context sender) ifNil: [ - (sender := context home sender) ifNil: [ ^ (self bumpBy: count) tallyPath: context in: aProcess by: count]. "Find the node for the sending context (or add it if necessary)" ^ (self tally: sender in: aProcess by: count) tallyPath: context in: aProcess by: count! From marcel.taeumel at student.hpi.uni-potsdam.de Tue Jan 27 16:51:12 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Tue Jan 27 16:55:22 2015 Subject: [squeak-dev] Re: The Inbox: System-mt.697.mcz In-Reply-To: References: Message-ID: <1422377472227-4802005.post@n4.nabble.com> Is there any scenario, where #home is important for the tally? Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-System-mt-697-mcz-tp4802003p4802005.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From eliot.miranda at gmail.com Tue Jan 27 18:37:15 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 27 18:37:17 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Wow, that's quite the bug :-) On Tue, Jan 27, 2015 at 8:53 AM, wrote: > Marcel Taeumel uploaded a new version of System to project The Inbox: > http://source.squeak.org/inbox/System-mt.697.mcz > > ==================== Summary ==================== > > Name: System-mt.697 > Author: mt > Time: 27 January 2015, 5:53:38.431 pm > UUID: 9296f429-477d-0745-a878-6e11e7de5edd > Ancestors: System-cmm.696 > > Let message tally ignore #home but just use #sender to handle block > closures correctly. > > =============== Diff against System-cmm.696 =============== > > Item was changed: > ----- Method: MessageTally>>tally:by: (in category 'tallying') ----- > tally: context by: count > "Explicitly tally the specified context and its stack." > | sender | > > "Add to this node if appropriate" > context method == method ifTrue: [^self bumpBy: count]. > > "No sender? Add new branch to the tree." > + (sender := context sender) ifNil: [ > - (sender := context home sender)ifNil: [ > ^ (self bumpBy: count) tallyPath: context by: count]. > > "Find the node for the sending context (or add it if necessary)" > ^ (self tally: sender by: count) tallyPath: context by: count! > > Item was changed: > ----- Method: MessageTally>>tally:in:by: (in category 'tallying') ----- > tally: context in: aProcess by: count > "Explicitly tally the specified context and its stack." > | sender | > > "Add to this node if appropriate" > context method == method ifTrue: [^self bumpBy: count]. > > "No sender? Add new branch to the tree." > + (sender := context sender) ifNil: [ > - (sender := context home sender) ifNil: [ > ^ (self bumpBy: count) tallyPath: context in: aProcess by: > count]. > > "Find the node for the sending context (or add it if necessary)" > ^ (self tally: sender in: aProcess by: count) tallyPath: context > in: aProcess by: count! > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150127/03ff4ac1/attachment.htm From eliot.miranda at gmail.com Tue Jan 27 18:37:48 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 27 18:37:51 2015 Subject: [squeak-dev] Re: The Inbox: System-mt.697.mcz In-Reply-To: <1422377472227-4802005.post@n4.nabble.com> References: <1422377472227-4802005.post@n4.nabble.com> Message-ID: On Tue, Jan 27, 2015 at 8:51 AM, Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > Is there any scenario, where #home is important for the tally? > Not as far as I can tell. I think you have it right. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150127/959bd0eb/attachment.htm From eliot.miranda at gmail.com Tue Jan 27 18:40:02 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 27 18:40:04 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.599.mcz In-Reply-To: References: <1421655586903-4800301.post@n4.nabble.com> <1421659350139-4800312.post@n4.nabble.com> <1421660290104-4800317.post@n4.nabble.com> Message-ID: On Mon, Jan 26, 2015 at 11:12 PM, Levente Uzonyi wrote: > On Mon, 26 Jan 2015, Eliot Miranda wrote: > > >> >> On Mon, Jan 19, 2015 at 11:32 AM, Levente Uzonyi wrote: >> I never said it was easy. >> Another way to do it is to compact eagerly on removal (as it's done >> in >> Pharo). This gives better mass removal performance, and some of the >> code >> becomes significantly simpler. This results in further performance >> boost. >> >> Removal still takes O(n) time, which means mass removal is in >> O(n^2), but with a significantly smaller constant (~1/10), which improves >> the >> usability of the collection quite a bit: >> >> | n random array | >> n := 10000. >> random := Random seed: 36rSQUEAK. >> array := Array new: n streamContents: [ :stream | >> n timesRepeat: [ stream nextPut: (random nextInt: >> 1073741823) -> 1 ] ]. >> { OrderedDictionary. LinkedDictionary } collect: [ :class | >> Smalltalk garbageCollect. >> [ >> | instance | >> instance := class new. >> instance addAll: array. >> array do: [ :each | instance removeKey: each key ] ] >> timeToRun ]. >> "==> #(78 10)" >> >> (If n is 100k, then the result is still pretty bad: #(7055 136).) >> >> You can find these changes in the Inbox. >> >> >> In Spur, self become: self copyEmpty should be cheap. This takes about >> 18 usecs on my 2.2GHz i7. So at some point the become will be cheaper for >> removeAll. >> > > This benchmark shows that it takes O(n) time to remove a single element > using random access, while it takes O(1) time with the linked > implementation. > > For #removeAll, if we want to go to the direction where we allocate new > arrays (instead of replacing all the elements with nil - as it is done > now), then I think assigning them to the instance variables will always be > faster than #become:. > Of course, that's much better. Simply replace the linked list with an empty one. > > 0.018ms sounds great for #become:. It's a key part of the design of Spur. Levente > > > >> Levente >> >> On Mon, 19 Jan 2015, Marcel Taeumel wrote: >> >> Woah, managing such a lookup index between "array" and >> "order" is quite >> complicated with the current implementation of Dictionary. :D >> >> Best, >> Marcel >> >> >> >> -- >> View this message in context: http://forum.world.st/The- >> Trunk-Collections-mt-599-mcz-tp4800299p4800317.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> >> >> >> >> >> >> -- >> best,Eliot >> >> > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150127/a0a6dcca/attachment.htm From bert at freudenbergs.de Tue Jan 27 18:54:06 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue Jan 27 18:54:11 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150127/dc6ade10/smime.bin From asqueaker at gmail.com Tue Jan 27 20:07:06 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue Jan 27 20:07:09 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> Message-ID: This is easy for an expert to glance at and understand the nature of the bug but could someone explain it to help our Smalltalk-user community understand what has been wrong with MessageTally all these years? Thanks! On Tue, Jan 27, 2015 at 12:54 PM, Bert Freudenberg wrote: > On 27.01.2015, at 19:37, Eliot Miranda wrote: > > > Wow, that's quite the bug :-) > > > Indeed. I wonder how this could have ever worked. Or maybe just nobody > noticed that certain chains were missing? > > - Bert - > > > > On Tue, Jan 27, 2015 at 8:53 AM, wrote: >> >> Marcel Taeumel uploaded a new version of System to project The Inbox: >> http://source.squeak.org/inbox/System-mt.697.mcz >> >> ==================== Summary ==================== >> >> Name: System-mt.697 >> Author: mt >> Time: 27 January 2015, 5:53:38.431 pm >> UUID: 9296f429-477d-0745-a878-6e11e7de5edd >> Ancestors: System-cmm.696 >> >> Let message tally ignore #home but just use #sender to handle block >> closures correctly. >> >> =============== Diff against System-cmm.696 =============== >> >> Item was changed: >> ----- Method: MessageTally>>tally:by: (in category 'tallying') ----- >> tally: context by: count >> "Explicitly tally the specified context and its stack." >> | sender | >> >> "Add to this node if appropriate" >> context method == method ifTrue: [^self bumpBy: count]. >> >> "No sender? Add new branch to the tree." >> + (sender := context sender) ifNil: [ >> - (sender := context home sender)ifNil: [ >> ^ (self bumpBy: count) tallyPath: context by: count]. >> >> "Find the node for the sending context (or add it if necessary)" >> ^ (self tally: sender by: count) tallyPath: context by: count! >> >> Item was changed: >> ----- Method: MessageTally>>tally:in:by: (in category 'tallying') ----- >> tally: context in: aProcess by: count >> "Explicitly tally the specified context and its stack." >> | sender | >> >> "Add to this node if appropriate" >> context method == method ifTrue: [^self bumpBy: count]. >> >> "No sender? Add new branch to the tree." >> + (sender := context sender) ifNil: [ >> - (sender := context home sender) ifNil: [ >> ^ (self bumpBy: count) tallyPath: context in: aProcess by: >> count]. >> >> "Find the node for the sending context (or add it if necessary)" >> ^ (self tally: sender in: aProcess by: count) tallyPath: context >> in: aProcess by: count! >> >> > > > > -- > best, > Eliot > > > > > > From leves at elte.hu Tue Jan 27 21:21:17 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue Jan 27 21:21:22 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> Message-ID: AndreasSystemProfiler has the same bug, and it's annoyed me forever, so thanks for the fix. I'm not an expert, but here's an example: AndreasSystemProfiler spyOn: [ [ #((1 2 3)) do: [ :each | each findLast: [ :ea | ea squared = ea ] ] ] bench ]. Before the patch you got: 99.98 (5,018) UndefinedObject DoIt 10.39 (521) Array [SequenceableCollection] findLast: 9.68 (486) Array [SequenceableCollection] do: 5.94 (298) Time class millisecondClockValue But the profiled block doesn't send #findLast, nor #do:, and neither #millisecondClockValue. It sends #bench to a block, and nothing else. After the fix it's: 99.98 (5,018) UndefinedObject DoIt 99.98 (5,018) BlockClosure bench 99.96 (5,017) UndefinedObject DoIt 20.9 (1,049) Array [SequenceableCollection] do: |16.01 (804) UndefinedObject DoIt | 16.01 (803) Array [SequenceableCollection] findLast: 5.7 (286) Time class millisecondClockValue Which is much better, and almost exact. #millisecondsClockValue is sent from #bench, not from a block. Levente On Tue, 27 Jan 2015, Chris Muller wrote: > This is easy for an expert to glance at and understand the nature of > the bug but could someone explain it to help our Smalltalk-user > community understand what has been wrong with MessageTally all these > years? > > Thanks! > > On Tue, Jan 27, 2015 at 12:54 PM, Bert Freudenberg wrote: >> On 27.01.2015, at 19:37, Eliot Miranda wrote: >> >> >> Wow, that's quite the bug :-) >> >> >> Indeed. I wonder how this could have ever worked. Or maybe just nobody >> noticed that certain chains were missing? >> >> - Bert - >> >> >> >> On Tue, Jan 27, 2015 at 8:53 AM, wrote: >>> >>> Marcel Taeumel uploaded a new version of System to project The Inbox: >>> http://source.squeak.org/inbox/System-mt.697.mcz >>> >>> ==================== Summary ==================== >>> >>> Name: System-mt.697 >>> Author: mt >>> Time: 27 January 2015, 5:53:38.431 pm >>> UUID: 9296f429-477d-0745-a878-6e11e7de5edd >>> Ancestors: System-cmm.696 >>> >>> Let message tally ignore #home but just use #sender to handle block >>> closures correctly. >>> >>> =============== Diff against System-cmm.696 =============== >>> >>> Item was changed: >>> ----- Method: MessageTally>>tally:by: (in category 'tallying') ----- >>> tally: context by: count >>> "Explicitly tally the specified context and its stack." >>> | sender | >>> >>> "Add to this node if appropriate" >>> context method == method ifTrue: [^self bumpBy: count]. >>> >>> "No sender? Add new branch to the tree." >>> + (sender := context sender) ifNil: [ >>> - (sender := context home sender)ifNil: [ >>> ^ (self bumpBy: count) tallyPath: context by: count]. >>> >>> "Find the node for the sending context (or add it if necessary)" >>> ^ (self tally: sender by: count) tallyPath: context by: count! >>> >>> Item was changed: >>> ----- Method: MessageTally>>tally:in:by: (in category 'tallying') ----- >>> tally: context in: aProcess by: count >>> "Explicitly tally the specified context and its stack." >>> | sender | >>> >>> "Add to this node if appropriate" >>> context method == method ifTrue: [^self bumpBy: count]. >>> >>> "No sender? Add new branch to the tree." >>> + (sender := context sender) ifNil: [ >>> - (sender := context home sender) ifNil: [ >>> ^ (self bumpBy: count) tallyPath: context in: aProcess by: >>> count]. >>> >>> "Find the node for the sending context (or add it if necessary)" >>> ^ (self tally: sender in: aProcess by: count) tallyPath: context >>> in: aProcess by: count! >>> >>> >> >> >> >> -- >> best, >> Eliot >> >> >> >> >> >> > > From Das.Linux at gmx.de Tue Jan 27 21:39:08 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue Jan 27 21:39:12 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> Message-ID: <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> Hi, On 27.01.2015, at 22:21, Levente Uzonyi wrote: > AndreasSystemProfiler This is not in trunk, right? If so, why? Best -Tobias From leves at elte.hu Tue Jan 27 21:49:15 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue Jan 27 21:49:17 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> Message-ID: Good question. It uses some primitives, which may not be supported by the interpreter VM. Levente On Tue, 27 Jan 2015, Tobias Pape wrote: > Hi, > > On 27.01.2015, at 22:21, Levente Uzonyi wrote: > >> AndreasSystemProfiler > > This is not in trunk, right? > If so, why? > > Best > -Tobias > > > From eliot.miranda at gmail.com Tue Jan 27 21:51:52 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 27 21:51:55 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> Message-ID: On Tue, Jan 27, 2015 at 1:39 PM, Tobias Pape wrote: > Hi, > > On 27.01.2015, at 22:21, Levente Uzonyi wrote: > > > AndreasSystemProfiler > > This is not in trunk, right? > If so, why? > It came from Qwaq/Terf so it ended up in http://ss3.gemstone.com/ss/AndreasSystemProfiler. Further, as Levente says it depends on support that is in Cog VMs (JIT, Stack & Interpreter) but not (yet) in the trunk Interpreter. So I guess it doesn't belong in trunk until the Cog Interpreter has been merged with the trunk Interpreter. That's a fair amount of work, and neither David nor I have the time for it right now. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150127/e82daf08/attachment.htm From eliot.miranda at gmail.com Tue Jan 27 21:55:45 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue Jan 27 21:55:47 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> Message-ID: On Tue, Jan 27, 2015 at 1:21 PM, Levente Uzonyi wrote: > AndreasSystemProfiler has the same bug, and it's annoyed me forever, so > thanks for the fix. > > I'm not an expert, but here's an example: > > AndreasSystemProfiler spyOn: [ > [ #((1 2 3)) do: [ :each | > each findLast: [ :ea | > ea squared = ea ] ] ] bench ]. > > Before the patch you got: > > 99.98 (5,018) UndefinedObject DoIt > 10.39 (521) Array [SequenceableCollection] findLast: > 9.68 (486) Array [SequenceableCollection] do: > 5.94 (298) Time class millisecondClockValue > > But the profiled block doesn't send #findLast, nor #do:, and neither > #millisecondClockValue. It sends #bench to a block, and nothing else. > > After the fix it's: > > 99.98 (5,018) UndefinedObject DoIt > 99.98 (5,018) BlockClosure bench > 99.96 (5,017) UndefinedObject DoIt > 20.9 (1,049) Array [SequenceableCollection] do: > |16.01 (804) UndefinedObject DoIt > | 16.01 (803) Array [SequenceableCollection] findLast: > 5.7 (286) Time class millisecondClockValue > > Which is much better, and almost exact. #millisecondsClockValue is sent > from #bench, not from a block. There's a printing bug there. IMO it should look like 99.98 (5,018) UndefinedObject DoIt 99.98 (5,018) BlockClosure bench 99.96 (5,017) [] in UndefinedObject DoIt 20.9 (1,049) Array [SequenceableCollection] do: |16.01 (804) [] in UndefinedObject DoIt | 16.01 (803) Array [SequenceableCollection] findLast: 5.7 (286) Time class millisecondClockValue I'll take a look. > > Levente > > > On Tue, 27 Jan 2015, Chris Muller wrote: > > This is easy for an expert to glance at and understand the nature of >> the bug but could someone explain it to help our Smalltalk-user >> community understand what has been wrong with MessageTally all these >> years? >> >> Thanks! >> >> On Tue, Jan 27, 2015 at 12:54 PM, Bert Freudenberg >> wrote: >> >>> On 27.01.2015, at 19:37, Eliot Miranda wrote: >>> >>> >>> Wow, that's quite the bug :-) >>> >>> >>> Indeed. I wonder how this could have ever worked. Or maybe just nobody >>> noticed that certain chains were missing? >>> >>> - Bert - >>> >>> >>> >>> On Tue, Jan 27, 2015 at 8:53 AM, wrote: >>> >>>> >>>> Marcel Taeumel uploaded a new version of System to project The Inbox: >>>> http://source.squeak.org/inbox/System-mt.697.mcz >>>> >>>> ==================== Summary ==================== >>>> >>>> Name: System-mt.697 >>>> Author: mt >>>> Time: 27 January 2015, 5:53:38.431 pm >>>> UUID: 9296f429-477d-0745-a878-6e11e7de5edd >>>> Ancestors: System-cmm.696 >>>> >>>> Let message tally ignore #home but just use #sender to handle block >>>> closures correctly. >>>> >>>> =============== Diff against System-cmm.696 =============== >>>> >>>> Item was changed: >>>> ----- Method: MessageTally>>tally:by: (in category 'tallying') ----- >>>> tally: context by: count >>>> "Explicitly tally the specified context and its stack." >>>> | sender | >>>> >>>> "Add to this node if appropriate" >>>> context method == method ifTrue: [^self bumpBy: count]. >>>> >>>> "No sender? Add new branch to the tree." >>>> + (sender := context sender) ifNil: [ >>>> - (sender := context home sender)ifNil: [ >>>> ^ (self bumpBy: count) tallyPath: context by: count]. >>>> >>>> "Find the node for the sending context (or add it if necessary)" >>>> ^ (self tally: sender by: count) tallyPath: context by: count! >>>> >>>> Item was changed: >>>> ----- Method: MessageTally>>tally:in:by: (in category 'tallying') >>>> ----- >>>> tally: context in: aProcess by: count >>>> "Explicitly tally the specified context and its stack." >>>> | sender | >>>> >>>> "Add to this node if appropriate" >>>> context method == method ifTrue: [^self bumpBy: count]. >>>> >>>> "No sender? Add new branch to the tree." >>>> + (sender := context sender) ifNil: [ >>>> - (sender := context home sender) ifNil: [ >>>> ^ (self bumpBy: count) tallyPath: context in: aProcess >>>> by: >>>> count]. >>>> >>>> "Find the node for the sending context (or add it if necessary)" >>>> ^ (self tally: sender in: aProcess by: count) tallyPath: context >>>> in: aProcess by: count! >>>> >>>> >>>> >>> >>> >>> -- >>> best, >>> Eliot >>> >>> >>> >>> >>> >>> >>> >> >> > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150127/0824b0dd/attachment-0001.htm From bert at freudenbergs.de Tue Jan 27 23:34:33 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue Jan 27 23:34:36 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> Message-ID: <68B96ECC-1423-4430-9ADD-56C97FCE9BEC@freudenbergs.de> > On 27.01.2015, at 22:21, Levente Uzonyi wrote: > > AndreasSystemProfiler has the same bug, and it's annoyed me forever, so thanks for the fix. Yep, Marcel is on a roll. Keep it coming! :) - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 6112 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150128/8e693493/smime.bin From lewis at mail.msen.com Wed Jan 28 00:00:57 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed Jan 28 00:01:01 2015 Subject: [Vm-dev] Re: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> Message-ID: <20150128000057.GA32028@shell.msen.com> On Tue, Jan 27, 2015 at 01:51:52PM -0800, Eliot Miranda wrote: > > On Tue, Jan 27, 2015 at 1:39 PM, Tobias Pape wrote: > > > Hi, > > > > On 27.01.2015, at 22:21, Levente Uzonyi wrote: > > > > > AndreasSystemProfiler > > > > This is not in trunk, right? > > If so, why? > > > > It came from Qwaq/Terf so it ended up in > http://ss3.gemstone.com/ss/AndreasSystemProfiler. Further, as Levente says > it depends on support that is in Cog VMs (JIT, Stack & Interpreter) but not > (yet) in the trunk Interpreter. So I guess it doesn't belong in trunk > until the Cog Interpreter has been merged with the trunk Interpreter. > That's a fair amount of work, and neither David nor I have the time for it > right now. I did spend some time last year trying to get the primitives working in trunk Interpreter, but I was a bit out of my depth and did not get it right. Reminder and background info is on Mantis at http://bugs.squeak.org/view.php?id=7746 As far as putting the profiler into trunk, I should think that there would be some way to have more than one profiler, and fall back to the old one if the VM does not provide the needed support for AndreasSystemProfiler. This seems like a worthwhile thing to do. Anyone care to take it on? Dave From eliot.miranda at gmail.com Wed Jan 28 00:14:24 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed Jan 28 00:14:41 2015 Subject: [Vm-dev] Re: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: <20150128000057.GA32028@shell.msen.com> References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> <20150128000057.GA32028@shell.msen.com> Message-ID: <5459606D-482B-4787-82A0-7C328E2760EE@gmail.com> On Jan 27, 2015, at 4:00 PM, "David T. Lewis" wrote: > > On Tue, Jan 27, 2015 at 01:51:52PM -0800, Eliot Miranda wrote: >> >> On Tue, Jan 27, 2015 at 1:39 PM, Tobias Pape wrote: >> >>> Hi, >>> >>> On 27.01.2015, at 22:21, Levente Uzonyi wrote: >>> >>>> AndreasSystemProfiler >>> >>> This is not in trunk, right? >>> If so, why? >> >> It came from Qwaq/Terf so it ended up in >> http://ss3.gemstone.com/ss/AndreasSystemProfiler. Further, as Levente says >> it depends on support that is in Cog VMs (JIT, Stack & Interpreter) but not >> (yet) in the trunk Interpreter. So I guess it doesn't belong in trunk >> until the Cog Interpreter has been merged with the trunk Interpreter. >> That's a fair amount of work, and neither David nor I have the time for it >> right now. > > I did spend some time last year trying to get the primitives working in > trunk Interpreter, but I was a bit out of my depth and did not get it right. Since the code is in the Cog Interpreter the right way to do this IMO us to port bug fixes to primitives etc into the Cog Interpreter and call the Cog VMMaker trunk. Going the other way takes longer to get to the same place. > > Reminder and background info is on Mantis at http://bugs.squeak.org/view.php?id=7746 > > As far as putting the profiler into trunk, I should think that there would > be some way to have more than one profiler, and fall back to the old one > if the VM does not provide the needed support for AndreasSystemProfiler. > > This seems like a worthwhile thing to do. Anyone care to take it on? > > Dave > From lewis at mail.msen.com Wed Jan 28 03:15:28 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed Jan 28 03:15:31 2015 Subject: [Vm-dev] Re: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: <5459606D-482B-4787-82A0-7C328E2760EE@gmail.com> References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> <20150128000057.GA32028@shell.msen.com> <5459606D-482B-4787-82A0-7C328E2760EE@gmail.com> Message-ID: <20150128031528.GA59499@shell.msen.com> On Tue, Jan 27, 2015 at 04:14:24PM -0800, Eliot Miranda wrote: > On Jan 27, 2015, at 4:00 PM, "David T. Lewis" wrote: > > On Tue, Jan 27, 2015 at 01:51:52PM -0800, Eliot Miranda wrote: > >> On Tue, Jan 27, 2015 at 1:39 PM, Tobias Pape wrote: > >>> On 27.01.2015, at 22:21, Levente Uzonyi wrote: > >>> > >>>> AndreasSystemProfiler > >>> > >>> This is not in trunk, right? > >>> If so, why? > >> > >> It came from Qwaq/Terf so it ended up in > >> http://ss3.gemstone.com/ss/AndreasSystemProfiler. Further, as Levente says > >> it depends on support that is in Cog VMs (JIT, Stack & Interpreter) but not > >> (yet) in the trunk Interpreter. So I guess it doesn't belong in trunk > >> until the Cog Interpreter has been merged with the trunk Interpreter. > >> That's a fair amount of work, and neither David nor I have the time for it > >> right now. > > > > I did spend some time last year trying to get the primitives working in > > trunk Interpreter, but I was a bit out of my depth and did not get it right. > > Since the code is in the Cog Interpreter the right way to do this IMO us > to port bug fixes to primitives etc into the Cog Interpreter and call the > Cog VMMaker trunk. Going the other way takes longer to get to the same place. > Hi Eliot, Was Andreas' profiler fully functional on an Interpreter generated from oscog at one point? I know that Andreas had done at least an initial implementation in that part of the code. I had assumed that his main focus in that time frame would have been on Cog, so I was not entirely sure if the Interpreter implementation was complete. Of course I was trying to adopt the implementation from the oscog branch when I looked at this last year. But given that I was not successful, I won't attempt to argue that this was the best possible approach. Thanks, Dave From eliot.miranda at gmail.com Wed Jan 28 03:43:27 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed Jan 28 03:43:30 2015 Subject: [Vm-dev] Re: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: <20150128031528.GA59499@shell.msen.com> References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> <20150128000057.GA32028@shell.msen.com> <5459606D-482B-4787-82A0-7C328E2760EE@gmail.com> <20150128031528.GA59499@shell.msen.com> Message-ID: On Tue, Jan 27, 2015 at 7:15 PM, David T. Lewis wrote: > > On Tue, Jan 27, 2015 at 04:14:24PM -0800, Eliot Miranda wrote: > > On Jan 27, 2015, at 4:00 PM, "David T. Lewis" > wrote: > > > On Tue, Jan 27, 2015 at 01:51:52PM -0800, Eliot Miranda wrote: > > >> On Tue, Jan 27, 2015 at 1:39 PM, Tobias Pape > wrote: > > >>> On 27.01.2015, at 22:21, Levente Uzonyi wrote: > > >>> > > >>>> AndreasSystemProfiler > > >>> > > >>> This is not in trunk, right? > > >>> If so, why? > > >> > > >> It came from Qwaq/Terf so it ended up in > > >> http://ss3.gemstone.com/ss/AndreasSystemProfiler. Further, as > Levente says > > >> it depends on support that is in Cog VMs (JIT, Stack & Interpreter) > but not > > >> (yet) in the trunk Interpreter. So I guess it doesn't belong in trunk > > >> until the Cog Interpreter has been merged with the trunk Interpreter. > > >> That's a fair amount of work, and neither David nor I have the time > for it > > >> right now. > > > > > > I did spend some time last year trying to get the primitives working in > > > trunk Interpreter, but I was a bit out of my depth and did not get it > right. > > > > Since the code is in the Cog Interpreter the right way to do this IMO us > > to port bug fixes to primitives etc into the Cog Interpreter and call the > > Cog VMMaker trunk. Going the other way takes longer to get to the same > place. > > > > Hi Eliot, > > Was Andreas' profiler fully functional on an Interpreter generated from > oscog > at one point? I know that Andreas had done at least an initial > implementation > in that part of the code. I had assumed that his main focus in that time > frame > would have been on Cog, so I was not entirely sure if the Interpreter > implementation was complete. > When I joined Qwaq, Andreas' fork of VMMaker and svn trunk was the VM in use. The Interpreter contained all of the support for Andreas' profiler. That VMMaker was my starting point for Cog and I simply supported in the Stack and Cog VMs what was in the Interpreter. There was much else in there too; support for a high-priority media=-processing thread which was used for Qwaq's voice channel; extensions to the host window plugin etc, etc. This had to continue working as the VM was sped-up using first the Stack VM and then Cog. I guess the Qwaq VM forked from trunk in about 2005. > Of course I was trying to adopt the implementation from the oscog branch > when I looked at this last year. But given that I was not successful, I > won't attempt to argue that this was the best possible approach. > > Thanks, > Dave > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150127/b5287706/attachment.htm From lewis at mail.msen.com Wed Jan 28 04:11:49 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed Jan 28 04:11:51 2015 Subject: [squeak-dev] AndreasSystemProfiler primitives (was: The Inbox: System-mt.697.mcz) In-Reply-To: References: <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> <9E4BEC04-4127-445B-8AF9-BB75CF06AF41@gmx.de> <20150128000057.GA32028@shell.msen.com> <5459606D-482B-4787-82A0-7C328E2760EE@gmail.com> <20150128031528.GA59499@shell.msen.com> Message-ID: <20150128041149.GA67923@shell.msen.com> On Tue, Jan 27, 2015 at 07:43:27PM -0800, Eliot Miranda wrote: > On Tue, Jan 27, 2015 at 7:15 PM, David T. Lewis wrote: > > > > On Tue, Jan 27, 2015 at 04:14:24PM -0800, Eliot Miranda wrote: > > > > Was Andreas' profiler fully functional on an Interpreter generated from oscog > > at one point? I know that Andreas had done at least an initial implementation > > in that part of the code. I had assumed that his main focus in that time frame > > would have been on Cog, so I was not entirely sure if the Interpreter > > implementation was complete. > > > > When I joined Qwaq, Andreas' fork of VMMaker and svn trunk was the VM in > use. The Interpreter contained all of the support for Andreas' profiler. > That VMMaker was my starting point for Cog and I simply supported in the > Stack and Cog VMs what was in the Interpreter. > > There was much else in there too; support for a high-priority > media=-processing thread which was used for Qwaq's voice channel; > extensions to the host window plugin etc, etc. This had to continue > working as the VM was sped-up using first the Stack VM and then Cog. I > guess the Qwaq VM forked from trunk in about 2005. > Thanks Eliot, That probably sounded like a dumb question, but I actually was not sure if I was looking at a complete and functional implemention, or just a rough draft. Obviously it would have made more sense for me to have asked the question a year or so ago. I can't look into it further now, but the issue remains documented on Mantis at http://bugs.squeak.org/view.php?id=7746 so hopefully either I or some other motivated person will follow through on it in the not too distant future. Dave > > > Of course I was trying to adopt the implementation from the oscog branch > > when I looked at this last year. But given that I was not successful, I > > won't attempt to argue that this was the best possible approach. > > > > Thanks, > > Dave > > > > -- > best, > Eliot > From commits at source.squeak.org Wed Jan 28 08:03:34 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 28 08:03:34 2015 Subject: [squeak-dev] The Trunk: System-mt.697.mcz Message-ID: Marcel Taeumel uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-mt.697.mcz ==================== Summary ==================== Name: System-mt.697 Author: mt Time: 27 January 2015, 5:53:38.431 pm UUID: 9296f429-477d-0745-a878-6e11e7de5edd Ancestors: System-cmm.696 Let message tally ignore #home but just use #sender to handle block closures correctly. =============== Diff against System-cmm.696 =============== Item was changed: ----- Method: MessageTally>>tally:by: (in category 'tallying') ----- tally: context by: count "Explicitly tally the specified context and its stack." | sender | "Add to this node if appropriate" context method == method ifTrue: [^self bumpBy: count]. "No sender? Add new branch to the tree." + (sender := context sender) ifNil: [ - (sender := context home sender)ifNil: [ ^ (self bumpBy: count) tallyPath: context by: count]. "Find the node for the sending context (or add it if necessary)" ^ (self tally: sender by: count) tallyPath: context by: count! Item was changed: ----- Method: MessageTally>>tally:in:by: (in category 'tallying') ----- tally: context in: aProcess by: count "Explicitly tally the specified context and its stack." | sender | "Add to this node if appropriate" context method == method ifTrue: [^self bumpBy: count]. "No sender? Add new branch to the tree." + (sender := context sender) ifNil: [ - (sender := context home sender) ifNil: [ ^ (self bumpBy: count) tallyPath: context in: aProcess by: count]. "Find the node for the sending context (or add it if necessary)" ^ (self tally: sender in: aProcess by: count) tallyPath: context in: aProcess by: count! From bert at freudenbergs.de Wed Jan 28 10:45:37 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Wed Jan 28 10:45:40 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> Message-ID: Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150128/e804751e/smime.bin From marcel.taeumel at student.hpi.uni-potsdam.de Wed Jan 28 15:49:56 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Wed Jan 28 15:54:13 2015 Subject: [squeak-dev] Re: The Inbox: System-mt.697.mcz In-Reply-To: References: <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> Message-ID: <1422460196992-4802221.post@n4.nabble.com> If we keep record of MethodContext >> #isExecutingBlock in MessageTally >> #tallyPath:by: (resp. #tallyPath:in:by:) we could change the printing to prepend "[] in" again. :) Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-System-mt-697-mcz-tp4802003p4802221.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From eliot.miranda at gmail.com Wed Jan 28 15:54:41 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed Jan 28 15:54:49 2015 Subject: [squeak-dev] The Inbox: System-mt.697.mcz In-Reply-To: References: <54c7c2a6.841ee00a.322a.ffff8040SMTPIN_ADDED_MISSING@mx.google.com> <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> Message-ID: <94C264C3-D3A5-4C1D-B8D2-1987FA3997FE@gmail.com> Hi Bert, On Jan 28, 2015, at 2:45 AM, Bert Freudenberg wrote: > On 27.01.2015, at 22:55, Eliot Miranda wrote: >> >> >>> 99.98 (5,018) UndefinedObject DoIt >>> 99.98 (5,018) BlockClosure bench >>> 99.96 (5,017) UndefinedObject DoIt >>> 20.9 (1,049) Array [SequenceableCollection] do: >>> |16.01 (804) UndefinedObject DoIt >>> | 16.01 (803) Array [SequenceableCollection] findLast: >>> 5.7 (286) Time class millisecondClockValue >>> >>> Which is much better, and almost exact. #millisecondsClockValue is sent from #bench, not from a block. >> >> There's a printing bug there. IMO it should look like >> >> 99.98 (5,018) UndefinedObject DoIt >> 99.98 (5,018) BlockClosure bench >> 99.96 (5,017) [] in UndefinedObject DoIt >> 20.9 (1,049) Array [SequenceableCollection] do: >> |16.01 (804) [] in UndefinedObject DoIt >> | 16.01 (803) Array [SequenceableCollection] findLast: >> 5.7 (286) Time class millisecondClockValue >> >> I'll take a look. > > > Tallies currently only count per-method, not per-block. Maybe that is the reason why previously it tried to go via a block?s home? Perhaps. I fixed it in Andreas' profiler by adding a block nesting count to ASPTally. I'll back port it to MessageTally soon. > > - Bert - > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150128/deb2c9dd/attachment.htm From eliot.miranda at gmail.com Wed Jan 28 16:36:25 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed Jan 28 16:36:30 2015 Subject: [squeak-dev] Re: The Inbox: System-mt.697.mcz In-Reply-To: <1422460196992-4802221.post@n4.nabble.com> References: <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> <1422460196992-4802221.post@n4.nabble.com> Message-ID: <06E9216B-DA34-465E-B187-B83FB8E9E65C@gmail.com> Hi Marcel, On Jan 28, 2015, at 7:49 AM, Marcel Taeumel wrote: > If we keep record of MethodContext >> #isExecutingBlock in MessageTally >> > #tallyPath:by: (resp. #tallyPath:in:by:) we could change the printing to > prepend "[] in" again. :) Look at my fix in AndreasSystemProfiler. I introduced a blockNesting count. This allows printing block nesting that I chose to write as [] in UndefinedObject doit Collection foo [[]] in UndefinedObject doit etc > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Inbox-System-mt-697-mcz-tp4802003p4802221.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From michal-list at auf.net Wed Jan 28 18:47:48 2015 From: michal-list at auf.net (Michal) Date: Wed Jan 28 18:47:52 2015 Subject: [squeak-dev] moving a class betwen two monticello packages Message-ID: <20150128184748.GA29914@auf.net> hello -- What is the best way of moving a class from one mcz package to another? I typically load my packages with 'load' in the monticello browser. This means that when I move class C from pkg1 to pkg2, if I then load pkg1, C is removed from the system. Not what I want! So is there a way of loading multiple packages at the same time which avoids that? Or some other solution? thanks! From marcel.taeumel at student.hpi.uni-potsdam.de Wed Jan 28 18:53:20 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Wed Jan 28 18:57:38 2015 Subject: [squeak-dev] Re: moving a class betwen two monticello packages In-Reply-To: <20150128184748.GA29914@auf.net> References: <20150128184748.GA29914@auf.net> Message-ID: <1422471200519-4802287.post@n4.nabble.com> I pkg2 is loaded, too, C should still be present in the System. 1. Fresh Squeak install. 2. Load Pkg1. 3. Load Pkg2. 4. Move C from Pkg1 to Pkg2 by changing its System Category from, e.g., "Pkg1-Core" to "Pkg2-Core". 5. Saving Pkg1 in Monticello recognizes the deletion of class C. This is fine. 6. Saving Pkg2 in Monticello recognizes addition of class C. Also fine. Having a system with old Pkg1 to update with new version, C will be removed. However, if you continue to load/update Pkg2, the class C should be there again. Maybe even stay, if you start loading Pkg2 and then *merging* Pkg1. What exactly did you do? :) Best, Marcel -- View this message in context: http://forum.world.st/moving-a-class-betwen-two-monticello-packages-tp4802285p4802287.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From michal-list at auf.net Wed Jan 28 19:12:00 2015 From: michal-list at auf.net (Michal) Date: Wed Jan 28 19:12:03 2015 Subject: [squeak-dev] Re: moving a class betwen two monticello packages In-Reply-To: <1422471200519-4802287.post@n4.nabble.com> References: <20150128184748.GA29914@auf.net> <1422471200519-4802287.post@n4.nabble.com> Message-ID: <20150128191200.GA30145@auf.net> hi Marcel - Thanks for your answer, and yes, I should have been clearer: > What exactly did you do? :) A version of this: > Having a system with old Pkg1 to update with new version, C will be removed. That is: mv class C from Pkg1 to Pkg2 in a development image, load Pkg1 and then Pkg2 in the server image (this is Seaside related). And yes, depending on the order of loading, C will come back, but it will have lost its state, if any, obviously. So the question stands, I think: What is the best way of moving a class from one mcz package to another, and then load those packages in a different image without ever getting C removed from the image? From cunningham.cb at gmail.com Wed Jan 28 19:21:00 2015 From: cunningham.cb at gmail.com (Chris Cunningham) Date: Wed Jan 28 19:21:03 2015 Subject: [squeak-dev] Re: moving a class betwen two monticello packages In-Reply-To: <20150128191200.GA30145@auf.net> References: <20150128184748.GA29914@auf.net> <1422471200519-4802287.post@n4.nabble.com> <20150128191200.GA30145@auf.net> Message-ID: If you load Pkg2 first, then the code will migrate over to that package (making Pkg1 dirty). Then loading Pkg1 would 'clean' it up. doing this, there should be no loss of the state during loading. Yes, it does require loading them in a specific order. And, yes, if you moved Class C from Pkg1 to Pkg2, and Class D from Pkg2 to Pkg1 in the same commits, you need to figure out how to do simultaeous loading. Or, as I think is more common, don't do this all at once, but rather do them as two steps with specif loading ordering. -cbc On Wed, Jan 28, 2015 at 11:12 AM, Michal wrote: > > hi Marcel - > > Thanks for your answer, and yes, I should have been clearer: > > > What exactly did you do? :) > > A version of this: > > > Having a system with old Pkg1 to update with new version, C will be > removed. > > That is: mv class C from Pkg1 to Pkg2 in a development image, load Pkg1 > and then Pkg2 in the server image (this is Seaside related). > > And yes, depending on the order of loading, C will come back, but it will > have lost its state, if any, obviously. So the question stands, I think: > > What is the best way of moving a class from one mcz package to another, > and then load those packages in a different image without ever getting C > removed from the image? > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150128/45441c9c/attachment.htm From leves at elte.hu Wed Jan 28 19:28:02 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed Jan 28 19:28:06 2015 Subject: [squeak-dev] Re: moving a class betwen two monticello packages In-Reply-To: <20150128191200.GA30145@auf.net> References: <20150128184748.GA29914@auf.net> <1422471200519-4802287.post@n4.nabble.com> <20150128191200.GA30145@auf.net> Message-ID: I guess the new version of Pkg2 depends on the new version of Pkg1. In this case you can create a third package (Pkg3), and move class C to that package. In your server image, load Pkg3 first (this will keep class C in your image), then update Pkg1 and Pkg2, and finally unload Pkg3 (which should be empty by now, because Pkg2 contains the class). Levente On Wed, 28 Jan 2015, Michal wrote: > > hi Marcel - > > Thanks for your answer, and yes, I should have been clearer: > >> What exactly did you do? :) > > A version of this: > >> Having a system with old Pkg1 to update with new version, C will be removed. > > That is: mv class C from Pkg1 to Pkg2 in a development image, load Pkg1 and then Pkg2 in the server image (this is Seaside related). > > And yes, depending on the order of loading, C will come back, but it will have lost its state, if any, obviously. So the question stands, I think: > > What is the best way of moving a class from one mcz package to another, and then load those packages in a different image without ever getting C removed from the image? > > > From commits at source.squeak.org Wed Jan 28 19:42:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed Jan 28 19:42:11 2015 Subject: [squeak-dev] The Inbox: Kernel-ul.894.mcz Message-ID: Levente Uzonyi uploaded a new version of Kernel to project The Inbox: http://source.squeak.org/inbox/Kernel-ul.894.mcz ==================== Summary ==================== Name: Kernel-ul.894 Author: ul Time: 28 January 2015, 8:41:20.772 pm UUID: fedfafb3-de95-42eb-bb32-609455c6b1b9 Ancestors: Kernel-ul.893 Avoid the frequent time checks, and the clock rollover bug in BlockClosure >> #bench. Introduce #bench:, a variant of #bench, which takes the duration of the benchmark as parameter. E.g.: [ 10 factorial ] bench: 0.1 seconds. [ 100 factorial ] bench: 10 seconds. =============== Diff against Kernel-ul.893 =============== Item was changed: ----- Method: BlockClosure>>bench (in category 'evaluating') ----- bench "See how many times I can value in 5 seconds. I'll answer a meaningful description." + ^self bench: 5 seconds! - | startTime endTime count roundTo3Digits | - roundTo3Digits := [:num | - | rounded lowDigit | - rounded := (num * 1000) rounded. "round to 1/1000" - lowDigit := (rounded numberOfDigitsInBase: 10) - 3. "keep only first 3 digits" - rounded := rounded roundTo:(10 raisedTo: lowDigit). - (lowDigit >= 3 or: [rounded \\ 1000 = 0]) "display fractional part only when needed" - ifTrue: [(rounded // 1000) asStringWithCommas] - ifFalse: [(rounded / 1000.0) printString]]. - count := 0. - endTime := Time millisecondClockValue + 5000. - startTime := Time millisecondClockValue. - [ Time millisecondClockValue > endTime ] whileFalse: [ self value. count := count + 1 ]. - endTime := Time millisecondClockValue. - ^count = 1 - ifTrue: [ (roundTo3Digits value: (endTime - startTime) / 1000) , ' seconds.' ] - ifFalse: - [ (roundTo3Digits value: (count * 1000) / (endTime - startTime)) , ' per second.' ]! Item was added: + ----- Method: BlockClosure>>bench: (in category 'evaluating') ----- + bench: aDuration + "See how many times I can value within the given duration. I'll answer a meaningful description." + + | startTime elapsedTime count roundTo3Digits | + roundTo3Digits := [:num | + | rounded lowDigit | + rounded := (num * 1000) rounded. "round to 1/1000" + lowDigit := (rounded numberOfDigitsInBase: 10) - 3. "keep only first 3 digits" + rounded := rounded roundTo:(10 raisedTo: lowDigit). + (lowDigit >= 3 or: [rounded \\ 1000 = 0]) "display fractional part only when needed" + ifTrue: [(rounded // 1000) asStringWithCommas] + ifFalse: [(rounded / 1000.0) printString]]. + count := 0. + [ + startTime := Time millisecondClockValue. + [ + self value. + count := count + 1 ] repeat ] + valueWithin: aDuration + onTimeout: [ elapsedTime := Time millisecondsSince: startTime ]. + ^count = 1 + ifTrue: [ (roundTo3Digits value: elapsedTime / 1000) , ' seconds.' ] + ifFalse: + [ (roundTo3Digits value: (count * 1000) / elapsedTime) , ' per second.' ]! From eliot.miranda at gmail.com Wed Jan 28 19:47:29 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed Jan 28 19:47:36 2015 Subject: [squeak-dev] Re: moving a class betwen two monticello packages In-Reply-To: References: <20150128184748.GA29914@auf.net> <1422471200519-4802287.post@n4.nabble.com> <20150128191200.GA30145@auf.net> Message-ID: <4FA5D4CB-8C0E-48D9-A9BE-4B30ACB113B1@gmail.com> On Jan 28, 2015, at 11:21 AM, Chris Cunningham wrote: > If you load Pkg2 first, then the code will migrate over to that package (making Pkg1 dirty). Then loading Pkg1 would 'clean' it up. doing this, there should be no loss of the state during loading. > Yes, it does require loading them in a specific order. > And, yes, if you moved Class C from Pkg1 to Pkg2, and Class D from Pkg2 to Pkg1 in the same commits, you need to figure out how to do simultaeous loading. Or, as I think is more common, don't do this all at once, but rather do them as two steps with specif loading ordering. Right. And the way to manage that order dependency is with a configuration. You commit the version of pkg2 with the class moved into it from pkg1. You create and commit a configuration for that state (new pkg2, old pkg1). Then you commit the new pkg2 with the class missing. The configuration ensures that the new pkg2 is loaded b4 the new pkg1, and hence that the class is not lost. Search the list for info in Monticello configs. There's a menu pick to open the MCConfigurationBrowser which will help. > > -cbc > > On Wed, Jan 28, 2015 at 11:12 AM, Michal wrote: >> >> hi Marcel - >> >> Thanks for your answer, and yes, I should have been clearer: >> >> > What exactly did you do? :) >> >> A version of this: >> >> > Having a system with old Pkg1 to update with new version, C will be removed. >> >> That is: mv class C from Pkg1 to Pkg2 in a development image, load Pkg1 and then Pkg2 in the server image (this is Seaside related). >> >> And yes, depending on the order of loading, C will come back, but it will have lost its state, if any, obviously. So the question stands, I think: >> >> What is the best way of moving a class from one mcz package to another, and then load those packages in a different image without ever getting C removed from the image? > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150128/f367ffcd/attachment-0001.htm From bert at freudenbergs.de Wed Jan 28 19:54:49 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Wed Jan 28 19:54:53 2015 Subject: [squeak-dev] Re: moving a class betwen two monticello packages In-Reply-To: <4FA5D4CB-8C0E-48D9-A9BE-4B30ACB113B1@gmail.com> References: <20150128184748.GA29914@auf.net> <1422471200519-4802287.post@n4.nabble.com> <20150128191200.GA30145@auf.net> <4FA5D4CB-8C0E-48D9-A9BE-4B30ACB113B1@gmail.com> Message-ID: <4DD5C593-C201-4AB2-BD35-E0ED05DCC938@freudenbergs.de> Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150128/ee9149f4/smime.bin From bert at freudenbergs.de Wed Jan 28 19:56:16 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Wed Jan 28 19:56:20 2015 Subject: [squeak-dev] Re: The Inbox: System-mt.697.mcz In-Reply-To: <06E9216B-DA34-465E-B187-B83FB8E9E65C@gmail.com> References: <2023B7F8-5B48-4CCB-ABC3-0DD57F06533A@freudenbergs.de> <1422460196992-4802221.post@n4.nabble.com> <06E9216B-DA34-465E-B187-B83FB8E9E65C@gmail.com> Message-ID: <36A2B069-F476-4754-8533-20904ABA4687@freudenbergs.de> On 28.01.2015, at 17:36, Eliot Miranda wrote: > > Hi Marcel, > > On Jan 28, 2015, at 7:49 AM, Marcel Taeumel wrote: > >> If we keep record of MethodContext >> #isExecutingBlock in MessageTally >> >> #tallyPath:by: (resp. #tallyPath:in:by:) we could change the printing to >> prepend "[] in" again. :) > > Look at my fix in AndreasSystemProfiler. I introduced a blockNesting count. This allows printing block nesting that I chose to write as > [] in UndefinedObject doit > Collection foo > [[]] in UndefinedObject doit > etc Ah, neat. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150128/0ec60713/smime.bin From eliot.miranda at gmail.com Wed Jan 28 20:11:41 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed Jan 28 20:11:44 2015 Subject: [squeak-dev] Re: moving a class betwen two monticello packages In-Reply-To: <4DD5C593-C201-4AB2-BD35-E0ED05DCC938@freudenbergs.de> References: <20150128184748.GA29914@auf.net> <1422471200519-4802287.post@n4.nabble.com> <20150128191200.GA30145@auf.net> <4FA5D4CB-8C0E-48D9-A9BE-4B30ACB113B1@gmail.com> <4DD5C593-C201-4AB2-BD35-E0ED05DCC938@freudenbergs.de> Message-ID: <25A63777-5C5F-477E-8FA4-04AC5C6E82A0@gmail.com> Hi Bert, On Jan 28, 2015, at 11:54 AM, Bert Freudenberg wrote: > On 28.01.2015, at 20:47, Eliot Miranda wrote: >> >> On Jan 28, 2015, at 11:21 AM, Chris Cunningham wrote: >> >>> If you load Pkg2 first, then the code will migrate over to that package (making Pkg1 dirty). Then loading Pkg1 would 'clean' it up. doing this, there should be no loss of the state during loading. >>> Yes, it does require loading them in a specific order. >>> And, yes, if you moved Class C from Pkg1 to Pkg2, and Class D from Pkg2 to Pkg1 in the same commits, you need to figure out how to do simultaeous loading. Or, as I think is more common, don't do this all at once, but rather do them as two steps with specif loading ordering. >> >> >> Right. And the way to manage that order dependency is with a configuration. You commit the version of pkg2 with the class moved into it from pkg1. You create and commit a configuration for that state (new pkg2, old pkg1). Then you commit the new pkg2 with the class missing. >> >> The configuration ensures that the new pkg2 is loaded b4 the new pkg1, and hence that the class is not lost. >> >> Search the list for info in Monticello configs. There's a menu pick to open the MCConfigurationBrowser which will help. > > > +1 on MCConfigs. > > And didn?t we make them correctly handle moves between packages last year? I think you just need a single config with new versions of both Pkg1 and Pkg2. D'u remember how that works? I'm curious. > - Bert - Eliot (phone) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150128/07dab6d3/attachment.htm From bert at freudenbergs.de Wed Jan 28 20:18:19 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Wed Jan 28 20:18:23 2015 Subject: [squeak-dev] Re: moving a class betwen two monticello packages In-Reply-To: <25A63777-5C5F-477E-8FA4-04AC5C6E82A0@gmail.com> References: <20150128184748.GA29914@auf.net> <1422471200519-4802287.post@n4.nabble.com> <20150128191200.GA30145@auf.net> <4FA5D4CB-8C0E-48D9-A9BE-4B30ACB113B1@gmail.com> <4DD5C593-C201-4AB2-BD35-E0ED05DCC938@freudenbergs.de> <25A63777-5C5F-477E-8FA4-04AC5C6E82A0@gmail.com> Message-ID: <5766E091-A73A-4856-A4A5-DD9C1B0DB6A9@freudenbergs.de> Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150128/f6071b5b/smime.bin From michal-list at auf.net Thu Jan 29 00:20:59 2015 From: michal-list at auf.net (Michal) Date: Thu Jan 29 00:21:03 2015 Subject: [squeak-dev] Re: moving a class betwen two monticello packages In-Reply-To: <4FA5D4CB-8C0E-48D9-A9BE-4B30ACB113B1@gmail.com> References: <20150128184748.GA29914@auf.net> <1422471200519-4802287.post@n4.nabble.com> <20150128191200.GA30145@auf.net> <4FA5D4CB-8C0E-48D9-A9BE-4B30ACB113B1@gmail.com> Message-ID: <20150129002059.GA32129@auf.net> >> Yes, it does require loading them in a specific order. > Right. And the way to manage that order dependency is with a configuration. Ok, that clear things up. Thanks to all of you, this whole thread was very helpful! From commits at source.squeak.org Thu Jan 29 00:23:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 29 00:23:25 2015 Subject: [squeak-dev] The Trunk: System-eem.698.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-eem.698.mcz ==================== Summary ==================== Name: System-eem.698 Author: eem Time: 28 January 2015, 4:23:02.59 pm UUID: 4313b773-c100-4366-b164-2ee69f4f3c26 Ancestors: System-mt.697 Provide an obsolete method for ObjectHistory that kills the current ObjectHistory's mark process if the class is removed. This allows Spur to easily remove ObjectHistory, which it does not support. =============== Diff against System-mt.697 =============== Item was added: + ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- + obsolete + "Kill the mark process before removing the class." + Current ifNotNil: + [:objectHistory| + objectHistory terminate]! Item was added: + ----- Method: ObjectHistory>>terminate (in category 'private') ----- + terminate + markProcess ifNotNil: + [markProcess terminate]! From commits at source.squeak.org Thu Jan 29 00:50:15 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 29 00:50:16 2015 Subject: [squeak-dev] The Trunk: System-eem.699.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-eem.699.mcz ==================== Summary ==================== Name: System-eem.699 Author: eem Time: 28 January 2015, 4:49:52.494 pm UUID: 7aa9dbe2-e1cf-4547-bee4-c122268381d9 Ancestors: System-eem.698 Add block nesting to MessageTally. c.f. AndreasProfiler-eem.10 =============== Diff against System-eem.698 =============== Item was changed: Magnitude subclass: #MessageTally + instanceVariableNames: 'class method blockNesting process tally receivers senders time gcStats maxClassNameSize maxClassPlusSelectorSize maxTabs reportOtherProcesses time0 startTime endTime preHibernationCopy' - instanceVariableNames: 'class method process tally receivers senders time gcStats maxClassNameSize maxClassPlusSelectorSize maxTabs reportOtherProcesses time0 startTime endTime preHibernationCopy' classVariableNames: 'DefaultPollPeriod ShowProcesses Timer' poolDictionaries: '' category: 'System-Tools'! !MessageTally commentStamp: 'eem 7/16/2012 17:10' prior: 0! My instances observe and report the amount of time spent in methods. NOTE: a higher-level user interface (combining the MessageTally result tree with a method browser) is available from TimeProfileBrowser. Note that TimeProfileBrowser was not fancy with the different setting possibilities. TimeProfileBrowser spyOn: [20 timesRepeat: [Transcript show: 100 factorial printString]] Strategies ----------- MessageTally provides two different strategies available for profiling: * spyOn: and friends use a high-priority Process to interrupt the block or process being spied on at periodic intervals. The interrupted call stack is then examined for caller information. See below for an example showing different settings * tallySends: and friends use the interpreter simulator to run the block, recording every method call. The two give you different results: * spyOn: gives you a view of where the time is being spent in your program, at least on a rough statistical level (assuming you've run the block for long enough and have a high enough poll rate). If you're trying to optimize your code, start here and optimize the methods where most of the time is being spent first. * tallySends: gives you accurate counts of how many times methods get called, and by exactly which route. If you're debugging, or trying to figure out if a given method is getting called too many times, this is your tool. Q: How do you interpret MessageTally>>tallySends A: The methods #tallySends and #spyOn: measure two very different quantities, but broken down in the same who-called-who format. #spyOn: is approximate, but more indicative of real time spent, whereas #tallySends is exact and a precise record of how many times each method got executed. Examples ---------- Here you can see all the processes computation time [1000 timesRepeat: [3.14159 printString. Processor yield]] fork. [1000 timesRepeat: [30 factorial. Processor yield]] fork. [1000 timesRepeat: [30 factorial. Processor yield]] fork. MessageTally spyAllOn: [ (Delay forMilliseconds: 100) wait] This profiles across a snapshot, writing the output to {imageName}.N.profile | fn | fn := (FileDirectory baseNameFor: Smalltalk image imageName), '.profile'. [MessageTally spyOn: [Smalltalk image snapshot: true andQuit: true] toFileNamed: fn reportOtherProcesses: true] on: FileExistsException do: [:ex| ex resume: (FileStream forceNewFileNamed: (FileDirectory default nextNameFor: (FileDirectory localNameFor: (FileDirectory baseNameFor: fn)) extension: 'profile'))] Settings --------- You can change the printing format (that is, the whitespace and string compression) by using these instance methods: maxClassNameSize: maxClassPlusSelectorSize: maxTabs: You can change the default polling period (initially set to 1) by calling MessageTally defaultPollPeriod: numberOfMilliseconds To understand the difference ---------------------------------- Here we see all the processes [1000 timesRepeat: [ 100 timesRepeat: [120 factorial]. (Delay forMilliseconds: 10) wait ]] forkAt: 45 named: '45'. MessageTally spyAllOn: [10000 timesRepeat: [1.23 printString]] Here we only see the execution of the expression [10000 timesRepeat: [1.23 printString] [1000 timesRepeat: [ 100 timesRepeat: [120 factorial]. (Delay forMilliseconds: 10) wait ]] forkAt: 45 named: '45'. MessageTally spyOn: [10000 timesRepeat: [1.23 printString]] Here we only check the exact message sends: this is not a pc-sampling approach [1000 timesRepeat: [ 100 timesRepeat: [120 factorial]. (Delay forMilliseconds: 10) wait ]] forkAt: 45 named: '45'. MessageTally tallySends: [10000 timesRepeat: [1.23 printString]] ! Item was added: + ----- Method: MessageTally>>blockNesting (in category 'accessing') ----- + blockNesting + ^blockNesting! Item was added: + ----- Method: MessageTally>>blockNestingCountOf: (in category 'tallying') ----- + blockNestingCountOf: context + | count nest | + count := 0. + nest := context. + [nest closure notNil] whileTrue: + [count := count + 1. + nest := nest closure outerContext]. + ^count! Item was changed: ----- Method: MessageTally>>class:method: (in category 'private') ----- class: aClass method: aMethod class := aClass. method := aMethod. + tally := blockNesting := 0. + receivers := {}! - tally := 0. - receivers := Array new: 0! Item was added: + ----- Method: MessageTally>>class:method:nesting: (in category 'private') ----- + class: aClass method: aMethod nesting: blockNestingCount + + class := aClass. + method := aMethod. + blockNesting := blockNestingCount. + tally := 0. + receivers := {}! Item was changed: ----- Method: MessageTally>>copyWithTally: (in category 'private') ----- copyWithTally: hitCount + ^ (MessageTally new class: class method: method nesting: blockNesting) - ^ (MessageTally new class: class method: method) reportOtherProcesses: reportOtherProcesses; process: process; bump: hitCount! Item was changed: ----- Method: MessageTally>>into:fromSender: (in category 'collecting leaves') ----- into: leafDict fromSender: senderTally | leafNode | + leafNode := leafDict + at: method + ifAbsentPut: + [(self class new class: class method: method nesting: blockNesting) + process: process; + reportOtherProcesses: reportOtherProcesses]. - leafNode := leafDict at: method - ifAbsentPut: [(self class new class: class method: method) - process: process; - reportOtherProcesses: reportOtherProcesses]. leafNode bump: tally fromSender: senderTally! Item was changed: ----- Method: MessageTally>>printOn: (in category 'printing') ----- printOn: aStream | className | (class isNil or: [method isNil]) ifTrue: [^super printOn: aStream]. className := method methodClass name contractTo: self maxClassNameSize. + blockNesting ifNotNil: + [blockNesting timesRepeat: + [aStream nextPutAll: '[] in ']]. aStream nextPutAll: className; nextPutAll: ' >> '; nextPutAll: (method selector contractTo: self maxClassPlusSelectorSize - className size)! Item was changed: ----- Method: MessageTally>>printOn:total:totalTime:tallyExact: (in category 'printing') ----- printOn: aStream total: total totalTime: totalTime tallyExact: isExact | aSelector className myTally aClass percentage | isExact ifTrue: [myTally := tally. receivers == nil ifFalse: [receivers do: [:r | myTally := myTally - r tally]]. aStream print: myTally; space] ifFalse: [percentage := tally asFloat / total * 100.0. aStream nextPutAll: (percentage printShowingDecimalPlaces: 1); nextPutAll: '% {'; print: (percentage * totalTime / 100) rounded; nextPutAll: 'ms} ']. receivers == nil ifTrue: [aStream nextPutAll: 'primitives'; cr] ifFalse: [aSelector := method selector. aClass := method methodClass. className := aClass name contractTo: self maxClassNameSize. + blockNesting > 0 ifTrue: + [aStream + next: blockNesting put: $[; + next: blockNesting put: $]; + space]. aStream nextPutAll: class name; nextPutAll: (aClass = class ifTrue: ['>>'] ifFalse: ['(' , aClass name , ')>>']); nextPutAll: (aSelector contractTo: self maxClassPlusSelectorSize - className size); cr]! Item was changed: ----- Method: MessageTally>>sonsOver: (in category 'comparing') ----- sonsOver: threshold | hereTally last sons | + receivers basicSize = 0 ifTrue: [^#()]. - (receivers == nil or: [receivers size = 0]) ifTrue: [^#()]. hereTally := tally. sons := receivers select: "subtract subNode tallies for primitive hits here" [:son | hereTally := hereTally - son tally. son tally > threshold]. + hereTally > threshold ifTrue: + [last := MessageTally new class: class method: method nesting: blockNesting. + last process: process. + last reportOtherProcesses: reportOtherProcesses. + ^sons copyWith: (last primitives: hereTally)]. - hereTally > threshold - ifTrue: [ - last := MessageTally new class: class method: method. - last process: process. - last reportOtherProcesses: reportOtherProcesses. - ^sons copyWith: (last primitives: hereTally)]. ^sons! Item was changed: ----- Method: MessageTally>>tally:in:by: (in category 'tallying') ----- tally: context in: aProcess by: count "Explicitly tally the specified context and its stack." + | sender nesting | + nesting := self blockNestingCountOf: context. - | sender | "Add to this node if appropriate" + (context method == method + and: [blockNesting = nesting]) ifTrue: + [^self bumpBy: count]. - context method == method ifTrue: [^self bumpBy: count]. "No sender? Add new branch to the tree." + (sender := context sender) ifNil: + [^(self bumpBy: count) tallyPath: context in: aProcess by: count]. - (sender := context sender) ifNil: [ - ^ (self bumpBy: count) tallyPath: context in: aProcess by: count]. "Find the node for the sending context (or add it if necessary)" ^ (self tally: sender in: aProcess by: count) tallyPath: context in: aProcess by: count! Item was changed: ----- Method: MessageTally>>tallyPath:by: (in category 'tallying') ----- tallyPath: context by: count + | aMethod nesting path | - | aMethod path | aMethod := context method. + nesting := self blockNestingCountOf: context. + - "Find the correct child (if there)" + path := receivers + detect: [:oldTally | + oldTally method == aMethod + and: [oldTally blockNesting = nesting]] + ifNone: []. - receivers do: [ :oldTally | - oldTally method == aMethod ifTrue: [path := oldTally]]. "Add new child if needed" + path ifNil: + [path := MessageTally new class: context receiver class method: aMethod nesting: nesting. - path ifNil: [ - path := MessageTally new class: context receiver class method: aMethod. path reportOtherProcesses: reportOtherProcesses. receivers := receivers copyWith: path]. ^ path bumpBy: count! Item was changed: ----- Method: MessageTally>>tallyPath:in:by: (in category 'tallying') ----- tallyPath: context in: aProcess by: count + | aMethod nesting path | - | aMethod path | aMethod := context method. + nesting := self blockNestingCountOf: context. + - "Find the correct child (if there)" + path := receivers + detect: [:oldTally | + oldTally method == aMethod + and: [oldTally process == aProcess + and: [oldTally blockNesting = nesting]]] + ifNone: []. + - receivers do: [ :oldTally | - (oldTally method == aMethod and: [oldTally process == aProcess]) - ifTrue: [path := oldTally]]. - "Add new child if needed" + path ifNil: + [path := MessageTally new + class: context receiver class method: aMethod nesting: nesting; + process: aProcess; + reportOtherProcesses: reportOtherProcesses; + maxClassNameSize: maxClassNameSize; + maxClassPlusSelectorSize: maxClassPlusSelectorSize; + maxTabs: maxTabs. - path ifNil:[ - path := MessageTally new class: context receiver class method: aMethod; - process: aProcess; - reportOtherProcesses: reportOtherProcesses; - maxClassNameSize: maxClassNameSize; - maxClassPlusSelectorSize: maxClassPlusSelectorSize; - maxTabs: maxTabs. receivers := receivers copyWith: path]. + ^path bumpBy: count! - ^ path bumpBy: count! From asqueaker at gmail.com Thu Jan 29 02:12:41 2015 From: asqueaker at gmail.com (Chris Muller) Date: Thu Jan 29 02:12:44 2015 Subject: [squeak-dev] The Inbox: Kernel-ul.894.mcz In-Reply-To: <54c93b96.89158c0a.6d9a.17b2SMTPIN_ADDED_MISSING@mx.google.com> References: <54c93b96.89158c0a.6d9a.17b2SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Thanks, #bench could really use some more improvements too. I feel comfortable to criticize bench because I wrote it. The other day I used it and it said, "7.124 seconds" which made me pause to consider how the output is totally inverted when it is over 5 seconds. One can't simply glance at "the number," you have to read and interpret the whole thing. If "per second" then higher numbers are better. If "seconds" then lower numbers are better. In seems inelegant, at least, but haven't thought of something better that can still meet the "requirements" we want bench to meet (sufficient samples, short run-time, easy output). Another thing. When I see "1.5 million per second", I find myself asking, "is that fast?" With all of these different VM's and speeds, I feel like I want the output to be augmented with some kind of "relative" % measurement to the maximum speed; i.e., divide by the speed of [] bench but then Bert the other day pointed out how this is not useful for really fast things because it ends up being slowed down by the #value primitive (or something) so there is yet another shortcoming of bench. And yet, one more is that we don't have a useful Magnitudinal output for interpretation by scripts, except by parsing the string.. On Wed, Jan 28, 2015 at 1:42 PM, wrote: > Levente Uzonyi uploaded a new version of Kernel to project The Inbox: > http://source.squeak.org/inbox/Kernel-ul.894.mcz > > ==================== Summary ==================== > > Name: Kernel-ul.894 > Author: ul > Time: 28 January 2015, 8:41:20.772 pm > UUID: fedfafb3-de95-42eb-bb32-609455c6b1b9 > Ancestors: Kernel-ul.893 > > Avoid the frequent time checks, and the clock rollover bug in BlockClosure >> #bench. > Introduce #bench:, a variant of #bench, which takes the duration of the benchmark as parameter. E.g.: > > [ 10 factorial ] bench: 0.1 seconds. > [ 100 factorial ] bench: 10 seconds. > > =============== Diff against Kernel-ul.893 =============== > > Item was changed: > ----- Method: BlockClosure>>bench (in category 'evaluating') ----- > bench > "See how many times I can value in 5 seconds. I'll answer a meaningful description." > > + ^self bench: 5 seconds! > - | startTime endTime count roundTo3Digits | > - roundTo3Digits := [:num | > - | rounded lowDigit | > - rounded := (num * 1000) rounded. "round to 1/1000" > - lowDigit := (rounded numberOfDigitsInBase: 10) - 3. "keep only first 3 digits" > - rounded := rounded roundTo:(10 raisedTo: lowDigit). > - (lowDigit >= 3 or: [rounded \\ 1000 = 0]) "display fractional part only when needed" > - ifTrue: [(rounded // 1000) asStringWithCommas] > - ifFalse: [(rounded / 1000.0) printString]]. > - count := 0. > - endTime := Time millisecondClockValue + 5000. > - startTime := Time millisecondClockValue. > - [ Time millisecondClockValue > endTime ] whileFalse: [ self value. count := count + 1 ]. > - endTime := Time millisecondClockValue. > - ^count = 1 > - ifTrue: [ (roundTo3Digits value: (endTime - startTime) / 1000) , ' seconds.' ] > - ifFalse: > - [ (roundTo3Digits value: (count * 1000) / (endTime - startTime)) , ' per second.' ]! > > Item was added: > + ----- Method: BlockClosure>>bench: (in category 'evaluating') ----- > + bench: aDuration > + "See how many times I can value within the given duration. I'll answer a meaningful description." > + > + | startTime elapsedTime count roundTo3Digits | > + roundTo3Digits := [:num | > + | rounded lowDigit | > + rounded := (num * 1000) rounded. "round to 1/1000" > + lowDigit := (rounded numberOfDigitsInBase: 10) - 3. "keep only first 3 digits" > + rounded := rounded roundTo:(10 raisedTo: lowDigit). > + (lowDigit >= 3 or: [rounded \\ 1000 = 0]) "display fractional part only when needed" > + ifTrue: [(rounded // 1000) asStringWithCommas] > + ifFalse: [(rounded / 1000.0) printString]]. > + count := 0. > + [ > + startTime := Time millisecondClockValue. > + [ > + self value. > + count := count + 1 ] repeat ] > + valueWithin: aDuration > + onTimeout: [ elapsedTime := Time millisecondsSince: startTime ]. > + ^count = 1 > + ifTrue: [ (roundTo3Digits value: elapsedTime / 1000) , ' seconds.' ] > + ifFalse: > + [ (roundTo3Digits value: (count * 1000) / elapsedTime) , ' per second.' ]! > > From marcel.taeumel at student.hpi.uni-potsdam.de Thu Jan 29 08:50:04 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Thu Jan 29 08:54:26 2015 Subject: [squeak-dev] Process-specific state difficult to debug... Message-ID: <1422521404841-4802422.post@n4.nabble.com> Hi! There are process-specific variables. However, #doStep in Debugger does #completeStep: on the process object and Processor >> #activeProcess will be wrong during that execution. Is this a general problem of global state or could we fix that somehow? Best, Marcel -- View this message in context: http://forum.world.st/Process-specific-state-difficult-to-debug-tp4802422.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Das.Linux at gmx.de Thu Jan 29 09:06:55 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu Jan 29 09:06:58 2015 Subject: [squeak-dev] Process-specific state difficult to debug... In-Reply-To: <1422521404841-4802422.post@n4.nabble.com> References: <1422521404841-4802422.post@n4.nabble.com> Message-ID: Hi On 29.01.2015, at 09:50, Marcel Taeumel wrote: > Hi! > > There are process-specific variables. However, #doStep in Debugger does > #completeStep: on the process object and Processor >> #activeProcess will be > wrong during that execution. > > Is this a general problem of global state or could we fix that somehow? The same problem exists for DynamicVariables that are not implemented with process-specific variables but with Notifications. Just want to throw that in :) Best -Tobias From Das.Linux at gmx.de Thu Jan 29 10:29:25 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu Jan 29 10:29:29 2015 Subject: [squeak-dev] Process-specific state difficult to debug... In-Reply-To: References: <1422521404841-4802422.post@n4.nabble.com> Message-ID: On 29.01.2015, at 10:06, Tobias Pape wrote: > Hi > > On 29.01.2015, at 09:50, Marcel Taeumel wrote: > >> Hi! >> >> There are process-specific variables. However, #doStep in Debugger does >> #completeStep: on the process object and Processor >> #activeProcess will be >> wrong during that execution. >> >> Is this a general problem of global state or could we fix that somehow? > > The same problem exists for DynamicVariables that are not implemented with > process-specific variables but with Notifications. Just want to throw that > in :) To clarify, for example WADynamicVariable from Seaside. Best -Tobias From btc at openInWorld.com Thu Jan 29 15:57:41 2015 From: btc at openInWorld.com (Ben Coman) Date: Thu Jan 29 15:57:44 2015 Subject: [squeak-dev] Process-specific state difficult to debug... In-Reply-To: <1422521404841-4802422.post@n4.nabble.com> References: <1422521404841-4802422.post@n4.nabble.com> Message-ID: I don't know much about it, but I've been poking around there recently in Pharo, so maybe I can l learn something more looking at this. Can you be specific about the specific variable you are referring to? And can you report a short script for others to test against to get to the point of your question? cheers - On Thu, Jan 29, 2015 at 4:50 PM, Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > Hi! > > There are process-specific variables. However, #doStep in Debugger does > #completeStep: on the process object and Processor >> #activeProcess will > be > wrong during that execution. > > Is this a general problem of global state or could we fix that somehow? > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/Process-specific-state-difficult-to-debug-tp4802422.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150129/8bd4a699/attachment.htm From frank.shearar at gmail.com Thu Jan 29 16:22:59 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Thu Jan 29 16:23:02 2015 Subject: [squeak-dev] Process-specific state difficult to debug... In-Reply-To: References: <1422521404841-4802422.post@n4.nabble.com> Message-ID: On 29 January 2015 at 09:06, Tobias Pape wrote: > Hi > > On 29.01.2015, at 09:50, Marcel Taeumel wrote: > >> Hi! >> >> There are process-specific variables. However, #doStep in Debugger does >> #completeStep: on the process object and Processor >> #activeProcess will be >> wrong during that execution. >> >> Is this a general problem of global state or could we fix that somehow? > > The same problem exists for DynamicVariables that are not implemented with > process-specific variables but with Notifications. Just want to throw that > in :) Yes: debugging with dynamic variables is Hard(tm), regardless of whether nice (delimited, through Notifications) or nasty (undelimited, through ProcessSpecificVariable), because you typically want the value of the variable in the context in which the code under debug is running, but asking it "what is your value?" returns the value of the variable in the context of the debugger. Which I guess is the answer: the debugger needs to recognise you're working with a dynamic variable, and it must perform that current-value-lookup in the correct context (that of the process you're debugging). frank > Best > -Tobias From frank.shearar at gmail.com Thu Jan 29 16:24:14 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Thu Jan 29 16:24:17 2015 Subject: [squeak-dev] Process-specific state difficult to debug... In-Reply-To: References: <1422521404841-4802422.post@n4.nabble.com> Message-ID: On 29 January 2015 at 16:22, Frank Shearar wrote: > On 29 January 2015 at 09:06, Tobias Pape wrote: >> Hi >> >> On 29.01.2015, at 09:50, Marcel Taeumel wrote: >> >>> Hi! >>> >>> There are process-specific variables. However, #doStep in Debugger does >>> #completeStep: on the process object and Processor >> #activeProcess will be >>> wrong during that execution. >>> >>> Is this a general problem of global state or could we fix that somehow? >> >> The same problem exists for DynamicVariables that are not implemented with >> process-specific variables but with Notifications. Just want to throw that >> in :) > > Yes: debugging with dynamic variables is Hard(tm), regardless of > whether nice (delimited, through Notifications) or nasty (undelimited, > through ProcessSpecificVariable), because you typically want the value > of the variable in the context in which the code under debug is > running, but asking it "what is your value?" returns the value of the > variable in the context of the debugger. > > Which I guess is the answer: the debugger needs to recognise you're > working with a dynamic variable, and it must perform that > current-value-lookup in the correct context (that of the process > you're debugging). Oh, I should add: I usually pin the (current) value of the dynamic variable down by assigning its value to a local variable. It's invasive, but it does work. frank > >> Best >> -Tobias From eliot.miranda at gmail.com Thu Jan 29 17:09:30 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu Jan 29 17:09:33 2015 Subject: [squeak-dev] Process-specific state difficult to debug... In-Reply-To: <1422521404841-4802422.post@n4.nabble.com> References: <1422521404841-4802422.post@n4.nabble.com> Message-ID: Hi Marcel, can you give a specific example? Andreas and I came up with a solution for accessing Processor activeProcess correctly in the debugger. It works like this: ProcessorScheduler>>activeProcess ^activeProcess effectiveProcess Process>>effectiveProcess "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self] Process>>evaluate: aBlock onBehalfOf: aProcess "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess] and then in activateReturn:value: complete: popTo: popTo:value: return:value: step step: stepToCallee stepToSendOrReturn it is used as in Process>>step ^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self Perhaps all that is needed is the access of process-specific variables to use effectiveProcess? On Thu, Jan 29, 2015 at 12:50 AM, Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > Hi! > > There are process-specific variables. However, #doStep in Debugger does > #completeStep: on the process object and Processor >> #activeProcess will > be > wrong during that execution. > > Is this a general problem of global state or could we fix that somehow? > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/Process-specific-state-difficult-to-debug-tp4802422.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150129/5df5f7ba/attachment-0001.htm From Lou at Keystone-Software.com Thu Jan 29 18:28:40 2015 From: Lou at Keystone-Software.com (Louis LaBrunda) Date: Thu Jan 29 18:28:58 2015 Subject: [squeak-dev] How to talk to a modem via a com port Message-ID: Hi All, Does anyone have some sample code to talk to a telephone modem through a com port? It is a USB modem that shows up on COM3. I want to play with getting the caller Id info. Any help is appreciated, so thanks in advance. Lou ----------------------------------------------------------- Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon mailto:Lou@Keystone-Software.com http://www.Keystone-Software.com From leves at elte.hu Thu Jan 29 18:29:06 2015 From: leves at elte.hu (Levente Uzonyi) Date: Thu Jan 29 18:29:11 2015 Subject: [squeak-dev] Process-specific state difficult to debug... In-Reply-To: References: <1422521404841-4802422.post@n4.nabble.com> Message-ID: That would help, but it seems like the effectiveProcess variable is not set correctly. At least I don't see it being set while debugging the following: | ep | ep := Processor activeProcess instVarNamed: #effectiveProcess. self haltIf: ep isNil Levente On Thu, 29 Jan 2015, Eliot Miranda wrote: > Hi Marcel, > ? ? can you give a specific example?? Andreas and I came up with a solution for accessing Processor activeProcess correctly in the debugger.? It works like this: > > ProcessorScheduler>>activeProcess > ? ? ^activeProcess effectiveProcess > > Process>>effectiveProcess > "effectiveProcess is a mechanism to allow process-faithful debugging.? The debugger executes code > on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not > correctly maintained when debugging code.? The debugger uses evaluate:onBehalfOf: to assign the > debugged process as the effectiveProcess of the process executing the code, preserving process > identity." > ^effectiveProcess ifNil: [self] > > Process>>evaluate: aBlock onBehalfOf: aProcess > "Evaluate aBlock setting effectiveProcess to aProcess.? Used > in the execution simulation machinery to ensure that > Processor activeProcess evaluates correctly when debugging." > | oldEffectiveProcess | > oldEffectiveProcess := effectiveProcess. > effectiveProcess := aProcess. > ^aBlock ensure: [effectiveProcess := oldEffectiveProcess] > > and then in activateReturn:value: complete: popTo: popTo:value: return:value: step step: stepToCallee stepToSendOrReturn it is used as in > > Process>>step > > ^Processor activeProcess > evaluate: [suspendedContext := suspendedContext step] > onBehalfOf: self > > Perhaps all that is needed is the access of process-specific variables to use effectiveProcess? > > On Thu, Jan 29, 2015 at 12:50 AM, Marcel Taeumel wrote: > Hi! > > There are process-specific variables. However, #doStep in Debugger does > #completeStep: on the process object and Processor >> #activeProcess will be > wrong during that execution. > > Is this a general problem of global state or could we fix that somehow? > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/Process-specific-state-difficult-to-debug-tp4802422.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > > > > -- > best,Eliot > > From commits at source.squeak.org Thu Jan 29 18:55:08 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 29 18:55:08 2015 Subject: [squeak-dev] The Trunk: Kernel-eem.894.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-eem.894.mcz ==================== Summary ==================== Name: Kernel-eem.894 Author: eem Time: 29 January 2015, 10:54:41.65 am UUID: 4c8074eb-6db4-4d9b-bbfe-cd8f7197b999 Ancestors: Kernel-ul.893 Access a process's environment from effectiveProcess to provide correct environment access when debugging. =============== Diff against Kernel-ul.893 =============== Item was added: + ----- Method: Process>>effectiveEnvironment (in category 'private') ----- + effectiveEnvironment + "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code + on behalf of processes, so unless some effort is made, the identity of Processor activeProcess is not + correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the + debugged process as the effectiveProcess of the process executing the code, preserving process + identity. By using the effectiveProcess's environment, access in the debugger is correct." + ^effectiveProcess + ifNil: [env] + ifNotNil: + [:theEffectiveProcess| + theEffectiveProcess effectiveEnvironment]! Item was changed: ----- Method: Process>>effectiveProcess (in category 'accessing') ----- effectiveProcess "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code + on behalf of processes, so unless some effort is made, the identity of Processor activeProcess is not - on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]! Item was changed: ----- Method: Process>>environmentAt:ifAbsent: (in category 'process specific') ----- environmentAt: key ifAbsent: aBlock + ^(self effectiveEnvironment ifNil: [ ^aBlock value ]) at: key ifAbsent: aBlock.! - ^(env ifNil: [ ^aBlock value ]) at: key ifAbsent: aBlock.! Item was changed: ----- Method: Process>>environmentAt:ifAbsentPut: (in category 'process specific') ----- environmentAt: key ifAbsentPut: aBlock + ^self setEffectiveEnvironment at: key ifAbsentPut: aBlock! - ^(env ifNil: [ env := Dictionary new ]) at: key ifAbsentPut: aBlock.! Item was changed: ----- Method: Process>>environmentAt:put: (in category 'process specific') ----- environmentAt: key put: value + ^self setEffectiveEnvironment at: key put: value! - ^(env ifNil: [ env := Dictionary new ]) at: key put: value.! Item was changed: ----- Method: Process>>environmentRemoveKey:ifAbsent: (in category 'process specific') ----- environmentRemoveKey: key ifAbsent: errorBlock + ^(self effectiveEnvironment ifNil: [^errorBlock value]) + removeKey: key + ifAbsent: errorBlock! - ^(env ifNil: [ ^errorBlock value ]) removeKey: key ifAbsent: errorBlock! Item was added: + ----- Method: Process>>setEffectiveEnvironment (in category 'private') ----- + setEffectiveEnvironment + "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code + on behalf of processes, so unless some effort is made, the identity of Processor activeProcess is not + correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the + debugged process as the effectiveProcess of the process executing the code, preserving process + identity. By using the effectiveProcess's environment, access in the debugger is correct." + ^effectiveProcess + ifNil: [env ifNil: [env := Dictionary new]] + ifNotNil: + [:theEffectiveProcess| + theEffectiveProcess setEffectiveEnvironment]! From commits at source.squeak.org Thu Jan 29 19:38:32 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 29 19:38:33 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.697.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.697.mcz ==================== Summary ==================== Name: System.spur-mt.697 Author: eem Time: 29 January 2015, 11:35:41.872 am UUID: c5404a70-5b08-4bdb-85d1-dcc6b9248882 Ancestors: System-mt.697, System.spur-cmm.696 System-mt.697 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.237 Let message tally ignore #home but just use #sender to handle block closures correctly. =============== Diff against System-mt.697 =============== Item was removed: - ----- Method: Object>>oopAge (in category '*system-support') ----- - oopAge - ^ ObjectHistory current ageOf: self! Item was removed: - ----- Method: Object>>oopTimestamp (in category '*system-support') ----- - oopTimestamp - ^ ObjectHistory current timestampOf: self! Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Thu Jan 29 19:38:32 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 29 19:38:37 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.698.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.698.mcz ==================== Summary ==================== Name: System.spur-eem.698 Author: eem Time: 29 January 2015, 11:35:33.911 am UUID: 46cbb32d-d5af-43bb-945b-d8b66adc67eb Ancestors: System-eem.698 System-eem.698 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.237 Provide an obsolete method for ObjectHistory that kills the current ObjectHistory's mark process if the class is removed. This allows Spur to easily remove ObjectHistory, which it does not support. =============== Diff against System-eem.698 =============== Item was removed: - ----- Method: Object>>oopAge (in category '*system-support') ----- - oopAge - ^ ObjectHistory current ageOf: self! Item was removed: - ----- Method: Object>>oopTimestamp (in category '*system-support') ----- - oopTimestamp - ^ ObjectHistory current timestampOf: self! Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Thu Jan 29 19:38:32 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 29 19:38:43 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.699.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.699.mcz ==================== Summary ==================== Name: System.spur-eem.699 Author: eem Time: 29 January 2015, 11:35:36.303 am UUID: 66bc8fe3-a105-4f4f-8275-21235bbac975 Ancestors: System-eem.699, System.spur-eem.698 System-eem.699 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.237 Add block nesting to MessageTally. c.f. AndreasProfiler-eem.10 =============== Diff against System-eem.699 =============== Item was removed: - ----- Method: Object>>oopAge (in category '*system-support') ----- - oopAge - ^ ObjectHistory current ageOf: self! Item was removed: - ----- Method: Object>>oopTimestamp (in category '*system-support') ----- - oopTimestamp - ^ ObjectHistory current timestampOf: self! Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From eliot.miranda at gmail.com Thu Jan 29 20:29:21 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu Jan 29 20:29:24 2015 Subject: [squeak-dev] Process-specific state difficult to debug... In-Reply-To: References: <1422521404841-4802422.post@n4.nabble.com> Message-ID: Hi Levente, On Thu, Jan 29, 2015 at 10:29 AM, Levente Uzonyi wrote: > That would help, but it seems like the effectiveProcess variable is not > set correctly. At least I don't see it being set while debugging the > following: > > | ep | > ep := Processor activeProcess instVarNamed: #effectiveProcess. > self haltIf: ep isNil That is correct behavior. effectiveProcess is only ever non-nil in the process the debugger is using to run code on behalf of another. In a normal process effectiveProcess is always nil, and therefore the effectiveProcess is the process itself. Try this instead, stepping over the second environment access. If you look at the stack top you'll see it is #present. Processor activeProcess environmentAt: #foo put: #present. self halt. Processor activeProcess environmentAt: #foo Try it without the System-eem.699 changes and you'll get the environment key not found error. Levente > > > On Thu, 29 Jan 2015, Eliot Miranda wrote: > > Hi Marcel, >> can you give a specific example? Andreas and I came up with a >> solution for accessing Processor activeProcess correctly in the debugger. >> It works like this: >> >> ProcessorScheduler>>activeProcess >> ^activeProcess effectiveProcess >> >> Process>>effectiveProcess >> "effectiveProcess is a mechanism to allow process-faithful debugging. >> The debugger executes code >> on behalf of processes, so unless some effort is made the identity of >> Processor activeProcess is not >> correctly maintained when debugging code. The debugger uses >> evaluate:onBehalfOf: to assign the >> debugged process as the effectiveProcess of the process executing the >> code, preserving process >> identity." >> ^effectiveProcess ifNil: [self] >> >> Process>>evaluate: aBlock onBehalfOf: aProcess >> "Evaluate aBlock setting effectiveProcess to aProcess. Used >> in the execution simulation machinery to ensure that >> Processor activeProcess evaluates correctly when debugging." >> | oldEffectiveProcess | >> oldEffectiveProcess := effectiveProcess. >> effectiveProcess := aProcess. >> ^aBlock ensure: [effectiveProcess := oldEffectiveProcess] >> >> and then in activateReturn:value: complete: popTo: popTo:value: >> return:value: step step: stepToCallee stepToSendOrReturn it is used as in >> >> Process>>step >> >> ^Processor activeProcess >> evaluate: [suspendedContext := suspendedContext step] >> onBehalfOf: self >> >> Perhaps all that is needed is the access of process-specific variables to >> use effectiveProcess? >> >> On Thu, Jan 29, 2015 at 12:50 AM, Marcel Taeumel < >> marcel.taeumel@student.hpi.uni-potsdam.de> wrote: >> Hi! >> >> There are process-specific variables. However, #doStep in Debugger >> does >> #completeStep: on the process object and Processor >> >> #activeProcess will be >> wrong during that execution. >> >> Is this a general problem of global state or could we fix that >> somehow? >> >> Best, >> Marcel >> >> >> >> -- >> View this message in context: http://forum.world.st/Process- >> specific-state-difficult-to-debug-tp4802422.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> >> >> >> >> -- >> best,Eliot >> >> > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150129/5b4f3cd5/attachment-0001.htm From eliot.miranda at gmail.com Thu Jan 29 20:32:59 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu Jan 29 20:33:01 2015 Subject: [squeak-dev] Process-specific state difficult to debug... In-Reply-To: References: <1422521404841-4802422.post@n4.nabble.com> Message-ID: On Thu, Jan 29, 2015 at 12:29 PM, Eliot Miranda wrote: > Hi Levente, > > On Thu, Jan 29, 2015 at 10:29 AM, Levente Uzonyi wrote: > >> That would help, but it seems like the effectiveProcess variable is not >> set correctly. At least I don't see it being set while debugging the >> following: >> >> | ep | >> ep := Processor activeProcess instVarNamed: #effectiveProcess. >> self haltIf: ep isNil > > > That is correct behavior. effectiveProcess is only ever non-nil in the > process the debugger is using to run code on behalf of another. In a > normal process effectiveProcess is always nil, and therefore the > effectiveProcess is the process itself. Try this instead, stepping over > the second environment access. If you look at the stack top you'll see it > is #present. > > Processor activeProcess environmentAt: #foo put: #present. > self halt. > Processor activeProcess environmentAt: #foo > > Try it without the System-eem.699 changes and you'll get the environment > key not found error. > Hmmm. Perhaps a better fix would be to install the debugged process's env in the debugger's process during evaluate:onBehalfOf: > > Levente >> >> >> On Thu, 29 Jan 2015, Eliot Miranda wrote: >> >> Hi Marcel, >>> can you give a specific example? Andreas and I came up with a >>> solution for accessing Processor activeProcess correctly in the debugger. >>> It works like this: >>> >>> ProcessorScheduler>>activeProcess >>> ^activeProcess effectiveProcess >>> >>> Process>>effectiveProcess >>> "effectiveProcess is a mechanism to allow process-faithful debugging. >>> The debugger executes code >>> on behalf of processes, so unless some effort is made the identity of >>> Processor activeProcess is not >>> correctly maintained when debugging code. The debugger uses >>> evaluate:onBehalfOf: to assign the >>> debugged process as the effectiveProcess of the process executing the >>> code, preserving process >>> identity." >>> ^effectiveProcess ifNil: [self] >>> >>> Process>>evaluate: aBlock onBehalfOf: aProcess >>> "Evaluate aBlock setting effectiveProcess to aProcess. Used >>> in the execution simulation machinery to ensure that >>> Processor activeProcess evaluates correctly when debugging." >>> | oldEffectiveProcess | >>> oldEffectiveProcess := effectiveProcess. >>> effectiveProcess := aProcess. >>> ^aBlock ensure: [effectiveProcess := oldEffectiveProcess] >>> >>> and then in activateReturn:value: complete: popTo: popTo:value: >>> return:value: step step: stepToCallee stepToSendOrReturn it is used as in >>> >>> Process>>step >>> >>> ^Processor activeProcess >>> evaluate: [suspendedContext := suspendedContext step] >>> onBehalfOf: self >>> >>> Perhaps all that is needed is the access of process-specific variables >>> to use effectiveProcess? >>> >>> On Thu, Jan 29, 2015 at 12:50 AM, Marcel Taeumel < >>> marcel.taeumel@student.hpi.uni-potsdam.de> wrote: >>> Hi! >>> >>> There are process-specific variables. However, #doStep in Debugger >>> does >>> #completeStep: on the process object and Processor >> >>> #activeProcess will be >>> wrong during that execution. >>> >>> Is this a general problem of global state or could we fix that >>> somehow? >>> >>> Best, >>> Marcel >>> >>> >>> >>> -- >>> View this message in context: http://forum.world.st/Process- >>> specific-state-difficult-to-debug-tp4802422.html >>> Sent from the Squeak - Dev mailing list archive at Nabble.com. >>> >>> >>> >>> >>> -- >>> best,Eliot >>> >>> >> >> >> > > > -- > best, > Eliot > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150129/83783ef0/attachment.htm From commits at source.squeak.org Thu Jan 29 21:53:04 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 29 21:53:07 2015 Subject: [squeak-dev] The Trunk: Kernel-eem.895.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-eem.895.mcz ==================== Summary ==================== Name: Kernel-eem.895 Author: eem Time: 29 January 2015, 1:52:39.767 pm UUID: 2872309b-7fd4-4911-9606-9993d569e1c7 Ancestors: Kernel-ul.893 Change Process>>evaluate:onBehalfOf: to update all non-scheduling variables, such as name and env, to ensure that access to these variables during debugging answers those of the debugged process. This is a smaller, if tricker, change than that in Kernel-eem.894 =============== Diff against Kernel-ul.893 =============== Item was changed: ----- Method: Process>>evaluate:onBehalfOf: (in category 'private') ----- evaluate: aBlock onBehalfOf: aProcess + "Evaluate aBlock setting effectiveProcess to aProcess, and all other variables other than + the scheduling ones to those of aProcess. Used in the execution simulation machinery + to ensure that Processor activeProcess evaluates correctly when debugging." + | range savedVariables | + "range accesses everything after myList, e.g. threadId, effectiveProcess, name, island, env" + range := 5 to: Process instSize. + savedVariables := range collect: [:i| self instVarAt: i]. + range do: + [:i| self instVarAt: i put: (aProcess instVarAt: i)]. - "Evaluate aBlock setting effectiveProcess to aProcess. Used - in the execution simulation machinery to ensure that - Processor activeProcess evaluates correctly when debugging." - | oldEffectiveProcess | - oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. + ^aBlock ensure: + ["write back any assigned-to variables." + range do: + [:i| | v | + (v := self instVarAt: i) ~~ (aProcess instVarAt: i) ifTrue: + [aProcess instVarAt: i put: v]]. + "restore old values" + range with: savedVariables do: + [:i :var| self instVarAt: i put: var]]! - ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]! From commits at source.squeak.org Thu Jan 29 22:29:48 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu Jan 29 22:29:50 2015 Subject: [squeak-dev] The Trunk: Kernel-eem.896.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-eem.896.mcz ==================== Summary ==================== Name: Kernel-eem.896 Author: eem Time: 29 January 2015, 2:29:21.555 pm UUID: da5f62a8-f18c-4630-a319-d3130d2d4312 Ancestors: Kernel-eem.895 Tweak the write-back of variables in Process>>evaluate:onBehalfOf: so as not to smash variables initialized in the process. =============== Diff against Kernel-eem.895 =============== Item was changed: ----- Method: Process>>evaluate:onBehalfOf: (in category 'private') ----- evaluate: aBlock onBehalfOf: aProcess "Evaluate aBlock setting effectiveProcess to aProcess, and all other variables other than the scheduling ones to those of aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | range savedVariables | "range accesses everything after myList, e.g. threadId, effectiveProcess, name, island, env" range := 5 to: Process instSize. savedVariables := range collect: [:i| self instVarAt: i]. range do: [:i| self instVarAt: i put: (aProcess instVarAt: i)]. effectiveProcess := aProcess. ^aBlock ensure: ["write back any assigned-to variables." range do: [:i| | v | + ((v := self instVarAt: i) ~~ (aProcess instVarAt: i) + and: [v notNil]) ifTrue: - (v := self instVarAt: i) ~~ (aProcess instVarAt: i) ifTrue: [aProcess instVarAt: i put: v]]. "restore old values" range with: savedVariables do: [:i :var| self instVarAt: i put: var]]! From eliot.miranda at gmail.com Fri Jan 30 01:26:18 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 30 01:26:20 2015 Subject: [squeak-dev] New Cog VMs available Message-ID: at http://www.mirandabanda.org/files/Cog/VM/VM.r3236/ CogVM binaries as per VMMaker.oscog-eem.1029/r3236 Fix stupid, stupid bug in copying vm profile samples between buffers when the circular buffer index has wrapped. Fix monumental blunder in jitted store-check code. The saved registers mask needs to be the *or* of the value reg and the caller-saved registers, not the *and*!! Make the pin primitives Spur-only. Never inline mapStackPages, for debugging. Spur: Reduce the max num literals in the alternate header format to 15, and steal the bit for the Sista optimized method flag. Make postBecomeAction's stack sweep only occur in Spur (fix regression). Refactor so that the scan is not inlined. Don't assume newMethod is non-immediate in post-become actions. Fix stack adjust slip in primitiveSmallFloatTimesTwoPower Make ensureBehaviorHash: fail for uninitialized behaviours and hence fix the Behavior basicNew basicNew hang. Optionalize some api methods the Spur Cogit doesn't use. Rename and correct ensureSemaphoreForwardedThroughContext: to ensureSemaphoreUnforwardedThroughContext:, its intended function. Make shouldRemapObj: filter-out objects already in newSpace since mapStackPages, via mapInterpreterOops, can visit objects twice in a scavenge, GC, compact sequence. Make sure the caller (& saved) context(s) in base frames stack page are followed post-become in followForwardingPointersInStackZone:. Fix bad bug introduced in become changes in VMMaker.oscog-eem.841 through 844. The class table contains puns, e.g. using Array and WeakArray. These class index puns must not mislead the allInstances primitive into concluding that the class in question is at multiple indices and wrongly purge it. Fix slip in primitivePin. Also be lenient w.r.t. unpinning married contexts. Move the check down into StackInterpreter's version. This allows e.g. self allObjectsDo: [:o| o unpin] Bow to the inevitable and add a manual override for primitive accessor depth. Use it in at: & at:put:. If manual override is not used then the automatically computed depth is too deep because of context access. Newspeak: Integrate Ryan's newer absent receiver sends, which first apeared in VMMaker.oscog-eem.919, abandoned because of Glue issues now resolved. Includes nice refactoring of absent send argument marshalling into its own routine. LargeIntegersPlugin: Remove/fix assumption of 32-bit digit length in normalization routines. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150129/589e3c3d/attachment.htm From asqueaker at gmail.com Fri Jan 30 03:53:36 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri Jan 30 03:53:38 2015 Subject: [squeak-dev] Re: [Vm-dev] New Cog VMs available In-Reply-To: References: Message-ID: Congratulations Eliot! This is a major milestone for Spur's stability and robustness. With this release, I am comfortable to move the rest of my production to Spur. This is so great! On Thu, Jan 29, 2015 at 7:26 PM, Eliot Miranda wrote: > > at http://www.mirandabanda.org/files/Cog/VM/VM.r3236/ > > CogVM binaries as per VMMaker.oscog-eem.1029/r3236 > > Fix stupid, stupid bug in copying vm profile samples between buffers when the > circular buffer index has wrapped. > > Fix monumental blunder in jitted store-check code. The saved registers mask > needs to be the *or* of the value reg and the caller-saved registers, not the > *and*!! > > Make the pin primitives Spur-only. > > Never inline mapStackPages, for debugging. > > Spur: > Reduce the max num literals in the alternate header format to 15, and steal > the bit for the Sista optimized method flag. > > Make postBecomeAction's stack sweep only occur in Spur (fix regression). > Refactor so that the scan is not inlined. Don't assume newMethod is > non-immediate in post-become actions. > > Fix stack adjust slip in primitiveSmallFloatTimesTwoPower > > Make ensureBehaviorHash: fail for uninitialized > behaviours and hence fix the Behavior basicNew basicNew hang. > > Optionalize some api methods the Spur Cogit doesn't use. > > Rename and correct ensureSemaphoreForwardedThroughContext: to > ensureSemaphoreUnforwardedThroughContext:, its intended function. > > Make shouldRemapObj: filter-out objects already in newSpace > since mapStackPages, via mapInterpreterOops, can visit objects > twice in a scavenge, GC, compact sequence. > > Make sure the caller (& saved) context(s) in base frames stack page are > followed post-become in followForwardingPointersInStackZone:. > > Fix bad bug introduced in become changes in VMMaker.oscog-eem.841 through 844. > The class table contains puns, e.g. using Array and WeakArray. These class > index puns must not mislead the allInstances primitive into concluding that > the class in question is at multiple indices and wrongly purge it. > > Fix slip in primitivePin. Also be lenient w.r.t. unpinning married contexts. > Move the check down into StackInterpreter's version. This allows e.g. > self allObjectsDo: [:o| o unpin] > > Bow to the inevitable and add a manual override for primitive accessor depth. > Use it in at: & at:put:. If manual override is not used then the automatically > computed depth is too deep because of context access. > > Newspeak: > Integrate Ryan's newer absent receiver sends, which first apeared in > VMMaker.oscog-eem.919, abandoned because of Glue issues now resolved. Includes > nice refactoring of absent send argument marshalling into its own routine. > > LargeIntegersPlugin: > Remove/fix assumption of 32-bit digit length in normalization routines. > > -- > best, > Eliot > From unoduetre at poczta.onet.pl Fri Jan 30 10:08:31 2015 From: unoduetre at poczta.onet.pl (Mateusz Grotek) Date: Fri Jan 30 09:39:59 2015 Subject: [squeak-dev] How to talk to a modem via a com port In-Reply-To: (from Lou@Keystone-Software.com on Thu Jan 29 19:28:40 2015) Message-ID: <1422612511.12577.0@mglap> Dnia 29.01.2015 19:28:40, Louis LaBrunda napisa?(a): > Hi All, > > Does anyone have some sample code to talk to a telephone modem > through a > com port? It is a USB modem that shows up on COM3. I want to play > with > getting the caller Id info. Any help is appreciated, so thanks in > advance. > > Lou > ----------------------------------------------------------- > Louis LaBrunda > Keystone Software Corp. > SkypeMe callto://PhotonDemon > mailto:Lou@Keystone-Software.com http://www.Keystone-Software.com > > > Hi, There is a class called SerialPort. You use it like that: |port input output| port := SerialPort new. "Here you can set up the port, check the settings protocol of the SerialPort class." port openPort: 0. "Here you can put a number, or a string like '/dev/ttyS0' in Linux" output := port nextPutAll: 'ATI0',Character cr. Transcript showln: port readString. ATI0 is an example of the Hayes AT commands used to control modems (they are use for most modems, not only Hayes), see here: http://en.wikipedia.org/wiki/Hayes_command_set BTW. if you have problems with the SerialPort class on Windows or OSX, try Linux instead. Mateusz From Lou at Keystone-Software.com Fri Jan 30 14:28:54 2015 From: Lou at Keystone-Software.com (Louis LaBrunda) Date: Fri Jan 30 14:29:07 2015 Subject: [squeak-dev] How to talk to a modem via a com port References: <1422612511.12577.0@mglap> Message-ID: <955nca9hdvb3ksiisk67vep37lg2olkpnd@4ax.com> Hi Mateusz, Thanks for the reply. Late yesterday I discovered SerialPort and have it working for the basics. Lou On Fri, 30 Jan 2015 11:08:31 +0100, Mateusz Grotek wrote: >Dnia 29.01.2015 19:28:40, Louis LaBrunda napisa?(a): >> Hi All, >> >> Does anyone have some sample code to talk to a telephone modem >> through a >> com port? It is a USB modem that shows up on COM3. I want to play >> with >> getting the caller Id info. Any help is appreciated, so thanks in >> advance. >> >> Lou >> ----------------------------------------------------------- >> Louis LaBrunda >> Keystone Software Corp. >> SkypeMe callto://PhotonDemon >> mailto:Lou@Keystone-Software.com http://www.Keystone-Software.com >> >> >> > >Hi, > >There is a class called SerialPort. >You use it like that: >|port input output| >port := SerialPort new. >"Here you can set up the port, check the settings protocol of the >SerialPort class." >port openPort: 0. "Here you can put a number, or a string like >'/dev/ttyS0' in Linux" >output := port nextPutAll: 'ATI0',Character cr. >Transcript showln: port readString. > >ATI0 is an example of the Hayes AT commands used to control modems >(they are use for most modems, not only Hayes), see here: >http://en.wikipedia.org/wiki/Hayes_command_set > >BTW. if you have problems with the SerialPort class on Windows or OSX, >try Linux instead. > >Mateusz > ----------------------------------------------------------- Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon mailto:Lou@Keystone-Software.com http://www.Keystone-Software.com From trygver at ifi.uio.no Fri Jan 30 14:36:25 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Fri Jan 30 14:36:31 2015 Subject: [squeak-dev] [BUG?]SMSimpleInstaller>>fileIntoChangeSetNamed:fromStream: In-Reply-To: <4F715307-38F1-48BF-8245-C9A13ACBE84C@gmx.de> References: <54B39D40.5010302@ifi.uio.no> <4F715307-38F1-48BF-8245-C9A13ACBE84C@gmx.de> Message-ID: <54CB96E9.4090804@ifi.uio.no> Sorry. My knowledge of Monticello isn't sufficient to post a single method into the inbox. =-O On 12.01.2015 11:39, Tobias Pape wrote: > Hi > > On 12.01.2015, at 11:09, Trygve Reenskaug wrote: > >> SMSimpleInstaller>>fileIntoChangeSetNamed: aString fromStream: stream >> "We let the user confirm filing into an existing ChangeSet >> or specify another ChangeSet name if >> the name derived from the filename already exists." >> | changeSet newName oldChanges global | >> newName := aString. >> changeSet := SMInstaller changeSetNamed: newName. >> changeSet ifNotNil: [ >> newName := self silent ifNil: [UIManager default >> request: 'ChangeSet already present, just confirm to overwrite or enter a new name:' >> initialAnswer: newName] >> ifNotNil: [newName]. >> ++++++ >> >> AFAICS, 'self silent' cannot return nil, it always returns a boolan. > you're right :) > Care to put a fixed version into the inbox? > http://source.squeak.org/inbox.html > > Best > -Tobia > > Sorry. I can't find a way to post input (a method source) directly into the inbox and my knowledge of Monticello etc. isn't sufficient to let me post a single method into the repository and my knowledge of SMSimpleInstaller isn't sufficient for me to write a meaningful test. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150130/1db03827/attachment.htm From tim at rowledge.org Fri Jan 30 20:27:10 2015 From: tim at rowledge.org (tim Rowledge) Date: Fri Jan 30 20:27:15 2015 Subject: [squeak-dev] asking browser for references to a class finds a method that merely refers to a symbol of the same name Message-ID: <1F3FC8A1-441F-4270-ADB3-8A61E9E5A7D4@rowledge.org> Seriously? How did that happen? tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim "Bother," said Pooh. "Eeyore - ready two photon torpedoes and lock phasers on the Heffalump. Piglet, meet me in Transporter Room Three." From eliot.miranda at gmail.com Fri Jan 30 20:36:04 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 30 20:36:07 2015 Subject: [squeak-dev] asking browser for references to a class finds a method that merely refers to a symbol of the same name In-Reply-To: <1F3FC8A1-441F-4270-ADB3-8A61E9E5A7D4@rowledge.org> References: <1F3FC8A1-441F-4270-ADB3-8A61E9E5A7D4@rowledge.org> Message-ID: On Fri, Jan 30, 2015 at 12:27 PM, tim Rowledge wrote: > Seriously? How did that happen? > I did it. It's so that one finds usages such as Smalltalk classNamed: #Array If it doesn't do that one's hosed One can always use the allCallsOn: aClass binding if one wants the more restrictive form. > tim > -- > tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim > "Bother," said Pooh. "Eeyore - ready two photon torpedoes and lock phasers > on the Heffalump. Piglet, meet me in Transporter Room Three." > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150130/dda365a4/attachment.htm From asqueaker at gmail.com Fri Jan 30 20:41:01 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri Jan 30 20:41:03 2015 Subject: [squeak-dev] asking browser for references to a class finds a method that merely refers to a symbol of the same name In-Reply-To: <1F3FC8A1-441F-4270-ADB3-8A61E9E5A7D4@rowledge.org> References: <1F3FC8A1-441F-4270-ADB3-8A61E9E5A7D4@rowledge.org> Message-ID: "Thorough Senders" preference? On Fri, Jan 30, 2015 at 2:27 PM, tim Rowledge wrote: > Seriously? How did that happen? > > tim > -- > tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim > "Bother," said Pooh. "Eeyore - ready two photon torpedoes and lock phasers on the Heffalump. Piglet, meet me in Transporter Room Three." > > From eliot.miranda at gmail.com Fri Jan 30 20:48:01 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri Jan 30 20:48:04 2015 Subject: [squeak-dev] asking browser for references to a class finds a method that merely refers to a symbol of the same name In-Reply-To: References: <1F3FC8A1-441F-4270-ADB3-8A61E9E5A7D4@rowledge.org> Message-ID: On Fri, Jan 30, 2015 at 12:41 PM, Chris Muller wrote: > "Thorough Senders" preference? > No. The thorough senders preference controls whether scanning for literals descends into nested literal arrays. On Fri, Jan 30, 2015 at 2:27 PM, tim Rowledge wrote: > > Seriously? How did that happen? > > > > tim > > -- > > tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim > > "Bother," said Pooh. "Eeyore - ready two photon torpedoes and lock > phasers on the Heffalump. Piglet, meet me in Transporter Room Three." > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150130/8c753513/attachment.htm From tim at rowledge.org Fri Jan 30 21:15:23 2015 From: tim at rowledge.org (tim Rowledge) Date: Fri Jan 30 21:15:27 2015 Subject: [squeak-dev] asking browser for references to a class finds a method that merely refers to a symbol of the same name In-Reply-To: References: <1F3FC8A1-441F-4270-ADB3-8A61E9E5A7D4@rowledge.org> Message-ID: <4C8D4E0A-A352-4F3E-B53C-750709491A5B@rowledge.org> On 30-01-2015, at 12:36 PM, Eliot Miranda wrote: > > > On Fri, Jan 30, 2015 at 12:27 PM, tim Rowledge wrote: > Seriously? How did that happen? > > I did it. It's so that one finds usages such as > > Smalltalk classNamed: #Array Hmm, ok. It?s more than a bit disconcerting but I kinda see your logic. Can?t even really argue for double-checking against the ?classNamed:? since obviously anyone could come up with an analogous message that would screw that. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Useful Latin Phrases:- Braccae illae virides cum subucula rosea et tunica Caledonia-quam elenganter concinnatur! = Those green pants go so well with that pink shirt and the plaid jacket! From Das.Linux at gmx.de Fri Jan 30 21:37:33 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri Jan 30 21:37:38 2015 Subject: [squeak-dev] asking browser for references to a class finds a method that merely refers to a symbol of the same name In-Reply-To: <4C8D4E0A-A352-4F3E-B53C-750709491A5B@rowledge.org> References: <1F3FC8A1-441F-4270-ADB3-8A61E9E5A7D4@rowledge.org> <4C8D4E0A-A352-4F3E-B53C-750709491A5B@rowledge.org> Message-ID: <5FF66DB7-DD12-483B-9BE7-E8AF90C56D20@gmx.de> On 30.01.2015, at 22:15, tim Rowledge wrote: > On 30-01-2015, at 12:36 PM, Eliot Miranda wrote: > >> >> >> On Fri, Jan 30, 2015 at 12:27 PM, tim Rowledge wrote: >> Seriously? How did that happen? >> >> I did it. It's so that one finds usages such as >> >> Smalltalk classNamed: #Array > > Hmm, ok. It?s more than a bit disconcerting but I kinda see your logic. Can?t even really argue for double-checking against the ?classNamed:? since obviously anyone could come up with an analogous message that would screw that. > Yes. For example, I have written code like this (don't ask why ;)) possibleRuleClasses ^ (self subclassesIfAvailable: #GRSlimeBlockLintRule), (self subclassesIfAvailable: #GRSlimeParseTreeLintRule) select: [:cls | cls name beginsWith: 'GR'] Best -Tobias From marcel.taeumel at student.hpi.uni-potsdam.de Sat Jan 31 13:19:04 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sat Jan 31 13:23:43 2015 Subject: [squeak-dev] Oblivous caching: DynamicVariable >> #default Message-ID: <1422710344937-4802924.post@n4.nabble.com> Hi, there! After calling #value:during: for a dynamic variable, the #default result is cached in the env variable of the process. Changing the result of #default will have no effect on #value until the process is killed... I think, this is wrong... :-/ Best, Marcel -- View this message in context: http://forum.world.st/Oblivous-caching-DynamicVariable-default-tp4802924.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Sat Jan 31 13:23:00 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sat Jan 31 13:27:38 2015 Subject: [squeak-dev] Re: Oblivous caching: DynamicVariable >> #default In-Reply-To: <1422710344937-4802924.post@n4.nabble.com> References: <1422710344937-4802924.post@n4.nabble.com> Message-ID: <1422710580979-4802926.post@n4.nabble.com> This would work: value: anObject during: aBlock | p oldValue defaultUsed | p := Processor activeProcess. defaultUsed := false. oldValue := p environmentAt: self ifAbsent: [defaultUsed := true. nil]. ^[ p environmentAt: self put: anObject. aBlock value ] ensure: [ defaultUsed ifFalse: [p environmentAt: self put: oldValue] ]. -- View this message in context: http://forum.world.st/Oblivous-caching-DynamicVariable-default-tp4802924p4802926.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Sat Jan 31 14:17:55 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sat Jan 31 14:22:32 2015 Subject: [squeak-dev] Re: Oblivous caching: DynamicVariable >> #default In-Reply-To: <1422710580979-4802926.post@n4.nabble.com> References: <1422710344937-4802924.post@n4.nabble.com> <1422710580979-4802926.post@n4.nabble.com> Message-ID: <1422713875567-4802936.post@n4.nabble.com> Actually, *this* seems to work now: value: anObject during: aBlock | p oldValue defaultUsed | p := Processor activeProcess. defaultUsed := false. oldValue := p environmentAt: self ifAbsent: [defaultUsed := true. nil]. ^[ p environmentAt: self put: anObject. aBlock value ] ensure: [ defaultUsed ifTrue: [p environmentRemoveKey: self] ifFalse: [p environmentAt: self put: oldValue] ]. -- View this message in context: http://forum.world.st/Oblivous-caching-DynamicVariable-default-tp4802924p4802936.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From leves at elte.hu Sat Jan 31 16:07:37 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sat Jan 31 16:07:42 2015 Subject: [squeak-dev] Re: Oblivous caching: DynamicVariable >> #default In-Reply-To: <1422713875567-4802936.post@n4.nabble.com> References: <1422710344937-4802924.post@n4.nabble.com> <1422710580979-4802926.post@n4.nabble.com> <1422713875567-4802936.post@n4.nabble.com> Message-ID: This change looks right to me. Levente On Sat, 31 Jan 2015, Marcel Taeumel wrote: > Actually, *this* seems to work now: > > value: anObject during: aBlock > > | p oldValue defaultUsed | > p := Processor activeProcess. > defaultUsed := false. > oldValue := p environmentAt: self ifAbsent: [defaultUsed := true. nil]. > ^[ > p environmentAt: self put: anObject. > aBlock value ] > ensure: [ defaultUsed > ifTrue: [p environmentRemoveKey: self] > ifFalse: [p environmentAt: self put: oldValue] ]. > > > > -- > View this message in context: http://forum.world.st/Oblivous-caching-DynamicVariable-default-tp4802924p4802936.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From marcel.taeumel at student.hpi.uni-potsdam.de Sat Jan 31 16:45:53 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sat Jan 31 16:50:32 2015 Subject: [squeak-dev] Re: The Trunk: System-eem.699.mcz In-Reply-To: References: Message-ID: <1422722753198-4802948.post@n4.nabble.com> I think you missed to adapt #tally:by: ... :) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-System-eem-699-mcz-tp4802367p4802948.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Sat Jan 31 17:16:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 31 17:16:29 2015 Subject: [squeak-dev] The Trunk: Kernel-mt.897.mcz Message-ID: Marcel Taeumel uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-mt.897.mcz ==================== Summary ==================== Name: Kernel-mt.897 Author: mt Time: 31 January 2015, 6:16:02.184 pm UUID: 3fdc3270-04ea-1e45-a02e-1cc17c459fde Ancestors: Kernel-eem.896 Dynamic variables will not store their default values into the process' env anymore. This supports changing the result of #default without having to terminate that process (or fiddling with the env var directly...) =============== Diff against Kernel-eem.896 =============== Item was changed: ----- Method: DynamicVariable class>>value:during: (in category 'accessing') ----- value: anObject during: aBlock + | p oldValue outerScopeWasDynamic | - | p oldValue | p := Processor activeProcess. + outerScopeWasDynamic := true. + oldValue := p + environmentAt: self + ifAbsent: [outerScopeWasDynamic := false. nil]. - oldValue := p environmentAt: self ifAbsent: [self default]. ^[ p environmentAt: self put: anObject. aBlock value ] + ensure: [ outerScopeWasDynamic + ifTrue: [p environmentAt: self put: oldValue] + ifFalse: [p environmentRemoveKey: self ifAbsent: []] ].! - ensure: [ p environmentAt: self put: oldValue ].! From commits at source.squeak.org Sat Jan 31 17:18:34 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 31 17:18:36 2015 Subject: [squeak-dev] The Trunk: KernelTests-mt.286.mcz Message-ID: Marcel Taeumel uploaded a new version of KernelTests to project The Trunk: http://source.squeak.org/trunk/KernelTests-mt.286.mcz ==================== Summary ==================== Name: KernelTests-mt.286 Author: mt Time: 31 January 2015, 6:18:24.491 pm UUID: b7aeaa5e-4732-5343-8a30-5b7d241a2964 Ancestors: KernelTests-nice.285 new test for dynamic variables added =============== Diff against KernelTests-nice.285 =============== Item was changed: ----- Method: ProcessSpecificTest>>checkDynamic: (in category 'testing') ----- checkDynamic: value + + self assert: value equals: TestDynamicVariable value.! - self assert: TestDynamicVariable value = value! Item was changed: ----- Method: ProcessSpecificTest>>checkLocal: (in category 'testing') ----- checkLocal: value + + self assert: value equals: TestLocalVariable value.! - self assert: TestLocalVariable value = value! Item was changed: ----- Method: ProcessSpecificTest>>tearDown (in category 'running') ----- tearDown "Make sure we don't pollute the running process' environment with the test variables" { TestLocalVariable. TestDynamicVariable } do: [ :each | + Processor activeProcess environmentRemoveKey: each ifAbsent: [] ]. + + TestDynamicVariable default: nil.! - Processor activeProcess environmentRemoveKey: each ifAbsent: [] ]! Item was added: + ----- Method: ProcessSpecificTest>>testDynamicVariableDefault (in category 'testing') ----- + testDynamicVariableDefault + + "Just double-check our fixture." + TestDynamicVariable default: #default. + self assert: #default equals: TestDynamicVariable default. + + "Now check for default lookup out of any dynamic scope." + self checkDynamic: #default.. + + "Ignore default value by setting dynamic scope." + TestDynamicVariable value: #dynamic during: [ + self checkDynamic: #dynamic]. + + "Out of that scope, we should fall back to the default again." + self checkDynamic: #default. + + "...even if that default value changes." + TestDynamicVariable default: #anotherDefault. + self checkDynamic: #anotherDefault. + ! Item was changed: DynamicVariable subclass: #TestDynamicVariable instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'KernelTests-Processes'! + TestDynamicVariable class + instanceVariableNames: 'defaultValue'! !TestDynamicVariable commentStamp: 'mvl 3/13/2007 13:51' prior: 0! TestDynamicVariable is a test class using in ProcessSpecificTest. ! + TestDynamicVariable class + instanceVariableNames: 'defaultValue'! Item was added: + ----- Method: TestDynamicVariable class>>default (in category 'accessing') ----- + default + + ^ defaultValue! Item was added: + ----- Method: TestDynamicVariable class>>default: (in category 'accessing') ----- + default: anObject + + defaultValue := anObject.! From Das.Linux at gmx.de Sat Jan 31 18:03:26 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Sat Jan 31 18:03:28 2015 Subject: [squeak-dev] The Trunk: KernelTests-mt.286.mcz Message-ID: <8FEA9969-6572-4AC6-8174-BBE125AA182B@gmx.de> On 31.01.2015, at 17:18, commits@source.squeak.org wrote: > + self checkDynamic: #default.. > + You should kill one dot? Best -Tobias From commits at source.squeak.org Sat Jan 31 20:48:15 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 31 20:48:18 2015 Subject: [squeak-dev] The Trunk: Morphic-cmm.755.mcz Message-ID: Chris Muller uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-cmm.755.mcz ==================== Summary ==================== Name: Morphic-cmm.755 Author: cmm Time: 31 January 2015, 2:47:31.992 pm UUID: 46064dd7-97b4-48a7-856a-968440827256 Ancestors: Morphic-mt.754 Let the "Compare to Clipboard" function compare just the selected text to the clipboard text. =============== Diff against Morphic-mt.754 =============== Item was changed: ----- Method: TextEditor>>compareToClipboard (in category 'menu messages') ----- compareToClipboard "Check to see if whether the receiver's text is the same as the text currently on the clipboard, and inform the user." | s1 s2 | s1 := self clipboardText string. + s2 := self selection string. - s2 := paragraph text string. s1 = s2 ifTrue: [^ self inform: 'Exact match']. (StringHolder new textContents: (TextDiffBuilder buildDisplayPatchFrom: s1 to: s2)) openLabel: 'Comparison to Clipboard Text'! From commits at source.squeak.org Sat Jan 31 21:02:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat Jan 31 21:02:57 2015 Subject: [squeak-dev] The Trunk: Help-Squeak-Project-cmm.21.mcz Message-ID: Chris Muller uploaded a new version of Help-Squeak-Project to project The Trunk: http://source.squeak.org/trunk/Help-Squeak-Project-cmm.21.mcz ==================== Summary ==================== Name: Help-Squeak-Project-cmm.21 Author: cmm Time: 31 January 2015, 3:02:47.068 pm UUID: 13b1debf-e7ca-43d7-b5d4-6e3e37bb0fe8 Ancestors: Help-Squeak-Project-dtl.20 - Update Compare To Clipboard description. =============== Diff against Help-Squeak-Project-dtl.20 =============== Item was changed: ----- Method: SqueakTutorialsCommandKey class>>commandKeyMappings (in category 'as yet unclassified') ----- commandKeyMappings "This method was automatically generated. Edit it using:" "SqueakTutorialsCommandKey edit: #commandKeyMappings" ^HelpTopic title: 'Command Key Mappings' contents: 'Lower-case command keys (use with Cmd key on Mac and Alt key on other platforms) a Select all b Browse it (selection is a class name or cursor is over a class-list or message-list) c Copy selection d Do it (selection is a valid expression) e Exchange selection with prior selection f Find g Find again h Set selection as search string for find again i Inspect it (selection is a valid expression, or selection is over an inspect-ilst) j Again once (do the last text-related operation again) k Set font l Cancel m Implementors of it (selection is a message selector or cursor is over a class-list or message-list) n Senders of it (selection is a message selector or cursor is over a class-list or message-list) o Spawn current method p Print it (selection is a valid expression) q Query symbol (toggle all possible completion for a given prefix) r Recognizer s Save (i.e. accept) t Finds a Transcript (when cursor is over the desktop) u Toggle alignment v Paste w Delete preceding word (over text); Close-window (over morphic desktop) x Cut selection y Swap characters z Undo Note: for Do it, Senders of it, etc., a null selection will be expanded to a word or to the current line in an attempt to do what you want. Also note that Senders/Implementors of it will find the outermost keyword selector in a large selection, as when you have selected a bracketed expression or an entire line. Finally note that the same cmd-m and cmd-n (and cmd-v for versions) work in the message pane of most browsers. Upper-case command keys (use with Shift-Cmd, or Ctrl on Mac or Shift-Alt on other platforms; sometimes Ctrl works too) A Advance argument B Browse it in this same browser (in System browsers only) + C Compare the selected text to the clipboard contents - C Compare argument to clipboard D Duplicate E Method strings containing it F Insert ''ifFalse:'' G fileIn from it (a file name) H cursor TopHome: I Inspect via Object Explorer J Again many (apply the previous text command repeatedly until the end of the text) K Set style L Outdent (move selection one tab-stop left) M Select current type-in N References to it (selection is a class name, or cursor is over a class-list or message-list) O Open single-message browser (in message lists) P Make project link R Indent (move selection one tab-stap right) S Search T Insert ''ifTrue:'' U Convert linefeeds to carriage returns in selection V Paste author''s initials W Selectors containing it (in text); show-world-menu (when issued with cursor over desktop) X Force selection to lowercase Y Force selection to uppercase Z Capitalize all words in selection Other special keys Backspace Backward delete character Del Forward delete character Shift-Bksp Backward delete word Shift-Del Forward delete word Esc Pop up the Desktop Menu \ Send top window to back Cursor keys left, right, up, down Move cursor left, right, up or down Ctrl-left Move cursor left one word Ctrl-right Move cursor right one word Home Move cursor to begin of line or begin of text End Move cursor to end of line or end of text PgUp, Ctrl-up Move cursor up one page PgDown, Ctrl-Dn Move cursor down one page Note all these keys can be used together with Shift to define or enlarge the selection. You cannot however shrink that selection again, as in some other systems. Other Cmd-key combinations (not available on all platforms) Return Insert return followed by as many tabs as the previous line (with a further adjustment for additional brackets in that line) Space Select the current word as with double clicking Enclose the selection in a kind of bracket. Each is a toggle. (not available on all platforms) Ctrl-( Enclose within ( and ), or remove enclosing ( and ) Ctrl-[ Enclose within [ and ], or remove enclosing [ and ] Crtl-{ Enclose within { and }, or remove enclosing { and } Ctrl-< Enclose within < and >, or remove enclosing < and > Ctrl-'' Enclose within '' and '', or remove enclosing '' and '' Ctrl-" Enclose within " and ", or remove enclosing " and " Note also that you can double-click just inside any of the above delimiters, or at the beginning or end of a line, to select the text enclosed. Text Emphasis (not available on all platforms) Cmd-1 type the first method argument Cmd-2 type the second method argument Cmd-3 type the third method argument Cmd-4 type the fourth method argument Cmd-5 for future use Cmd-6 color, action-on-click, link to class comment, link to method, url Brings up a menu. To remove these properties, select more than the active part and then use command-0. Cmd-7 bold Cmd-8 italic Cmd-9 narrow (same as negative kern) Cmd-0 plain text (resets all emphasis) Cmd-- underlined (toggles it) Cmd-= struck out (toggles it) Shift-Cmd-- (aka :=) negative kern (letters 1 pixel closer) Shift-Cmd-+ positive kern (letters 1 pixel larger spread) Docking Bar Ctrl- opens the n-th (where n is between 0 and 7) menu if such exists, otherwise it moves the keyboard focus to the Search Bar. Currently this means: Ctrl-0 Activates Search Bar Ctrl-1 Squeak menu Ctrl-2 Projects menu Ctrl-3 Tools menu Ctrl-4 Apps menu Ctrl-5 Extras menu Ctrl-6 Windows menu Ctrl-7 Help menu !!' readStream nextChunkText!