It was noticed that we flush the instruction cache three times for a single C1 compilation:
(1) Flushing of the temporary code buffer:
AbstractICache::invalidate_range
AbstractAssembler::flush
Compilation::emit_code_epilog
Compilation::emit_code_body
Compilation::compile_java_method
Compilation::compile_method
Why is that even required? We don't execute code in the buffer but copy it to the code cache first.
(2) When copying from the temporary buffer into the code cache:
AbstractICache::invalidate_range
CodeBuffer::copy_code_to
CodeBuffer::copy_code_and_locs_to
nmethod::nmethod
nmethod::new_nmethod
ciEnv::register_method
Compilation::install_code
Compilation::compile_method
(3) And again when committing the code in the code cache:
AbstractICache::invalidate_range
CodeCache::commit
nmethod::nmethod
nmethod::new_nmethod
ciEnv::register_method
Compilation::install_code
Compilation::compile_method
C2 seems to omit (1) but does (2) and (3) as well.
From [~kvn]:
"C2 does not flush his temp buffer. But it does the same 2 flushes during code installation. We need to investigate that"
"CodeBuffer::copy_code_to() is used also for runtime stubs and other codes generation.
CodeCache::commit() is used for adapters too. But adapters uses RuntimeBlob which calls copy_code_to().
It seems we can try to skip flashing in CodeCache::commit() in such case.
It could be some historical conflicting changes.
We need RFE and track all paths to AbstractICache::invalidate_range() when we publish code to CodeCache."