Hi, In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin. What does that do? you can call on a method #createTwin (ReflectivityExamples>>#exampleMethod) createTwin. after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod (they form a twin). (ReflectivityExamples>>#exampleMethod) reflectiveMethod The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed. ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the method dict and then executes the method: (ReflectivityExamples>>#exampleMethod) createTwin. (ReflectivityExamples>>#exampleMethod) invalidate. self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod. self assert: ReflectivityExamples new exampleMethod = 5. self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod. Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code. e.g. try on Morph: Morph methods do: #createTwin. Morph methods do: #invalidate. Counting which twin is installed shows us the working set of Morph: (Morph methods select: [ :each | each class = CompiledMethod ]) size some 330 method out of nearly 900â¦. So what can one do with this? In essence this turns the AST into a reflective representation for Methods (if you care to set up twin creation + invalidation correctly). What will this allow us to do? stay tuned... Marcus
This is excellent!
On Feb 26, 2015, at 20:07, Marcus Denker <marcus.denker@inria.fr> wrote:
Hi,
In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin.
What does that do?
you can call on a method #createTwin
(ReflectivityExamples>>#exampleMethod) createTwin.
after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod (they form a twin).
(ReflectivityExamples>>#exampleMethod) reflectiveMethod
The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed.
ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the method dict and then executes the method:
(ReflectivityExamples>>#exampleMethod) createTwin. (ReflectivityExamples>>#exampleMethod) invalidate. self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod. self assert: ReflectivityExamples new exampleMethod = 5. self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod.
Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code.
e.g. try on Morph:
Morph methods do: #createTwin. Morph methods do: #invalidate.
Counting which twin is installed shows us the working set of Morph:
(Morph methods select: [ :each | each class = CompiledMethod ]) size
some 330 method out of nearly 900â¦.
So what can one do with this? In essence this turns the AST into a reflective representation for Methods (if you care to set up twin creation + invalidation correctly).
What will this allow us to do? stay tuned...
Marcus
---> Save our in-boxes! http://emailcharter.org <--- Johan Fabry - http://pleiad.cl/~jfabry PLEIAD lab - Computer Science Department (DCC) - University of Chile
Wow!!! This means that one can call #createTwin, modify the AST, and simply call it! Impressive!!! Is it per default in Pharo 40516? Alexandre
On Feb 26, 2015, at 8:07 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
Hi,
In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin.
What does that do?
you can call on a method #createTwin
(ReflectivityExamples>>#exampleMethod) createTwin.
after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod (they form a twin).
(ReflectivityExamples>>#exampleMethod) reflectiveMethod
The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed.
ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the method dict and then executes the method:
(ReflectivityExamples>>#exampleMethod) createTwin. (ReflectivityExamples>>#exampleMethod) invalidate. self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod. self assert: ReflectivityExamples new exampleMethod = 5. self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod.
Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code.
e.g. try on Morph:
Morph methods do: #createTwin. Morph methods do: #invalidate.
Counting which twin is installed shows us the working set of Morph:
(Morph methods select: [ :each | each class = CompiledMethod ]) size
some 330 method out of nearly 900â¦.
So what can one do with this? In essence this turns the AST into a reflective representation for Methods (if you care to set up twin creation + invalidation correctly).
What will this allow us to do? stay tuned...
Marcus
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
Cool! (spotter does not work on this methods, do we have to change this in the class ReactiveMethod or spotter?)
On 27 Feb 2015, at 00:15, Alexandre Bergel <alexandre.bergel@me.com> wrote:
Wow!!! This means that one can call #createTwin, modify the AST, and simply call it! Impressive!!!
You need to handle invalidation yourself, too. (for now). I want to first concentrate on purely âannotationâ based MOP: instead of changing the AST it is annotated with MetaLinks. When a link is set, the twin creation + invalidation happens. When the last Link is removed, the twin disappears automatically.
Is it per default in Pharo 40516?
Yes. Marcus
On 27 Feb 2015, at 00:26, Marcus Denker <marcus.denker@inria.fr> wrote:
On 27 Feb 2015, at 00:15, Alexandre Bergel <alexandre.bergel@me.com> wrote:
Wow!!! This means that one can call #createTwin, modify the AST, and simply call it! Impressive!!!
You need to handle invalidation yourself, too. (for now). I want to first concentrate on purely âannotationâ based MOP: instead of changing the AST it is annotated with MetaLinks. When a link is set, the twin creation + invalidation happens. When the last Link is removed, the twin disappears automatically.
Is it per default in Pharo 40516?
Yes.
and it does not yet recompile⦠recompileAST self flag: #TBD. "compile the ASTâ :-)
I hope that we will get better profilers alex :) Le 27/2/15 00:15, Alexandre Bergel a écrit :
Wow!!! This means that one can call #createTwin, modify the AST, and simply call it! Impressive!!! Is it per default in Pharo 40516?
Alexandre
On Feb 26, 2015, at 8:07 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
Hi,
In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin.
What does that do?
you can call on a method #createTwin
(ReflectivityExamples>>#exampleMethod) createTwin.
after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod (they form a twin).
(ReflectivityExamples>>#exampleMethod) reflectiveMethod
The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed.
ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the method dict and then executes the method:
(ReflectivityExamples>>#exampleMethod) createTwin. (ReflectivityExamples>>#exampleMethod) invalidate. self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod. self assert: ReflectivityExamples new exampleMethod = 5. self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod.
Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code.
e.g. try on Morph:
Morph methods do: #createTwin. Morph methods do: #invalidate.
Counting which twin is installed shows us the working set of Morph:
(Morph methods select: [ :each | each class = CompiledMethod ]) size
some 330 method out of nearly 900â¦.
So what can one do with this? In essence this turns the AST into a reflective representation for Methods (if you care to set up twin creation + invalidation correctly).
What will this allow us to do? stay tuned...
Marcus
So many cool things! We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing. Thanks a lot, Doru On Fri, Feb 27, 2015 at 12:07 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
Hi,
In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin.
What does that do?
you can call on a method #createTwin
(ReflectivityExamples>>#exampleMethod) createTwin.
after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod (they form a twin).
(ReflectivityExamples>>#exampleMethod) reflectiveMethod
The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed.
ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the method dict and then executes the method:
(ReflectivityExamples>>#exampleMethod) createTwin. (ReflectivityExamples>>#exampleMethod) invalidate. self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod. self assert: ReflectivityExamples new exampleMethod = 5. self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod.
Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code.
e.g. try on Morph:
Morph methods do: #createTwin. Morph methods do: #invalidate.
Counting which twin is installed shows us the working set of Morph:
(Morph methods select: [ :each | each class = CompiledMethod ]) size
some 330 method out of nearly 900â¦.
So what can one do with this? In essence this turns the AST into a reflective representation for Methods (if you care to set up twin creation + invalidation correctly).
What will this allow us to do? stay tuned...
Marcus
-- www.tudorgirba.com "Every thing has its own flow"
On Fri, Feb 27, 2015 at 12:35 PM, Tudor Girba <tudor@tudorgirba.com> wrote:
So many cool things!
We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing.
Interestingly, the world view of most people is different... they never realise this, they seem to fundamentally not see this connection. I have not yet found out why... Marcus
I can explain why, its the language you use. For example this feature, I have no clue what you guys are talking about. For people to be impressed first they need to understand what they should be impressed with. On Fri, Feb 27, 2015 at 2:12 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Fri, Feb 27, 2015 at 12:35 PM, Tudor Girba <tudor@tudorgirba.com> wrote:
So many cool things!
We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing.
Interestingly, the world view of most people is different... they never realise this, they seem to fundamentally not see this connection. I have not yet found out why...
Marcus
On 27 Feb 2015, at 13:24, kilon alios <kilon.alios@gmail.com> wrote:
I can explain why, its the language you use.
For example this feature, I have no clue what you guys are talking about.
For people to be impressed first they need to understand what they should be impressed with.
I did not mean this feature. I mean the abstract concept of improvement having an effect.
On Fri, Feb 27, 2015 at 2:12 PM, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On Fri, Feb 27, 2015 at 12:35 PM, Tudor Girba <tudor@tudorgirba.com <mailto:tudor@tudorgirba.com>> wrote: So many cool things!
We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing.
Interestingly, the world view of most people is different... they never realise this, they seem to fundamentally not see this connection. I have not yet found out why...
Marcus
Looks super cool :) Now that I finished my exams I can get back on this too... Thanks a lot Marcus :) 2015-02-27 9:34 GMT-03:00 Marcus Denker <marcus.denker@inria.fr>:
On 27 Feb 2015, at 13:24, kilon alios <kilon.alios@gmail.com> wrote:
I can explain why, its the language you use.
For example this feature, I have no clue what you guys are talking about.
For people to be impressed first they need to understand what they should be impressed with.
I did not mean this feature. I mean the abstract concept of improvement having an effect.
On Fri, Feb 27, 2015 at 2:12 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Fri, Feb 27, 2015 at 12:35 PM, Tudor Girba <tudor@tudorgirba.com> wrote:
So many cool things!
We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing.
Interestingly, the world view of most people is different... they never realise this, they seem to fundamentally not see this connection. I have not yet found out why...
Marcus
On 27 Feb 2015, at 13:59, Clara Allende <clari.allende@gmail.com> wrote:
Looks super cool :) Now that I finished my exams I can get back on this too...
Very good! The idea is to step-by-step take your prototype and move it over. Next I will do the link-setting infrastructure: - set a link on the AST -> create twin/invalidate - remove last link -> twin disappears. For the AST transformer I want to build a tiny Plugin-Architecture for Opal (which then people can use for more crazy experiments, too). Marcus
Great news! I'll get in touch with you and see how I can help :) 2015-02-27 10:16 GMT-03:00 Marcus Denker <marcus.denker@inria.fr>:
On 27 Feb 2015, at 13:59, Clara Allende <clari.allende@gmail.com> wrote:
Looks super cool :) Now that I finished my exams I can get back on this too...
Very good!
The idea is to step-by-step take your prototype and move it over.
Next I will do the link-setting infrastructure: - set a link on the AST -> create twin/invalidate - remove last link -> twin disappears.
For the AST transformer I want to build a tiny Plugin-Architecture for Opal (which then people can use for more crazy experiments, too).
Yay! I love this :)
Marcus
Thanks clara. Le 27/2/15 14:24, Clara Allende a écrit :
Great news! I'll get in touch with you and see how I can help :)
2015-02-27 10:16 GMT-03:00 Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>>:
> On 27 Feb 2015, at 13:59, Clara Allende <clari.allende@gmail.com <mailto:clari.allende@gmail.com>> wrote: > > Looks super cool :) Now that I finished my exams I can get back on this too...
Very good!
The idea is to step-by-step take your prototype and move it over.
Next I will do the link-setting infrastructure: - set a link on the AST -> create twin/invalidate - remove last link -> twin disappears.
For the AST transformer I want to build a tiny Plugin-Architecture for Opal (which then people can use for more crazy experiments, too).
Yay! I love this :)
Marcus
Sooner or later then you will have to name people, because talking generally wont change the situation. Who in this community believe that improving Pharo is pointless / does not have an effect ? I am getting totally opposite feeling with this community. One the reasons I enjoy Pharo. On Fri, Feb 27, 2015 at 2:34 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 27 Feb 2015, at 13:24, kilon alios <kilon.alios@gmail.com> wrote:
I can explain why, its the language you use.
For example this feature, I have no clue what you guys are talking about.
For people to be impressed first they need to understand what they should be impressed with.
I did not mean this feature. I mean the abstract concept of improvement having an effect.
On Fri, Feb 27, 2015 at 2:12 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Fri, Feb 27, 2015 at 12:35 PM, Tudor Girba <tudor@tudorgirba.com> wrote:
So many cool things!
We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing.
Interestingly, the world view of most people is different... they never realise this, they seem to fundamentally not see this connection. I have not yet found out why...
Marcus
Sooner or later then you will have to name people, because talking generally wont change the situation.
Who in this community believe that improving Pharo is pointless / does not have an effect ?
marcus is not mentioning people in this community but outside.
I am getting totally opposite feeling with this community. One the reasons I enjoy Pharo.
Me too. And the infrastructure is getting really really great. To be point that I cannot see what the people will do with it. So this is great,
On Fri, Feb 27, 2015 at 2:34 PM, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On 27 Feb 2015, at 13:24, kilon alios <kilon.alios@gmail.com <mailto:kilon.alios@gmail.com>> wrote:
I can explain why, its the language you use.
For example this feature, I have no clue what you guys are talking about.
For people to be impressed first they need to understand what they should be impressed with.
I did not mean this feature. I mean the abstract concept of improvement having an effect.
On Fri, Feb 27, 2015 at 2:12 PM, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On Fri, Feb 27, 2015 at 12:35 PM, Tudor Girba <tudor@tudorgirba.com <mailto:tudor@tudorgirba.com>> wrote:
So many cool things!
We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing.
Interestingly, the world view of most people is different... they never realise this, they seem to fundamentally not see this connection. I have not yet found out why...
Marcus
I see , I did not realise there is so much negative about Pharo since most people dont seem to be aware of it and the moment they understand what it is they are impressed. At least people I introduced to Pharo. "Me too. And the infrastructure is getting really really great. To be point that I cannot see what the people will do with it. So this is great," I am also interested into maybe creating my own sub language in Pharo that can turn to pharo code but also offer features more orientated towards visual coding. But that is way down the road.
in essence we can annotate an AST and the annotations can become live at runtime and can also represents the computation itself. So you can have objects that represent properties of the execution itself and change the execution or something like that :). So with that we can for example build better debugger, profilers, Le 27/2/15 13:24, kilon alios a écrit :
I can explain why, its the language you use.
For example this feature, I have no clue what you guys are talking about.
For people to be impressed first they need to understand what they should be impressed with.
On Fri, Feb 27, 2015 at 2:12 PM, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
On Fri, Feb 27, 2015 at 12:35 PM, Tudor Girba <tudor@tudorgirba.com <mailto:tudor@tudorgirba.com>> wrote:
So many cool things!
We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing.
Interestingly, the world view of most people is different... they never realise this, they seem to fundamentally not see this connection. I have not yet found out why...
Marcus
so essentially live coding the live coding, wow that sounds impressive indeed. Thanks for taking the time explaining it. I guess this feature will be also very useful for people building DSLs with Pharo. On Fri, Feb 27, 2015 at 5:24 PM, stepharo <stepharo@free.fr> wrote:
in essence we can annotate an AST and the annotations can become live at runtime and can also represents the computation itself. So you can have objects that represent properties of the execution itself and change the execution or something like that :).
So with that we can for example build better debugger, profilers,
Le 27/2/15 13:24, kilon alios a écrit :
I can explain why, its the language you use.
For example this feature, I have no clue what you guys are talking about.
For people to be impressed first they need to understand what they should be impressed with.
On Fri, Feb 27, 2015 at 2:12 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On Fri, Feb 27, 2015 at 12:35 PM, Tudor Girba <tudor@tudorgirba.com> wrote:
So many cool things!
We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing.
Interestingly, the world view of most people is different... they never realise this, they seem to fundamentally not see this connection. I have not yet found out why...
Marcus
So many cool things!
We cannot even imagine at this point what all these little conceptual things will bring in downstream projects. This is amazing.
well there are large conceptual things made looking like little conceptual things :) This is the trick but yes we know were we go and I love it.
Thanks a lot, Doru
On Fri, Feb 27, 2015 at 12:07 AM, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
Hi,
In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin.
What does that do?
you can call on a method #createTwin
(ReflectivityExamples>>#exampleMethod) createTwin.
after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod (they form a twin).
(ReflectivityExamples>>#exampleMethod) reflectiveMethod
The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed.
ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the method dict and then executes the method:
(ReflectivityExamples>>#exampleMethod) createTwin. (ReflectivityExamples>>#exampleMethod) invalidate. self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod. self assert: ReflectivityExamples new exampleMethod = 5. self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod.
Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code.
e.g. try on Morph:
Morph methods do: #createTwin. Morph methods do: #invalidate.
Counting which twin is installed shows us the working set of Morph:
(Morph methods select: [ :each | each class = CompiledMethod ]) size
some 330 method out of nearly 900â¦.
So what can one do with this? In essence this turns the AST into a reflective representation for Methods (if you care to set up twin creation + invalidation correctly).
What will this allow us to do? stay tuned...
Marcus
-- www.tudorgirba.com <http://www.tudorgirba.com>
"Every thing has its own flow"
:) pay attention I have a lot of ideas for you to implement :) Stef Le 27/2/15 00:07, Marcus Denker a écrit :
Hi,
In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin.
What does that do?
you can call on a method #createTwin
(ReflectivityExamples>>#exampleMethod) createTwin.
after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod (they form a twin).
(ReflectivityExamples>>#exampleMethod) reflectiveMethod
The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed.
ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the method dict and then executes the method:
(ReflectivityExamples>>#exampleMethod) createTwin. (ReflectivityExamples>>#exampleMethod) invalidate. self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod. self assert: ReflectivityExamples new exampleMethod = 5. self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod.
Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code.
e.g. try on Morph:
Morph methods do: #createTwin. Morph methods do: #invalidate.
Counting which twin is installed shows us the working set of Morph:
(Morph methods select: [ :each | each class = CompiledMethod ]) size
some 330 method out of nearly 900â¦.
So what can one do with this? In essence this turns the AST into a reflective representation for Methods (if you care to set up twin creation + invalidation correctly).
What will this allow us to do? stay tuned...
Marcus
Hi Markus, if I understand correctly some of the possibilities: - I can use RBParseTreeSearcher / RBParseTreeRewriter on the twin AST. (any example how to install / invalidate the twin AST after an effective RBParseTreeRewriter operation?) - Any change to the Twin AST is reflected in the method bytecode (as long as one does invalidate). This would mean being able to put tracing code with RB patterns, no? And without having to do a recompilation of the traced method? Thierry Le 27/02/2015 00:07, Marcus Denker a écrit :
Hi,
In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin.
What does that do?
you can call on a method #createTwin
(ReflectivityExamples>>#exampleMethod) createTwin.
after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod (they form a twin).
(ReflectivityExamples>>#exampleMethod) reflectiveMethod
The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed.
ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the method dict and then executes the method:
(ReflectivityExamples>>#exampleMethod) createTwin. (ReflectivityExamples>>#exampleMethod) invalidate. self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod. self assert: ReflectivityExamples new exampleMethod = 5. self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod.
Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code.
e.g. try on Morph:
Morph methods do: #createTwin. Morph methods do: #invalidate.
Counting which twin is installed shows us the working set of Morph:
(Morph methods select: [ :each | each class = CompiledMethod ]) size
some 330 method out of nearly 900â¦.
So what can one do with this? In essence this turns the AST into a reflective representation for Methods (if you care to set up twin creation + invalidation correctly).
What will this allow us to do? stay tuned...
Marcus
Hi thierry f this implementation follows persephone the bytecode is the result of the first execution of the AST. So a kind of JIT inside the system. The AST is annotated with properties (link to meta objects that can define the semantics of the annotation). Stef Le 27/2/15 19:48, Thierry Goubier a écrit :
Hi Markus,
if I understand correctly some of the possibilities:
- I can use RBParseTreeSearcher / RBParseTreeRewriter on the twin AST.
(any example how to install / invalidate the twin AST after an effective RBParseTreeRewriter operation?)
- Any change to the Twin AST is reflected in the method bytecode (as long as one does invalidate).
This would mean being able to put tracing code with RB patterns, no? And without having to do a recompilation of the traced method?
Thierry
Le 27/02/2015 00:07, Marcus Denker a écrit :
Hi,
In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin.
What does that do?
you can call on a method #createTwin
(ReflectivityExamples>>#exampleMethod) createTwin.
after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod (they form a twin).
(ReflectivityExamples>>#exampleMethod) reflectiveMethod
The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed.
ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the method dict and then executes the method:
(ReflectivityExamples>>#exampleMethod) createTwin. (ReflectivityExamples>>#exampleMethod) invalidate. self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod. self assert: ReflectivityExamples new exampleMethod = 5. self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod.
Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code.
e.g. try on Morph:
Morph methods do: #createTwin. Morph methods do: #invalidate.
Counting which twin is installed shows us the working set of Morph:
(Morph methods select: [ :each | each class = CompiledMethod ]) size
some 330 method out of nearly 900â¦.
So what can one do with this? In essence this turns the AST into a reflective representation for Methods (if you care to set up twin creation + invalidation correctly).
What will this allow us to do? stay tuned...
Marcus
On 27 Feb 2015, at 19:48, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Hi Markus,
if I understand correctly some of the possibilities:
- I can use RBParseTreeSearcher / RBParseTreeRewriter on the twin AST.
(any example how to install / invalidate the twin AST after an effective RBParseTreeRewriter operation?)
Yes, but I would do it on a copy⦠that is, do the change in run:with:in: on a copy, generate code from that, keep the original. An AST that follows the text is kind of nice for e.g. navigation.
- Any change to the Twin AST is reflected in the method bytecode (as long as one does invalidate).
yes.
This would mean being able to put tracing code with RB patterns, no? And without having to do a recompilation of the traced method?
Yes. At first I want to have something simple: a MOP based on the MetaLinks. But one could do the same with RB transformations: put them as annotation on the method, then on recompile take them into account. Marcus
On 27 Feb 2015, at 20:26, Marcus Denker <marcus.denker@inria.fr> wrote:
On 27 Feb 2015, at 19:48, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Hi Markus,
if I understand correctly some of the possibilities:
- I can use RBParseTreeSearcher / RBParseTreeRewriter on the twin AST.
(any example how to install / invalidate the twin AST after an effective RBParseTreeRewriter operation?)
Yes, but I would do it on a copy⦠that is, do the change in run:with:in: on a copy, generate code from that, keep the original. An AST that follows the text is kind of nice for e.g. navigation
The reason is that we actually cache the AST if you request it from a CompiledMethod, this means you do not want to change that cached version as e.g. the Browser uses it for Navigation or the âSuggestionsâ menu. Marcus
Le 27/02/2015 20:26, Marcus Denker a écrit :
On 27 Feb 2015, at 19:48, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Hi Markus,
if I understand correctly some of the possibilities:
- I can use RBParseTreeSearcher / RBParseTreeRewriter on the twin AST.
(any example how to install / invalidate the twin AST after an effective RBParseTreeRewriter operation?)
Yes, but I would do it on a copy⦠that is, do the change in run:with:in: on a copy, generate code from that, keep the original. An AST that follows the text is kind of nice for e.g. navigation.
- Any change to the Twin AST is reflected in the method bytecode (as long as one does invalidate).
yes.
This would mean being able to put tracing code with RB patterns, no? And without having to do a recompilation of the traced method?
Yes. At first I want to have something simple: a MOP based on the MetaLinks. But one could do the same with RB transformations: put them as annotation on the method, then on recompile take them into account.
Maybe I'm not understanding everything, so would that be correct: - If I inject additional behavior with meta-links, then they just annotate the AST and do not really change it. Now, since writing dedicated ast visitors takes quite some code, what could work is to have a RBParseTreeMetaWriter: use a RB pattern to find the right ast node, and add whatever meta-link there. Thierry
On 27 Feb 2015, at 23:11, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 27/02/2015 20:26, Marcus Denker a écrit :
On 27 Feb 2015, at 19:48, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Hi Markus,
if I understand correctly some of the possibilities:
- I can use RBParseTreeSearcher / RBParseTreeRewriter on the twin AST.
(any example how to install / invalidate the twin AST after an effective RBParseTreeRewriter operation?)
Yes, but I would do it on a copy⦠that is, do the change in run:with:in: on a copy, generate code from that, keep the original. An AST that follows the text is kind of nice for e.g. navigation.
- Any change to the Twin AST is reflected in the method bytecode (as long as one does invalidate).
yes.
This would mean being able to put tracing code with RB patterns, no? And without having to do a recompilation of the traced method?
Yes. At first I want to have something simple: a MOP based on the MetaLinks. But one could do the same with RB transformations: put them as annotation on the method, then on recompile take them into account.
Maybe I'm not understanding everything, so would that be correct:
- If I inject additional behavior with meta-links, then they just annotate the AST and do not really change it.
Now, since writing dedicated ast visitors takes quite some code, what could work is to have a RBParseTreeMetaWriter: use a RB pattern to find the right ast node, and add whatever meta-link there.
Yes. The experiment right now does not use the rewriter, but we should have a look. Marcus
participants (9)
-
Alexandre Bergel -
Clara Allende -
Johan Fabry -
kilon alios -
Marcus Denker -
Nicolai Hess -
stepharo -
Thierry Goubier -
Tudor Girba