(original) (raw)
# HG changeset patch # User adinn # Date 1516702051 0 # Tue Jan 23 10:07:31 2018 +0000 # Node ID a7e77acacaad73682a6dd70801502dad55450d41 # Parent 8f451978683ce3193c302f6140ecf05afee1754a revert wrong commit of 8195685 diff -r 8f451978683c -r a7e77acacaad src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Tue Jan 23 08:55:47 2018 +0100 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Tue Jan 23 10:07:31 2018 +0000 @@ -963,12 +963,8 @@ RegisterOrConstant itable_index, Register method_result, Register 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"); + Label& L_no_such_interface) { + assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); assert(itable_index.is_constant() || itable_index.as_register() == method_result, "caller must use same register for non-constant itable index as for method"); @@ -986,14 +982,12 @@ lea(scan_temp, Address(recv_klass, scan_temp, Address::lsl(3))); add(scan_temp, scan_temp, vtable_base); - 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); - } + // 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) { @@ -1027,10 +1021,8 @@ bind(found_method); // Got a hit. - 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))); - } + ldr(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes())); + ldr(method_result, Address(recv_klass, scan_temp)); } // virtual method calling diff -r 8f451978683c -r a7e77acacaad src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Tue Jan 23 08:55:47 2018 +0100 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Tue Jan 23 10:07:31 2018 +0000 @@ -875,8 +875,7 @@ RegisterOrConstant itable_index, Register method_result, Register scan_temp, - Label& no_such_interface, - bool return_method = true); + Label& no_such_interface); // virtual method calling // n.b. x86 allows RegisterOrConstant for vtable_index diff -r 8f451978683c -r a7e77acacaad src/hotspot/cpu/aarch64/templateTable_aarch64.cpp --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Tue Jan 23 08:55:47 2018 +0100 +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Tue Jan 23 10:07:31 2018 +0000 @@ -3279,11 +3279,11 @@ transition(vtos, vtos); assert(byte_no == f1_byte, "use this argument"); - prepare_invoke(byte_no, r0, rmethod, // get f1 Klass*, f2 Method* + prepare_invoke(byte_no, r0, rmethod, // get f1 Klass*, f2 itable index r2, r3); // recv, flags // r0: interface klass (from f1) - // rmethod: method (from f2) + // rmethod: itable index (from f2) // r2: receiver // r3: flags @@ -3302,27 +3302,10 @@ __ null_check(r2, oopDesc::klass_offset_in_bytes()); __ load_klass(r3, r2); - Label no_such_interface, no_such_method; - - // Receiver subtype check against REFC. - // Superklass in r0. Subklass in r3. Blows rscratch2, r13 - __ lookup_interface_method(// inputs: rec. class, interface, itable index - r3, r0, noreg, - // outputs: scan temp. reg, scan temp. reg - rscratch2, r13, - no_such_interface, - /*return_method=*/false); - // profile this call __ profile_virtual_call(r3, r13, r19); - // Get declaring interface class from method, and itable index - __ ldr(r0, Address(rmethod, Method::const_offset())); - __ ldr(r0, Address(r0, ConstMethod::constants_offset())); - __ ldr(r0, Address(r0, ConstantPool::pool_holder_offset_in_bytes())); - __ ldrw(rmethod, Address(rmethod, Method::itable_index_offset())); - __ subw(rmethod, rmethod, Method::itable_index_max); - __ negw(rmethod, rmethod); + Label no_such_interface, no_such_method; __ lookup_interface_method(// inputs: rec. class, interface, itable index r3, r0, rmethod, diff -r 8f451978683c -r a7e77acacaad src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp --- a/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp Tue Jan 23 08:55:47 2018 +0100 +++ b/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp Tue Jan 23 10:07:31 2018 +0000 @@ -29,7 +29,6 @@ #include "code/vtableStubs.hpp" #include "interp_masm_aarch64.hpp" #include "memory/resourceArea.hpp" -#include "oops/compiledICHolder.hpp" #include "oops/instanceKlass.hpp" #include "oops/klassVtable.hpp" #include "runtime/sharedRuntime.hpp" @@ -141,44 +140,28 @@ #endif // Entry arguments: - // rscratch2: CompiledICHolder + // rscratch2: Interface // j_rarg0: Receiver - - // Most registers are in use; we'll use r0, rmethod, r10, r11 - const Register recv_klass_reg = r10; - const Register holder_klass_reg = r0; // declaring interface klass (DECC) - const Register resolved_klass_reg = rmethod; // resolved interface klass (REFC) - const Register temp_reg = r11; - const Register icholder_reg = rscratch2; - - Label L_no_such_interface; - - __ ldr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset())); - __ ldr(holder_klass_reg, Address(icholder_reg, CompiledICHolder::holder_metadata_offset())); + // Free registers (non-args) are r0 (interface), rmethod // get receiver (need to skip return address on top of stack) + assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0"); // get receiver klass (also an implicit null-check) address npe_addr = __ pc(); - __ load_klass(recv_klass_reg, j_rarg0); - // Receiver subtype check against REFC. - // Destroys recv_klass_reg value. - __ lookup_interface_method(// inputs: rec. class, interface - recv_klass_reg, resolved_klass_reg, noreg, - // outputs: scan temp. reg1, scan temp. reg2 - recv_klass_reg, temp_reg, - L_no_such_interface, - /*return_method=*/false); + // Most registers are in use; we'll use r0, rmethod, r10, r11 + __ load_klass(r10, j_rarg0); - // Get selected method from declaring class and itable index - __ load_klass(recv_klass_reg, j_rarg0); // restore recv_klass_reg + Label throw_icce; + + // Get Method* and entrypoint for compiler __ lookup_interface_method(// inputs: rec. class, interface, itable index - recv_klass_reg, holder_klass_reg, itable_index, - // outputs: method, scan temp. reg - rmethod, temp_reg, - L_no_such_interface); + r10, rscratch2, itable_index, + // outputs: method, scan temp. reg + rmethod, r11, + throw_icce); // method (rmethod): Method* // j_rarg0: receiver @@ -200,7 +183,7 @@ __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset())); __ br(rscratch1); - __ bind(L_no_such_interface); + __ bind(throw_icce); __ far_jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); __ flush(); @@ -222,11 +205,11 @@ int size = DebugVtables ? 216 : 0; if (CountCompiledCalls) size += 6 * 4; - // FIXME: vtable stubs only need 36 bytes + // FIXME if (is_vtable_stub) size += 52; else - size += 176; + size += 104; return size; // In order to tune these parameters, run the JVM with VM options @@ -234,58 +217,33 @@ // actual itable stubs. Run it with -Xmx31G -XX:+UseCompressedOops. // // If Universe::narrow_klass_base is nonzero, decoding a compressed - // class can take zeveral instructions. + // class can take zeveral instructions. Run it with -Xmx31G + // -XX:+UseCompressedOops. // // The JVM98 app. _202_jess has a megamorphic interface call. // The itable code looks like this: - - // ldr xmethod, [xscratch2,#CompiledICHolder::holder_klass_offset] - // ldr x0, [xscratch2] - // ldr w10, [x1,#oopDesc::klass_offset_in_bytes] - // mov xheapbase, #0x3c000000 // #narrow_klass_base - // movk xheapbase, #0x3f7, lsl #32 - // add x10, xheapbase, x10 - // mov xheapbase, #0xe7ff0000 // #heapbase - // movk xheapbase, #0x3f7, lsl #32 - // ldr w11, [x10,#vtable_length_offset] - // add x11, x10, x11, uxtx #3 - // add x11, x11, #itableMethodEntry::method_offset_in_bytes - // ldr x10, [x11] - // cmp xmethod, x10 - // b.eq found_method - // search: - // cbz x10, no_such_interface - // add x11, x11, #0x10 - // ldr x10, [x11] - // cmp xmethod, x10 - // b.ne search - // found_method: - // ldr w10, [x1,#oopDesc::klass_offset_in_bytes] - // mov xheapbase, #0x3c000000 // #narrow_klass_base - // movk xheapbase, #0x3f7, lsl #32 - // add x10, xheapbase, x10 - // mov xheapbase, #0xe7ff0000 // #heapbase - // movk xheapbase, #0x3f7, lsl #32 - // ldr w11, [x10,#vtable_length_offset] - // add x11, x10, x11, uxtx #3 - // add x11, x11, #itableMethodEntry::method_offset_in_bytes - // add x10, x10, #itentry_off - // ldr xmethod, [x11] - // cmp x0, xmethod - // b.eq found_method2 - // search2: - // cbz xmethod, 0x000003ffa872e6cc - // add x11, x11, #0x10 - // ldr xmethod, [x11] - // cmp x0, xmethod - // b.ne search2 - // found_method2: - // ldr w11, [x11,#itableOffsetEntry::offset_offset_in_bytes] - // ldr xmethod, [x10,w11,uxtw] - // ldr xscratch1, [xmethod,#Method::from_compiled_offset] - // br xscratch1 - // no_such_interface: - // b throw_ICCE_entry + // Decoding VtableStub itbl[1]@12 + // ldr w10, [x1,#8] + // lsl x10, x10, #3 + // ldr w11, [x10,#280] + // add x11, x10, x11, uxtx #3 + // add x11, x11, #0x1b8 + // ldr x12, [x11] + // cmp x9, x12 + // b.eq success + // loop: + // cbz x12, throw_icce + // add x11, x11, #0x10 + // ldr x12, [x11] + // cmp x9, x12 + // b.ne loop + // success: + // ldr x11, [x11,#8] + // ldr x12, [x10,x11] + // ldr x8, [x12,#72] + // br x8 + // throw_icce: + // b throw_ICCE_entry }