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_short(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_short(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
1219 if (ProfileInterpreter) {
1220 Label profile_continue;
1221
1222 // If no method data exists, go to profile_continue.
1223 test_method_data_pointer(mdp, profile_continue);
1224
1225 // We are making a call. Increment the count.
1226 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1227
1228 // The method data pointer needs to be updated to reflect the new target.
1229 update_mdp_by_constant(mdp,
1230 in_bytes(VirtualCallData::
1231 virtual_call_data_size()));
1232 bind(profile_continue);
1233 }
1234 }
1235
1236
1237 void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
1238 Register mdp,
1239 Register reg2) {
1240 if (ProfileInterpreter) {
1241 Label profile_continue;
1242
1243 // If no method data exists, go to profile_continue.
1244 test_method_data_pointer(mdp, profile_continue);
1245
1246 // We are making a call. Increment the count.
1247 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1248
1249 // Record the receiver type.
1250 record_klass_in_profile(receiver, mdp, reg2);
1251
1252 // The method data pointer needs to be updated to reflect the new target.
1253 update_mdp_by_constant(mdp,
1254 in_bytes(VirtualCallData::
1255 virtual_call_data_size()));
1256 bind(profile_continue);
1257 }
1258 }
1259
1260 // This routine creates a state machine for updating the multi-row
1261 // type profile at a virtual call site (or other type-sensitive bytecode).
1262 // The machine visits each row (of receiver/count) until the receiver type
1263 // is found, or until it runs out of rows. At the same time, it remembers
1264 // the location of the first empty row. (An empty row records null for its
1265 // receiver, and can be allocated for a newly-observed receiver type.)
1266 // Because there are two degrees of freedom in the state, a simple linear
1267 // search will not work; it must be a decision tree. Hence this helper
1268 // function is recursive, to generate the required tree structured code.
1269 // It's the interpreter, so we are trading off code space for speed.
1270 // 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_short(index, Address(r13, bcp_offset));
194 } else {
195 assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
196 movl(index, Address(r13, bcp_offset));
197 // Check if the secondary index definition is still ~x, otherwise
198 // we have to change the following assembler code to calculate the
199 // plain index.
200 assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
201 notl(index); // convert to plain index
202 }
203 }
204
205
206 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
207 Register index,
208 int bcp_offset,
209 bool giant_index) {
210 assert(cache != index, "must use different registers");
211 get_cache_index_at_bcp(index, bcp_offset, giant_index);
212 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
213 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
214 // convert from field index to ConstantPoolCacheEntry index
215 shll(index, 2);
216 }
217
218
219 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
220 Register tmp,
221 int bcp_offset,
222 bool giant_index) {
223 assert(cache != tmp, "must use different register");
224 get_cache_index_at_bcp(tmp, bcp_offset, giant_index);
225 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
226 // convert from field index to ConstantPoolCacheEntry index
227 // and from word offset to byte offset
228 shll(tmp, 2 + LogBytesPerWord);
229 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
230 // skip past the header
231 addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset()));
232 addptr(cache, tmp); // construct pointer to cache entry
233 }
234
235
236 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a
237 // subtype of super_klass.
238 //
239 // Args:
240 // rax: superklass
241 // Rsub_klass: subklass
242 //
243 // Kills:
244 // rcx, rdi
1237 if (ProfileInterpreter) {
1238 Label profile_continue;
1239
1240 // If no method data exists, go to profile_continue.
1241 test_method_data_pointer(mdp, profile_continue);
1242
1243 // We are making a call. Increment the count.
1244 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1245
1246 // The method data pointer needs to be updated to reflect the new target.
1247 update_mdp_by_constant(mdp,
1248 in_bytes(VirtualCallData::
1249 virtual_call_data_size()));
1250 bind(profile_continue);
1251 }
1252 }
1253
1254
1255 void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
1256 Register mdp,
1257 Register reg2,
1258 bool receiver_can_be_null) {
1259 if (ProfileInterpreter) {
1260 Label profile_continue;
1261
1262 // If no method data exists, go to profile_continue.
1263 test_method_data_pointer(mdp, profile_continue);
1264
1265 // We are making a call. Increment the count.
1266 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1267
1268 Label skip_receiver_profile;
1269 if (receiver_can_be_null) {
1270 testptr(receiver, receiver);
1271 jcc(Assembler::zero, skip_receiver_profile);
1272 }
1273
1274 // Record the receiver type.
1275 record_klass_in_profile(receiver, mdp, reg2);
1276 bind(skip_receiver_profile);
1277
1278 // The method data pointer needs to be updated to reflect the new target.
1279 update_mdp_by_constant(mdp,
1280 in_bytes(VirtualCallData::
1281 virtual_call_data_size()));
1282 bind(profile_continue);
1283 }
1284 }
1285
1286 // This routine creates a state machine for updating the multi-row
1287 // type profile at a virtual call site (or other type-sensitive bytecode).
1288 // The machine visits each row (of receiver/count) until the receiver type
1289 // is found, or until it runs out of rows. At the same time, it remembers
1290 // the location of the first empty row. (An empty row records null for its
1291 // receiver, and can be allocated for a newly-observed receiver type.)
1292 // Because there are two degrees of freedom in the state, a simple linear
1293 // search will not work; it must be a decision tree. Hence this helper
1294 // function is recursive, to generate the required tree structured code.
1295 // It's the interpreter, so we are trading off code space for speed.
1296 // See below for example code.
|