Last active
December 13, 2022 22:48
-
-
Save navyxliu/74d0546004a773cb5219754f6ed63d43 to your computer and use it in GitHub Desktop.
Example3_1.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// java -Xms16M -Xmx16M -XX:+AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:-UseOnStackReplacement -XX:-UseTLAB -XX:CompileOnly='Example3_1.foo' -XX:+DoPartialEscapeAnalysis Example3_1 | |
import java.util.ArrayList; | |
class Example3_1 { | |
public ArrayList<Integer> _cache; | |
public void foo(boolean cond) { | |
ArrayList<Integer> x = new ArrayList<Integer>(); | |
if (cond) { | |
_cache = x; | |
} | |
} | |
public void test1(boolean cond) { | |
foo(cond); | |
} | |
public static void main(String[] args) { | |
Example3_1 kase = new Example3_1(); | |
// Epsilon Test: | |
// By setting the maximal heap and use EpsilonGC, let's see how long and how many iterations the program can sustain. | |
// if PEA manages to reduce allocation rate, we expect the program to stay longer. | |
// Roman commented it with a resonable doubt: "or your code slow down the program..." | |
// That's why I suggest to observe iterations. It turns out not trivial because inner OOME will implode hotspot. We don't have a chance to execute the final statement... | |
long iterations = 0; | |
try { | |
while (true) { | |
kase.test1(0 == (iterations & 0xf)); | |
if (kase._cache != null) { | |
kase._cache.add(1); | |
} | |
iterations++; | |
} | |
} finally { | |
System.err.println("Epsilon Test: " + iterations); | |
} | |
} | |
} |
Author
navyxliu
commented
Dec 13, 2022
Here is the generated code for Example3_1.
- allocation at 05f is conditional. B1 conducts test and only allocate ArrayList on demand.
- we initialize elementData at 064 using constant address. Other fields(modCount and size) are zero and implicitly initialized.
------------------------ OptoAssembly for Compile_id = 2 -----------------------
#
# void ( Example3_1:NotNull *, int )
#
000 N63: # out( B1 ) <- BLOCK HEAD IS JUNK Freq: 1
000 movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()] # compressed klass
decode_klass_not_null rscratch1, rscratch1
cmpq rax, rscratch1 # Inline cache check
jne SharedRuntime::_ic_miss_stub
nop # nops to align entry point
nop # 4 bytes pad for loops and calls
020 B1: # out( B3 B2 ) <- BLOCK HEAD IS JUNK Freq: 1
020 # stack bang (136 bytes)
pushq rbp # Save rbp
subq rsp, #16 # Create frame
03a movq RBP, RSI # spill
03d testl RDX, RDX
03f jne,s B3 P=0.062523 C=5534.000000
041 B2: # out( N63 ) <- in( B4 B1 ) Freq: 0.999999
041 addq rsp, 16 # Destroy frame
popq rbp
cmpq rsp, poll_offset[r15_thread]
ja #safepoint_stub # Safepoint: poll for GC
053 ret
054 B3: # out( B5 B4 ) <- in( B1 ) Freq: 0.0625226
054 movq RSI, precise java/util/ArrayList: 0x00007f1e84013c68:Constant:exact * # ptr
nop # 1 bytes pad for loops and calls
05f call,static wrapper for: _new_instance_Java
# Example3_1::foo @ bci:14 (line 10) L[0]=_ L[1]=_ L[2]=_ STK[0]=RBP
# OopMap {rbp=Oop off=100/0x64}
064 B4: # out( B2 ) <- in( B3 ) Freq: 0.0625213
# Block is sole successor of call
064 movl [RAX + #20 (8-bit)], narrowoop: narrowoop: java/lang/Object *[int:0]<ciObjArray length=0 type=<ciObjArrayKlass name=[Ljava/lang/Object; loaded=true ident=1336 address=0x00007f1ec8034b00> ident=1344 address=0x00007f1ec8037800> * # compressed ptr
06b
06b # checkcastPP of RAX
06b encode_heap_oop_not_null R11,RAX
0ac movl [RBP + #12 (8-bit)], R11 # compressed ptr ! Field: Example3_1._cache
0b0 jmp,s B2
0b2 B5: # out( N63 ) <- in( B3 ) Freq: 6.25226e-07
0b2 # exception oop is in rax; no code emitted
0b2 movq RSI, RAX # spill
0b5 addq rsp, 16 # Destroy frame
popq rbp
0ba jmp rethrow_stub
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment