oop* InterpretedIC::inline_cache_miss() { NoGCVerifier noGC; // get ic info frame f = DeltaProcess::active()->last_frame(); InterpretedIC* ic = f.current_interpretedIC(); Bytecodes::Code send_code = ic->send_code(); oop receiver = ic->argument_spec() == Bytecodes::args_only // Are we at a self or super send? ? f.receiver() // yes: take receiver of frame : f.expr(ic->nof_arguments()); // no: take receiver pushed before the arguments // do the lookup klassOop klass = receiver->klass(); LookupResult result = Bytecodes::is_super_send(send_code) ? interpreter_super_lookup(ic->selector()) : interpreter_normal_lookup(klass, ic->selector()); // tracing if (TraceInlineCacheMiss) { std->print("IC miss, "); trace_inline_cache_miss(ic, klass, result); } // handle the lookup result if (!result.is_empty()) { update_inline_cache(ic, &f, ic->send_code(), klass, result); return NULL; } else { return cacheMissResult(does_not_understand(receiver, ic, &f), ic->nof_arguments() + (ic->argument_spec() == Bytecodes::args_only ? 0 : 1))->objs(1); } }
void PerformanceDebugger::report_block(Node* n, BlockPReg* blk, const char* what) { if (!DebugPerformance) return; if (blocks->contains(blk)) return; if (blk->method()->is_clean_block()) return; Reporter r(this); str->print(" could not eliminate block in "); blk->method()->home()->selector()->print_symbol_on(str); str->print(" because it is %s in scope %s at bytecode %d", what, n->scope()->key()->print_string(), n->bci()); InterpretedIC* ic = n->scope()->method()->ic_at(n->bci()); if (ic) str->print(" (send of %s)", ic->selector()->copy_null_terminated()); str->print("\n"); blocks->append(blk); }
InterpretedIC* frame::current_interpretedIC() const { if (is_interpreted_frame()) { methodOop m = method(); int bci = m->bci_from(hp()); u_char* codeptr = m->codes(bci); if (Bytecodes::is_send_code(Bytecodes::Code(*codeptr))) { InterpretedIC* ic = as_InterpretedIC((char*)hp()); assert(ic->send_code_addr() == codeptr, "found wrong ic"); return ic; } else { return NULL; // perform, dll call, etc. } } return NULL; // doesn't have InterpretedIC }
IC_Iterator* frame::current_ic_iterator() const { if (is_interpreted_frame()) { InterpretedIC* ic = current_interpretedIC(); if (ic && !Bytecodes::is_send_code(ic->send_code())) return NULL; return ic ? new InterpretedIC_Iterator(ic) : NULL; } if (is_compiled_frame()) { CompiledIC* ic = current_compiledIC(); return ic->inlineCache() ? new CompiledIC_Iterator(ic) : NULL; // a perform, not a send } // entry or deoptimized frame return NULL; }
bool patch_last_delta_frame(int* fr, int* dist) { // change the current to next bci; frame v(NULL, fr, NULL); methodOop method = methodOopDesc::methodOop_from_hcode(v.hp()); // The interpreter is in the middle of executing a byte code // and the hp pointer points to the current bci and NOT the next bci. int bci = method->next_bci_from(v.hp()); // in case of single step we ignore the case with // an empty inline cache since the send is reexecuted. InterpretedIC* ic = method->ic_at(bci); if (ic && ic->is_empty()) return false; *dist = method->next_bci(bci) - bci; v.set_hp(v.hp() + *dist); return true; }
void InterpretedIC::inline_cache_miss() { NoGCVerifier noGC; // get ic info frame f = DeltaProcess::active()->last_frame(); InterpretedIC* ic = f.current_interpretedIC(); Bytecodes::Code send_code = ic->send_code(); oop receiver = ic->argument_spec() == Bytecodes::args_only // Are we at a self or super send? ? f.receiver() // yes: take receiver of frame : f.expr(ic->nof_arguments()); // no: take receiver pushed before the arguments // do the lookup klassOop klass = receiver->klass(); LookupResult result = Bytecodes::is_super_send(send_code) ? interpreter_super_lookup(ic->selector()) : interpreter_normal_lookup(klass, ic->selector()); // tracing if (TraceMessageSend) std->print_cr("inline cache miss"); if (TraceLookup) trace_inline_cache_miss(ic, klass, result); // handle the lookup result if (!result.is_empty()) update_inline_cache(ic, &f, send_code, klass, result); else { does_not_understand(receiver, ic, &f); // If the program continues we'll redo the inline_cache_miss if (!have_nlr_through_C) inline_cache_miss(); } }