request for advice: safepoints in the JSR 292 spec

Jim Laskey jlaskey at me.com
Sat Dec 11 08:31:46 PST 2010


> public static void syncTargets(MutableCallSite[] sites, MethodHandle[] newTargets)

+1

I think this provides the most flexibility, performance and ease.  If a developer wants to use a wrapper method to do one up 'set and sync', they have the flexibility to do so.

Naive question: If setTarget is removed and set is done either by constructor or by syncTargets, do we still need both these flavours of CallSite?

Cheers,

-- Jim



On 2010-12-11, at 10:52 AM, Rich Hickey wrote:

> 
> On Dec 10, 2010, at 9:04 PM, John Rose wrote:
> 
>> On Dec 10, 2010, at 5:08 AM, Doug Lea wrote:
>> 
>>> On 12/09/10 19:09, John Rose wrote:
>>>> I started a thread on Google Groups to get more advice on  
>>>> safepoint-based
>>>> invalidation, which the EG is naming MutableCallSite#sync.
>>>> 
>>>> http://groups.google.com/group/jvm-languages/browse_thread/thread/9c9d3e84fc745676#
>>>> 
>>> 
>>> TL;DR version: The scheme you laid out here seems sound.
>> 
>> Thanks very much, Doug.  I assume you are primarily referring to  
>> part (a) of my question:
>> 
>>>> In order to work, the specification has to (a) make logical sense  
>>>> in the terms of the JMM, (b) be reasonably implementable by JVMs,  
>>>> and (c) be useful to programmers.
>> 
>> Does anyone have a take on (c)?  (See my comments below on using  
>> this API...)
>> 
>> In the JSR 292 case, we are supporting languages (like Java!) which  
>> can dynamically change their type schemas, but do so infrequently,  
>> perhaps at phase changes.  The changes will in general require  
>> complex sets of call sites to be updated, implying a dependency  
>> mechanism (see the Switcher class for this).  But the actual change- 
>> over can be slow, and may involve safepoints, as today with  
>> devirtualization that happens when new classes are loaded.
>> 
>> (See Universe::flush_dependents_on around line 1100 of:
>> http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/tip/src/share/vm/memory/universe.cpp 
>> )
>> 
>> The idea is that the type schema change would be prepared (as a  
>> "next global state") by a writer thread #1.  At this point some call  
>> sites become "invalid in next state".  Those call sites would be  
>> switched, either by a switcher (which would in general control many  
>> call sites at once) or by editing them individually, and then  
>> calling 'sync' on them.
>> 
>> The new state of all call sites must at this point be consistent  
>> with both the current and next global state of the type schema.   
>> Typically, a lock would be held on the schema by writer thread #1,  
>> and the updated call site paths (now switched in and sync-ed) would  
>> pile up on the schema lock.  After the next global state is  
>> installed as current, the writer thread #1 lets go of the lock, and  
>> callers are free to shake out the new state of affairs.
>> 
>> The shake-out may include installing optimized call paths in various  
>> call sites.  This means that a mutable call site might undergo two  
>> mutations, the first to get into a state consistent with both old  
>> and new schemas (perhaps seizing a lock, as above) and the second to  
>> optimize calling within the new state.  Both transitions generally  
>> need to grab a lock so they can have a consistent view of the global  
>> schema state.
>> 
>> As an extra complication, the editing of call sites is probably  
>> performed in a concurrent manner, and lazily.  There might be writer  
>> thread #2, etc., performing updates to mutable call sites.  It it  
>> not clear to me whether the second write also needs a sync, but it  
>> looks like that may be the case to get performance.  Perhaps the  
>> right way to go is avoid the second write, and have the first write  
>> install the optimized path immediately, and queuing a 'sync' request  
>> to be executed after a short delay.  One key concern is to avoid  
>> "safepoint storms", by batching 'sync' requests.
>> 
>> -- John
> 
> Thanks for this work, John!
> I'm concerned about the separation of update and publication in this  
> API. It seems intractably difficult to reason about the behavior of  
> the system between multiple setTarget() calls and a subsequent sync().
> 
> I'd much rather see (if possible):
> 
> public static void syncTargets(MutableCallSite[] sites, MethodHandle[]  
> newTargets)
> 
> Then we can create arbitrary composite updates, out of view and over  
> time, using mere-mortals programming, and deliver them atomically.
> 
> Ditto Switchers (if they would even still be needed). And I wonder  
> about VolatileCallSite. Who would ever use that, given MutableCallSite?
> 
> Perhaps setTarget() should simply go away?
> 
> Regards,
> 
> Rich 
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev



More information about the mlvm-dev mailing list