I second (third?) Charlie and Remi’s comments. SwitchPoint per method has 
worked very nicely to reduce the amount of code invalidated by meta-programming 
shenanigans. You could go further and try for a class-and-method switch point, 
but that makes it harder to eliminate class checks or use CHA.

The downside of all this kind of thing is that when stuff is invalidated it’s 
often fairly heavy weight, so it’s worth putting some thought into designing 
things to minimise the amount of code which will be invalidated when you flip a 
SwitchPoint and only invalidating things that really need it (that’s where a 
switch point per method often pays off).


From: mlvm-dev 
on behalf of Charles Oliver Nutter 
Reply-To: Da Vinci Machine Project 
Date: Wednesday, 5 October 2016 at 15:00
To: Da Vinci Machine Project 
Subject: EXT: Re: series of switchpoints or better

Hi Jochen!

On Wed, Oct 5, 2016 at 7:37 AM, Jochen Theodorou 
<blackd...@gmx.org<mailto:blackd...@gmx.org>> wrote:
If the meta class for A is changed, all handles operating on instances of A may 
have to reselect. the handles for B and Object need not to be affected. If the 
meta class for Object changes, I need to invalidate all the handles for A, B 
and Object.

This is exactly how JRuby's type-modification guards work. We've used this 
technique since our first implementation of indy call sites.

Doing this with switchpoints means probably one switchpoint per metaclass and a 
small number of meta classes per class (in total 3 in my example). This would 
mean my MethodHandle would have to get through a bunch of switchpoints, before 
it can do the actual method invocation. And while switchpoints might be fast it 
does not sound good to me.

>From what I've seen, it's fine as far as hot performance. Adding complexity to 
>your handle chains likely impacts cold perf, of course.

Can you elaborate on the structure? JRuby has 6-deep (configurable) polymorphic 
caching, with each entry being a GWT (to check type) and a SP (to check 
modification) before hitting the plumbing for the method itself.

I will say that using SwitchPoints is FAR better than our alternative 
mechanism: pinging the (meta)class each time and checking a serial number.

Or I can do one switchpoint for all methodhandles in the system, which makes me 
wonder if after a meta class change the callsite ever gets Jitted again. The 
later performance penalty is actually also not very attractive to me.

We have fought to keep the JIT from giving up on us, and I believe that as of 
today you can invalidate call sites forever and the JIT will still recompile 
them (within memory, code cache, and other limits of course).

However, you'll be invalidating every call site for every modification. If the 
system eventually settles, that's fine. If it doesn't, you're going to be stuck 
with cold call site performance most of the time.

So what is the way to go here? Or is there an even better way?

I strongly recommend the switchpoint-per-class granularity (or finer, like 
switchpoint-per-class-and-method-name, which I am playing with now).

- Charlie

mlvm-dev mailing list

Reply via email to