Weird ASM produced around type guards
With
# VM version: JDK 17.0.7, Java HotSpot(TM) 64-Bit Server VM, 17.0.7+8-LTS-224
red.hat.puzzles.polymorphism.InstanceOfScalabilityBenchmark.encodeFullType -pencoderType=a -ppollutionCases=20000 -t 16 -f 4 -prof perfasm
where
# Benchmark: red.hat.puzzles.polymorphism.InstanceOfScalabilityBenchmark.encodeFullType
# Parameters: (encoderType = a, polluteExistingTypes = true, pollutionCases = 20000)
reports:
....[Hottest Region 1]..............................................................................
c2, level 4, red.hat.puzzles.polymorphism.jmh_generated.InstanceOfScalabilityBenchmark_encodeFullType_jmhTest::encodeFullType_avgt_jmhStub, version 858 (22 bytes)
0x00007f66fd0309fa: mov %r11d,0x4(%rsp)
0x00007f66fd0309ff: call 0x00007f66fc86c480 ; ImmutableOopMap {[48]=Oop [56]=Oop [64]=Oop [0]=NarrowOop }
;*ifeq {reexecute=1 rethrow=0 return_oop=0}
; - (reexecute) red.hat.puzzles.polymorphism.ReferenceCounted::release@4 (line 8)
; - red.hat.puzzles.polymorphism.HttpObjectEncoderA::encode@51 (line 25)
; - red.hat.puzzles.polymorphism.InstanceOfScalabilityBenchmark::encodeFullType@8 (line 126)
; - red.hat.puzzles.polymorphism.jmh_generated.InstanceOfScalabilityBenchmark_encodeFullType_jmhTest::encodeFullType_avgt_jmhStub@15 (line 186)
; {runtime_call UncommonTrapBlob}
0x00007f66fd030a04: movabs $0x800c27058,%rax ; {metadata('red/hat/puzzles/polymorphism/Encoder$HttpMessage')}
0x00007f66fd030a0e: mov 0x28(%rsi),%rdi
35.85% 0x00007f66fd030a12: mov (%rdi),%ecx
0.01% 0x00007f66fd030a14: add $0x8,%rdi
0x00007f66fd030a18: test %rax,%rax
0x00007f66fd030a1b: repnz scas %es:(%rdi),%rax
╭ 0x00007f66fd030a1e: jne 0x00007f66fd030a28
│ 0x00007f66fd030a24: mov %rax,0x20(%rsi)
0.53% ↘ 0x00007f66fd030a28: je 0x00007f66fd030983
0x00007f66fd030a2e: mov $0xffffff45,%esi
0x00007f66fd030a33: mov %r9,0x30(%rsp)
0x00007f66fd030a38: mov %r11,(%rsp)
0x00007f66fd030a3c: mov %r10d,0x8(%rsp)
0x00007f66fd030a41: xchg %ax,%ax
0x00007f66fd030a43: call 0x00007f66fc86c480 ; ImmutableOopMap {[48]=Oop [56]=Oop [64]=Oop [0]=Oop [8]=NarrowOop }
;*ifeq {reexecute=1 rethrow=0 return_oop=0}
; - (reexecute) red.hat.puzzles.polymorphism.HttpObjectEncoderA::encode@4 (line 13)
; - red.hat.puzzles.polymorphism.InstanceOfScalabilityBenchmark::encodeFullType@8 (line 126)
; - red.hat.puzzles.polymorphism.jmh_generated.InstanceOfScalabilityBenchmark_encodeFullType_jmhTest::encodeFullType_avgt_jmhStub@15 (line 186)
....................................................................................................
36.38% <total for region 1>
Where
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
@Override
public void encode(Object o) {
try {
if (o instanceof HttpMessage) {
H msg = (H) o; // <---------- this check here vs HttpMessage
encodeHttpMessage(msg);
}
if (o instanceof HttpContent) {
if (o instanceof HttpLastContent) {
encodeLastHttpContent((HttpLastContent) o);
} else {
encodeHttpNotLastContent((HttpContent) o);
}
}
} finally {
release(o);
}
}
While on jdk main
:
....[Hottest Region 1]..............................................................................
c2, level 4, red.hat.puzzles.polymorphism.HttpObjectEncoderA::encode, version 1176 (19 bytes)
# [sp+0x40] (sp of caller)
0x00007f6160a57ae0: mov 0x8(%rsi),%r10d
0x00007f6160a57ae4: cmp %r10,%rax
0x00007f6160a57ae7: jne 0x00007f6160265280 ; {runtime_call ic_miss_stub}
0x00007f6160a57aed: data16 xchg %ax,%ax
[Verified Entry Point]
0x00007f6160a57af0: mov %eax,-0x14000(%rsp)
0x00007f6160a57af7: push %rbp
0x00007f6160a57af8: sub $0x30,%rsp
0x00007f6160a57afc: cmpl $0x1,0x20(%r15)
0.03% 0x00007f6160a57b04: jne 0x00007f6160a57d66 ;*synchronization entry
; - red.hat.puzzles.polymorphism.HttpObjectEncoderA::encode@-1 (line 13)
0.01% 0x00007f6160a57b0a: mov %rsi,(%rsp)
0.01% 0x00007f6160a57b0e: mov 0x8(%rdx),%ebp ; implicit exception: dispatches to 0x00007f6160a57d19
0x00007f6160a57b11: mov %ebp,%esi
0x00007f6160a57b13: mov 0x20(%rsi),%r10
80.23% 0x00007f6160a57b17: cmp $0xbb13c240,%ebp ; {metadata('red/hat/puzzles/polymorphism/InstanceOfScalabilityBenchmark$DefaultFullHttpResponse')}
? 0x00007f6160a57b1d: je 0x00007f6160a57b3a
? 0x00007f6160a57b1f: cmp $0xbb13c000,%ebp ; {metadata('red/hat/puzzles/polymorphism/InstanceOfScalabilityBenchmark$DefaultHttpResponse')}
?? 0x00007f6160a57b25: je 0x00007f6160a57b3a
?? 0x00007f6160a57b27: movabs $0xbb112d50,%rax ; {metadata('red/hat/puzzles/polymorphism/Encoder$HttpMessage')}
?? 0x00007f6160a57b31: cmp %rax,%r10
?? 0x00007f6160a57b34: jne 0x00007f6160a57cd0 ;*instanceof {reexecute=0 rethrow=0 return_oop=0}
?? ; - red.hat.puzzles.polymorphism.HttpObjectEncoderA::encode@1 (line 13)
?? 0x00007f6160a57b3a: mov %r10,0x18(%rsp)
0x00007f6160a57b3f: mov %rsi,0x10(%rsp)
0x00007f6160a57b44: mov %rdx,0x8(%rsp) ;*checkcast {reexecute=0 rethrow=0 return_oop=0}
....................................................................................................
80.27% <total for region 1>
which refer to the same encode
method shown before but the present a weird order while loading secondary_super_cache
and guards, which is:
0x00007f6160a57b13: mov 0x20(%rsi),%r10
i.e. load currentKlass::secondary_super_cache
- compare against 2 known types (which were ones with highest frequency) i.e.
DefaultHttpResponse
,DefaultFullHttpResponse
- if not any of the previous concrete types, compare the previous load
secondary_super
withHttpMessage
I would have expected the guards to happen before and the load + cmp secondary_super, after, instead.