This article is out-of-date! 
Please look at this article, 
or articles written after June 2016.

Hey guys,

The first step toward a running adaptive recompiler is the hotspot detector. This part was not implemented by me but by Eliot Miranda (the guy next to the guitar on the picture in the link). Therefore I will just give a brief overview of how it works. When the Sista will be in production, I guess he will write a blog post about this part on his blog anyway.

Issue

The hot spot detector needs to find methods that are very frequently used with the least performance lost possible.

Eliot’s implementation

Eliot decided to edit the JIT’s byte code to native code compiler to add counters on specific spots to count the number of execution of methods. Based on a Java VM idea, he added counters on each conditional jumps. As a reminder, the current pharo compilers inline conditions and loops at compilation time into jumps to increase performance (current optimized messages includes #ifNil:, #ifNotNil:, #ifTrue:, #ifFalse:, #whileTrue:, #whileFalse:, #to:do:, #to:by:do:). Therefore counters are added on all these message sends.

The counter is divided in 2 parts, and each execution increase 1 counter or the other depending on which branch is taken. Each time a counter is increased, a test is triggered to see if the counter has reached a certain amount (which is currently set to 30000 based on strongtalk reports). If this is the case, the tripping counter calls a method in the image on the current context, method precised through the special objects array. Then, the in-image optimizer will take care of it.

With this implementation, not only the performance loss is not very important (~20%), but the adaptive recompiler has in addition information about the control flow, knowing for each branch how many times it has been taken or not.

As methods in the native code cache are temporaries, being replaced by other methods from time to time, the counters are automatically decreased from time to time.

Advertisements