1 /* 2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2014, Red Hat Inc. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #include "precompiled.hpp" 27 #include "asm/macroAssembler.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(r19, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); 67 __ incrementw(Address(r19)); 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(r19, j_rarg0); 77 78 #ifndef PRODUCT 79 if (DebugVtables) { 80 Label L; 81 // check offset vs vtable length 82 __ ldrw(rscratch1, Address(r19, 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(r19, 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 r19, rmethod, r10, r11 149 const Register recv_klass_reg = r10; 150 const Register holder_klass_reg = r19; // 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 __ far_jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); 205 206 __ flush(); 207 208 if (PrintMiscellaneous && (WizardMode || Verbose)) { 209 tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d", 210 itable_index, p2i(s->entry_point()), 211 (int)(s->code_end() - s->entry_point()), 212 (int)(s->code_end() - __ pc())); 213 } 214 guarantee(__ pc() <= s->code_end(), "overflowed buffer"); 215 216 s->set_exception_points(npe_addr, ame_addr); 217 return s; 218 } 219 220 221 int VtableStub::pd_code_size_limit(bool is_vtable_stub) { 222 int size = DebugVtables ? 216 : 0; 223 if (CountCompiledCalls) 224 size += 6 * 4; 225 // FIXME: vtable stubs only need 36 bytes 226 if (is_vtable_stub) 227 size += 52; 228 else 229 size += 176; 230 return size; 231 232 // In order to tune these parameters, run the JVM with VM options 233 // +PrintMiscellaneous and +WizardMode to see information about 234 // actual itable stubs. Run it with -Xmx31G -XX:+UseCompressedOops. 235 // 236 // If Universe::narrow_klass_base is nonzero, decoding a compressed 237 // class can take zeveral instructions. 238 // 239 // The JVM98 app. _202_jess has a megamorphic interface call. 240 // The itable code looks like this: 241 242 // ldr xmethod, [xscratch2,#CompiledICHolder::holder_klass_offset] 243 // ldr x0, [xscratch2] 244 // ldr w10, [x1,#oopDesc::klass_offset_in_bytes] 245 // mov xheapbase, #0x3c000000 // #narrow_klass_base 246 // movk xheapbase, #0x3f7, lsl #32 247 // add x10, xheapbase, x10 248 // mov xheapbase, #0xe7ff0000 // #heapbase 249 // movk xheapbase, #0x3f7, lsl #32 250 // ldr w11, [x10,#vtable_length_offset] 251 // add x11, x10, x11, uxtx #3 252 // add x11, x11, #itableMethodEntry::method_offset_in_bytes 253 // ldr x10, [x11] 254 // cmp xmethod, x10 255 // b.eq found_method 256 // search: 257 // cbz x10, no_such_interface 258 // add x11, x11, #0x10 259 // ldr x10, [x11] 260 // cmp xmethod, x10 261 // b.ne search 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 289 290 } 291 292 int VtableStub::pd_code_alignment() { return 4; }