168 // same-named entrypoint in the generated interpreter code.
169 movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset()));
170 movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_tos_offset()));
171 call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), c_rarg0);
172 jmp(rax);
173 bind(L);
174 }
175 }
176
177
178 void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(
179 Register reg,
180 int bcp_offset) {
181 assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
182 movl(reg, Address(r13, bcp_offset));
183 bswapl(reg);
184 shrl(reg, 16);
185 }
186
187
188 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
189 Register index,
190 int bcp_offset) {
191 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
192 assert(cache != index, "must use different registers");
193 load_unsigned_word(index, Address(r13, bcp_offset));
194 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
195 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
196 // convert from field index to ConstantPoolCacheEntry index
197 shll(index, 2);
198 }
199
200
201 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
202 Register tmp,
203 int bcp_offset) {
204 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
205 assert(cache != tmp, "must use different register");
206 load_unsigned_word(tmp, Address(r13, bcp_offset));
207 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
208 // convert from field index to ConstantPoolCacheEntry index
209 // and from word offset to byte offset
210 shll(tmp, 2 + LogBytesPerWord);
211 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
212 // skip past the header
213 addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset()));
214 addptr(cache, tmp); // construct pointer to cache entry
215 }
216
217
218 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a
219 // subtype of super_klass.
220 //
221 // Args:
222 // rax: superklass
223 // Rsub_klass: subklass
224 //
225 // Kills:
226 // rcx, rdi
1271 if (ProfileInterpreter) {
1272 Label profile_continue;
1273
1274 // If no method data exists, go to profile_continue.
1275 test_method_data_pointer(mdp, profile_continue);
1276
1277 // We are making a call. Increment the count.
1278 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1279
1280 // The method data pointer needs to be updated to reflect the new target.
1281 update_mdp_by_constant(mdp,
1282 in_bytes(VirtualCallData::
1283 virtual_call_data_size()));
1284 bind(profile_continue);
1285 }
1286 }
1287
1288
1289 void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
1290 Register mdp,
1291 Register reg2) {
1292 if (ProfileInterpreter) {
1293 Label profile_continue;
1294
1295 // If no method data exists, go to profile_continue.
1296 test_method_data_pointer(mdp, profile_continue);
1297
1298 // We are making a call. Increment the count.
1299 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1300
1301 // Record the receiver type.
1302 record_klass_in_profile(receiver, mdp, reg2);
1303
1304 // The method data pointer needs to be updated to reflect the new target.
1305 update_mdp_by_constant(mdp,
1306 in_bytes(VirtualCallData::
1307 virtual_call_data_size()));
1308 bind(profile_continue);
1309 }
1310 }
1311
1312 // This routine creates a state machine for updating the multi-row
1313 // type profile at a virtual call site (or other type-sensitive bytecode).
1314 // The machine visits each row (of receiver/count) until the receiver type
1315 // is found, or until it runs out of rows. At the same time, it remembers
1316 // the location of the first empty row. (An empty row records null for its
1317 // receiver, and can be allocated for a newly-observed receiver type.)
1318 // Because there are two degrees of freedom in the state, a simple linear
1319 // search will not work; it must be a decision tree. Hence this helper
1320 // function is recursive, to generate the required tree structured code.
1321 // It's the interpreter, so we are trading off code space for speed.
1322 // See below for example code.
|
168 // same-named entrypoint in the generated interpreter code.
169 movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset()));
170 movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_tos_offset()));
171 call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), c_rarg0);
172 jmp(rax);
173 bind(L);
174 }
175 }
176
177
178 void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(
179 Register reg,
180 int bcp_offset) {
181 assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
182 movl(reg, Address(r13, bcp_offset));
183 bswapl(reg);
184 shrl(reg, 16);
185 }
186
187
188 void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
189 int bcp_offset,
190 bool giant_index) {
191 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
192 if (!giant_index) {
193 load_unsigned_word(index, Address(r13, bcp_offset));
194 } else {
195 assert(InvokeDynamic, "giant index used only for InvokeDynamic");
196 movl(index, Address(r13, bcp_offset));
197 assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
198 notl(index); // convert to plain index
199 }
200 }
201
202
203 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
204 Register index,
205 int bcp_offset,
206 bool giant_index) {
207 assert(cache != index, "must use different registers");
208 get_cache_index_at_bcp(index, bcp_offset, giant_index);
209 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
210 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
211 // convert from field index to ConstantPoolCacheEntry index
212 shll(index, 2);
213 }
214
215
216 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
217 Register tmp,
218 int bcp_offset,
219 bool giant_index) {
220 assert(cache != tmp, "must use different register");
221 get_cache_index_at_bcp(tmp, bcp_offset, giant_index);
222 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
223 // convert from field index to ConstantPoolCacheEntry index
224 // and from word offset to byte offset
225 shll(tmp, 2 + LogBytesPerWord);
226 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
227 // skip past the header
228 addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset()));
229 addptr(cache, tmp); // construct pointer to cache entry
230 }
231
232
233 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a
234 // subtype of super_klass.
235 //
236 // Args:
237 // rax: superklass
238 // Rsub_klass: subklass
239 //
240 // Kills:
241 // rcx, rdi
1286 if (ProfileInterpreter) {
1287 Label profile_continue;
1288
1289 // If no method data exists, go to profile_continue.
1290 test_method_data_pointer(mdp, profile_continue);
1291
1292 // We are making a call. Increment the count.
1293 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1294
1295 // The method data pointer needs to be updated to reflect the new target.
1296 update_mdp_by_constant(mdp,
1297 in_bytes(VirtualCallData::
1298 virtual_call_data_size()));
1299 bind(profile_continue);
1300 }
1301 }
1302
1303
1304 void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
1305 Register mdp,
1306 Register reg2,
1307 bool receiver_can_be_null) {
1308 if (ProfileInterpreter) {
1309 Label profile_continue;
1310
1311 // If no method data exists, go to profile_continue.
1312 test_method_data_pointer(mdp, profile_continue);
1313
1314 // We are making a call. Increment the count.
1315 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1316
1317 Label skip_receiver_profile;
1318 if (receiver_can_be_null) {
1319 testptr(receiver, receiver);
1320 jcc(Assembler::zero, skip_receiver_profile);
1321 }
1322
1323 // Record the receiver type.
1324 record_klass_in_profile(receiver, mdp, reg2);
1325 bind(skip_receiver_profile);
1326
1327 // The method data pointer needs to be updated to reflect the new target.
1328 update_mdp_by_constant(mdp,
1329 in_bytes(VirtualCallData::
1330 virtual_call_data_size()));
1331 bind(profile_continue);
1332 }
1333 }
1334
1335 // This routine creates a state machine for updating the multi-row
1336 // type profile at a virtual call site (or other type-sensitive bytecode).
1337 // The machine visits each row (of receiver/count) until the receiver type
1338 // is found, or until it runs out of rows. At the same time, it remembers
1339 // the location of the first empty row. (An empty row records null for its
1340 // receiver, and can be allocated for a newly-observed receiver type.)
1341 // Because there are two degrees of freedom in the state, a simple linear
1342 // search will not work; it must be a decision tree. Hence this helper
1343 // function is recursive, to generate the required tree structured code.
1344 // It's the interpreter, so we are trading off code space for speed.
1345 // See below for example code.
|