src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp
changeset 48701 48ce4b11bc17
parent 47216 71c04702a3d5
child 48669 51d97ee431ff
equal deleted inserted replaced
48700:953eca1167b6 48701:48ce4b11bc17
    27 #include "asm/macroAssembler.hpp"
    27 #include "asm/macroAssembler.hpp"
    28 #include "assembler_aarch64.inline.hpp"
    28 #include "assembler_aarch64.inline.hpp"
    29 #include "code/vtableStubs.hpp"
    29 #include "code/vtableStubs.hpp"
    30 #include "interp_masm_aarch64.hpp"
    30 #include "interp_masm_aarch64.hpp"
    31 #include "memory/resourceArea.hpp"
    31 #include "memory/resourceArea.hpp"
       
    32 #include "oops/compiledICHolder.hpp"
    32 #include "oops/instanceKlass.hpp"
    33 #include "oops/instanceKlass.hpp"
    33 #include "oops/klassVtable.hpp"
    34 #include "oops/klassVtable.hpp"
    34 #include "runtime/sharedRuntime.hpp"
    35 #include "runtime/sharedRuntime.hpp"
    35 #include "vmreg_aarch64.inline.hpp"
    36 #include "vmreg_aarch64.inline.hpp"
    36 #ifdef COMPILER2
    37 #ifdef COMPILER2
   138     __ incrementw(Address(r10));
   139     __ incrementw(Address(r10));
   139   }
   140   }
   140 #endif
   141 #endif
   141 
   142 
   142   // Entry arguments:
   143   // Entry arguments:
   143   //  rscratch2: Interface
   144   //  rscratch2: CompiledICHolder
   144   //  j_rarg0: Receiver
   145   //  j_rarg0: Receiver
   145 
   146 
   146   // Free registers (non-args) are r0 (interface), rmethod
   147 
       
   148   // Most registers are in use; we'll use r0, rmethod, r10, r11
       
   149   const Register recv_klass_reg     = r10;
       
   150   const Register holder_klass_reg   = r0; // declaring interface klass (DECC)
       
   151   const Register resolved_klass_reg = rmethod; // resolved interface klass (REFC)
       
   152   const Register temp_reg           = r11;
       
   153   const Register icholder_reg       = rscratch2;
       
   154 
       
   155   Label L_no_such_interface;
       
   156 
       
   157   __ ldr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset()));
       
   158   __ ldr(holder_klass_reg,   Address(icholder_reg, CompiledICHolder::holder_metadata_offset()));
   147 
   159 
   148   // get receiver (need to skip return address on top of stack)
   160   // get receiver (need to skip return address on top of stack)
   149 
       
   150   assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
   161   assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
   151   // get receiver klass (also an implicit null-check)
   162   // get receiver klass (also an implicit null-check)
   152   address npe_addr = __ pc();
   163   address npe_addr = __ pc();
   153 
   164   __ load_klass(recv_klass_reg, j_rarg0);
   154   // Most registers are in use; we'll use r0, rmethod, r10, r11
   165 
   155   __ load_klass(r10, j_rarg0);
   166   // Receiver subtype check against REFC.
   156 
   167   // Destroys recv_klass_reg value.
   157   Label throw_icce;
   168   __ lookup_interface_method(// inputs: rec. class, interface
   158 
   169                              recv_klass_reg, resolved_klass_reg, noreg,
   159   // Get Method* and entrypoint for compiler
   170                              // outputs:  scan temp. reg1, scan temp. reg2
       
   171                              recv_klass_reg, temp_reg,
       
   172                              L_no_such_interface,
       
   173                              /*return_method=*/false);
       
   174 
       
   175   // Get selected method from declaring class and itable index
       
   176   __ load_klass(recv_klass_reg, j_rarg0);   // restore recv_klass_reg
   160   __ lookup_interface_method(// inputs: rec. class, interface, itable index
   177   __ lookup_interface_method(// inputs: rec. class, interface, itable index
   161                              r10, rscratch2, itable_index,
   178                        recv_klass_reg, holder_klass_reg, itable_index,
   162                              // outputs: method, scan temp. reg
   179                        // outputs: method, scan temp. reg
   163                              rmethod, r11,
   180                        rmethod, temp_reg,
   164                              throw_icce);
   181                        L_no_such_interface);
   165 
   182 
   166   // method (rmethod): Method*
   183   // method (rmethod): Method*
   167   // j_rarg0: receiver
   184   // j_rarg0: receiver
   168 
   185 
   169 #ifdef ASSERT
   186 #ifdef ASSERT
   181   // j_rarg0: receiver
   198   // j_rarg0: receiver
   182   address ame_addr = __ pc();
   199   address ame_addr = __ pc();
   183   __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
   200   __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
   184   __ br(rscratch1);
   201   __ br(rscratch1);
   185 
   202 
   186   __ bind(throw_icce);
   203   __ bind(L_no_such_interface);
   187   __ far_jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
   204   __ far_jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
   188 
   205 
   189   __ flush();
   206   __ flush();
   190 
   207 
   191   if (PrintMiscellaneous && (WizardMode || Verbose)) {
   208   if (PrintMiscellaneous && (WizardMode || Verbose)) {
   203 
   220 
   204 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
   221 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
   205   int size = DebugVtables ? 216 : 0;
   222   int size = DebugVtables ? 216 : 0;
   206   if (CountCompiledCalls)
   223   if (CountCompiledCalls)
   207     size += 6 * 4;
   224     size += 6 * 4;
   208   // FIXME
   225   // FIXME: vtable stubs only need 36 bytes
   209   if (is_vtable_stub)
   226   if (is_vtable_stub)
   210     size += 52;
   227     size += 52;
   211   else
   228   else
   212     size += 104;
   229     size += 176;
   213   return size;
   230   return size;
   214 
   231 
   215   // In order to tune these parameters, run the JVM with VM options
   232   // In order to tune these parameters, run the JVM with VM options
   216   // +PrintMiscellaneous and +WizardMode to see information about
   233   // +PrintMiscellaneous and +WizardMode to see information about
   217   // actual itable stubs.  Run it with -Xmx31G -XX:+UseCompressedOops.
   234   // actual itable stubs.  Run it with -Xmx31G -XX:+UseCompressedOops.
   218   //
   235   //
   219   // If Universe::narrow_klass_base is nonzero, decoding a compressed
   236   // If Universe::narrow_klass_base is nonzero, decoding a compressed
   220   // class can take zeveral instructions.  Run it with -Xmx31G
   237   // class can take zeveral instructions.
   221   // -XX:+UseCompressedOops.
       
   222   //
   238   //
   223   // The JVM98 app. _202_jess has a megamorphic interface call.
   239   // The JVM98 app. _202_jess has a megamorphic interface call.
   224   // The itable code looks like this:
   240   // The itable code looks like this:
   225   // Decoding VtableStub itbl[1]@12
   241 
   226   //     ldr     w10, [x1,#8]
   242   //    ldr    xmethod, [xscratch2,#CompiledICHolder::holder_klass_offset]
   227   //     lsl     x10, x10, #3
   243   //    ldr    x0, [xscratch2]
   228   //     ldr     w11, [x10,#280]
   244   //    ldr    w10, [x1,#oopDesc::klass_offset_in_bytes]
   229   //     add     x11, x10, x11, uxtx #3
   245   //    mov    xheapbase, #0x3c000000                //   #narrow_klass_base
   230   //     add     x11, x11, #0x1b8
   246   //    movk    xheapbase, #0x3f7, lsl #32
   231   //     ldr     x12, [x11]
   247   //    add    x10, xheapbase, x10
   232   //     cmp     x9, x12
   248   //    mov    xheapbase, #0xe7ff0000                //   #heapbase
   233   //     b.eq    success
   249   //    movk    xheapbase, #0x3f7, lsl #32
   234   // loop:
   250   //    ldr    w11, [x10,#vtable_length_offset]
   235   //     cbz     x12, throw_icce
   251   //    add    x11, x10, x11, uxtx #3
   236   //     add     x11, x11, #0x10
   252   //    add    x11, x11, #itableMethodEntry::method_offset_in_bytes
   237   //     ldr     x12, [x11]
   253   //    ldr    x10, [x11]
   238   //     cmp     x9, x12
   254   //    cmp    xmethod, x10
   239   //     b.ne    loop
   255   //    b.eq    found_method
   240   // success:
   256   // search:
   241   //     ldr     x11, [x11,#8]
   257   //    cbz    x10, no_such_interface
   242   //     ldr     x12, [x10,x11]
   258   //    add    x11, x11, #0x10
   243   //     ldr     x8, [x12,#72]
   259   //    ldr    x10, [x11]
   244   //     br      x8
   260   //    cmp    xmethod, x10
   245   // throw_icce:
   261   //    b.ne    search
   246   //     b      throw_ICCE_entry
   262   // found_method:
       
   263   //    ldr    w10, [x1,#oopDesc::klass_offset_in_bytes]
       
   264   //    mov    xheapbase, #0x3c000000                //   #narrow_klass_base
       
   265   //    movk    xheapbase, #0x3f7, lsl #32
       
   266   //    add    x10, xheapbase, x10
       
   267   //    mov    xheapbase, #0xe7ff0000                //   #heapbase
       
   268   //    movk    xheapbase, #0x3f7, lsl #32
       
   269   //    ldr    w11, [x10,#vtable_length_offset]
       
   270   //    add    x11, x10, x11, uxtx #3
       
   271   //    add    x11, x11, #itableMethodEntry::method_offset_in_bytes
       
   272   //    add    x10, x10, #itentry_off
       
   273   //    ldr    xmethod, [x11]
       
   274   //    cmp    x0, xmethod
       
   275   //    b.eq    found_method2
       
   276   // search2:
       
   277   //    cbz    xmethod, 0x000003ffa872e6cc
       
   278   //    add    x11, x11, #0x10
       
   279   //    ldr    xmethod, [x11]
       
   280   //    cmp    x0, xmethod
       
   281   //    b.ne    search2
       
   282   // found_method2:
       
   283   //    ldr    w11, [x11,#itableOffsetEntry::offset_offset_in_bytes]
       
   284   //    ldr    xmethod, [x10,w11,uxtw]
       
   285   //    ldr    xscratch1, [xmethod,#Method::from_compiled_offset]
       
   286   //    br    xscratch1
       
   287   // no_such_interface:
       
   288   //    b      throw_ICCE_entry
   247 
   289 
   248 }
   290 }
   249 
   291 
   250 int VtableStub::pd_code_alignment() { return 4; }
   292 int VtableStub::pd_code_alignment() { return 4; }