Skip to content

Instantly share code, notes, and snippets.

@ytoshima
Created November 18, 2011 16:39
Show Gist options
  • Save ytoshima/1376983 to your computer and use it in GitHub Desktop.
Save ytoshima/1376983 to your computer and use it in GitHub Desktop.
Code comparison between C1 and C2
C1
$ ~/jdk1.7.0-b147/fastdebug/bin/java -XX:CompileOnly=gvnex::doHashSum -XX:+PrintLIR -client gvnex
VM option 'CompileOnly=gvnex::doHashSum'
VM option '+PrintLIR'
CompileOnly: compileonly *gvnex*.doHashSum
LIR:
B1 [0, 0] sux: B0
__id_Instruction___________________________________________
0 label [label:0x939c62c]
2 std_entry
move [ecx|L] [stack:3|L]
B0 std [0, 68] preds: B1
__id_Instruction___________________________________________
8 label [label:0x939a9bc]
10 move [Base:[ecx|L] Disp: 8|J] [ediesi|J]
12 move [Base:[ecx|L] Disp: 16|L] [ebx|L]
14 null_check [ebx|L] [bci:9]
16 move [ebx|L] [ecx|L]
move [ediesi|J] [dbl_stack:1|J]
18 optvirtual call: [addr: 0x0] [recv: [ecx|L]] [result: [eax|I]] [bci:9]
22 convert [i2l] [eax|I] [ecxeax|J]
24 move [dbl_stack:1|J] [ediesi|J]
26 add [ediesi|J] [ecxeax|J] [ediesi|J]
move [stack:3|L] [ecx|L]
28 move [ediesi|J] [Base:[ecx|L] Disp: 8|J]
30 move [Base:[ecx|L] Disp: 16|L] [ebx|L]
32 null_check [ebx|L] [bci:26]
34 move [ebx|L] [ecx|L]
move [ediesi|J] [dbl_stack:5|J]
36 optvirtual call: [addr: 0x0] [recv: [ecx|L]] [result: [eax|I]] [bci:26]
40 convert [i2l] [eax|I] [ecxeax|J]
move [dbl_stack:5|J] [ediesi|J]
44 add [ecxeax|J] [ediesi|J] [ecxeax|J]
move [stack:3|L] [esi|L]
46 move [ecxeax|J] [Base:[esi|L] Disp: 8|J]
48 move [Base:[esi|L] Disp: 16|L] [edi|L]
50 null_check [edi|L] [bci:43]
move [ecxeax|J] [dbl_stack:7|J]
52 move [edi|L] [ecx|L]
54 optvirtual call: [addr: 0x0] [recv: [ecx|L]] [result: [eax|I]] [bci:43]
58 convert [i2l] [eax|I] [ecxeax|J]
move [dbl_stack:7|J] [ediesi|J]
62 add [ecxeax|J] [ediesi|J] [ecxeax|J]
move [stack:3|L] [esi|L]
64 move [ecxeax|J] [Base:[esi|L] Disp: 8|J]
66 move [Base:[esi|L] Disp: 16|L] [edi|L]
68 null_check [edi|L] [bci:60]
move [ecxeax|J] [dbl_stack:9|J]
70 move [edi|L] [ecx|L]
72 optvirtual call: [addr: 0x0] [recv: [ecx|L]] [result: [eax|I]] [bci:60]
76 convert [i2l] [eax|I] [eaxesi|J]
move [dbl_stack:9|J] [ecxedi|J]
80 add [eaxesi|J] [ecxedi|J] [eaxesi|J]
move [stack:3|L] [ecx|L]
82 move [eaxesi|J] [Base:[ecx|L] Disp: 8|J]
84 return
C2
looks like next name.hashCode's name is loaded before storing previous result.
jdk1.7.0-b147/fastdebug/bin/java -XX:CompileOnly=gvnex::doHashSum -XX:+PrintOptoAssembly gvnex
VM option 'CompileOnly=gvnex::doHashSum'
VM option '+PrintOptoAssembly'
CompileOnly: compileonly *gvnex*.doHashSum
{method}
- klass: {other class}
- this oop: 0x91238080
- method holder: 'gvnex'
- constants: 0x91237e10 constant pool [38] for 'gvnex' cache=0x912382e0
- access: 0x81000000
- name: 'doHashSum'
- signature: '()V'
- max stack: 5
- max locals: 1
- size of params: 1
- method size: 24
- vtable index: 5
- i2i entry: 0xb4759e20
- adapter: 0x09d8b6cc
- compiled entry 0xb47f8ee8
- code size: 69
- code start: 0x91238030
- code end (excl): 0x91238075
- method data: 0x91238950
- checked ex length: 0
- linenumber start: 0x91238075
- localvar length: 0
#
# void ( gvnex:NotNull * )
#
#r000 ecx : parm 0: gvnex:NotNull *
# -- Old esp -- Framesize: 48 --
#r045 esp+44: return address
#r044 esp+40: pad2, in_preserve
#r043 esp+36: pad2, in_preserve
#r042 esp+32: Fixed slot 0
#r053 esp+28: spill
#r052 esp+24: spill
#r051 esp+20: spill
#r050 esp+16: spill
#r049 esp+12: spill
#r048 esp+ 8: spill
#r047 esp+ 4: spill
#r046 esp+ 0: spill
#
000 N201: # B1 <- BLOCK HEAD IS JUNK Freq: 1
000 CMP EAX,[ECX+4] # Inline cache check
JNE SharedRuntime::handle_ic_miss_stub
NOP
NOP
NOP
000
00c B1: # B10 B2 <- BLOCK HEAD IS JUNK Freq: 1
00c # stack bang
PUSHL EBP
SUB ESP,40 # Create frame
01a MOV EBP,ECX
01c MOV ECX,[ECX + #16] ! Field gvnex.name
01f TEST ECX,ECX
021 Je B10 P=0.000001 C=-1.000000
021
027 B2: # B14 B3 <- B1 Freq: 0.999999
027 MOV ESI,EBP
029 MOV EAX.lo,[ESI + #8] # long
MOV EAX.hi,[ESI + #8]+4 ! Field gvnex.sum
02f MOV [ESP + #16],EAX
MOV [ESP + #20],EDX
037 CALL,static java.lang.String::hashCode
# gvnex::doHashSum @ bci:9 L[0]=EBP STK[0]=EBP STK[1]=esp + #16 STK[2]=_
# OopMap{ebp=Oop off=60}
03c
03c B3: # B11 B4 <- B2 Freq: 0.999979
# Block is sole successor of call
03c MOV ECX,[EBP + #16] ! Field gvnex.name
03f MOV EAX.lo,EAX
MOV EAX.hi,EAX
SAR EAX.hi,31
044 ADD EAX.lo,[ESP + #16]
ADC EAX.hi,[ESP + #16]+4
04c MOV [ESP + #8],EAX
MOV [ESP + #12],EDX
054 MOV [EBP + #8],EAX.lo
MOV [EBP + #8]+4,EAX.hi ! Field gvnex.sum
05a TEST ECX,ECX
05c Je B11 P=0.000001 C=-1.000000
05c
062 B4: # B15 B5 <- B3 Freq: 0.999978
062 NOP # 1 bytes pad for loops and calls
063 CALL,static java.lang.String::hashCode
# gvnex::doHashSum @ bci:26 L[0]=EBP STK[0]=EBP STK[1]=esp + #8 STK[2]=_
# OopMap{ebp=Oop off=104}
068
068 B5: # B12 B6 <- B4 Freq: 0.999958
# Block is sole successor of call
068 MOV ECX,[EBP + #16] ! Field gvnex.name
06b MOV EAX.lo,EAX
MOV EAX.hi,EAX
SAR EAX.hi,31
070 ADD EAX.lo,[ESP + #8]
ADC EAX.hi,[ESP + #8]+4
078 MOV [ESP + #8],EAX
MOV [ESP + #12],EDX
080 MOV [EBP + #8],EAX.lo
MOV [EBP + #8]+4,EAX.hi ! Field gvnex.sum
086 TEST ECX,ECX
088 Je,s B12 P=0.000001 C=-1.000000
088
08a B6: # B16 B7 <- B5 Freq: 0.999957
08a NOP # 1 bytes pad for loops and calls
08b CALL,static java.lang.String::hashCode
# gvnex::doHashSum @ bci:43 L[0]=EBP STK[0]=EBP STK[1]=esp + #8 STK[2]=_
# OopMap{ebp=Oop off=144}
090
090 B7: # B13 B8 <- B6 Freq: 0.999937
# Block is sole successor of call
090 MOV ECX,[EBP + #16] ! Field gvnex.name
093 MOV EAX.lo,EAX
MOV EAX.hi,EAX
SAR EAX.hi,31
098 ADD EAX.lo,[ESP + #8]
ADC EAX.hi,[ESP + #8]+4
0a0 MOV [ESP + #0],EAX
MOV [ESP + #4],EDX
0a7 MOV [EBP + #8],EAX.lo
MOV [EBP + #8]+4,EAX.hi ! Field gvnex.sum
0ad TEST ECX,ECX
0af Je,s B13 P=0.000001 C=-1.000000
0af
0b1 B8: # B17 B9 <- B7 Freq: 0.999936
0b1 NOP # 2 bytes pad for loops and calls
0b3 CALL,static java.lang.String::hashCode
# gvnex::doHashSum @ bci:60 L[0]=_ STK[0]=EBP STK[1]=esp + #0 STK[2]=_
# OopMap{ebp=Oop off=184}
0b8
0b8 B9: # N201 <- B8 Freq: 0.999916
# Block is sole successor of call
0b8 MOV ECX.lo,EAX
MOV ECX.hi,EAX
SAR ECX.hi,31
0bf ADD ECX.lo,[ESP + #0]
ADC ECX.hi,[ESP + #0]+4
0c6 MOV [EBP + #8],ECX.lo
MOV [EBP + #8]+4,ECX.hi ! Field gvnex.sum
0cc ADD ESP,40 # Destroy frame
POPL EBP
TEST PollPage,EAX ! Poll Safepoint
0d6 RET
0d6
0d7 B10: # N201 <- B1 Freq: 1.01328e-06
0d7 MOV ECX,#-10
0dc NOP # 3 bytes pad for loops and calls
0df CALL,static wrapper for: uncommon_trap(reason='null_check' action='maybe_recompile')
# gvnex::doHashSum @ bci:9 L[0]=_ STK[0]=_ STK[1]=_ STK[2]=_ STK[3]=#NULL
# OopMap{off=228}
0e4 INT3 ; ShouldNotReachHere
0e4
0e9 B11: # N201 <- B3 Freq: 1.01326e-06
0e9 MOV ECX,#-10
0ee NOP # 1 bytes pad for loops and calls
0ef CALL,static wrapper for: uncommon_trap(reason='null_check' action='maybe_recompile')
# gvnex::doHashSum @ bci:26 L[0]=_ STK[0]=_ STK[1]=_ STK[2]=_ STK[3]=#NULL
# OopMap{off=244}
0f4 INT3 ; ShouldNotReachHere
0f4
0f9 B12: # N201 <- B5 Freq: 1.01324e-06
0f9 MOV ECX,#-10
0fe NOP # 1 bytes pad for loops and calls
0ff CALL,static wrapper for: uncommon_trap(reason='null_check' action='maybe_recompile')
# gvnex::doHashSum @ bci:43 L[0]=_ STK[0]=_ STK[1]=_ STK[2]=_ STK[3]=#NULL
# OopMap{off=260}
104 INT3 ; ShouldNotReachHere
104
109 B13: # N201 <- B7 Freq: 1.01321e-06
109 MOV ECX,#-10
10e NOP # 1 bytes pad for loops and calls
10f CALL,static wrapper for: uncommon_trap(reason='null_check' action='maybe_recompile')
# gvnex::doHashSum @ bci:60 L[0]=_ STK[0]=_ STK[1]=_ STK[2]=_ STK[3]=#NULL
# OopMap{off=276}
114 INT3 ; ShouldNotReachHere
114
119 B14: # B18 <- B2 Freq: 9.99999e-06
119 # exception oop is in EAX; no code emitted
119 MOV ECX,EAX
11b JMP,s B18
11b
11d B15: # B18 <- B4 Freq: 9.99978e-06
11d # exception oop is in EAX; no code emitted
11d MOV ECX,EAX
11f JMP,s B18
11f
121 B16: # B18 <- B6 Freq: 9.99957e-06
121 # exception oop is in EAX; no code emitted
121 MOV ECX,EAX
123 JMP,s B18
123
125 B17: # B18 <- B8 Freq: 9.99936e-06
125 # exception oop is in EAX; no code emitted
125 MOV ECX,EAX
125
127 B18: # N201 <- B14 B15 B16 B17 Freq: 3.99987e-05
127 ADD ESP,40 # Destroy frame
POPL EBP
12b JMP rethrow_stub
12b
public class gvnex {
String name;
public static void main(String[] args) {
gvnex ge = new gvnex("john");
for (int i = 0; i < 1000000; i++) {
ge.doHashSum();
}
}
void doHashSum() {
sum += name.hashCode();
sum += name.hashCode();
sum += name.hashCode();
sum += name.hashCode();
}
public gvnex(String name) { this.name = name; }
long sum = 0L;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment