bool CompiledIC::is_call_to_interpreted() const { assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); // Call to interpreter if destination is either calling to a stub (if it // is optimized), or calling to an I2C blob bool is_call_to_interpreted = false; if (!is_optimized()) { // must use unsafe because the destination can be a zombie (and we're cleaning) // and the print_compiled_ic code wants to know if site (in the non-zombie) // is to the interpreter. CodeBlob* cb = CodeCache::find_blob_unsafe(ic_destination()); is_call_to_interpreted = (cb != NULL && cb->is_adapter_blob()); assert(!is_call_to_interpreted || (is_icholder_call() && cached_icholder() != NULL), "sanity check"); } else { // Check if we are calling into our own codeblob (i.e., to a stub) CodeBlob* cb = CodeCache::find_blob(_ic_call->instruction_address()); address dest = ic_destination(); #ifdef ASSERT { CodeBlob* db = CodeCache::find_blob_unsafe(dest); assert(!db->is_adapter_blob(), "must use stub!"); } #endif /* ASSERT */ is_call_to_interpreted = cb->contains(dest); } return is_call_to_interpreted; }
bool CompiledIC::is_call_to_interpreted() const { assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); // Call to interpreter if destination is either calling to a stub (if it // is optimized), or calling to an I2C bool is_call_to_interpreted = false; #ifdef COMPILER1 if (!is_optimized()) { is_call_to_interpreted = Runtime1::blob_for(Runtime1::interpreter_entries_id)->contains(ic_destination()); } else { // Check if we are calling into our own codeblob (i.e., to a stub) CodeBlob* cb = CodeCache::find_blob(_ic_call->instruction_address()); is_call_to_interpreted = cb->contains(ic_destination()); } #else if (!is_optimized()) { CodeBlob* cb = CodeCache::find_blob(ic_destination()); is_call_to_interpreted = (cb != NULL && cb->is_c2i_adapter()); } else { // Check if we are calling into our own codeblob (i.e., to a stub) CodeBlob* cb = CodeCache::find_blob(_ic_call->instruction_address()); is_call_to_interpreted = cb->contains(ic_destination()); } #endif // COMPILER1 assert(!is_call_to_interpreted || is_optimized() || (cached_oop() != NULL && cached_oop()->is_compiledICHolder()), "sanity check"); return is_call_to_interpreted; }
// true if destination is megamorphic stub bool CompiledIC::is_megamorphic() const { assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); assert(!is_optimized(), "an optimized call cannot be megamorphic"); // Cannot rely on cached_oop. It is either an interface or a method. return VtableStubs::is_entry_point(ic_destination()); }
bool CompiledIC::is_call_to_compiled() const { assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); // Use unsafe, since an inline cache might point to a zombie method. However, the zombie // method is guaranteed to still exist, since we only remove methods after all inline caches // has been cleaned up CodeBlob* cb = CodeCache::find_blob_unsafe(ic_destination()); bool is_monomorphic = (cb != NULL && cb->is_nmethod()); // Check that the cached_oop is a klass for non-optimized monomorphic calls // This assertion is invalid for compiler1: a call that does not look optimized (no static stub) can be used // for calling directly to vep without using the inline cache (i.e., cached_oop == NULL) #ifdef ASSERT #ifdef TIERED CodeBlob* caller = CodeCache::find_blob_unsafe(instruction_address()); bool is_c1_method = caller->is_compiled_by_c1(); #else #ifdef COMPILER1 bool is_c1_method = true; #else bool is_c1_method = false; #endif // COMPILER1 #endif // TIERED assert( is_c1_method || !is_monomorphic || is_optimized() || (cached_oop() != NULL && cached_oop()->is_klass()), "sanity check"); #endif // ASSERT return is_monomorphic; }
bool CompiledIC::is_clean() const { assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); bool is_clean = false; address dest = ic_destination(); is_clean = dest == SharedRuntime::get_resolve_opt_virtual_call_stub() || dest == SharedRuntime::get_resolve_virtual_call_stub(); assert(!is_clean || is_optimized() || cached_value() == NULL, "sanity check"); return is_clean; }
bool CompiledIC::is_clean() const { assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); bool is_clean = false; address dest = ic_destination(); #ifdef COMPILER1 is_clean = dest == Runtime1::entry_for(Runtime1::resolve_invokevirtual_id) || dest == Runtime1::entry_for(Runtime1::resolve_invoke_opt_virtual_id); #else is_clean = dest == OptoRuntime::resolve_virtual_call_Java() || dest == OptoRuntime::resolve_opt_virtual_call_Java(); #endif assert(!is_clean || is_optimized() || cached_oop() == NULL, "sanity check"); return is_clean; }
bool CompiledIC::is_call_to_compiled() const { assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); // Use unsafe, since an inline cache might point to a zombie method. However, the zombie // method is guaranteed to still exist, since we only remove methods after all inline caches // has been cleaned up CodeBlob* cb = CodeCache::find_blob_unsafe(ic_destination()); bool is_monomorphic = (cb != NULL && cb->is_nmethod()); // Check that the cached_value is a klass for non-optimized monomorphic calls // This assertion is invalid for compiler1: a call that does not look optimized (no static stub) can be used // for calling directly to vep without using the inline cache (i.e., cached_value == NULL). // For JVMCI this occurs because CHA is only used to improve inlining so call sites which could be optimized // virtuals because there are no currently loaded subclasses of a type are left as virtual call sites. #ifdef ASSERT CodeBlob* caller = CodeCache::find_blob_unsafe(instruction_address()); bool is_c1_or_jvmci_method = caller->is_compiled_by_c1() || caller->is_compiled_by_jvmci(); assert( is_c1_or_jvmci_method || !is_monomorphic || is_optimized() || !caller->is_alive() || (cached_metadata() != NULL && cached_metadata()->is_klass()), "sanity check"); #endif // ASSERT return is_monomorphic; }
void CompiledIC::print_compiled_ic() { tty->print("Inline cache at " INTPTR_FORMAT ", calling %s " INTPTR_FORMAT " cached_value " INTPTR_FORMAT, p2i(instruction_address()), is_call_to_interpreted() ? "interpreted " : "", p2i(ic_destination()), p2i(is_optimized() ? NULL : cached_value())); }
bool CompiledIC::is_icholder_call() const { assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); return !_is_optimized && is_icholder_entry(ic_destination()); }
void CompiledIC::print_compiled_ic() { tty->print("Inline cache at " INTPTR_FORMAT ", calling %s " INTPTR_FORMAT, instruction_address(), is_call_to_interpreted() ? "interpreted " : "", ic_destination()); }