Download presentation
Presentation is loading. Please wait.
Published byRandolf Warren Modified over 9 years ago
1
Parallel Checking of Expressive Heap Assertions Greta YorshMartin VechevEran YahavBard Bloom IBM T.J. Watson Research Center
2
Motivation Unrestricted use of aliasing is evil Unrestricted use of aliasing in the presence of concurrency is ultimate evil
3
Motivating Example: Azureus Over 360 million downloads
4
Runtime Error org.eclipse.swt.SWTException: Graphic is disposed at org.eclipse.swt.SWT.error(SWT.java:3744) at org.eclipse.swt.SWT.error(SWT.java:3662) at org.eclipse.swt.SWT.error(SWT.java:3633) at org.eclipse.swt.graphics.GC.getClipping(GC.java:2266) at com.aelitis.azureus.ui.swt.views.list.ListRow.doPaint(ListRow.java:260) at com.aelitis.azureus.ui.swt.views.list.ListRow.doPaint(ListRow.java:237) at com.aelitis.azureus.ui.swt.views.list.ListView.handleResize(ListView.java:867) at com.aelitis.azureus.ui.swt.views.list.ListView$5$2.runSupport(ListView.java:406) at org.gudy.azureus2.core3.util.AERunnable.run(AERunnable.java:38) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:130) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3323) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2985) at org.gudy.azureus2.ui.swt.mainwindow.SWTThread. (SWTThread.java:183) at org.gudy.azureus2.ui.swt.mainwindow.SWTThread.createInstance(SWTThread.java: 67) ….
5
What Happened? protected void handleRefresh(boolean bForce) { //... gc.dispose(); } protected void handleResize(boolean bForce) { //... myGC.getClipping(…) } GC gc myGC Native resource
6
If only I could check… protected void handleRefresh(boolean bForce) { //... // @assert object pointed to by gc is not shared gc.dispose(); } protected void handleResize(boolean bForce) { //... myGC.getClipping(…) } GC gc myGC Native resource
7
Motivating Example II: jdbf public class Database { private ConnectionManager cm; public int insert(...) throws MappingEx { Connection c = cm.getConnection(...);... }... } public class ConnectionManager { private Map conns = Collections.synchronizedMap(new HashMap()); public Connection getConnection(String s) throws MappingException { try { ConnectionSource c = conns.get(s); if (c != null) return c.getConnection(); throw new MappingException(...); } catch (SQLEx e) {... } } public class ConnectionSource { private Connection conn; private boolean used; public Connection getConnection() throws SQLEx { if (!used) { used = true; return conn; } throw new SQLEx(...); }
8
Running Thread Stack Database Root Running Thread Stack HashMap Connection Source Connection Source Connection Static Connection Source Connection Manager ct Motivating Example II: jdbf If only I could check… @invariant: every conncetion is only reachable from one thread (avoiding connection manager)
9
Phalanx Challenges Expressing heap queries Is object shared? Is object reachable? Is object reachable when avoiding paths through some other objects? Is object owned? … Checking heap queries at runtime
10
Expressing Heap Queries Use JML Extended with additional primitives reach(Object o, Object[] avoiding) pred(Object o) dom(Object o1,Object o2) …
11
Examples Object o is shared pred(o).size() > 1 Set of threads that can reach o, while avoiding objects in avoid: { Thread t | running().has(t) && (reach(t,avoid).has(o) || reach(stack(t),avoid).has(o)) }
12
Checking Heap Queries: Wish List Support wide range of queries We have a nice extended JML + primitives Overhead low enough to permit running realistic applications Debugging Program understanding Maybe even production
13
Checking Heap Queries: First Attempt We need to traverse the heap to answer our queries The garbage collector (GC) already traverses the heap periodically GC can be parallel and leverage available system cores Piggyback the GC !
14
Crash Course: Tracing GC r1 r2
15
Crash Course: Parallel Tracing GC r1 r2 Thread 1 Thread 2
16
Checking Heap Queries: How can we use the GC? reach(o) Know that objects are reachable, but not whether they are reachable from o reach(o1,o2) With GC I would only know o1,o2 are reachable from roots Now what? reach(o1) reach(o2) = Requires two marked sets Now what? ……
17
Supported Primitives? reach(Object o) pred(Object o) reach(Object o, Object[] avoiding) dom(Object o1,Object o2) Some primitives cannot be computed by piggybacking a GC traversal
18
What can we do in parallel? Is object o shared? pred(o).size() > 1 Disjoint reach set? reach(o1) reach(o2) =
19
Checking Heap Queries: Second Attempt We need new parallel algorithms We can use components of a parallel GC as building blocks for our parallel algorithms
20
New Algorithms Based on GC components New parallel algorithms for common queries New operations performed on GC steps New synchronization structures for computing answers to heap queries Leverage available system cores Modified JMLC maps common queries to parallel implementations
21
Back to our example: isShared isShared(t m, o) t m.sources ; mark-threads(tm, Ta) trace(tm) lock(allsources) allsources allsources tm.sources unlock(allsources) if barrier-and-release-master() if |allsources| > 1 result true else result false release-blocked-evaluators() trace-step(s; t) if (o = t) t m.sources t m.sources { s }
22
Parallel Checking of isShared r1 r2 Thread 1 Thread 2 Is shared? t 1.sources = { A } A B t 2.sources = { B } allsources = { A, B } isShared = true
23
isObjectOwned(source,target) isObjectOwned(tm, source, target) { tag-object(tm, source) result false phase skip barrier() mark-roots(tm, Ta) barrier() phase none trace(tm) barrier() if (target Marked) barrier() push-object(tm; source) trace(tm) if barrier-and-release-master() if (target Marked) result true release-blocked-evaluators() } tag-step(t) if (phase = skip t = target) return false
24
isObjectOwned(source,target) source r2 r1 r3 target Phase 1: tag source
25
isObjectOwned(source,target) source r2 r1 r3 target Phase 2: mark roots (except target)
26
isObjectOwned(source,target) source r2 r1 r3 target Phase 3: trace from roots (except from source)
27
Parallel Algorithms QueryDescriptionProbe pred(o).size() > 0Is o pointed to by a heap object? isHeap(Object o) pred(o).size() > 1Is o pointed to by two or more heap objects? isShared(Object o) reach(src).has(dst)Is dst reachable from src?isReachable(Object src, Object dst) !(exists Object v; reach(o1).has(v) ; reach(o2).has(v)) Is there an object reachable from both o1 and o2? isDisjoint(Object o1, Object o2) !(exists Object v ; reach(o).has(v) ; !dom(o,v)) Does o dominate all objects reachable from it? isUniqueOwner(Object o) !reach(o1,cut).has(o2)Does every path from o1 to o2 go through an object in cut reachThrough(Object o1, o2, Object[] cut) dom(Thread.currentThread(), o) Does the current thread dominate o? isObjectOwned(Object o1, Object o2) …
28
Experimental Evaluation Implemented on top of QVM platform IBM J9 production virtual machine Can leverage QVM adaptive overhead manager (not in this talk) Provide a portable reference implementation based on JVMTI Less efficient, no parallel algorithms Still useful in some cases Modified JML Compiler
29
Speedup / #objects
30
Time / #cores
31
Speedup / #cores
32
Probes in Real Applications Disposal of Shared SWT Resources replace code of the form: exp.dispose(); with code of the form if (Phalanx.isShared(exp)) Phalanx.warning(”disposal of \ shared resource”+exp) ; exp.dispose();
33
Probes in Real Applications Redundant Synchronization replace code of the form: synchronized(exp) {... } with code of the form synchronized(exp) { if(Phalanx.dom(Thread.currentThread(),exp)) Phalanx.warning(”synchronziation on \ an owned object”+exp) ;... }
34
Probes in Real Applications ApplicationLOCProbesViolations AOI111,333100 Azureus425,36733416 Freemind70,483162 Frostwire245,9591842 JEdit93,790660 jrisk20,8074512 rssowl74,280953 tvbrowser105,471401 TVLA57,594100
35
Summary
36
GC Details
37
The End
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.