Harry Xu May 2012
Complex, concurrent software Precision (no false positives) Find real bugs in real executions
Need to modify JVM (e.g., object layout, GC, or ISA-level code) Need to demonstrate realism (usually performance)
Otherwise use RoadRunner, BCEL, Pin, LLVM, …
Keeping track of stuff as the program executes? Change application behavior (add instrumentation) Store per-object/per-field metadata Piggyback on GC
Keeping track of stuff as the program executes? JVM written in Java?! Change application behavior (add instrumentation) Store per-object/per-field metadata Piggyback on GC Uninterruptible code
Jikes RVM { Guide Research Archive Research mailing list
Jikes RVM { Guide Research Archive Research mailing list
Jikes RVM source code Boot image writer Dynamic compilers
Jikes RVM source code Boot image Run with writer another JVM Dynamic compilers
Jikes RVM source code Boot image Run with writer another JVM Dynamic compilers Boot image (native code + initial heap space)
Build configurations: Base Base Jikes RVM source code Base Adaptive Full Adaptive Fast Adaptive Boot image Run with writer another JVM Dynamic compilers Boot image (native code + initial heap space)
Build configurations: Base Base (prototype) Jikes RVM source code Base Adaptive (prototype-opt) Full Adaptive (development) Fast Adaptive (production) Boot image Run with writer another JVM Dynamic compilers Boot image (native code + initial heap space)
Build configurations: Base Base Jikes RVM source code Testing Base Adaptive Full Adaptive Fast Adaptive Boot image Run with writer another JVM Dynamic compilers Boot image (native code + initial heap space)
Build configurations: Base Base Faster builds Jikes RVM source code Base Adaptive Full Adaptive Fast Adaptive Boot image Run with writer another JVM Dynamic compilers Boot image (native code + initial heap space)
Build configurations: Base Base Jikes RVM source code Base Adaptive Faster runs Full Adaptive Fast Adaptive Boot image Run with writer another JVM Dynamic compilers Boot image (native code + initial heap space)
Build configurations: Base Base Jikes RVM source code Base Adaptive Full Adaptive Performance Fast Adaptive Boot image Run with writer another JVM Dynamic compilers Boot image (native code + initial heap space)
Jikes RVM source code Boot image Run with writer another JVM Dynamic compilers Boot image (native code + initial heap space)
Jikes RVM source code Edit with Eclipse (see Guide) Boot image Run with writer another JVM Dynamic compilers Boot image (native code + initial heap space)
Keeping track of stuff as the program executes? Change application behavior (add instrumentation) Store per-object/per-field metadata Piggyback on GC
Baseline compiler Bytecode Native code
Baseline compiler Bytecode Native code Each bytecode several x86 instructions (BaselineCompilerImpl.java)
Baseline compiler Bytecode Native code Each bytecode several x86 instructions (BaselineCompilerImpl.java)
Baseline compiler Bytecode Native code Profiling Adaptive optimization system
Baseline compiler Bytecode Native code Profiling (Faster) native code Optimizing compiler Adaptive optimization system
Baseline compiler Bytecode Native code Profiling (Faster) native code Optimizing compiler Adaptive optimization system
Bytecode (Faster) native code Optimizing compiler
Bytecode Resembles bytecode HIR (Faster) native code LIR Resembles typical compiler IR (3-address code) MIR Resembles assembly code
Bytecode HIR (Faster) native code LIR Opt levels: 0, 1, 2 (Even faster) native code MIR
Bytecode HIR ExpandRuntimeServices.java (Faster) Add instrumentation at native code reads, writes, allocation, LIR synchronization MIR
Keeping track of stuff as the program executes? Change application behavior (add instrumentation) Store per-object/per-field metadata Piggyback on GC
header field0 field1 field2 Low address High address
Object reference type info locking & field0 field1 field2 block GC
Object reference type info locking & field0 field1 field2 block GC Object reference type info locking & Array elem0 elem1 block GC length
Object reference type info locking & field0 field1 field2 block GC Steal bits
Object reference type info locking & misc field0 field1 field2 block GC MiscHeader.java
Object reference type info locking & counter field0 field1 field2 block GC
Object reference type info locking & counter field0 field1 field2 block GC Compiles down to three Magic! x86 instructions
Object reference type info locking & counter field0 field1 field2 block GC 2 Gotcha: can’t actually use LSB of leftmost word
Object reference type info locking & counter field0 field1 field2 block GC 2 What’s the problem with this code?
Object reference type info locking & counter field0 field1 field2 block GC 2
Object reference type info locking & not used field0 field1 field2 block GC
Object reference type info locking & not used field0 field1 field2 block GC Compiles down to three x86 instructions
Object reference type info locking & misc field0 field1 field2 block GC
Object reference type info locking & misc field0 field1 field2 block GC What if GC moves object? What if GC collects object?
Keeping track of stuff as the program executes? Change application behavior (add instrumentation) Store per-object/per-field metadata Piggyback on GC
Object reference type info locking & field0 field1 field2 block GC // Initially worklist populated with roots while worklist has elements Object obj = worklist.pop() foreach reference field obj.f obj.f = markAndPossiblyCopy(obj.f) worklist.push(obj.f)
Object reference type info locking & field0 field1 field2 block GC // Initially worklist populated with roots while worklist has elements Object obj = worklist.pop() foreach reference field obj.f obj.f = markAndPossiblyCopy(obj.f) worklist.push(obj.f)
Object reference type info locking & field0 field1 field2 block GC // Initially worklist populated with roots while worklist has elements Object obj = worklist.pop() foreach reference field obj.f obj.f = markAndPossiblyCopy(obj.f) worklist.push(obj.f)
Object reference type info locking & misc field0 field1 field2 block GC // Initially worklist populated with roots while worklist has elements Object obj = worklist.pop() foreach reference field obj.f obj.f = markAndPossiblyCopy(obj.f) worklist.push(obj.f) obj.misc = markAndPossiblyCopy(obj.f) worklist.push(obj.misc)
Object reference type info locking & misc field0 field1 field2 block GC // Initially worklist populated with roots while worklist has elements Object obj = worklist.pop() foreach reference field obj.f obj.f = markAndPossiblyCopy(obj.f) worklist.push(obj.f) obj.misc = markAndPossiblyCopy(obj.f) worklist.push(obj.misc)
Object reference type info locking & misc field0 field1 field2 block GC // Initially worklist populated with roots while worklist has elements Object obj = worklist.pop() foreach reference field obj.f obj.f = markAndPossiblyCopy(obj.f) worklist.push(obj.f) obj.misc = markAndPossiblyCopy(obj.f) TraceLocal.scanObject() worklist.push(obj.misc)
Object reference type info locking & field0 field1 field2 block GC // Initially worklist populated with roots while worklist has elements Object obj = worklist.pop() foreach reference field obj.f obj.f = markAndPossiblyCopy(obj.f) worklist.push(obj.f)
Object reference type info locking & field0 field1 field2 block GC // Initially worklist populated with roots while worklist has elements Object obj = worklist.pop() foreach reference field obj.f obj.f = markAndPossiblyCopy(obj.f) worklist.push(obj.f) TraceLocal.processNode()
Keeping track of stuff as the program executes? Change application behavior (add instrumentation) Store per-object/per-field metadata Piggyback on GC Uninterruptible code
Normal application code can be interrupted Allocation GC Synchronization & yield points join a GC Some VM code shouldn’t be interrupted Heap etc. in inconsistent state Most instrumentation can’t be interrupted Reads & writes aren’t GC-safe points
@Uninterruptible static void myMethod(Object o) { // No allocation or synchronization // No calls to interruptible methods }
@Uninterruptible static void myMethod(Object o) { currentThread.deferGC = true; Metadata m = new Metadata(); currentThread.deferGC = false; setMiscHeader(o, offset, m); }
Recommend
More recommend