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 ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.