sendDesc* frame::send_desc() { assert(RecompilationInProgress || is_self_frame(), "Only Self frames have sendDescs"); if (is_interpreted_self_frame()) return sendDesc::sendDesc_from_return_PC( return_addr()); // for Conversion::convert (& new_dummy_vframe) # if defined(FAST_COMPILER) || defined(SIC_COMPILER) int32* callp = (int32*)sendDesc::sendDesc_from_return_PC( return_addr())->call_instruction_addr(); if (!isCall(callp)) { callp--; // prim frames get ret pc bumped so C can return } if (!isCall(callp)) { // nlr code callp -= 2; // 2 instructions if (!isCall(callp)) { // usually an error, but some callers tolerate it so don't break here return NULL; } } else if (isCall(callp - 2)) { // the "call" might be the register mask of a send/prim call return slow_send_desc(callp); } // assert(((sendDesc*)callp)->verify(), "doesn't verify"); // wouldn't always work (e.g. during GCs) return sendDesc::sendDesc_from_call_instruction(callp); # else ShouldNotReachHere(); // compiled frame but no compiler? return NULL; # endif }
frame frame::sender() const { frame result; if (is_entry_frame()) { // Delta frame called from C; skip all C frames and return top C // frame of that chunk as the sender assert(has_next_Delta_fp(), "next Delta fp must be non zero"); assert(next_Delta_fp() > _fp, "must be above this frame on stack"); result = frame(next_Delta_sp(), next_Delta_fp()); } else if (is_deoptimized_frame()) { result = frame(real_sender_sp(), link(), return_addr()); } else { result = frame(sender_sp(), link(), return_addr()); } return result; }
frame* frame::make_full_frame_on_user_stack() { if (!isOnVMStack(this)) return this; assert(!isOnVMStack(my_sp()), "must cross stacks"); return my_sp()->push_new_sp(return_addr(), 0, false) -> as_callers_frame(); }
char* frame::c_return_pc() { // 2 words: the call, the delay slot return return_addr() + 8; }
sendDesc* frame::send_desc() { return sendDesc::sendDesc_from_return_PC( return_addr()); // it is always the same on PPC }
char* frame::c_return_pc() { return return_addr(); }
BOOLEAN bpact() { register BPINFO *p; BPINFO *prev, *next; BOOLEAN found; ADDRESS oldpc; delayed = NONE; found = FALSE; prev = NIL; for (p = bphead; p != NIL; p = next) { next = p->bpnext; if (p->bpaddr == pc) { prbpfound(p); found = TRUE; if (p->bpcond == NIL || isswitch(p->bptype) || cond(p->bpcond)) { prbphandled(); if (handlebp(p) == NOSAVE) { prbpnosave(); if (prev == NIL) { bphead = next; } else { prev->bpnext = next; } dispose(p); } else { prbpsave(); prev = p; } } else { prev = p; } } else { prev = p; } } if (delayed != NONE) { oldpc = pc; runtofirst(); if ((delayed&DELAY_CALL) == DELAY_CALL) { SYM *s, *t; s = curfunc; t = whatblock(return_addr()); if (t == NIL) { panic("can't find block for caller addr %d", caller_addr()); } printcall(s, t); addbp(return_addr(), RETURN, s, NIL, NIL, 0); } if (pc != oldpc) { bpact(); } if (isstopped) { printstatus(); } } else { if (isstopped) { printstatus(); } } fflush(stdout); return(found); }