158 |
158 |
159 //----------------------------------------------------------------------------- |
159 //----------------------------------------------------------------------------- |
160 // High-level access to an inline cache. Guaranteed to be MT-safe. |
160 // High-level access to an inline cache. Guaranteed to be MT-safe. |
161 |
161 |
162 |
162 |
163 void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { |
163 bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { |
164 assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); |
164 assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); |
165 assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); |
165 assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); |
166 assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); |
166 assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); |
167 |
167 |
168 address entry; |
168 address entry; |
169 if (call_info->call_kind() == CallInfo::itable_call) { |
169 if (call_info->call_kind() == CallInfo::itable_call) { |
170 assert(bytecode == Bytecodes::_invokeinterface, ""); |
170 assert(bytecode == Bytecodes::_invokeinterface, ""); |
171 int itable_index = call_info->itable_index(); |
171 int itable_index = call_info->itable_index(); |
172 entry = VtableStubs::find_itable_stub(itable_index); |
172 entry = VtableStubs::find_itable_stub(itable_index); |
|
173 if (entry == false) { |
|
174 return false; |
|
175 } |
173 #ifdef ASSERT |
176 #ifdef ASSERT |
174 assert(entry != NULL, "entry not computed"); |
|
175 int index = call_info->resolved_method()->itable_index(); |
177 int index = call_info->resolved_method()->itable_index(); |
176 assert(index == itable_index, "CallInfo pre-computes this"); |
178 assert(index == itable_index, "CallInfo pre-computes this"); |
177 #endif //ASSERT |
179 #endif //ASSERT |
178 InstanceKlass* k = call_info->resolved_method()->method_holder(); |
180 InstanceKlass* k = call_info->resolved_method()->method_holder(); |
179 assert(k->verify_itable_index(itable_index), "sanity check"); |
181 assert(k->verify_itable_index(itable_index), "sanity check"); |
182 assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable"); |
184 assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable"); |
183 // Can be different than selected_method->vtable_index(), due to package-private etc. |
185 // Can be different than selected_method->vtable_index(), due to package-private etc. |
184 int vtable_index = call_info->vtable_index(); |
186 int vtable_index = call_info->vtable_index(); |
185 assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); |
187 assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); |
186 entry = VtableStubs::find_vtable_stub(vtable_index); |
188 entry = VtableStubs::find_vtable_stub(vtable_index); |
|
189 if (entry == NULL) { |
|
190 return false; |
|
191 } |
187 InlineCacheBuffer::create_transition_stub(this, NULL, entry); |
192 InlineCacheBuffer::create_transition_stub(this, NULL, entry); |
188 } |
193 } |
189 |
194 |
190 if (TraceICs) { |
195 if (TraceICs) { |
191 ResourceMark rm; |
196 ResourceMark rm; |
198 // we ran out of space in the inline cache buffer trying to do the |
203 // we ran out of space in the inline cache buffer trying to do the |
199 // set_next and we safepointed to free up space. This is a benign |
204 // set_next and we safepointed to free up space. This is a benign |
200 // race because the IC entry was complete when we safepointed so |
205 // race because the IC entry was complete when we safepointed so |
201 // cleaning it immediately is harmless. |
206 // cleaning it immediately is harmless. |
202 // assert(is_megamorphic(), "sanity check"); |
207 // assert(is_megamorphic(), "sanity check"); |
|
208 return true; |
203 } |
209 } |
204 |
210 |
205 |
211 |
206 // true if destination is megamorphic stub |
212 // true if destination is megamorphic stub |
207 bool CompiledIC::is_megamorphic() const { |
213 bool CompiledIC::is_megamorphic() const { |