< prev index next >

src/hotspot/share/code/compiledIC.cpp


219   assert(ret == true, "relocInfo must exist at this address");                                                                       
220   assert(iter.addr() == ic_call, "must find ic_call");                                                                               
221 
222   initialize_from_iter(&iter);                                                                                                       
223 }                                                                                                                                    
224 
225 CompiledIC::CompiledIC(RelocIterator* iter)                                                                                          
226   : _method(iter->code())                                                                                                            
227 {                                                                                                                                    
228   _call = _method->call_wrapper_at(iter->addr());                                                                                    
229   address ic_call = _call->instruction_address();                                                                                    
230 
231   CompiledMethod* nm = iter->code();                                                                                                 
232   assert(ic_call != NULL, "ic_call address must be set");                                                                            
233   assert(nm != NULL, "must pass compiled method");                                                                                   
234   assert(nm->contains(ic_call), "must be in compiled method");                                                                       
235 
236   initialize_from_iter(iter);                                                                                                        
237 }                                                                                                                                    
238 
239 bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) {                                          
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
240   assert(CompiledICLocker::is_safe(_method), "mt unsafe call");                                                                      
241   assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic");                                                    
242   assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?");                                       
243 
244   address entry;                                                                                                                     
245   if (call_info->call_kind() == CallInfo::itable_call) {                                                                             
246     assert(bytecode == Bytecodes::_invokeinterface, "");                                                                             
247     int itable_index = call_info->itable_index();                                                                                    
248     entry = VtableStubs::find_itable_stub(itable_index);                                                                             
249     if (entry == NULL) {                                                                                                             
250       return false;                                                                                                                  
251     }                                                                                                                                
252 #ifdef ASSERT                                                                                                                        
253     int index = call_info->resolved_method()->itable_index();                                                                        
254     assert(index == itable_index, "CallInfo pre-computes this");                                                                     
255     InstanceKlass* k = call_info->resolved_method()->method_holder();                                                                
256     assert(k->verify_itable_index(itable_index), "sanity check");                                                                    
257 #endif //ASSERT                                                                                                                      
258     CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(),                                   
259                                                     call_info->resolved_klass(), false);                                             
260     holder->claim();                                                                                                                 
261     if (!InlineCacheBuffer::create_transition_stub(this, holder, entry)) {                                                           
262       delete holder;                                                                                                                 
                                                                                                                                     
263       return false;                                                                                                                  
264     }                                                                                                                                
265   } else {                                                                                                                           
266     assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable");                                              
267     // Can be different than selected_method->vtable_index(), due to package-private etc.                                            
268     int vtable_index = call_info->vtable_index();                                                                                    
269     assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check");                                          
270     entry = VtableStubs::find_vtable_stub(vtable_index);                                                                             
271     if (entry == NULL) {                                                                                                             
272       return false;                                                                                                                  
273     }                                                                                                                                
274     if (!InlineCacheBuffer::create_transition_stub(this, NULL, entry)) {                                                             
                                                                                                                                     
275       return false;                                                                                                                  
276     }                                                                                                                                
277   }                                                                                                                                  
278 
279   if (TraceICs) {                                                                                                                    
280     ResourceMark rm;                                                                                                                 
281     assert(!call_info->selected_method().is_null(), "Unexpected null selected method");                                              
282     tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT,                                                  
283                    p2i(instruction_address()), call_info->selected_method()->print_value_string(), p2i(entry));                      
284   }                                                                                                                                  
285 
286   // We can't check this anymore. With lazy deopt we could have already                                                              
287   // cleaned this IC entry before we even return. This is possible if                                                                
288   // we ran out of space in the inline cache buffer trying to do the                                                                 
289   // set_next and we safepointed to free up space. This is a benign                                                                  
290   // race because the IC entry was complete when we safepointed so                                                                   
291   // cleaning it immediately is harmless.                                                                                            
292   // assert(is_megamorphic(), "sanity check");                                                                                       
293   return true;                                                                                                                       

219   assert(ret == true, "relocInfo must exist at this address");
220   assert(iter.addr() == ic_call, "must find ic_call");
221 
222   initialize_from_iter(&iter);
223 }
224 
225 CompiledIC::CompiledIC(RelocIterator* iter)
226   : _method(iter->code())
227 {
228   _call = _method->call_wrapper_at(iter->addr());
229   address ic_call = _call->instruction_address();
230 
231   CompiledMethod* nm = iter->code();
232   assert(ic_call != NULL, "ic_call address must be set");
233   assert(nm != NULL, "must pass compiled method");
234   assert(nm->contains(ic_call), "must be in compiled method");
235 
236   initialize_from_iter(iter);
237 }
238 
239 // This function may fail for two reasons: either due to running out of vtable
240 // stubs, or due to running out of IC stubs in an attempted transition to a
241 // transitional state. The needs_ic_stub_refill value will be set if the failure
242 // was due to running out of IC stubs, in which case the caller will refill IC
243 // stubs and retry.
244 bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode,
245                                     bool& needs_ic_stub_refill, TRAPS) {
246   assert(CompiledICLocker::is_safe(_method), "mt unsafe call");
247   assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic");
248   assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?");
249 
250   address entry;
251   if (call_info->call_kind() == CallInfo::itable_call) {
252     assert(bytecode == Bytecodes::_invokeinterface, "");
253     int itable_index = call_info->itable_index();
254     entry = VtableStubs::find_itable_stub(itable_index);
255     if (entry == NULL) {
256       return false;
257     }
258 #ifdef ASSERT
259     int index = call_info->resolved_method()->itable_index();
260     assert(index == itable_index, "CallInfo pre-computes this");
261     InstanceKlass* k = call_info->resolved_method()->method_holder();
262     assert(k->verify_itable_index(itable_index), "sanity check");
263 #endif //ASSERT
264     CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(),
265                                                     call_info->resolved_klass(), false);
266     holder->claim();
267     if (!InlineCacheBuffer::create_transition_stub(this, holder, entry)) {
268       delete holder;
269       needs_ic_stub_refill = true;
270       return false;
271     }
272   } else {
273     assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable");
274     // Can be different than selected_method->vtable_index(), due to package-private etc.
275     int vtable_index = call_info->vtable_index();
276     assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check");
277     entry = VtableStubs::find_vtable_stub(vtable_index);
278     if (entry == NULL) {
279       return false;
280     }
281     if (!InlineCacheBuffer::create_transition_stub(this, NULL, entry)) {
282       needs_ic_stub_refill = true;
283       return false;
284     }
285   }
286 
287   if (TraceICs) {
288     ResourceMark rm;
289     assert(!call_info->selected_method().is_null(), "Unexpected null selected method");
290     tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT,
291                    p2i(instruction_address()), call_info->selected_method()->print_value_string(), p2i(entry));
292   }
293 
294   // We can't check this anymore. With lazy deopt we could have already
295   // cleaned this IC entry before we even return. This is possible if
296   // we ran out of space in the inline cache buffer trying to do the
297   // set_next and we safepointed to free up space. This is a benign
298   // race because the IC entry was complete when we safepointed so
299   // cleaning it immediately is harmless.
300   // assert(is_megamorphic(), "sanity check");
301   return true;
< prev index next >