[Pharo-project] about sharing class binding and others
While I love the idea of sharing the systemDictionary class binding in the method to gain immediate update in case of change I was questioning myself if we could not gain from not having (for example to get parametrized modules). The point is that we are not constantly changing classes especially when not programming but running program. So let us do some experiments: CompiledMethod allInstances size 58891 (CompiledMethod allInstances select: [:each | each classBinding value name = #Point]) size 100 [CompiledMethod allInstances select: [:each | each classBinding value name = #Point]] timeToRun 23 this is the best case since classBinding is at a fixed size now looking for any reference to Point (CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]) size 134 methods. [CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]] timeToRun 91 ms so it looks to me that this sharing is not something that we should not changed if needed. What do you think? Stef
On Nov 16, 2012, at 6:55 PM, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
While I love the idea of sharing the systemDictionary class binding in the method to gain immediate update in case of change I was questioning myself if we could not gain from not having (for example to get parametrized modules).
The point is that we are not constantly changing classes especially when not programming but running program.
The alternative to the current scheme would be to not hard-code the class at all in the method at compile time. Instead of looking up the class and compiling the shared literal association, we could compile a message send to the current environment. self class environment at: #NameOfClass And it should be noted that this could be evaluated at Jit-compile time... the same is true for ivar offsets. There is no reason why these should be visible at the image level. The image could talk about names and let the runtime translator infrastucture do the lookups needed for making a static version that is fast. Marcus -- Marcus Denker -- http://marcusdenker.de
On Nov 16, 2012, at 8:02 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Nov 16, 2012, at 6:55 PM, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
While I love the idea of sharing the systemDictionary class binding in the method to gain immediate update in case of change I was questioning myself if we could not gain from not having (for example to get parametrized modules).
The point is that we are not constantly changing classes especially when not programming but running program.
The alternative to the current scheme would be to not hard-code the class at all in the method at compile time.
Instead of looking up the class and compiling the shared literal association, we could compile a message send to the current environment.
self class environment at: #NameOfClass
And it should be noted that this could be evaluated at Jit-compile time... the same is true for ivar offsets. There is no reason why these should be visible at the image level. The image could talk about names and let the runtime translator infrastucture do the lookups needed for making a static version that is fast.
And it should be noted that we don't loose anything: -> Undeclareds would disappear. Using non-existing classes leads to a runtime error, like sending non-existing messages. -> It would be slower in the pure-interpreter case. But anyone who knows me knows that I want to get rid of bytecode as a user-visible artefact... this means, the interpreter would either be an AST interpreter or it would "JIT" the AST into the virtual processor instructions before running. So: the way to go. Marcus -- Marcus Denker -- http://marcusdenker.de
The alternative to the current scheme would be to not hard-code the class at all in the method at compile time.
Instead of looking up the class and compiling the shared literal association, we could compile a message send to the current environment.
self class environment at: #NameOfClass
And it should be noted that this could be evaluated at Jit-compile time... the same is true for ivar offsets. There is no reason why these should be visible at the image level. The image could talk about names and let the runtime translator infrastucture do the lookups needed for making a static version that is fast.
Yes I would like to measure that too. My benchmarks were to measure the worse case where we have to manually update the methods each time the class is modified.
On Sat, Nov 17, 2012 at 12:02 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
Instead of looking up the class and compiling the shared literal association, we could compile a message send to the current environment.
self class environment at: #NameOfClass
can something similar be done for instance variable references? -- Damien Cassou http://damiencassou.seasidehosting.st "Success is the ability to go from one failure to another without losing enthusiasm." Winston Churchill
On 2012-11-17, at 13:22, Damien Cassou <damien.cassou@gmail.com> wrote:
On Sat, Nov 17, 2012 at 12:02 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
Instead of looking up the class and compiling the shared literal association, we could compile a message send to the current environment.
self class environment at: #NameOfClass
can something similar be done for instance variable references?
slots + layouts will do that.
I don't see the benefit of the added complexity. As it is now, at compile time the reference is not bound to a global but to an Association holding the global. If you want to change the value of the global you can do so and the method will reference the new value. Also, if you want to do name-lookup at runtime you can explicitly code it to do that. My objection to always doing run-time name lookup is that I would like to be able to create a module that is self-contained and binds to the the classes I provide without risking that someone else will replace my classes. I would like you to be able to load my module, containing my classes and methods, and we both can be confident that your later changes (including different classes with the same name) will not impact my classes and methods. If you want a parameterized module, then the module should be explicitly coded to take a parameter and use it explicitly. I think it is not as clear to let the module think it is referencing a Point but in fact play a trick on it to have it reference a different class. - James On Nov 16, 2012, at 6:17 PM, Stéphane Ducasse wrote:
While I love the idea of sharing the systemDictionary class binding in the method to gain immediate update in case of change I was questioning myself if we could not gain from not having (for example to get parametrized modules).
The point is that we are not constantly changing classes especially when not programming but running program.
So let us do some experiments:
CompiledMethod allInstances size 58891
(CompiledMethod allInstances select: [:each | each classBinding value name = #Point]) size 100
[CompiledMethod allInstances select: [:each | each classBinding value name = #Point]] timeToRun 23
this is the best case since classBinding is at a fixed size
now looking for any reference to Point
(CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]) size 134 methods.
[CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]] timeToRun 91 ms
so it looks to me that this sharing is not something that we should not changed if needed.
What do you think?
Stef
On Sun, Nov 18, 2012 at 10:40 PM, James Foster <Smalltalk@jgfoster.net>wrote:
I don't see the benefit of the added complexity. As it is now, at compile time the reference is not bound to a global but to an Association holding the global. If you want to change the value of the global you can do so and the method will reference the new value. Also, if you want to do name-lookup at runtime you can explicitly code it to do that.
My objection to always doing run-time name lookup is that I would like to be able to create a module that is self-contained and binds to the the classes I provide without risking that someone else will replace my classes. I would like you to be able to load my module, containing my classes and methods, and we both can be confident that your later changes (including different classes with the same name) will not impact my classes and methods.
If you want a parameterized module, then the module should be explicitly coded to take a parameter and use it explicitly. I think it is not as clear to let the module think it is referencing a Point but in fact play a trick on it to have it reference a different class.
- James
On Nov 16, 2012, at 6:17 PM, Stéphane Ducasse wrote:
While I love the idea of sharing the systemDictionary class binding in the method to gain immediate update in case of change I was questioning myself if we could not gain from not having (for example to get parametrized modules).
The point is that we are not constantly changing classes especially when not programming but running program.
So let us do some experiments:
CompiledMethod allInstances size 58891
(CompiledMethod allInstances select: [:each | each classBinding value name = #Point]) size 100
[CompiledMethod allInstances select: [:each | each classBinding value name = #Point]] timeToRun 23
this is the best case since classBinding is at a fixed size
now looking for any reference to Point
(CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]) size 134 methods.
[CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]] timeToRun 91 ms
so it looks to me that this sharing is not something that we should not changed if needed.
What do you think?
Stef
+1 -- Cheers, Peter
On Nov 18, 2012, at 10:40 PM, James Foster wrote:
I don't see the benefit of the added complexity. As it is now, at compile time the reference is not bound to a global but to an Association holding the global. If you want to change the value of the global you can do so and the method will reference the new value. Also, if you want to do name-lookup at runtime you can explicitly code it to do that.
My objection to always doing run-time name lookup is that I would like to be able to create a module that is self-contained and binds to the the classes I provide without risking that someone else will replace my classes. I would like you to be able to load my module, containing my classes and methods, and we both can be confident that your later changes (including different classes with the same name) will not impact my classes and methods.
If you want a parameterized module, then the module should be explicitly coded to take a parameter and use it explicitly.
yes Module name: 'FOO' binds: #A to: #Core.Z Module name: 'FOO2' binds: #A to: #My.Z My original mail was to measure how much it costs to avoid to have the sharing of the system dictionary class binding in the method literal. Because the design above requires to not share binding. I'm going over the master of camille and I would like to make such points clearer. So with my little investigation it shows that we can support life programming without sharing bindings. Stef
I think it is not as clear to let the module think it is referencing a Point but in fact play a trick on it to have it reference a different class.
- James
On Nov 16, 2012, at 6:17 PM, Stéphane Ducasse wrote:
While I love the idea of sharing the systemDictionary class binding in the method to gain immediate update in case of change I was questioning myself if we could not gain from not having (for example to get parametrized modules).
The point is that we are not constantly changing classes especially when not programming but running program.
So let us do some experiments:
CompiledMethod allInstances size 58891
(CompiledMethod allInstances select: [:each | each classBinding value name = #Point]) size 100
[CompiledMethod allInstances select: [:each | each classBinding value name = #Point]] timeToRun 23
this is the best case since classBinding is at a fixed size
now looking for any reference to Point
(CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]) size 134 methods.
[CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]] timeToRun 91 ms
so it looks to me that this sharing is not something that we should not changed if needed.
What do you think?
Stef
On 18 November 2012 21:53, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
On Nov 18, 2012, at 10:40 PM, James Foster wrote:
I don't see the benefit of the added complexity. As it is now, at compile time the reference is not bound to a global but to an Association holding the global. If you want to change the value of the global you can do so and the method will reference the new value. Also, if you want to do name-lookup at runtime you can explicitly code it to do that.
My objection to always doing run-time name lookup is that I would like to be able to create a module that is self-contained and binds to the the classes I provide without risking that someone else will replace my classes. I would like you to be able to load my module, containing my classes and methods, and we both can be confident that your later changes (including different classes with the same name) will not impact my classes and methods.
If you want a parameterized module, then the module should be explicitly coded to take a parameter and use it explicitly.
yes
Module name: 'FOO' binds: #A to: #Core.Z
Module name: 'FOO2' binds: #A to: #My.Z
My original mail was to measure how much it costs to avoid to have the sharing of the system dictionary class binding in the method literal. Because the design above requires to not share binding.
I'm going over the master of camille and I would like to make such points clearer. So with my little investigation it shows that we can support life programming without sharing bindings.
Once Squeak 4.4 has been released, we'll be re-importing Colin Putney's Environments work, which seeks to do this. It might be worthwhile talking to him about modularisation. (Environments right now only handles class-level issues; it doesn't do anything like selector namespacing or classboxes or anything like that.) frank
Stef
I think it is not as clear to let the module think it is referencing a Point but in fact play a trick on it to have it reference a different class.
- James
On Nov 16, 2012, at 6:17 PM, Stéphane Ducasse wrote:
While I love the idea of sharing the systemDictionary class binding in the method to gain immediate update in case of change I was questioning myself if we could not gain from not having (for example to get parametrized modules).
The point is that we are not constantly changing classes especially when not programming but running program.
So let us do some experiments:
CompiledMethod allInstances size 58891
(CompiledMethod allInstances select: [:each | each classBinding value name = #Point]) size 100
[CompiledMethod allInstances select: [:each | each classBinding value name = #Point]] timeToRun 23
this is the best case since classBinding is at a fixed size
now looking for any reference to Point
(CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]) size 134 methods.
[CompiledMethod allInstances select: [:cm | cm literals anySatisfy: [:each | each class = Association and: [each key = #Point ]]]] timeToRun 91 ms
so it looks to me that this sharing is not something that we should not changed if needed.
What do you think?
Stef
participants (7)
-
Camillo Bruni -
Damien Cassou -
Frank Shearar -
James Foster -
Marcus Denker -
Peter Hugosson-Miller -
Stéphane Ducasse