1 /* 2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2012, 2018 SAP SE. 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.inline.hpp" 28 #include "code/vtableStubs.hpp" 29 #include "interp_masm_ppc.hpp" 30 #include "memory/resourceArea.hpp" 31 #include "oops/compiledICHolder.hpp" 32 #include "oops/instanceKlass.hpp" 33 #include "oops/klassVtable.hpp" 34 #include "runtime/sharedRuntime.hpp" 35 #include "vmreg_ppc.inline.hpp" 36 #ifdef COMPILER2 37 #include "opto/runtime.hpp" 38 #endif 39 40 #define __ masm-> 41 42 #ifdef PRODUCT 43 #define BLOCK_COMMENT(str) // nothing 44 #else 45 #define BLOCK_COMMENT(str) __ block_comment(str) 46 #endif 47 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") 48 49 #ifndef PRODUCT 50 extern "C" void bad_compiled_vtable_index(JavaThread* thread, oopDesc* receiver, int index); 51 #endif 52 53 // Used by compiler only; may use only caller saved, non-argument 54 // registers. 55 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { 56 // PPC port: use fixed size. 57 const int code_length = VtableStub::pd_code_size_limit(true); 58 VtableStub* s = new (code_length) VtableStub(true, vtable_index); 59 60 // Can be NULL if there is no free space in the code cache. 61 if (s == NULL) { 62 return NULL; 63 } 64 65 ResourceMark rm; 66 CodeBuffer cb(s->entry_point(), code_length); 67 MacroAssembler* masm = new MacroAssembler(&cb); 68 69 #ifndef PRODUCT 70 if (CountCompiledCalls) { 71 int offs = __ load_const_optimized(R11_scratch1, SharedRuntime::nof_megamorphic_calls_addr(), R12_scratch2, true); 72 __ lwz(R12_scratch2, offs, R11_scratch1); 73 __ addi(R12_scratch2, R12_scratch2, 1); 74 __ stw(R12_scratch2, offs, R11_scratch1); 75 } 76 #endif 77 78 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1"); 79 80 // Get receiver klass. 81 const Register rcvr_klass = R11_scratch1; 82 83 // We might implicit NULL fault here. 84 address npe_addr = __ pc(); // npe = null pointer exception 85 __ null_check(R3, oopDesc::klass_offset_in_bytes(), /*implicit only*/NULL); 86 __ load_klass(rcvr_klass, R3); 87 88 // Set method (in case of interpreted method), and destination address. 89 int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes(); 90 91 #ifndef PRODUCT 92 if (DebugVtables) { 93 Label L; 94 // Check offset vs vtable length. 95 const Register vtable_len = R12_scratch2; 96 __ lwz(vtable_len, in_bytes(Klass::vtable_length_offset()), rcvr_klass); 97 __ cmpwi(CCR0, vtable_len, vtable_index*vtableEntry::size()); 98 __ bge(CCR0, L); 99 __ li(R12_scratch2, vtable_index); 100 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), R3_ARG1, R12_scratch2, false); 101 __ bind(L); 102 } 103 #endif 104 105 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 106 107 __ ld(R19_method, (RegisterOrConstant)v_off, rcvr_klass); 108 109 #ifndef PRODUCT 110 if (DebugVtables) { 111 Label L; 112 __ cmpdi(CCR0, R19_method, 0); 113 __ bne(CCR0, L); 114 __ stop("Vtable entry is ZERO", 102); 115 __ bind(L); 116 } 117 #endif 118 119 // If the vtable entry is null, the method is abstract. 120 address ame_addr = __ pc(); // ame = abstract method error 121 __ null_check(R19_method, in_bytes(Method::from_compiled_offset()), /*implicit only*/NULL); 122 __ ld(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method); 123 __ mtctr(R12_scratch2); 124 __ bctr(); 125 126 masm->flush(); 127 128 guarantee(__ pc() <= s->code_end(), "overflowed buffer"); 129 130 s->set_exception_points(npe_addr, ame_addr); 131 132 return s; 133 } 134 135 VtableStub* VtableStubs::create_itable_stub(int itable_index) { 136 // PPC port: use fixed size. 137 const int code_length = VtableStub::pd_code_size_limit(false); 138 VtableStub* s = new (code_length) VtableStub(false, itable_index); 139 140 // Can be NULL if there is no free space in the code cache. 141 if (s == NULL) { 142 return NULL; 143 } 144 145 ResourceMark rm; 146 CodeBuffer cb(s->entry_point(), code_length); 147 MacroAssembler* masm = new MacroAssembler(&cb); 148 address start_pc; 149 150 #ifndef PRODUCT 151 if (CountCompiledCalls) { 152 int offs = __ load_const_optimized(R11_scratch1, SharedRuntime::nof_megamorphic_calls_addr(), R12_scratch2, true); 153 __ lwz(R12_scratch2, offs, R11_scratch1); 154 __ addi(R12_scratch2, R12_scratch2, 1); 155 __ stw(R12_scratch2, offs, R11_scratch1); 156 } 157 #endif 158 159 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1"); 160 161 // Entry arguments: 162 // R19_method: Interface 163 // R3_ARG1: Receiver 164 165 Label L_no_such_interface; 166 const Register rcvr_klass = R11_scratch1, 167 interface = R12_scratch2, 168 tmp1 = R21_tmp1, 169 tmp2 = R22_tmp2; 170 171 address npe_addr = __ pc(); // npe = null pointer exception 172 __ null_check(R3_ARG1, oopDesc::klass_offset_in_bytes(), /*implicit only*/NULL); 173 __ load_klass(rcvr_klass, R3_ARG1); 174 175 // Receiver subtype check against REFC. 176 __ ld(interface, CompiledICHolder::holder_klass_offset(), R19_method); 177 __ lookup_interface_method(rcvr_klass, interface, noreg, 178 R0, tmp1, tmp2, 179 L_no_such_interface, /*return_method=*/ false); 180 181 // Get Method* and entrypoint for compiler 182 __ ld(interface, CompiledICHolder::holder_metadata_offset(), R19_method); 183 __ lookup_interface_method(rcvr_klass, interface, itable_index, 184 R19_method, tmp1, tmp2, 185 L_no_such_interface, /*return_method=*/ true); 186 187 #ifndef PRODUCT 188 if (DebugVtables) { 189 Label ok; 190 __ cmpd(CCR0, R19_method, 0); 191 __ bne(CCR0, ok); 192 __ stop("method is null", 103); 193 __ bind(ok); 194 } 195 #endif 196 197 // If the vtable entry is null, the method is abstract. 198 address ame_addr = __ pc(); // ame = abstract method error 199 200 // Must do an explicit check if implicit checks are disabled. 201 __ null_check(R19_method, in_bytes(Method::from_compiled_offset()), &L_no_such_interface); 202 __ ld(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method); 203 __ mtctr(R12_scratch2); 204 __ bctr(); 205 206 // Handle IncompatibleClassChangeError in itable stubs. 207 // More detailed error message. 208 // We force resolving of the call site by jumping to the "handle 209 // wrong method" stub, and so let the interpreter runtime do all the 210 // dirty work. 211 __ bind(L_no_such_interface); 212 __ load_const_optimized(R11_scratch1, SharedRuntime::get_handle_wrong_method_stub(), R12_scratch2); 213 __ mtctr(R11_scratch1); 214 __ bctr(); 215 216 masm->flush(); 217 218 guarantee(__ pc() <= s->code_end(), "overflowed buffer"); 219 220 s->set_exception_points(npe_addr, ame_addr); 221 return s; 222 } 223 224 int VtableStub::pd_code_size_limit(bool is_vtable_stub) { 225 if (DebugVtables || CountCompiledCalls || VerifyOops) { 226 return 1000; 227 } 228 int size = is_vtable_stub ? 20 + 8 : 164 + 20; // Plain + safety 229 if (UseCompressedClassPointers) { 230 size += MacroAssembler::instr_size_for_decode_klass_not_null(); 231 } 232 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 233 size += is_vtable_stub ? 8 : 12; 234 } 235 return size; 236 } 237 238 int VtableStub::pd_code_alignment() { 239 const unsigned int icache_line_size = 32; 240 return icache_line_size; 241 }