Hi.
I investigate that #becomeForward: is not working for SmallInteger args. It is mentioned in method comment: Fails if either argument is a SmallInteger. I guess that it is not working for any immediate argument. For example it is failed for Character too. So I am interesting why it is not supported? |
On Thu, 17 Mar 2016, Denis Kudriashov wrote: Because they are immediate objects, so they don't exist on their own, only in a slot of another object. Using #becomeForward: would be an overkill anyway, because you can use assignment or #at:put: to achieve the same thing. Levente |
In reply to this post by Denis Kudriashov
On Thu, Mar 17, 2016 at 09:57:51AM +0100, Denis Kudriashov wrote: > > Hi. > > I investigate that #becomeForward: is not working for SmallInteger args. It > is mentioned in method comment: > > Fails if either argument is a SmallInteger. > > > I guess that it is not working for any immediate argument. For example it > is failed for Character too. > > So I am interesting why it is not supported? The become mechanism is swapping references to objects, such that the object pointers that pointed to one object are all now pointing to another. An immediate object such as SmallInteger is hiding its value within the object pointer itself (so it not really a pointer when used in this way). The immediate object "pointer" is therefore not able to participate in reference swapping. Dave |
So to implement becomeForward: with integer argument it is needed to scan all references to receiver and change pointers body to hold integer value. Am I right? 2016-03-17 13:52 GMT+01:00 David T. Lewis <[hidden email]>:
|
In reply to this post by David T. Lewis
> On 17.03.2016, at 13:52, David T. Lewis <[hidden email]> wrote: > > > On Thu, Mar 17, 2016 at 09:57:51AM +0100, Denis Kudriashov wrote: >> >> Hi. >> >> I investigate that #becomeForward: is not working for SmallInteger args. It >> is mentioned in method comment: >> >> Fails if either argument is a SmallInteger. >> >> >> I guess that it is not working for any immediate argument. For example it >> is failed for Character too. >> >> So I am interesting why it is not supported? > > The become mechanism is swapping references to objects, such that the > object pointers that pointed to one object are all now pointing to another. > An immediate object such as SmallInteger is hiding its value within the > object pointer itself (so it not really a pointer when used in this way). > The immediate object "pointer" is therefore not able to participate in > reference swapping. There’s only one technical reason I am aware of, and that is that becomeForward actually does change the argument’s identityHash: old := ‘old'. new := ’new'. idold := old identityHash. idnew := new identityHash. old becomeForward: new. {idold. idnew. new identityHash} ==> #(153 3753 153) In this case, b’s identity hash changed from 3753 to 153. This mechanism exists so that if ‘old’ was used as key in an IdentityDictionary before, then now ‘new’ can be found at the same position because it uses the same hash. And since there is no way to change the identity hash of an immediate value, this can not work. > On 17.03.2016, at 14:35, Denis Kudriashov <[hidden email]> wrote: > > So to implement becomeForward: with integer argument it is needed to scan all references to receiver and change pointers body to hold integer value. > Am I right? What *does* work, however (at least in Cog and SqueakJS, although not in the interpreter) is to use 'becomeForward: new copyHash: false’: old := 'hi'. old becomeForward: 3 copyHash: false. old ==> 3 ... because in the “copyHash: false” case the argument object is not modified in any way. - Bert - smime.p7s (5K) Download Attachment |
On Thu, Mar 17, 2016 at 11:42 AM, Bert Freudenberg <[hidden email]> wrote:
Couldn't that be solved using the #becomeForward:copyHash: flavor (passing `false` to copyHas:) ? old := ‘old'. |
On 17.03.2016, at 15:54, Mariano Martinez Peck <[hidden email]> wrote:
Sorry for my poor quoting.
- Bert - smime.p7s (5K) Download Attachment |
Ups...sorry..I didn't see that last part of the email. On Thu, Mar 17, 2016 at 11:56 AM, Bert Freudenberg <[hidden email]> wrote:
|
In reply to this post by Denis Kudriashov
Hi Denis,
_,,,^..^,,,_ (phone) |
In reply to this post by Denis Kudriashov
Hi Denis,
Half right :-). That's what happened before Spur. Now what happens is that the object gets modified into a forwarding pointer to the object it becomes. In a two-way become we create two copies of the objects and make the originals point to the other copy, unless they are the same size, in which case we exchange their contents. (remember that bug with zero-sized objects which was due to a C compiler aliasing bug?) In any case, the becomeForward:copyHash: false case should not fail for immediate targets. I'll make it so soon. But you're welcome to try yourself ;-) _,,,^..^,,,_ (phone)
|
In reply to this post by Bert Freudenberg
> On Mar 17, 2016, at 7:42 AM, Bert Freudenberg <[hidden email]> wrote: > > >> On 17.03.2016, at 13:52, David T. Lewis <[hidden email]> wrote: >> >> >>> On Thu, Mar 17, 2016 at 09:57:51AM +0100, Denis Kudriashov wrote: >>> >>> Hi. >>> >>> I investigate that #becomeForward: is not working for SmallInteger args. It >>> is mentioned in method comment: >>> >>> Fails if either argument is a SmallInteger. >>> >>> >>> I guess that it is not working for any immediate argument. For example it >>> is failed for Character too. >>> >>> So I am interesting why it is not supported? >> >> The become mechanism is swapping references to objects, such that the >> object pointers that pointed to one object are all now pointing to another. >> An immediate object such as SmallInteger is hiding its value within the >> object pointer itself (so it not really a pointer when used in this way). >> The immediate object "pointer" is therefore not able to participate in >> reference swapping. > > Well, that’s no reason we couldn’t just replace all references to the object with the immediate value. > > There’s only one technical reason I am aware of, and that is that becomeForward actually does change the argument’s identityHash: > > old := ‘old'. > new := ’new'. > idold := old identityHash. > idnew := new identityHash. > old becomeForward: new. > {idold. idnew. new identityHash} > > ==> #(153 3753 153) > > In this case, b’s identity hash changed from 3753 to 153. > > This mechanism exists so that if ‘old’ was used as key in an IdentityDictionary before, then now ‘new’ can be found at the same position because it uses the same hash. And since there is no way to change the identity hash of an immediate value, this can not work. > > >> On 17.03.2016, at 14:35, Denis Kudriashov <[hidden email]> wrote: >> >> So to implement becomeForward: with integer argument it is needed to scan all references to receiver and change pointers body to hold integer value. >> Am I right? > > What *does* work, however (at least in Cog and SqueakJS, although not in the interpreter) is to use 'becomeForward: new copyHash: false’: > > old := 'hi'. > old becomeForward: 3 copyHash: false. > old > ==> 3 > > ... because in the “copyHash: false” case the argument object is not modified in any way. +1. I'll make Spur support this too. > > - Bert - > |
Thank you for responses.
This is exactly what I need. About case when old object is dictionary item. Changing it hash (during become for example) should not break dictionary. It will only slowdown object lookup. Am I right? |
On 21.03.2016, at 10:28, Denis Kudriashov <[hidden email]> wrote:
No, it will break. If the hash changes, the lookup very likely fails because it is looking at the wrong index (even though the object is in the dictionary). You need to send #rehash to the dictionary to fix this. Of course this only applies if the object was used as key. Curious: what are you actually trying to do?
- Bert -
smime.p7s (5K) Download Attachment |
2016-03-21 16:14 GMT+01:00 Bert Freudenberg <[hidden email]>:
I implemented new version of Mocketry which will return new mocks for any unexpected message. And in the case when this resulted mock will be used in arithmetics I will substitute it with zero as default number value. Same logic I apply for boolean operations where returned mock is substituted by false when mustBeBoolean is detected. It should be correct behaviour for usual mock scenarios |
Free forum by Nabble | Edit this page |