62 63 #ifndef PRODUCT 64 if (CountCompiledCalls) { 65 __ load_const(R11_scratch1, SharedRuntime::nof_megamorphic_calls_addr()); 66 __ lwz(R12_scratch2, 0, R11_scratch1); 67 __ addi(R12_scratch2, R12_scratch2, 1); 68 __ stw(R12_scratch2, 0, R11_scratch1); 69 } 70 #endif 71 72 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1"); 73 74 // Get receiver klass. 75 const Register rcvr_klass = R11_scratch1; 76 77 // We might implicit NULL fault here. 78 address npe_addr = __ pc(); // npe = null pointer exception 79 __ load_klass_with_trap_null_check(rcvr_klass, R3); 80 81 // Set method (in case of interpreted method), and destination address. 82 int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); 83 84 #ifndef PRODUCT 85 if (DebugVtables) { 86 Label L; 87 // Check offset vs vtable length. 88 const Register vtable_len = R12_scratch2; 89 __ lwz(vtable_len, InstanceKlass::vtable_length_offset()*wordSize, rcvr_klass); 90 __ cmpwi(CCR0, vtable_len, vtable_index*vtableEntry::size()); 91 __ bge(CCR0, L); 92 __ li(R12_scratch2, vtable_index); 93 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), R3_ARG1, R12_scratch2, false); 94 __ bind(L); 95 } 96 #endif 97 98 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); 99 100 __ ld(R19_method, v_off, rcvr_klass); 101 102 #ifndef PRODUCT 103 if (DebugVtables) { 104 Label L; 105 __ cmpdi(CCR0, R19_method, 0); 106 __ bne(CCR0, L); 107 __ stop("Vtable entry is ZERO", 102); 108 __ bind(L); 109 } 110 #endif 111 112 // If the vtable entry is null, the method is abstract. 113 address ame_addr = __ pc(); // ame = abstract method error 114 115 __ load_with_trap_null_check(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method); 116 __ mtctr(R12_scratch2); 117 __ bctr(); 118 masm->flush(); 144 145 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1"); 146 147 // Entry arguments: 148 // R19_method: Interface 149 // R3_ARG1: Receiver 150 // 151 152 const Register rcvr_klass = R11_scratch1; 153 const Register vtable_len = R12_scratch2; 154 const Register itable_entry_addr = R21_tmp1; 155 const Register itable_interface = R22_tmp2; 156 157 // Get receiver klass. 158 159 // We might implicit NULL fault here. 160 address npe_addr = __ pc(); // npe = null pointer exception 161 __ load_klass_with_trap_null_check(rcvr_klass, R3_ARG1); 162 163 BLOCK_COMMENT("Load start of itable entries into itable_entry."); 164 __ lwz(vtable_len, InstanceKlass::vtable_length_offset() * wordSize, rcvr_klass); 165 __ slwi(vtable_len, vtable_len, exact_log2(vtableEntry::size() * wordSize)); 166 __ add(itable_entry_addr, vtable_len, rcvr_klass); 167 168 // Loop over all itable entries until desired interfaceOop(Rinterface) found. 169 BLOCK_COMMENT("Increment itable_entry_addr in loop."); 170 const int vtable_base_offset = InstanceKlass::vtable_start_offset() * wordSize; 171 __ addi(itable_entry_addr, itable_entry_addr, vtable_base_offset + itableOffsetEntry::interface_offset_in_bytes()); 172 173 const int itable_offset_search_inc = itableOffsetEntry::size() * wordSize; 174 Label search; 175 __ bind(search); 176 __ ld(itable_interface, 0, itable_entry_addr); 177 178 // Handle IncompatibleClassChangeError in itable stubs. 179 // If the entry is NULL then we've reached the end of the table 180 // without finding the expected interface, so throw an exception. 181 BLOCK_COMMENT("Handle IncompatibleClassChangeError in itable stubs."); 182 Label throw_icce; 183 __ cmpdi(CCR1, itable_interface, 0); 184 __ cmpd(CCR0, itable_interface, R19_method); 185 __ addi(itable_entry_addr, itable_entry_addr, itable_offset_search_inc); 186 __ beq(CCR1, throw_icce); 187 __ bne(CCR0, search); 188 189 // Entry found and itable_entry_addr points to it, get offset of vtable for interface. 190 | 62 63 #ifndef PRODUCT 64 if (CountCompiledCalls) { 65 __ load_const(R11_scratch1, SharedRuntime::nof_megamorphic_calls_addr()); 66 __ lwz(R12_scratch2, 0, R11_scratch1); 67 __ addi(R12_scratch2, R12_scratch2, 1); 68 __ stw(R12_scratch2, 0, R11_scratch1); 69 } 70 #endif 71 72 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1"); 73 74 // Get receiver klass. 75 const Register rcvr_klass = R11_scratch1; 76 77 // We might implicit NULL fault here. 78 address npe_addr = __ pc(); // npe = null pointer exception 79 __ load_klass_with_trap_null_check(rcvr_klass, R3); 80 81 // Set method (in case of interpreted method), and destination address. 82 int entry_offset = in_bytes(InstanceKlass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes(); 83 84 #ifndef PRODUCT 85 if (DebugVtables) { 86 Label L; 87 // Check offset vs vtable length. 88 const Register vtable_len = R12_scratch2; 89 __ lwz(vtable_len, in_bytes(InstanceKlass::vtable_length_offset()), rcvr_klass); 90 __ cmpwi(CCR0, vtable_len, vtable_index*vtableEntry::size()); 91 __ bge(CCR0, L); 92 __ li(R12_scratch2, vtable_index); 93 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), R3_ARG1, R12_scratch2, false); 94 __ bind(L); 95 } 96 #endif 97 98 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 99 100 __ ld(R19_method, v_off, rcvr_klass); 101 102 #ifndef PRODUCT 103 if (DebugVtables) { 104 Label L; 105 __ cmpdi(CCR0, R19_method, 0); 106 __ bne(CCR0, L); 107 __ stop("Vtable entry is ZERO", 102); 108 __ bind(L); 109 } 110 #endif 111 112 // If the vtable entry is null, the method is abstract. 113 address ame_addr = __ pc(); // ame = abstract method error 114 115 __ load_with_trap_null_check(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method); 116 __ mtctr(R12_scratch2); 117 __ bctr(); 118 masm->flush(); 144 145 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1"); 146 147 // Entry arguments: 148 // R19_method: Interface 149 // R3_ARG1: Receiver 150 // 151 152 const Register rcvr_klass = R11_scratch1; 153 const Register vtable_len = R12_scratch2; 154 const Register itable_entry_addr = R21_tmp1; 155 const Register itable_interface = R22_tmp2; 156 157 // Get receiver klass. 158 159 // We might implicit NULL fault here. 160 address npe_addr = __ pc(); // npe = null pointer exception 161 __ load_klass_with_trap_null_check(rcvr_klass, R3_ARG1); 162 163 BLOCK_COMMENT("Load start of itable entries into itable_entry."); 164 __ lwz(vtable_len, in_bytes(InstanceKlass::vtable_length_offset()), rcvr_klass); 165 __ slwi(vtable_len, vtable_len, exact_log2(vtableEntry::size_in_bytes())); 166 __ add(itable_entry_addr, vtable_len, rcvr_klass); 167 168 // Loop over all itable entries until desired interfaceOop(Rinterface) found. 169 BLOCK_COMMENT("Increment itable_entry_addr in loop."); 170 const int vtable_base_offset = in_bytes(InstanceKlass::vtable_start_offset()); 171 __ addi(itable_entry_addr, itable_entry_addr, vtable_base_offset + itableOffsetEntry::interface_offset_in_bytes()); 172 173 const int itable_offset_search_inc = itableOffsetEntry::size() * wordSize; 174 Label search; 175 __ bind(search); 176 __ ld(itable_interface, 0, itable_entry_addr); 177 178 // Handle IncompatibleClassChangeError in itable stubs. 179 // If the entry is NULL then we've reached the end of the table 180 // without finding the expected interface, so throw an exception. 181 BLOCK_COMMENT("Handle IncompatibleClassChangeError in itable stubs."); 182 Label throw_icce; 183 __ cmpdi(CCR1, itable_interface, 0); 184 __ cmpd(CCR0, itable_interface, R19_method); 185 __ addi(itable_entry_addr, itable_entry_addr, itable_offset_search_inc); 186 __ beq(CCR1, throw_icce); 187 __ bne(CCR0, search); 188 189 // Entry found and itable_entry_addr points to it, get offset of vtable for interface. 190 |