--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Mon Jan 22 12:00:41 2018 +0800
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Fri Jan 19 16:57:56 2018 +0000
@@ -963,8 +963,12 @@
RegisterOrConstant itable_index,
Register method_result,
Register scan_temp,
- Label& L_no_such_interface) {
- assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
+ Label& L_no_such_interface,
+ bool return_method) {
+ assert_different_registers(recv_klass, intf_klass, scan_temp);
+ assert_different_registers(method_result, intf_klass, scan_temp);
+ assert(recv_klass != method_result || !return_method,
+ "recv_klass can be destroyed when method isn't needed");
assert(itable_index.is_constant() || itable_index.as_register() == method_result,
"caller must use same register for non-constant itable index as for method");
@@ -982,12 +986,14 @@
lea(scan_temp, Address(recv_klass, scan_temp, Address::lsl(3)));
add(scan_temp, scan_temp, vtable_base);
- // Adjust recv_klass by scaled itable_index, so we can free itable_index.
- assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
- // lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
- lea(recv_klass, Address(recv_klass, itable_index, Address::lsl(3)));
- if (itentry_off)
- add(recv_klass, recv_klass, itentry_off);
+ if (return_method) {
+ // Adjust recv_klass by scaled itable_index, so we can free itable_index.
+ assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
+ // lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off));
+ lea(recv_klass, Address(recv_klass, itable_index, Address::lsl(3)));
+ if (itentry_off)
+ add(recv_klass, recv_klass, itentry_off);
+ }
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
// if (scan->interface() == intf) {
@@ -1021,8 +1027,10 @@
bind(found_method);
// Got a hit.
- ldr(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
- ldr(method_result, Address(recv_klass, scan_temp));
+ if (return_method) {
+ ldrw(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
+ ldr(method_result, Address(recv_klass, scan_temp, Address::uxtw(0)));
+ }
}
// virtual method calling