< prev index next >

src/hotspot/share/code/compiledIC.cpp

Print this page

184   return CompiledIC_at(nm, call_site);
185 }
186 
187 CompiledIC* CompiledIC_at(RelocIterator* reloc_iter) {
188   CompiledIC* c_ic = new CompiledIC(reloc_iter);
189   c_ic->verify();
190   return c_ic;
191 }
192 
193 void CompiledIC::ensure_initialized(CallInfo* call_info, Klass* receiver_klass) {
194   if (!_data->is_initialized()) {
195     _data->initialize(call_info, receiver_klass);
196   }
197 }
198 
199 void CompiledIC::set_to_clean() {
200   log_debug(inlinecache)("IC@" INTPTR_FORMAT ": set to clean", p2i(_call->instruction_address()));
201   _call->set_destination_mt_safe(SharedRuntime::get_resolve_virtual_call_stub());
202 }
203 
204 void CompiledIC::set_to_monomorphic() {
205   assert(data()->is_initialized(), "must be initialized");
206   Method* method = data()->speculated_method();
207   nmethod* code = method->code();
208   address entry;
209   bool to_compiled = code != nullptr && code->is_in_use() && !code->is_unloading();
210 
211   if (to_compiled) {
212     entry = code->entry_point();
213   } else {
214     entry = method->get_c2i_unverified_entry();
215   }
216 
217   log_trace(inlinecache)("IC@" INTPTR_FORMAT ": monomorphic to %s: %s",
218                          p2i(_call->instruction_address()),
219                          to_compiled ? "compiled" : "interpreter",
220                          method->print_value_string());
221 
222   _call->set_destination_mt_safe(entry);
223 }
224 
225 void CompiledIC::set_to_megamorphic(CallInfo* call_info) {
226   assert(data()->is_initialized(), "must be initialized");
227 
228   address entry;
229   if (call_info->call_kind() == CallInfo::direct_call) {
230     // C1 sometimes compiles a callsite before the target method is loaded, resulting in
231     // dynamically bound callsites that should really be statically bound. However, the
232     // target method might not have a vtable or itable. We just wait for better code to arrive
233     return;
234   } else if (call_info->call_kind() == CallInfo::itable_call) {
235     int itable_index = call_info->itable_index();
236     entry = VtableStubs::find_itable_stub(itable_index);
237     if (entry == nullptr) {
238       return;
239     }
240 #ifdef ASSERT
241     int index = call_info->resolved_method()->itable_index();
242     assert(index == itable_index, "CallInfo pre-computes this");
243     InstanceKlass* k = call_info->resolved_method()->method_holder();
244     assert(k->verify_itable_index(itable_index), "sanity check");
245 #endif //ASSERT
246   } else {
247     assert(call_info->call_kind() == CallInfo::vtable_call, "what else?");
248     // Can be different than selected_method->vtable_index(), due to package-private etc.
249     int vtable_index = call_info->vtable_index();
250     assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check");
251     entry = VtableStubs::find_vtable_stub(vtable_index);
252     if (entry == nullptr) {
253       return;
254     }
255   }
256 
257   log_trace(inlinecache)("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT,
258                          p2i(_call->instruction_address()), call_info->selected_method()->print_value_string(), p2i(entry));
259 
260   _call->set_destination_mt_safe(entry);
261   assert(is_megamorphic(), "sanity check");
262 }
263 
264 void CompiledIC::update(CallInfo* call_info, Klass* receiver_klass) {
265   // If this is the first time we fix the inline cache, we ensure it's initialized
266   ensure_initialized(call_info, receiver_klass);
267 
268   if (is_megamorphic()) {
269     // Terminal state for the inline cache
270     return;
271   }
272 
273   if (is_speculated_klass(receiver_klass)) {
274     // If the speculated class matches the receiver klass, we can speculate that will
275     // continue to be the case with a monomorphic inline cache
276     set_to_monomorphic();
277   } else {
278     // If the dynamic type speculation fails, we try to transform to a megamorphic state
279     // for the inline cache using stubs to dispatch in tables
280     set_to_megamorphic(call_info);
281   }
282 }
283 
284 bool CompiledIC::is_clean() const {
285   return destination() == SharedRuntime::get_resolve_virtual_call_stub();
286 }
287 
288 bool CompiledIC::is_monomorphic() const {
289   return !is_clean() && !is_megamorphic();
290 }
291 
292 bool CompiledIC::is_megamorphic() const {
293   return VtableStubs::entry_point(destination()) != nullptr;;
294 }
295 
296 bool CompiledIC::is_speculated_klass(Klass* receiver_klass) {
297   return data()->speculated_klass() == receiver_klass;
298 }
299 
300 // GC support
301 void CompiledIC::clean_metadata() {
302   data()->clean_metadata();
303 }
304 
305 void CompiledIC::metadata_do(MetadataClosure* cl) {
306   data()->metadata_do(cl);
307 }
308 
309 #ifndef PRODUCT
310 void CompiledIC::print() {
311   tty->print("Inline cache at " INTPTR_FORMAT ", calling " INTPTR_FORMAT " cached_value " INTPTR_FORMAT,
312              p2i(instruction_address()), p2i(destination()), p2i(data()));
313   tty->cr();

325   assert(CompiledICLocker::is_safe(instruction_address()), "mt unsafe call");
326   // Reset call site
327   RelocIterator iter((nmethod*)nullptr, instruction_address(), instruction_address() + 1);
328   while (iter.next()) {
329     switch(iter.type()) {
330     case relocInfo::static_call_type:
331       _call->set_destination_mt_safe(SharedRuntime::get_resolve_static_call_stub());
332       break;
333     case relocInfo::opt_virtual_call_type:
334       _call->set_destination_mt_safe(SharedRuntime::get_resolve_opt_virtual_call_stub());
335       break;
336     default:
337       ShouldNotReachHere();
338     }
339   }
340   assert(is_clean(), "should be clean after cleaning");
341 
342   log_debug(inlinecache)("DC@" INTPTR_FORMAT ": set to clean", p2i(_call->instruction_address()));
343 }
344 
345 void CompiledDirectCall::set(const methodHandle& callee_method) {
346   nmethod* code = callee_method->code();
347   nmethod* caller = CodeCache::find_nmethod(instruction_address());
348   assert(caller != nullptr, "did not find caller nmethod");
349 
350   bool to_interp_cont_enter = caller->method()->is_continuation_enter_intrinsic() &&
351                               ContinuationEntry::is_interpreted_call(instruction_address());
352 
353   bool to_compiled = !to_interp_cont_enter && code != nullptr && code->is_in_use() && !code->is_unloading();
354 
355   if (to_compiled) {
356     _call->set_destination_mt_safe(code->verified_entry_point());
357     assert(is_call_to_compiled(), "should be compiled after set to compiled");
358   } else {
359     // Patch call site to C2I adapter if code is deoptimized or unloaded.
360     // We also need to patch the static call stub to set the rmethod register
361     // to the callee_method so the c2i adapter knows how to build the frame
362     set_to_interpreted(callee_method, callee_method->get_c2i_entry());
363     assert(is_call_to_interpreted(), "should be interpreted after set to interpreted");
364   }
365 
366   log_trace(inlinecache)("DC@" INTPTR_FORMAT ": set to %s: %s: " INTPTR_FORMAT,
367                          p2i(_call->instruction_address()),
368                          to_compiled ? "compiled" : "interpreter",
369                          callee_method->print_value_string(),
370                          p2i(_call->destination()));
371 }
372 
373 bool CompiledDirectCall::is_clean() const {
374   return destination() == SharedRuntime::get_resolve_static_call_stub() ||
375          destination() == SharedRuntime::get_resolve_opt_virtual_call_stub();
376 }
377 
378 bool CompiledDirectCall::is_call_to_interpreted() const {
379   // It is a call to interpreted, if it calls to a stub. Hence, the destination
380   // must be in the stub part of the nmethod that contains the call
381   nmethod* nm = CodeCache::find_nmethod(instruction_address());
382   assert(nm != nullptr, "did not find nmethod");

184   return CompiledIC_at(nm, call_site);
185 }
186 
187 CompiledIC* CompiledIC_at(RelocIterator* reloc_iter) {
188   CompiledIC* c_ic = new CompiledIC(reloc_iter);
189   c_ic->verify();
190   return c_ic;
191 }
192 
193 void CompiledIC::ensure_initialized(CallInfo* call_info, Klass* receiver_klass) {
194   if (!_data->is_initialized()) {
195     _data->initialize(call_info, receiver_klass);
196   }
197 }
198 
199 void CompiledIC::set_to_clean() {
200   log_debug(inlinecache)("IC@" INTPTR_FORMAT ": set to clean", p2i(_call->instruction_address()));
201   _call->set_destination_mt_safe(SharedRuntime::get_resolve_virtual_call_stub());
202 }
203 
204 void CompiledIC::set_to_monomorphic(bool caller_is_c1) {
205   assert(data()->is_initialized(), "must be initialized");
206   Method* method = data()->speculated_method();
207   nmethod* code = method->code();
208   address entry;
209   bool to_compiled = code != nullptr && code->is_in_use() && !code->is_unloading();
210 
211   if (to_compiled) {
212     entry = caller_is_c1 ? code->inline_entry_point() : code->entry_point();
213   } else {
214     entry = caller_is_c1 ? method->get_c2i_unverified_inline_entry() : method->get_c2i_unverified_entry();
215   }
216 
217   log_trace(inlinecache)("IC@" INTPTR_FORMAT ": monomorphic to %s: %s",
218                          p2i(_call->instruction_address()),
219                          to_compiled ? "compiled" : "interpreter",
220                          method->print_value_string());
221 
222   _call->set_destination_mt_safe(entry);
223 }
224 
225 void CompiledIC::set_to_megamorphic(CallInfo* call_info, bool caller_is_c1) {
226   assert(data()->is_initialized(), "must be initialized");
227 
228   address entry;
229   if (call_info->call_kind() == CallInfo::direct_call) {
230     // C1 sometimes compiles a callsite before the target method is loaded, resulting in
231     // dynamically bound callsites that should really be statically bound. However, the
232     // target method might not have a vtable or itable. We just wait for better code to arrive
233     return;
234   } else if (call_info->call_kind() == CallInfo::itable_call) {
235     int itable_index = call_info->itable_index();
236     entry = VtableStubs::find_itable_stub(itable_index, caller_is_c1);
237     if (entry == nullptr) {
238       return;
239     }
240 #ifdef ASSERT
241     int index = call_info->resolved_method()->itable_index();
242     assert(index == itable_index, "CallInfo pre-computes this");
243     InstanceKlass* k = call_info->resolved_method()->method_holder();
244     assert(k->verify_itable_index(itable_index), "sanity check");
245 #endif //ASSERT
246   } else {
247     assert(call_info->call_kind() == CallInfo::vtable_call, "what else?");
248     // Can be different than selected_method->vtable_index(), due to package-private etc.
249     int vtable_index = call_info->vtable_index();
250     assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check");
251     entry = VtableStubs::find_vtable_stub(vtable_index, caller_is_c1);
252     if (entry == nullptr) {
253       return;
254     }
255   }
256 
257   log_trace(inlinecache)("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT,
258                          p2i(_call->instruction_address()), call_info->selected_method()->print_value_string(), p2i(entry));
259 
260   _call->set_destination_mt_safe(entry);
261   assert(is_megamorphic(), "sanity check");
262 }
263 
264 void CompiledIC::update(CallInfo* call_info, Klass* receiver_klass, bool caller_is_c1) {
265   // If this is the first time we fix the inline cache, we ensure it's initialized
266   ensure_initialized(call_info, receiver_klass);
267 
268   if (is_megamorphic()) {
269     // Terminal state for the inline cache
270     return;
271   }
272 
273   if (is_speculated_klass(receiver_klass)) {
274     // If the speculated class matches the receiver klass, we can speculate that will
275     // continue to be the case with a monomorphic inline cache
276     set_to_monomorphic(caller_is_c1);
277   } else {
278     // If the dynamic type speculation fails, we try to transform to a megamorphic state
279     // for the inline cache using stubs to dispatch in tables
280     set_to_megamorphic(call_info, caller_is_c1);
281   }
282 }
283 
284 bool CompiledIC::is_clean() const {
285   return destination() == SharedRuntime::get_resolve_virtual_call_stub();
286 }
287 
288 bool CompiledIC::is_monomorphic() const {
289   return !is_clean() && !is_megamorphic();
290 }
291 
292 bool CompiledIC::is_megamorphic() const {
293   return VtableStubs::entry_point(destination()) != nullptr;
294 }
295 
296 bool CompiledIC::is_speculated_klass(Klass* receiver_klass) {
297   return data()->speculated_klass() == receiver_klass;
298 }
299 
300 // GC support
301 void CompiledIC::clean_metadata() {
302   data()->clean_metadata();
303 }
304 
305 void CompiledIC::metadata_do(MetadataClosure* cl) {
306   data()->metadata_do(cl);
307 }
308 
309 #ifndef PRODUCT
310 void CompiledIC::print() {
311   tty->print("Inline cache at " INTPTR_FORMAT ", calling " INTPTR_FORMAT " cached_value " INTPTR_FORMAT,
312              p2i(instruction_address()), p2i(destination()), p2i(data()));
313   tty->cr();

325   assert(CompiledICLocker::is_safe(instruction_address()), "mt unsafe call");
326   // Reset call site
327   RelocIterator iter((nmethod*)nullptr, instruction_address(), instruction_address() + 1);
328   while (iter.next()) {
329     switch(iter.type()) {
330     case relocInfo::static_call_type:
331       _call->set_destination_mt_safe(SharedRuntime::get_resolve_static_call_stub());
332       break;
333     case relocInfo::opt_virtual_call_type:
334       _call->set_destination_mt_safe(SharedRuntime::get_resolve_opt_virtual_call_stub());
335       break;
336     default:
337       ShouldNotReachHere();
338     }
339   }
340   assert(is_clean(), "should be clean after cleaning");
341 
342   log_debug(inlinecache)("DC@" INTPTR_FORMAT ": set to clean", p2i(_call->instruction_address()));
343 }
344 
345 void CompiledDirectCall::set(const methodHandle& callee_method, bool caller_is_c1) {
346   nmethod* code = callee_method->code();
347   nmethod* caller = CodeCache::find_nmethod(instruction_address());
348   assert(caller != nullptr, "did not find caller nmethod");
349 
350   bool to_interp_cont_enter = caller->method()->is_continuation_enter_intrinsic() &&
351                               ContinuationEntry::is_interpreted_call(instruction_address());
352 
353   bool to_compiled = !to_interp_cont_enter && code != nullptr && code->is_in_use() && !code->is_unloading();
354 
355   if (to_compiled) {
356     _call->set_destination_mt_safe(caller_is_c1 ? code->verified_inline_entry_point() : code->verified_entry_point());
357     assert(is_call_to_compiled(), "should be compiled after set to compiled");
358   } else {
359     // Patch call site to C2I adapter if code is deoptimized or unloaded.
360     // We also need to patch the static call stub to set the rmethod register
361     // to the callee_method so the c2i adapter knows how to build the frame
362     set_to_interpreted(callee_method, caller_is_c1 ? callee_method->get_c2i_inline_entry() : callee_method->get_c2i_entry());
363     assert(is_call_to_interpreted(), "should be interpreted after set to interpreted");
364   }
365 
366   log_trace(inlinecache)("DC@" INTPTR_FORMAT ": set to %s: %s: " INTPTR_FORMAT,
367                          p2i(_call->instruction_address()),
368                          to_compiled ? "compiled" : "interpreter",
369                          callee_method->print_value_string(),
370                          p2i(_call->destination()));
371 }
372 
373 bool CompiledDirectCall::is_clean() const {
374   return destination() == SharedRuntime::get_resolve_static_call_stub() ||
375          destination() == SharedRuntime::get_resolve_opt_virtual_call_stub();
376 }
377 
378 bool CompiledDirectCall::is_call_to_interpreted() const {
379   // It is a call to interpreted, if it calls to a stub. Hence, the destination
380   // must be in the stub part of the nmethod that contains the call
381   nmethod* nm = CodeCache::find_nmethod(instruction_address());
382   assert(nm != nullptr, "did not find nmethod");
< prev index next >