[Slots] Invisible Slots
Hi, One of the power of slots is the concept of Virtual Slots that do not have an ivar to store their state. But of course, some uses fo this concept want to store state in the object. (e.g. imagine a property slot, all proper slots of the object would store into a property dictionary). The idea is that one can add iVars reflectively that are hidden from both introspection *and* the class definition. (the inspector should get a view to see reality, of course, similar to how we tread Dictionaries and OrderedCollection: The âbasicâ view is not relavant in most cases, it is just available in addition, the default is the high level view that is closer to the âmental modelâ of the programmer). https://pharo.fogbugz.com/f/cases/14786/Slots-add-HiddenInstanceVariableSlot... <https://pharo.fogbugz.com/f/cases/14786/Slots-add-HiddenInstanceVariableSlot...> -> Add a sublass of normal invar slots that is hidden -> change #slots of Behavior to return #allVisibleSlots Next: When building classes with Slots, the class builder need to call back on the slot and hand the class to each. Then the slot can reflectively change the class, e.g. the PropertySlot will check if there is already a hidden property base slot and if not, add it reflectively). Marcus
On 24 Jan 2015, at 11:24, Marcus Denker <marcus.denker@inria.fr> wrote:
Hi,
One of the power of slots is the concept of Virtual Slots that do not have an ivar to store their state. But of course, some uses fo this concept want to store state in the object. (e.g. imagine a property slot, all proper slots of the object would store into a property dictionary).
The idea is that one can add iVars reflectively that are hidden from both introspection *and* the class definition. (the inspector should get a view to see reality, of course, similar to how we tread Dictionaries and OrderedCollection: The âbasicâ view is not relavant in most cases, it is just available in addition, the default is the high level view that is closer to the âmental modelâ of the programmer).
https://pharo.fogbugz.com/f/cases/14786/Slots-add-HiddenInstanceVariableSlot... <https://pharo.fogbugz.com/f/cases/14786/Slots-add-HiddenInstanceVariableSlot...>
Ups, loading the Slice crashes the VM :-) This kind of shows why doing these things in tiny, tiny steps is they way to go⦠Marcus
On 24 Jan 2015, at 14:24, Marcus Denker <marcus.denker@inria.fr> wrote:
On 24 Jan 2015, at 11:24, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
Hi,
One of the power of slots is the concept of Virtual Slots that do not have an ivar to store their state. But of course, some uses fo this concept want to store state in the object. (e.g. imagine a property slot, all proper slots of the object would store into a property dictionary).
The idea is that one can add iVars reflectively that are hidden from both introspection *and* the class definition. (the inspector should get a view to see reality, of course, similar to how we tread Dictionaries and OrderedCollection: The âbasicâ view is not relavant in most cases, it is just available in addition, the default is the high level view that is closer to the âmental modelâ of the programmer).
https://pharo.fogbugz.com/f/cases/14786/Slots-add-HiddenInstanceVariableSlot... <https://pharo.fogbugz.com/f/cases/14786/Slots-add-HiddenInstanceVariableSlot...>
Ups, loading the Slice crashes the VM :-) This kind of shows why doing these things in tiny, tiny steps is they way to goâ¦
ok, in 40463 AbstractInstanceVariableSlot will be renamed to IndexedSlot (so if you subclass it, you need to change the supeclass in your code) Next: Hidden ivar Marcus
"hidden ivar" sounds like it would make understanding the system more complicated. What is its use-case? On Tue, Jan 27, 2015 at 1:03 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 24 Jan 2015, at 14:24, Marcus Denker <marcus.denker@inria.fr> wrote:
On 24 Jan 2015, at 11:24, Marcus Denker <marcus.denker@inria.fr> wrote:
Hi,
One of the power of slots is the concept of Virtual Slots that do not have an ivar to store their state. But of course, some uses fo this concept want to store state in the object. (e.g. imagine a property slot, all proper slots of the object would store into a property dictionary).
The idea is that one can add iVars reflectively that are hidden from both introspection *and* the class definition. (the inspector should get a view to see reality, of course, similar to how we tread Dictionaries and OrderedCollection: The âbasicâ view is not relavant in most cases, it is just available in addition, the default is the high level view that is closer to the âmental modelâ of the programmer).
https://pharo.fogbugz.com/f/cases/14786/Slots-add-HiddenInstanceVariableSlot...
Ups, loading the Slice crashes the VM :-) This kind of shows why doing these things in tiny, tiny steps is they way to goâ¦
ok, in 40463 AbstractInstanceVariableSlot will be renamed to IndexedSlot (so if you subclass it, you need to change the supeclass in your code)
Next: Hidden ivar
Marcus
On 26 Jan 2015, at 23:28, Ben Coman <btc@openInWorld.com> wrote:
"hidden ivar" sounds like it would make understanding the system more complicated. What is its use-case?
It will never be used for cases where it needs to be understood. Imagine a PropertySlot. This is like an ivar, but all these slots of the object will just be stored into one dictionary. Now from the mental model of the programmer, this dictionary does not exist (and you should for sure never modify it manualy). In this case hiding it makes the system even more understanable. The same as we hide the ârealâ state when looking at a OrderedCollection or Dictionary. Of course there will be a special inspector to see the real state, but the default will show the high level view. Marcus
The use case is to offer first-class support for objects that would otherwise store instance variables in opaque dictionaries. Doru On Mon, Jan 26, 2015 at 11:28 PM, Ben Coman <btc@openinworld.com> wrote:
"hidden ivar" sounds like it would make understanding the system more complicated. What is its use-case?
On Tue, Jan 27, 2015 at 1:03 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 24 Jan 2015, at 14:24, Marcus Denker <marcus.denker@inria.fr> wrote:
On 24 Jan 2015, at 11:24, Marcus Denker <marcus.denker@inria.fr> wrote:
Hi,
One of the power of slots is the concept of Virtual Slots that do not have an ivar to store their state. But of course, some uses fo this concept want to store state in the object. (e.g. imagine a property slot, all proper slots of the object would store into a property dictionary).
The idea is that one can add iVars reflectively that are hidden from both introspection *and* the class definition. (the inspector should get a view to see reality, of course, similar to how we tread Dictionaries and OrderedCollection: The âbasicâ view is not relavant in most cases, it is just available in addition, the default is the high level view that is closer to the âmental modelâ of the programmer).
https://pharo.fogbugz.com/f/cases/14786/Slots-add-HiddenInstanceVariableSlot...
Ups, loading the Slice crashes the VM :-) This kind of shows why doing these things in tiny, tiny steps is they way to goâ¦
ok, in 40463 AbstractInstanceVariableSlot will be renamed to IndexedSlot (so if you subclass it, you need to change the supeclass in your code)
Next: Hidden ivar
Marcus
-- www.tudorgirba.com "Every thing has its own flow"
On 27 Jan 2015, at 07:43, Tudor Girba <tudor@tudorgirba.com> wrote:
The use case is to offer first-class support for objects that would otherwise store instance variables in opaque dictionaries.
Yes, another way to put it: we move just code that is at the base level now to an âopened upâ language level (this is a MOP). With the effect of making the *real* design more clear. Marcus
On Mon, Jan 26, 2015 at 6:03 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
Next: Hidden ivar
This is now finally in #478. This is for notch just a subclass to have a normal InstanceVariable in a hidden version, later we will use the wrapping machism that we use already for MetaLinks to make it possible to hide any slot. (e.g. BooleanSlot will use a BitFieldSlot that might span multiple ivars). For the first version this simple version should be enough. Marcus
I also can't wait to have a slot to automatically add instance variables in the additional method state for CompiledMethod subclasses. This shouldn't be tricky for you any more, should it ? I'm bored of not being able to add instance variables to compiledMethod subclasses :-). Having automatically inst vars in a dictionary is interesting it could allow to have more inst vars than the maximum limit. 2015-02-05 16:51 GMT+01:00 Marcus Denker <marcus.denker@inria.fr>:
On Mon, Jan 26, 2015 at 6:03 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
Next: Hidden ivar
This is now finally in #478. This is for notch just a subclass to have a normal InstanceVariable in a hidden version, later we will use the wrapping machism that we use already for MetaLinks to make it possible to hide any slot. (e.g. BooleanSlot will use a BitFieldSlot that might span multiple ivars).
For the first version this simple version should be enough.
Marcus
On Thu, Feb 5, 2015 at 12:51 PM, Clément Bera <bera.clement@gmail.com> wrote:
I also can't wait to have a slot to automatically add instance variables in the additional method state for CompiledMethod subclasses. This shouldn't be tricky for you any more, should it ? I'm bored of not being able to add instance variables to compiledMethod subclasses :-).
+1. This is a great test case for Slots. Having automatically inst vars in a dictionary is interesting it could
allow to have more inst vars than the maximum limit.
or, as in AI frame languages, avoid representing and initializing infrequently-used inst vars
2015-02-05 16:51 GMT+01:00 Marcus Denker <marcus.denker@inria.fr>:
On Mon, Jan 26, 2015 at 6:03 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
Next: Hidden ivar
This is now finally in #478. This is for notch just a subclass to have a normal InstanceVariable in a hidden version, later we will use the wrapping machism that we use already for MetaLinks to make it possible to hide any slot. (e.g. BooleanSlot will use a BitFieldSlot that might span multiple ivars).
For the first version this simple version should be enough.
Marcus
-- best, Eliot
On 05 Feb 2015, at 21:51, Clément Bera <bera.clement@gmail.com> wrote:
I also can't wait to have a slot to automatically add instance variables in the additional method state for CompiledMethod subclasses. This shouldn't be tricky for you any more, should it ? I'm bored of not being able to add instance variables to compiledMethod subclasses :-).
It would be just working *if* CompiledMethodLayout would allow slots⦠slots are right now in PointerLayout and subclasses. (this came due to the virtual vs. indexed slots not being really explicly modelled in the first prototype) I will change that: all classes should be able to have *virtual* slots (and add them without having to migrate the instances).
Having automatically inst vars in a dictionary is interesting it could allow to have more inst vars than the maximum limit.
Yes, just think about MorphExtension⦠Marcus
Next: When building classes with Slots, the class builder need to call back on the slot and hand the class to each. Then the slot can reflectively change the class, e.g. the PropertySlot will check if there is already a hidden property base slot and if not, add it reflectively).
This is now done: https://pharo.fogbugz.com/f/cases/14876/Add-call-back-in-ClassBuilder-to-cal... Marcus
On 06 Feb 2015, at 11:50, Marcus Denker <marcus.denker@inria.fr> wrote:
Next: When building classes with Slots, the class builder need to call back on the slot and hand the class to each. Then the slot can reflectively change the class, e.g. the PropertySlot will check if there is already a hidden property base slot and if not, add it reflectively).
This is now done:
https://pharo.fogbugz.com/f/cases/14876/Add-call-back-in-ClassBuilder-to-cal...
For playing with this, in 479: InstanceVariableSlot subclass: #AccessorSlot slots: { } classVariables: { } category: âPackage' two methods, #installingIn and #removingFrom:, which are called by the class builder: installingIn: aClass | reader writer | reader := String streamContents: [ :str | str nextPutAll: self name; cr;tab; nextPutAll: ' ^'; nextPutAll: self name. ]. writer := String streamContents: [ :str | str nextPutAll: self name; nextPutAll: ': anObject'; cr;tab; nextPutAll: self name; nextPutAll: ':= anObject.'. ]. aClass compile: reader classified: 'accessing'. aClass compile: writer classified: 'accessingâ. removingFrom: aClass aClass removeSelector: self name. aClass removeSelector: self name asMutator. Now we can make a class and see how the accessors are automatically added (and removed when the slot is removed): Object subclass: #TT slots: { #tttt => AccessorSlot } classVariables: { } category: âPackage' NOTE: this is an example of what can be done with Slots. It is *not* an example of what *should* be done with Slots. (this we only will know after using them for a while). Marcus
I want relationships for certain modeling purposes What I like is that we should arrive to get a collection of useful slots with optimal implementation instead all of us reinventing the wheel. Stef Le 6/2/15 18:15, Marcus Denker a écrit :
On 06 Feb 2015, at 11:50, Marcus Denker <marcus.denker@inria.fr> wrote:
Next: When building classes with Slots, the class builder need to call back on the slot and hand the class to each. Then the slot can reflectively change the class, e.g. the PropertySlot will check if there is already a hidden property base slot and if not, add it reflectively). This is now done:
https://pharo.fogbugz.com/f/cases/14876/Add-call-back-in-ClassBuilder-to-cal...
For playing with this, in 479:
InstanceVariableSlot subclass: #AccessorSlot slots: { } classVariables: { } category: âPackage'
two methods, #installingIn and #removingFrom:, which are called by the class builder:
installingIn: aClass | reader writer |
reader := String streamContents: [ :str | str nextPutAll: self name; cr;tab; nextPutAll: ' ^'; nextPutAll: self name. ]. writer := String streamContents: [ :str | str nextPutAll: self name; nextPutAll: ': anObject'; cr;tab; nextPutAll: self name; nextPutAll: ':= anObject.'. ]. aClass compile: reader classified: 'accessing'. aClass compile: writer classified: 'accessingâ.
removingFrom: aClass
aClass removeSelector: self name. aClass removeSelector: self name asMutator.
Now we can make a class and see how the accessors are automatically added (and removed when the slot is removed):
Object subclass: #TT slots: { #tttt => AccessorSlot } classVariables: { } category: âPackage'
NOTE: this is an example of what can be done with Slots. It is *not* an example of what *should* be done with Slots. (this we only will know after using them for a while).
Marcus
On Sat, Feb 7, 2015 at 5:13 AM, stepharo <stepharo@free.fr> wrote:
I want relationships for certain modeling purposes What I like is that we should arrive to get a collection of useful slots with optimal implementation instead all of us reinventing the wheel.
Stef
In the Flexible Object Layouts paper, it was first class relationships that really caught my eye. Thats what I am hoping for to start having a dive into Slots. And since the paper says "no mainstream OOPL provides first-class relationships as a programming construct" it might be a nice feature to advertise with Pharo 4 release. "First-class relationships" is quite a catchy term ? cheers -ben
Le 6/2/15 18:15, Marcus Denker a écrit :
On 06 Feb 2015, at 11:50, Marcus Denker <marcus.denker@inria.fr> wrote:
Next: When building classes with Slots, the class builder need to call
back on the slot and hand the class to each. Then the slot can reflectively change the class, e.g. the PropertySlot will check if there is already a hidden property base slot and if not, add it reflectively).
This is now done:
https://pharo.fogbugz.com/f/cases/14876/Add-call-back-in- ClassBuilder-to-call-slots-when-building-a-class
For playing with this, in 479:
InstanceVariableSlot subclass: #AccessorSlot slots: { } classVariables: { } category: âPackage'
two methods, #installingIn and #removingFrom:, which are called by the class builder:
installingIn: aClass | reader writer |
reader := String streamContents: [ :str | str nextPutAll: self name; cr;tab; nextPutAll: ' ^'; nextPutAll: self name. ]. writer := String streamContents: [ :str | str nextPutAll: self name; nextPutAll: ': anObject'; cr;tab; nextPutAll: self name; nextPutAll: ':= anObject.'. ]. aClass compile: reader classified: 'accessing'. aClass compile: writer classified: 'accessingâ.
removingFrom: aClass
aClass removeSelector: self name. aClass removeSelector: self name asMutator.
Now we can make a class and see how the accessors are automatically added (and removed when the slot is removed):
Object subclass: #TT slots: { #tttt => AccessorSlot } classVariables: { } category: âPackage'
NOTE: this is an example of what can be done with Slots. It is *not* an example of what *should* be done with Slots. (this we only will know after using them for a while).
Marcus
On Fri, Feb 6, 2015 at 10:13 PM, stepharo <stepharo@free.fr> wrote:
I want relationships for certain modeling purposes What I like is that we should arrive to get a collection of useful slots with optimal implementation instead all of us reinventing the wheel.
I have started to collect the examples in Slots-Examples (in #481). At the start these are artificial (just testing/showing something), but slowly we will add useful ones, too.
I started to implement PropertySlot, this uses hidden slots, initialisation (to set the empty dictionary of the base slot), virtual slots (the proper slots), reflectively changing the class both when adding and removing (to add the base slot and remove it as needed). Marcus
On 07 Feb 2015, at 18:29, Marcus Denker <marcus.denker@inria.fr> wrote:
On Fri, Feb 6, 2015 at 10:13 PM, stepharo <stepharo@free.fr <mailto:stepharo@free.fr>> wrote: I want relationships for certain modeling purposes What I like is that we should arrive to get a collection of useful slots with optimal implementation instead all of us reinventing the wheel.
I have started to collect the examples in Slots-Examples (in #481). At the start these are artificial (just testing/showing something), but slowly we will add useful ones, too.
I started to implement PropertySlot, this uses hidden slots, initialisation (to set the empty dictionary of the base slot), virtual slots (the proper slots), reflectively changing the class both when adding and removing (to add the base slot and remove it as needed).
and custom byte code generation to read and write with just #at: and #at:put on the base slot⦠Marcus
On Sat, Feb 7, 2015 at 9:35 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 07 Feb 2015, at 18:29, Marcus Denker <marcus.denker@inria.fr> wrote:
On Fri, Feb 6, 2015 at 10:13 PM, stepharo <stepharo@free.fr> wrote:
I want relationships for certain modeling purposes What I like is that we should arrive to get a collection of useful slots with optimal implementation instead all of us reinventing the wheel.
I have started to collect the examples in Slots-Examples (in #481). At the start these are artificial (just testing/showing something), but slowly we will add useful ones, too.
I started to implement PropertySlot, this uses hidden slots, initialisation (to set the empty dictionary of the base slot), virtual slots (the proper slots), reflectively changing the class both when adding and removing (to add the base slot and remove it as needed).
and custom byte code generation to read and write with just #at: and #at:put on the base slotâ¦
and remember that the closure bytecodes can access a field without a bounds check 140 10001100 kkkkkkkk jjjjjjjj Push Temp At kkkkkkkk In Temp Vector At: jjjjjjjj 141 10001101 kkkkkkkk jjjjjjjj Store Temp At kkkkkkkk In Temp Vector At: jjjjjjjj 142 10001110 kkkkkkkk jjjjjjjj Pop and Store Temp At kkkkkkkk In Temp Vector At: jjjjjjjj -- best, Eliot
On 07 Feb 2015, at 21:11, Eliot Miranda <eliot.miranda@gmail.com> wrote:
On Sat, Feb 7, 2015 at 9:35 AM, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 07 Feb 2015, at 18:29, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On Fri, Feb 6, 2015 at 10:13 PM, stepharo <stepharo@free.fr <mailto:stepharo@free.fr>> wrote: I want relationships for certain modeling purposes What I like is that we should arrive to get a collection of useful slots with optimal implementation instead all of us reinventing the wheel.
I have started to collect the examples in Slots-Examples (in #481). At the start these are artificial (just testing/showing something), but slowly we will add useful ones, too.
I started to implement PropertySlot, this uses hidden slots, initialisation (to set the empty dictionary of the base slot), virtual slots (the proper slots), reflectively changing the class both when adding and removing (to add the base slot and remove it as needed).
and custom byte code generation to read and write with just #at: and #at:put on the base slotâ¦
and remember that the closure bytecodes can access a field without a bounds check
140 10001100 kkkkkkkk jjjjjjjj Push Temp At kkkkkkkk In Temp Vector At: jjjjjjjj 141 10001101 kkkkkkkk jjjjjjjj Store Temp At kkkkkkkk In Temp Vector At: jjjjjjjj 142 10001110 kkkkkkkk jjjjjjjj Pop and Store Temp At kkkkkkkk In Temp Vector At: jjjjjjjj
Yes! We can make a Slot that stores in a hidden Array⦠should be very efficient (both space and speed-wise). (of course with Spur no that needed anymoreâ¦) Marcus
On 07 Feb 2015, at 18:35, Marcus Denker <marcus.denker@inria.fr> wrote:
On 07 Feb 2015, at 18:29, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On Fri, Feb 6, 2015 at 10:13 PM, stepharo <stepharo@free.fr <mailto:stepharo@free.fr>> wrote: I want relationships for certain modeling purposes What I like is that we should arrive to get a collection of useful slots with optimal implementation instead all of us reinventing the wheel.
I have started to collect the examples in Slots-Examples (in #481). At the start these are artificial (just testing/showing something), but slowly we will add useful ones, too.
I started to implement PropertySlot, this uses hidden slots, initialisation (to set the empty dictionary of the base slot), virtual slots (the proper slots), reflectively changing the class both when adding and removing (to add the base slot and remove it as needed).
More progress⦠I will commit it after the CI is working again. - fix #usingMethods for non installed Slots - not yet completely working PropertySlot implementation (will add issue tracker entries for what is missing) - move example Slots to Slots-Examples - rename TestSlot and move it to Slots-Examples I added Project on the issue tracker for all Slot related issues. I will add everything there that needs to be done. I will do the same for Reflectivity later (the idea is to now have progress there every day, too). First things DONE: - pop when generating code with LinkWrapper Marcus
More progress⦠I will commit it after the CI is working again.
- fix #usingMethods for non installed Slots - not yet completely working PropertySlot implementation (will add issue tracker entries for what is missing) - move example Slots to Slots-Examples - rename TestSlot and move it to Slots-Examples
I added Project on the issue tracker for all Slot related issues. I will add everything there that needs to be done.
I will do the same for Reflectivity later (the idea is to now have progress there every day, too).
First things DONE:
- pop when generating code with LinkWrapper
This is now in 40 489 Marcus
On 13 Feb 2015, at 18:38, Marcus Denker <marcus.denker@inria.fr> wrote:
More progress⦠I will commit it after the CI is working again.
- fix #usingMethods for non installed Slots - not yet completely working PropertySlot implementation (will add issue tracker entries for what is missing) - move example Slots to Slots-Examples - rename TestSlot and move it to Slots-Examples
I added Project on the issue tracker for all Slot related issues. I will add everything there that needs to be done.
I will do the same for Reflectivity later (the idea is to now have progress there every day, too).
First things DONE:
- pop when generating code with LinkWrapper
This is now in 40 489
Marcus
This is great stuff you are doing, Marcus, lots of small steps ...
I started to implement PropertySlot, this uses hidden slots, initialisation (to set the empty dictionary of the base slot), virtual slots (the proper slots), reflectively changing the class both when adding and removing (to add the base slot and remove it as needed).
Next tiny step: 14914 #initializeSlots: should not skip hidden slots https://pharo.fogbugz.com/f/cases/14914/initializeSlots-should-not-skip-hidd... Now the slots get correctly called when initialising an object. To test: Object subclass: #TT slots: { #tt => PropertySlot } classVariables: { } category: âPlayground' The slot will add an #initialize methods to the class when it gets installed. When you inspect TT new you can see just the tt slot (you can change it in the inspector). Adding an accessor for tt will show what the compiler does: 21 <20> pushConstant: #tt => PropertySlot 22 <70> self 23 <E1> send: read: 24 <7C> returnTop this means that it compiles a reflective read for that slot. next: -> remove the hidden slot when removing the last property slot -> add a GTInspector view that shows the *real* object layout -> when adding a propertySlot higher up in the hierarchy where there are already some down, we need to move the base slot up. -> generate better byte code, the reflective read is of course slow. Tiny steps⦠Marcus
-> generate better byte code, the reflective read is of course slow.
this is easy. What we need to do is to override #emitValue: and #emitStore: emitValue: methodBuilder methodBuilder pushInstVar: baseSlot index; pushLiteral: self name; pushLiteral: nil; send: #at:ifAbsent: for storing, the problem is that the value to be saved is on top of the stack. so we need to first save it and pop it off to be able to use #at:put:: emitStore: methodBuilder | tempName | tempName := ('0generated_',self name) asSymbol. methodBuilder addTemp: tempName; storeTemp: tempName; popTop; pushInstVar: baseSlot index; pushLiteral: self name; pushTemp: tempName; send: #at:put: if we do that and recompile the accessors, we get: [(TT new tt: 1) tt] bench none: "'408,000 per second.'" + bc for write slot: "'455,000 per second.'" + bc for read: "'487,000 per second.'" (most of the time is spend in dictionary access, of course) Marcus
On 19 Feb 2015, at 10:45, Marcus Denker <marcus.denker@inria.fr> wrote:
-> generate better byte code, the reflective read is of course slow.
this is easy. What we need to do is to override #emitValue: and #emitStore:
emitValue: methodBuilder
methodBuilder pushInstVar: baseSlot index; pushLiteral: self name; pushLiteral: nil; send: #at:ifAbsent:
for storing, the problem is that the value to be saved is on top of the stack. so we need to first save it and pop it off to be able to use #at:put::
emitStore: methodBuilder | tempName |
tempName := ('0generated_',self name) asSymbol.
methodBuilder addTemp: tempName; storeTemp: tempName; popTop; pushInstVar: baseSlot index; pushLiteral: self name; pushTemp: tempName; send: #at:put:
committed. https://pharo.fogbugz.com/f/cases/14962/emit-bytecode-for-PropertySlot-impro... This in addition uses the same trick of the temp to not need a writeToSlot:of: method in object for the default code generated for reflective write of slots. Marcus
On 19 Feb 2015, at 10:19, Marcus Denker <marcus.denker@inria.fr> wrote:
I started to implement PropertySlot, this uses hidden slots, initialisation (to set the empty dictionary of the base slot), virtual slots (the proper slots), reflectively changing the class both when adding and removing (to add the base slot and remove it as needed).
Next tiny step:
14914 #initializeSlots: should not skip hidden slots https://pharo.fogbugz.com/f/cases/14914/initializeSlots-should-not-skip-hidd...
This is now finally in 502⦠5 days feel like eternity.
Now the slots get correctly called when initialising an object. To test:
Object subclass: #TT slots: { #tt => PropertySlot } classVariables: { } category: âPlayground'
The slot will add an #initialize methods to the class when it gets installed.
When you inspect
TT new
you can see just the tt slot (you can change it in the inspector).
Adding an accessor for tt will show what the compiler does:
21 <20> pushConstant: #tt => PropertySlot 22 <70> self 23 <E1> send: read: 24 <7C> returnTop
this means that it compiles a reflective read for that slot.
On 06 Feb 2015, at 18:15, Marcus Denker <marcus.denker@inria.fr> wrote:
On 06 Feb 2015, at 11:50, Marcus Denker <marcus.denker@inria.fr> wrote:
Next: When building classes with Slots, the class builder need to call back on the slot and hand the class to each. Then the slot can reflectively change the class, e.g. the PropertySlot will check if there is already a hidden property base slot and if not, add it reflectively).
This is now done:
https://pharo.fogbugz.com/f/cases/14876/Add-call-back-in-ClassBuilder-to-cal...
So, with this mechanism in place we can actually solve a nice problem: Slot initialisation. on #initialize, we want to hand the new object to each slot to give it a change to initialize it. Now adding self allSlots do: [ :slot | slot initialize: anObject ] to #initialize and doing that for all object is not good as this would slot down all #initialize calls. We might want to pay that later when if we happen to use it a lot, but now now. https://pharo.fogbugz.com/f/cases/14882/Slots-add-mechanism-for-initializing... <https://pharo.fogbugz.com/f/cases/14882/Slots-add-mechanism-for-initializing...> now implements it this way: 1) Slots that want #initialize: the be called on allocation need to implement #wantsInitalization 2) Then magically we add #initialize if needed and, if needed, add self class initializeSlots: self. to it. (this for now just uses text manipulation⦠later this will be a nice example for a concept that we need to reify as part of the MOP: âI want to hook into object initializationâ). Playing with it âââââââ (I need to add a testsâ¦) InstanceVariableSlot subclass: #InitSlot slots: { } classVariables: { } category: âPlayGround' initialize: anObject self write: 5 to: anObject. wantsInitalization ^ true Now create a class: Object subclass: #MyCClass slots: { #ttt => InitSlot } classVariables: { } category: âPlayGround' MyCClass new ==> ttt is initialised with 5. For what is this useful? âââââââââââ 1) e.g. the virtual slot that hold the dictionary for all PropertySlots needs to be initialised with an empty Dict 2) We can start to experiment with Slots that specify a value in the definition 3) â¦. Marcus
On 07 Feb 2015, at 10:13, Marcus Denker <marcus.denker@inria.fr> wrote:
On 06 Feb 2015, at 18:15, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 06 Feb 2015, at 11:50, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
Next: When building classes with Slots, the class builder need to call back on the slot and hand the class to each. Then the slot can reflectively change the class, e.g. the PropertySlot will check if there is already a hidden property base slot and if not, add it reflectively).
This is now done:
https://pharo.fogbugz.com/f/cases/14876/Add-call-back-in-ClassBuilder-to-cal... <https://pharo.fogbugz.com/f/cases/14876/Add-call-back-in-ClassBuilder-to-cal...>
So, with this mechanism in place we can actually solve a nice problem: Slot initialisation.
on #initialize, we want to hand the new object to each slot to give it a change to initialize it. Now adding self allSlots do: [ :slot | slot initialize: anObject ]
to #initialize and doing that for all object is not good as this would slot down all #initialize calls. We might want to pay that later when if we happen to use it a lot, but now now.
https://pharo.fogbugz.com/f/cases/14882/Slots-add-mechanism-for-initializing... <https://pharo.fogbugz.com/f/cases/14882/Slots-add-mechanism-for-initializing...>
This is now in update #470 Marcus
participants (7)
-
Ben Coman -
Clément Bera -
Eliot Miranda -
Marcus Denker -
stepharo -
Sven Van Caekenberghe -
Tudor Girba