void Method::link_method(const methodHandle& h_method, TRAPS) {
// If the code cache is full, we may reenter this function for the
// leftover methods that weren't linked.
if (is_shared()) {
address entry = Interpreter::entry_for_cds_method(h_method);
assert(Interpreter::entry_for_cds_method(h_method) == _i2i_entry,
"should be correctly set during dump time");
if (adapter() != NULL) {
return;
}
assert(entry == _from_interpreted_entry,
"should be correctly set during dump time");
} else if (_i2i_entry != NULL) {
return;
}
The "entry" is only used for purposes of some assertions, and Interpreter::entry_for_cds_method(h_method); does not have any side effect - but compilers can't see through into all parts of this call (specifically into abstractInterpreter::method_kind) to prove this and eliminate the code.
That means this simple patch is a small improvement on each method linked from the CDS archive, which has a measurable impact already on Hello World:
diff -r f227e770495f src/hotspot/share/oops/method.cpp
--- a/src/hotspot/share/oops/method.cpp Fri Feb 28 15:30:29 2020 -0800
+++ b/src/hotspot/share/oops/method.cpp Sun Mar 01 19:03:33 2020 +0100
@@ -1175,7 +1175,7 @@
// If the code cache is full, we may reenter this function for the
// leftover methods that weren't linked.
if (is_shared()) {
- address entry = Interpreter::entry_for_cds_method(h_method);
+ NOT_PRODUCT(address entry = Interpreter::entry_for_cds_method(h_method);)
assert(entry != NULL && entry == _i2i_entry,
"should be correctly set during dump time");
if (adapter() != NULL) {
Before:
111,869,073 instructions # 0.82 insns per cycle ( +- 0.07% )
22,206,305 branches # 421.885 M/sec ( +- 0.08% )
764,563 branch-misses # 3.44% of all branches ( +- 0.14% )
After:
111,399,179 instructions # 0.82 insns per cycle ( +- 0.08% )
22,055,916 branches # 420.503 M/sec ( +- 0.08% )
762,839 branch-misses # 3.46% of all branches ( +- 0.16% )
// If the code cache is full, we may reenter this function for the
// leftover methods that weren't linked.
if (is_shared()) {
address entry = Interpreter::entry_for_cds_method(h_method);
assert(Interpreter::entry_for_cds_method(h_method) == _i2i_entry,
"should be correctly set during dump time");
if (adapter() != NULL) {
return;
}
assert(entry == _from_interpreted_entry,
"should be correctly set during dump time");
} else if (_i2i_entry != NULL) {
return;
}
The "entry" is only used for purposes of some assertions, and Interpreter::entry_for_cds_method(h_method); does not have any side effect - but compilers can't see through into all parts of this call (specifically into abstractInterpreter::method_kind) to prove this and eliminate the code.
That means this simple patch is a small improvement on each method linked from the CDS archive, which has a measurable impact already on Hello World:
diff -r f227e770495f src/hotspot/share/oops/method.cpp
--- a/src/hotspot/share/oops/method.cpp Fri Feb 28 15:30:29 2020 -0800
+++ b/src/hotspot/share/oops/method.cpp Sun Mar 01 19:03:33 2020 +0100
@@ -1175,7 +1175,7 @@
// If the code cache is full, we may reenter this function for the
// leftover methods that weren't linked.
if (is_shared()) {
- address entry = Interpreter::entry_for_cds_method(h_method);
+ NOT_PRODUCT(address entry = Interpreter::entry_for_cds_method(h_method);)
assert(entry != NULL && entry == _i2i_entry,
"should be correctly set during dump time");
if (adapter() != NULL) {
Before:
111,869,073 instructions # 0.82 insns per cycle ( +- 0.07% )
22,206,305 branches # 421.885 M/sec ( +- 0.08% )
764,563 branch-misses # 3.44% of all branches ( +- 0.14% )
After:
111,399,179 instructions # 0.82 insns per cycle ( +- 0.08% )
22,055,916 branches # 420.503 M/sec ( +- 0.08% )
762,839 branch-misses # 3.46% of all branches ( +- 0.16% )