187 bswapl(reg); |
187 bswapl(reg); |
188 shrl(reg, 16); |
188 shrl(reg, 16); |
189 } |
189 } |
190 |
190 |
191 |
191 |
192 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset) { |
192 void InterpreterMacroAssembler::get_cache_index_at_bcp(Register reg, int bcp_offset, bool giant_index) { |
193 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
193 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
|
194 if (!giant_index) { |
|
195 load_unsigned_short(reg, Address(rsi, bcp_offset)); |
|
196 } else { |
|
197 assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic"); |
|
198 movl(reg, Address(rsi, bcp_offset)); |
|
199 assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line"); |
|
200 notl(reg); // convert to plain index |
|
201 } |
|
202 } |
|
203 |
|
204 |
|
205 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index, |
|
206 int bcp_offset, bool giant_index) { |
194 assert(cache != index, "must use different registers"); |
207 assert(cache != index, "must use different registers"); |
195 load_unsigned_short(index, Address(rsi, bcp_offset)); |
208 get_cache_index_at_bcp(index, bcp_offset, giant_index); |
196 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
209 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
197 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
210 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
198 shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index |
211 shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index |
199 } |
212 } |
200 |
213 |
201 |
214 |
202 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset) { |
215 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, |
203 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
216 int bcp_offset, bool giant_index) { |
204 assert(cache != tmp, "must use different register"); |
217 assert(cache != tmp, "must use different register"); |
205 load_unsigned_short(tmp, Address(rsi, bcp_offset)); |
218 get_cache_index_at_bcp(tmp, bcp_offset, giant_index); |
206 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
219 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
207 // convert from field index to ConstantPoolCacheEntry index |
220 // convert from field index to ConstantPoolCacheEntry index |
208 // and from word offset to byte offset |
221 // and from word offset to byte offset |
209 shll(tmp, 2 + LogBytesPerWord); |
222 shll(tmp, 2 + LogBytesPerWord); |
210 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
223 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
1212 bind (profile_continue); |
1225 bind (profile_continue); |
1213 } |
1226 } |
1214 } |
1227 } |
1215 |
1228 |
1216 |
1229 |
1217 void InterpreterMacroAssembler::profile_virtual_call(Register receiver, Register mdp, Register reg2) { |
1230 void InterpreterMacroAssembler::profile_virtual_call(Register receiver, Register mdp, |
|
1231 Register reg2, |
|
1232 bool receiver_can_be_null) { |
1218 if (ProfileInterpreter) { |
1233 if (ProfileInterpreter) { |
1219 Label profile_continue; |
1234 Label profile_continue; |
1220 |
1235 |
1221 // If no method data exists, go to profile_continue. |
1236 // If no method data exists, go to profile_continue. |
1222 test_method_data_pointer(mdp, profile_continue); |
1237 test_method_data_pointer(mdp, profile_continue); |
1223 |
1238 |
1224 // We are making a call. Increment the count. |
1239 // We are making a call. Increment the count. |
1225 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); |
1240 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); |
1226 |
1241 |
|
1242 Label skip_receiver_profile; |
|
1243 if (receiver_can_be_null) { |
|
1244 testptr(receiver, receiver); |
|
1245 jcc(Assembler::zero, skip_receiver_profile); |
|
1246 } |
|
1247 |
1227 // Record the receiver type. |
1248 // Record the receiver type. |
1228 record_klass_in_profile(receiver, mdp, reg2); |
1249 record_klass_in_profile(receiver, mdp, reg2); |
|
1250 bind(skip_receiver_profile); |
1229 |
1251 |
1230 // The method data pointer needs to be updated to reflect the new target. |
1252 // The method data pointer needs to be updated to reflect the new target. |
1231 update_mdp_by_constant(mdp, |
1253 update_mdp_by_constant(mdp, |
1232 in_bytes(VirtualCallData:: |
1254 in_bytes(VirtualCallData:: |
1233 virtual_call_data_size())); |
1255 virtual_call_data_size())); |