< prev index next >

src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp

Print this page
rev 51381 : [mq]: 8207343.patch


  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "assembler_aarch64.inline.hpp"
  29 #include "code/vtableStubs.hpp"
  30 #include "interp_masm_aarch64.hpp"
  31 #include "memory/resourceArea.hpp"
  32 #include "oops/compiledICHolder.hpp"
  33 #include "oops/instanceKlass.hpp"
  34 #include "oops/klassVtable.hpp"
  35 #include "runtime/sharedRuntime.hpp"
  36 #include "vmreg_aarch64.inline.hpp"
  37 #ifdef COMPILER2
  38 #include "opto/runtime.hpp"
  39 #endif
  40 
  41 // machine-dependent part of VtableStubs: create VtableStub of correct size and
  42 // initialize its code
  43 
  44 #define __ masm->
  45 
  46 #ifndef PRODUCT
  47 extern "C" void bad_compiled_vtable_index(JavaThread* thread,
  48                                           oop receiver,
  49                                           int index);
  50 #endif
  51 
  52 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
  53   const int aarch64_code_length = VtableStub::pd_code_size_limit(true);
  54   VtableStub* s = new(aarch64_code_length) VtableStub(true, vtable_index);

  55   // Can be NULL if there is no free space in the code cache.
  56   if (s == NULL) {
  57     return NULL;
  58   }
  59 







  60   ResourceMark rm;
  61   CodeBuffer cb(s->entry_point(), aarch64_code_length);
  62   MacroAssembler* masm = new MacroAssembler(&cb);
  63 
  64 #ifndef PRODUCT
  65   if (CountCompiledCalls) {
  66     __ lea(r16, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
  67     __ incrementw(Address(r16));
  68   }
  69 #endif
  70 
  71   // get receiver (need to skip return address on top of stack)
  72   assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
  73 
  74   // get receiver klass
  75   address npe_addr = __ pc();
  76   __ load_klass(r16, j_rarg0);
  77 
  78 #ifndef PRODUCT
  79   if (DebugVtables) {
  80     Label L;
  81     // check offset vs vtable length
  82     __ ldrw(rscratch1, Address(r16, Klass::vtable_length_offset()));
  83     __ cmpw(rscratch1, vtable_index * vtableEntry::size());
  84     __ br(Assembler::GT, L);
  85     __ enter();
  86     __ mov(r2, vtable_index);
  87     __ call_VM(noreg,
  88                CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), j_rarg0, r2);






  89     __ leave();
  90     __ bind(L);
  91   }
  92 #endif // PRODUCT
  93 

  94   __ lookup_virtual_method(r16, vtable_index, rmethod);



  95 

  96   if (DebugVtables) {
  97     Label L;
  98     __ cbz(rmethod, L);
  99     __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
 100     __ cbnz(rscratch1, L);
 101     __ stop("Vtable entry is NULL");
 102     __ bind(L);
 103   }


 104   // r0: receiver klass
 105   // rmethod: Method*
 106   // r2: receiver
 107   address ame_addr = __ pc();
 108   __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
 109   __ br(rscratch1);
 110 
 111   __ flush();

 112 
 113   if (PrintMiscellaneous && (WizardMode || Verbose)) {
 114     tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
 115                   vtable_index, p2i(s->entry_point()),
 116                   (int)(s->code_end() - s->entry_point()),
 117                   (int)(s->code_end() - __ pc()));
 118   }
 119   guarantee(__ pc() <= s->code_end(), "overflowed buffer");
 120 
 121   s->set_exception_points(npe_addr, ame_addr);
 122   return s;
 123 }
 124 
 125 
 126 VtableStub* VtableStubs::create_itable_stub(int itable_index) {
 127   // Note well: pd_code_size_limit is the absolute minimum we can get
 128   // away with.  If you add code here, bump the code stub size
 129   // returned by pd_code_size_limit!
 130   const int code_length = VtableStub::pd_code_size_limit(false);
 131   VtableStub* s = new(code_length) VtableStub(false, itable_index);









 132   ResourceMark rm;
 133   CodeBuffer cb(s->entry_point(), code_length);
 134   MacroAssembler* masm = new MacroAssembler(&cb);
 135 
 136 #ifndef PRODUCT
 137   if (CountCompiledCalls) {
 138     __ lea(r10, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
 139     __ incrementw(Address(r10));
 140   }
 141 #endif
 142 



 143   // Entry arguments:
 144   //  rscratch2: CompiledICHolder
 145   //  j_rarg0: Receiver
 146 
 147 
 148   // Most registers are in use; we'll use r16, rmethod, r10, r11
 149   const Register recv_klass_reg     = r10;
 150   const Register holder_klass_reg   = r16; // 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()));
 159 
 160   // get receiver (need to skip return address on top of stack)
 161   assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
 162   // get receiver klass (also an implicit null-check)
 163   address npe_addr = __ pc();
 164   __ load_klass(recv_klass_reg, j_rarg0);
 165 
 166   // Receiver subtype check against REFC.
 167   // Destroys recv_klass_reg value.
 168   __ lookup_interface_method(// inputs: rec. class, interface
 169                              recv_klass_reg, resolved_klass_reg, noreg,
 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
 177   __ lookup_interface_method(// inputs: rec. class, interface, itable index
 178                        recv_klass_reg, holder_klass_reg, itable_index,
 179                        // outputs: method, scan temp. reg
 180                        rmethod, temp_reg,
 181                        L_no_such_interface);
 182 
 183   // method (rmethod): Method*
 184   // j_rarg0: receiver






 185 
 186 #ifdef ASSERT
 187   if (DebugVtables) {
 188     Label L2;
 189     __ cbz(rmethod, L2);
 190     __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
 191     __ cbnz(rscratch1, L2);
 192     __ stop("compiler entrypoint is null");
 193     __ bind(L2);
 194   }
 195 #endif // ASSERT
 196 
 197   // rmethod: Method*
 198   // j_rarg0: receiver
 199   address ame_addr = __ pc();
 200   __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
 201   __ br(rscratch1);
 202 
 203   __ bind(L_no_such_interface);
 204   // Handle IncompatibleClassChangeError in itable stubs.
 205   // More detailed error message.
 206   // We force resolving of the call site by jumping to the "handle
 207   // wrong method" stub, and so let the interpreter runtime do all the
 208   // dirty work.

 209   __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
 210 
 211   __ flush();
 212 
 213   if (PrintMiscellaneous && (WizardMode || Verbose)) {
 214     tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
 215                   itable_index, p2i(s->entry_point()),
 216                   (int)(s->code_end() - s->entry_point()),
 217                   (int)(s->code_end() - __ pc()));
 218   }
 219   guarantee(__ pc() <= s->code_end(), "overflowed buffer");
 220 
 221   s->set_exception_points(npe_addr, ame_addr);
 222   return s;
 223 }
 224 
 225 
 226 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
 227   int size = DebugVtables ? 216 : 0;
 228   if (CountCompiledCalls)
 229     size += 6 * 4;
 230   // FIXME: vtable stubs only need 36 bytes
 231   if (is_vtable_stub)
 232     size += 52;
 233   else
 234     size += 176;
 235   return size;
 236 
 237   // In order to tune these parameters, run the JVM with VM options
 238   // +PrintMiscellaneous and +WizardMode to see information about
 239   // actual itable stubs.  Run it with -Xmx31G -XX:+UseCompressedOops.
 240   //
 241   // If Universe::narrow_klass_base is nonzero, decoding a compressed
 242   // class can take zeveral instructions.
 243   //
 244   // The JVM98 app. _202_jess has a megamorphic interface call.
 245   // The itable code looks like this:
 246 
 247   //    ldr    xmethod, [xscratch2,#CompiledICHolder::holder_klass_offset]
 248   //    ldr    x0, [xscratch2]
 249   //    ldr    w10, [x1,#oopDesc::klass_offset_in_bytes]
 250   //    mov    xheapbase, #0x3c000000                //   #narrow_klass_base
 251   //    movk    xheapbase, #0x3f7, lsl #32
 252   //    add    x10, xheapbase, x10
 253   //    mov    xheapbase, #0xe7ff0000                //   #heapbase
 254   //    movk    xheapbase, #0x3f7, lsl #32
 255   //    ldr    w11, [x10,#vtable_length_offset]
 256   //    add    x11, x10, x11, uxtx #3
 257   //    add    x11, x11, #itableMethodEntry::method_offset_in_bytes
 258   //    ldr    x10, [x11]
 259   //    cmp    xmethod, x10
 260   //    b.eq    found_method
 261   // search:
 262   //    cbz    x10, no_such_interface
 263   //    add    x11, x11, #0x10
 264   //    ldr    x10, [x11]
 265   //    cmp    xmethod, x10
 266   //    b.ne    search
 267   // found_method:
 268   //    ldr    w10, [x1,#oopDesc::klass_offset_in_bytes]
 269   //    mov    xheapbase, #0x3c000000                //   #narrow_klass_base
 270   //    movk    xheapbase, #0x3f7, lsl #32
 271   //    add    x10, xheapbase, x10
 272   //    mov    xheapbase, #0xe7ff0000                //   #heapbase
 273   //    movk    xheapbase, #0x3f7, lsl #32
 274   //    ldr    w11, [x10,#vtable_length_offset]
 275   //    add    x11, x10, x11, uxtx #3
 276   //    add    x11, x11, #itableMethodEntry::method_offset_in_bytes
 277   //    add    x10, x10, #itentry_off
 278   //    ldr    xmethod, [x11]
 279   //    cmp    x0, xmethod
 280   //    b.eq    found_method2
 281   // search2:
 282   //    cbz    xmethod, 0x000003ffa872e6cc
 283   //    add    x11, x11, #0x10
 284   //    ldr    xmethod, [x11]
 285   //    cmp    x0, xmethod
 286   //    b.ne    search2
 287   // found_method2:
 288   //    ldr    w11, [x11,#itableOffsetEntry::offset_offset_in_bytes]
 289   //    ldr    xmethod, [x10,w11,uxtw]
 290   //    ldr    xscratch1, [xmethod,#Method::from_compiled_offset]
 291   //    br    xscratch1
 292   // no_such_interface:
 293   //    b      throw_ICCE_entry
 294 
 295 }
 296 
 297 int VtableStub::pd_code_alignment() { return 4; }


  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "assembler_aarch64.inline.hpp"
  29 #include "code/vtableStubs.hpp"
  30 #include "interp_masm_aarch64.hpp"
  31 #include "memory/resourceArea.hpp"
  32 #include "oops/compiledICHolder.hpp"
  33 #include "oops/instanceKlass.hpp"
  34 #include "oops/klassVtable.hpp"
  35 #include "runtime/sharedRuntime.hpp"
  36 #include "vmreg_aarch64.inline.hpp"
  37 #ifdef COMPILER2
  38 #include "opto/runtime.hpp"
  39 #endif
  40 
  41 // machine-dependent part of VtableStubs: create VtableStub of correct size and
  42 // initialize its code
  43 
  44 #define __ masm->
  45 
  46 #ifndef PRODUCT
  47 extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int index);


  48 #endif
  49 
  50 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
  51   // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing.
  52   const int stub_code_length = VtableStub::code_size_limit(true);
  53   VtableStub* s = new(stub_code_length) VtableStub(true, vtable_index);
  54   // Can be NULL if there is no free space in the code cache.
  55   if (s == NULL) {
  56     return NULL;
  57   }
  58 
  59   // Count unused bytes in instruction sequences of variable size.
  60   // We add them to the computed buffer size in order to avoid
  61   // overflow in subsequently generated stubs.
  62   address   start_pc;
  63   int       slop_bytes = 0;
  64   int       slop_delta = 0;
  65 
  66   ResourceMark    rm;
  67   CodeBuffer      cb(s->entry_point(), stub_code_length);
  68   MacroAssembler* masm = new MacroAssembler(&cb);
  69 
  70 #if (!defined(PRODUCT) && defined(COMPILER2))
  71   if (CountCompiledCalls) {
  72     __ lea(r16, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
  73     __ incrementw(Address(r16));
  74   }
  75 #endif
  76 
  77   // get receiver (need to skip return address on top of stack)
  78   assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
  79 
  80   // get receiver klass
  81   address npe_addr = __ pc();
  82   __ load_klass(r16, j_rarg0);
  83 
  84 #ifndef PRODUCT
  85   if (DebugVtables) {
  86     Label L;
  87     // check offset vs vtable length
  88     __ ldrw(rscratch1, Address(r16, Klass::vtable_length_offset()));
  89     __ cmpw(rscratch1, vtable_index * vtableEntry::size());
  90     __ br(Assembler::GT, L);
  91     __ enter();
  92     __ mov(r2, vtable_index);
  93 
  94     // TODO: find upper bound for call_VM length.
  95     start_pc = __ pc();
  96     __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), j_rarg0, r2);
  97     slop_delta  = 470 - (__ pc() - start_pc);  // call_VM varies in length, depending on data
  98     slop_bytes += slop_delta;
  99     assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta);
 100 
 101     __ leave();
 102     __ bind(L);
 103   }
 104 #endif // PRODUCT
 105 
 106   start_pc = __ pc();
 107   __ lookup_virtual_method(r16, vtable_index, rmethod);
 108   slop_delta  = 8 - (int)(__ pc() - start_pc);
 109   slop_bytes += slop_delta;
 110   assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta);
 111 
 112 #ifndef PRODUCT
 113   if (DebugVtables) {
 114     Label L;
 115     __ cbz(rmethod, L);
 116     __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
 117     __ cbnz(rscratch1, L);
 118     __ stop("Vtable entry is NULL");
 119     __ bind(L);
 120   }
 121 #endif // PRODUCT
 122 
 123   // r0: receiver klass
 124   // rmethod: Method*
 125   // r2: receiver
 126   address ame_addr = __ pc();
 127   __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
 128   __ br(rscratch1);
 129 
 130   masm->flush();
 131   bookkeeping(masm, tty, s, npe_addr, ame_addr, true, vtable_index, slop_bytes, 0);
 132 









 133   return s;
 134 }
 135 
 136 
 137 VtableStub* VtableStubs::create_itable_stub(int itable_index) {
 138   // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing.
 139   const int stub_code_length = VtableStub::code_size_limit(false);
 140   VtableStub* s = new(stub_code_length) VtableStub(false, itable_index);
 141   // Can be NULL if there is no free space in the code cache.
 142   if (s == NULL) {
 143     return NULL;
 144   }
 145   // Count unused bytes in instruction sequences of variable size.
 146   // We add them to the computed buffer size in order to avoid
 147   // overflow in subsequently generated stubs.
 148   address   start_pc;
 149   int       slop_bytes = 0;
 150   int       slop_delta = 0;
 151 
 152   ResourceMark    rm;
 153   CodeBuffer      cb(s->entry_point(), stub_code_length);
 154   MacroAssembler* masm = new MacroAssembler(&cb);
 155 
 156 #if (!defined(PRODUCT) && defined(COMPILER2))
 157   if (CountCompiledCalls) {
 158     __ lea(r10, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
 159     __ incrementw(Address(r10));
 160   }
 161 #endif
 162 
 163   // get receiver (need to skip return address on top of stack)
 164   assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
 165 
 166   // Entry arguments:
 167   //  rscratch2: CompiledICHolder
 168   //  j_rarg0: Receiver
 169 

 170   // Most registers are in use; we'll use r16, rmethod, r10, r11
 171   const Register recv_klass_reg     = r10;
 172   const Register holder_klass_reg   = r16; // declaring interface klass (DECC)
 173   const Register resolved_klass_reg = rmethod; // resolved interface klass (REFC)
 174   const Register temp_reg           = r11;
 175   const Register icholder_reg       = rscratch2;
 176 
 177   Label L_no_such_interface;
 178 
 179   __ ldr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset()));
 180   __ ldr(holder_klass_reg,   Address(icholder_reg, CompiledICHolder::holder_metadata_offset()));
 181 
 182   start_pc = __ pc();
 183 
 184   // get receiver klass (also an implicit null-check)
 185   address npe_addr = __ pc();
 186   __ load_klass(recv_klass_reg, j_rarg0);
 187 
 188   // Receiver subtype check against REFC.
 189   // Destroys recv_klass_reg value.
 190   __ lookup_interface_method(// inputs: rec. class, interface
 191                              recv_klass_reg, resolved_klass_reg, noreg,
 192                              // outputs:  scan temp. reg1, scan temp. reg2
 193                              recv_klass_reg, temp_reg,
 194                              L_no_such_interface,
 195                              /*return_method=*/false);
 196 
 197   const ptrdiff_t  typecheckSize = __ pc() - start_pc;
 198   start_pc = __ pc();
 199 
 200   // Get selected method from declaring class and itable index
 201   __ load_klass(recv_klass_reg, j_rarg0);   // restore recv_klass_reg
 202   __ lookup_interface_method(// inputs: rec. class, interface, itable index
 203                              recv_klass_reg, holder_klass_reg, itable_index,
 204                              // outputs: method, scan temp. reg
 205                              rmethod, temp_reg,
 206                              L_no_such_interface);
 207 
 208   const ptrdiff_t lookupSize = __ pc() - start_pc;
 209 
 210   // Reduce "estimate" such that "padding" does not drop below 8.
 211   const ptrdiff_t estimate = 152;
 212   const ptrdiff_t codesize = typecheckSize + lookupSize;
 213   slop_delta  = (int)(estimate - codesize);
 214   slop_bytes += slop_delta;
 215   assert(slop_delta >= 0, "itable #%d: Code size estimate (%d) for lookup_interface_method too small, required: %d", itable_index, (int)estimate, (int)codesize);
 216 
 217 #ifdef ASSERT
 218   if (DebugVtables) {
 219     Label L2;
 220     __ cbz(rmethod, L2);
 221     __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
 222     __ cbnz(rscratch1, L2);
 223     __ stop("compiler entrypoint is null");
 224     __ bind(L2);
 225   }
 226 #endif // ASSERT
 227 
 228   // rmethod: Method*
 229   // j_rarg0: receiver
 230   address ame_addr = __ pc();
 231   __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
 232   __ br(rscratch1);
 233 
 234   __ bind(L_no_such_interface);
 235   // Handle IncompatibleClassChangeError in itable stubs.
 236   // More detailed error message.
 237   // We force resolving of the call site by jumping to the "handle
 238   // wrong method" stub, and so let the interpreter runtime do all the
 239   // dirty work.
 240   assert(SharedRuntime::get_handle_wrong_method_stub() != NULL, "check initialization order");
 241   __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
 242 
 243   masm->flush();
 244   bookkeeping(masm, tty, s, npe_addr, ame_addr, false, itable_index, slop_bytes, 0);







 245 

 246   return s;
 247 }
 248 
 249 int VtableStub::pd_code_alignment() {
 250   // aarch64 cache line size is not an architected constant. We just align on 4 bytes (instruction size).
 251   const unsigned int icache_line_size = 4;
 252   return icache_line_size;


































































 253 }


< prev index next >