< prev index next >

src/hotspot/share/code/compiledIC.cpp

Print this page

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

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

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

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