1 /* 2 * Copyright (c) 2014, Red Hat Inc. 3 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. 4 * All rights reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 * 25 */ 26 27 #include "precompiled.hpp" 28 #include "asm/macroAssembler.hpp" 29 #include "assembler_aarch64.inline.hpp" 30 #include "code/vtableStubs.hpp" 31 #include "interp_masm_aarch64.hpp" 32 #include "memory/resourceArea.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 ResourceMark rm; 56 CodeBuffer cb(s->entry_point(), aarch64_code_length); 57 MacroAssembler* masm = new MacroAssembler(&cb); 58 59 #ifndef PRODUCT 60 if (CountCompiledCalls) { 61 __ lea(r19, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); 62 __ incrementw(Address(r19)); 63 } 64 #endif 65 66 // get receiver (need to skip return address on top of stack) 67 assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0"); 68 69 // get receiver klass 70 address npe_addr = __ pc(); 71 __ load_klass(r19, j_rarg0); 72 73 #ifndef PRODUCT 74 if (DebugVtables) { 75 Label L; 76 // check offset vs vtable length 77 __ ldrw(rscratch1, Address(r19, InstanceKlass::vtable_length_offset() * wordSize)); 78 __ cmpw(rscratch1, vtable_index * vtableEntry::size()); 79 __ br(Assembler::GT, L); 80 __ enter(); 81 __ mov(r2, vtable_index); 82 __ call_VM(noreg, 83 CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), j_rarg0, r2); 84 __ leave(); 85 __ bind(L); 86 } 87 #endif // PRODUCT 88 89 __ lookup_virtual_method(r19, vtable_index, rmethod); 90 91 if (DebugVtables) { 92 Label L; 93 __ cbz(rmethod, L); 94 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset())); 95 __ cbnz(rscratch1, L); 96 __ stop("Vtable entry is NULL"); 97 __ bind(L); 98 } 99 // r0: receiver klass 100 // rmethod: Method* 101 // r2: receiver 102 address ame_addr = __ pc(); 103 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset())); 104 __ br(rscratch1); 105 106 __ flush(); 107 108 if (PrintMiscellaneous && (WizardMode || Verbose)) { 109 tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d", 110 vtable_index, p2i(s->entry_point()), 111 (int)(s->code_end() - s->entry_point()), 112 (int)(s->code_end() - __ pc())); 113 } 114 guarantee(__ pc() <= s->code_end(), "overflowed buffer"); 115 116 s->set_exception_points(npe_addr, ame_addr); 117 return s; 118 } 119 120 121 VtableStub* VtableStubs::create_itable_stub(int itable_index) { 122 // Note well: pd_code_size_limit is the absolute minimum we can get 123 // away with. If you add code here, bump the code stub size 124 // returned by pd_code_size_limit! 125 const int code_length = VtableStub::pd_code_size_limit(false); 126 VtableStub* s = new(code_length) VtableStub(false, itable_index); 127 ResourceMark rm; 128 CodeBuffer cb(s->entry_point(), code_length); 129 MacroAssembler* masm = new MacroAssembler(&cb); 130 131 #ifndef PRODUCT 132 if (CountCompiledCalls) { 133 __ lea(r10, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr())); 134 __ incrementw(Address(r10)); 135 } 136 #endif 137 138 // Entry arguments: 139 // rscratch2: Interface 140 // j_rarg0: Receiver 141 142 // Free registers (non-args) are r0 (interface), rmethod 143 144 // get receiver (need to skip return address on top of stack) 145 146 assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0"); 147 // get receiver klass (also an implicit null-check) 148 address npe_addr = __ pc(); 149 150 // Most registers are in use; we'll use r0, rmethod, r10, r11 151 __ load_klass(r10, j_rarg0); 152 153 Label throw_icce; 154 155 // Get Method* and entrypoint for compiler 156 __ lookup_interface_method(// inputs: rec. class, interface, itable index 157 r10, rscratch2, itable_index, 158 // outputs: method, scan temp. reg 159 rmethod, r11, 160 throw_icce); 161 162 // method (rmethod): Method* 163 // j_rarg0: receiver 164 165 #ifdef ASSERT 166 if (DebugVtables) { 167 Label L2; 168 __ cbz(rmethod, L2); 169 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset())); 170 __ cbnz(rscratch1, L2); 171 __ stop("compiler entrypoint is null"); 172 __ bind(L2); 173 } 174 #endif // ASSERT 175 176 // rmethod: Method* 177 // j_rarg0: receiver 178 address ame_addr = __ pc(); 179 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset())); 180 __ br(rscratch1); 181 182 __ bind(throw_icce); 183 __ far_jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); 184 185 __ flush(); 186 187 if (PrintMiscellaneous && (WizardMode || Verbose)) { 188 tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d", 189 itable_index, p2i(s->entry_point()), 190 (int)(s->code_end() - s->entry_point()), 191 (int)(s->code_end() - __ pc())); 192 } 193 guarantee(__ pc() <= s->code_end(), "overflowed buffer"); 194 195 s->set_exception_points(npe_addr, ame_addr); 196 return s; 197 } 198 199 200 int VtableStub::pd_code_size_limit(bool is_vtable_stub) { 201 int size = DebugVtables ? 216 : 0; 202 if (CountCompiledCalls) 203 size += 6 * 4; 204 // FIXME 205 if (is_vtable_stub) 206 size += 52; 207 else 208 size += 104; 209 return size; 210 211 // In order to tune these parameters, run the JVM with VM options 212 // +PrintMiscellaneous and +WizardMode to see information about 213 // actual itable stubs. Run it with -Xmx31G -XX:+UseCompressedOops. 214 // 215 // If Universe::narrow_klass_base is nonzero, decoding a compressed 216 // class can take zeveral instructions. Run it with -Xmx31G 217 // -XX:+UseCompressedOops. 218 // 219 // The JVM98 app. _202_jess has a megamorphic interface call. 220 // The itable code looks like this: 221 // Decoding VtableStub itbl[1]@12 222 // ldr w10, [x1,#8] 223 // lsl x10, x10, #3 224 // ldr w11, [x10,#280] 225 // add x11, x10, x11, uxtx #3 226 // add x11, x11, #0x1b8 227 // ldr x12, [x11] 228 // cmp x9, x12 229 // b.eq success 230 // loop: 231 // cbz x12, throw_icce 232 // add x11, x11, #0x10 233 // ldr x12, [x11] 234 // cmp x9, x12 235 // b.ne loop 236 // success: 237 // ldr x11, [x11,#8] 238 // ldr x12, [x10,x11] 239 // ldr x8, [x12,#72] 240 // br x8 241 // throw_icce: 242 // b throw_ICCE_entry 243 244 } 245 246 int VtableStub::pd_code_alignment() { return 4; }