示例#1
0
文件: deopt.c 项目: nanis/MoarVM
static void deopt_frame(MVMThreadContext *tc, MVMFrame *f, MVMint32 deopt_offset, MVMint32 deopt_target) {
    /* Found it; are we in an inline? */
    MVMSpeshInline *inlines = f->spesh_cand->inlines;
    if (inlines) {
        /* Yes, going to have to re-create the frames; uninline
         * moves the interpreter, so we can just tweak the last
         * frame. */
        uninline(tc, f, f->spesh_cand, deopt_offset, deopt_target, NULL);
        f->effective_bytecode    = f->static_info->body.bytecode;
        f->effective_handlers    = f->static_info->body.handlers;
        f->effective_spesh_slots = NULL;
        f->spesh_cand            = NULL;
        /*fprintf(stderr, "Completed deopt_one in '%s' (cuid '%s'), idx = %i, with uninlining\n",
          MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.name),
          MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.cuuid),
          i / 2);*/
    }
    else {
        /* No inlining; simple case. Switch back to the original code. */
        f->effective_bytecode        = f->static_info->body.bytecode;
        f->effective_handlers        = f->static_info->body.handlers;
        *(tc->interp_cur_op)         = f->effective_bytecode + deopt_target;
        *(tc->interp_bytecode_start) = f->effective_bytecode;
        f->effective_spesh_slots     = NULL;
        f->spesh_cand                = NULL;
        /*fprintf(stderr, "Completed deopt_one in '%s' (cuid '%s'), idx = %i\n",
          MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.name),
          MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.cuuid),
          i / 2);*/
    }

}
示例#2
0
static void
Ungetch(int c)
{
	if (Inlining<0)
		ungetc(c,yyin);
	else
		uninline();
	if (1)
	{	printf("\n<bs{%d}bs>\n", c);
	}
}
示例#3
0
文件: deopt.c 项目: nanis/MoarVM
/* De-optimizes all specialized frames on the call stack. Used when a change
 * is made the could invalidate all kinds of assumptions all over the place
 * (such as a mix-in). */
void MVM_spesh_deopt_all(MVMThreadContext *tc) {
    /* Walk frames looking for any callers in specialized bytecode. */
    MVMFrame *l = tc->cur_frame;
    MVMFrame *f = tc->cur_frame->caller;
    if (tc->instance->profiling)
        MVM_profiler_log_deopt_all(tc);
    while (f) {
        if (f->effective_bytecode != f->static_info->body.bytecode && f->spesh_log_idx < 0) {
            /* Found one. Is it JITted code? */
            if (f->spesh_cand->jitcode && f->jit_entry_label) {
                MVMint32 num_deopts = f->spesh_cand->jitcode->num_deopts;
                MVMJitDeopt *deopts = f->spesh_cand->jitcode->deopts;
                void       **labels = f->spesh_cand->jitcode->labels;
                MVMint32 i;
                for (i = 0; i < num_deopts; i++) {
                    if (labels[deopts[i].label] == f->jit_entry_label) {
                        /*
                        fprintf(stderr, "Found deopt label for JIT (%d) (label %d idx %d)\n", i,
                                deopts[i].label, deopts[i].idx);
                        */
                        /* Resolve offset and target. */
                        MVMint32 deopt_idx    = deopts[i].idx;
                        MVMint32 deopt_offset = f->spesh_cand->deopts[2 * deopt_idx + 1];
                        MVMint32 deopt_target = f->spesh_cand->deopts[2 * deopt_idx];

                        /* Switch frame itself back to the original code. */
                        f->effective_bytecode    = f->static_info->body.bytecode;
                        f->effective_handlers    = f->static_info->body.handlers;

                        /* Re-create any frames needed if we're in an inline; if not,
                        * just update return address. */
                        if (f->spesh_cand->inlines)
                            uninline(tc, f, f->spesh_cand, deopt_offset, deopt_target, l);
                        else
                            f->return_address = f->effective_bytecode + deopt_target;

                        /* No spesh cand/slots needed now. */
                        f->effective_spesh_slots = NULL;
                        f->spesh_cand            = NULL;
                        f->jit_entry_label       = NULL;

                        break;
                    }
                }
                /*
                if (i == num_deopts)
                    fprintf(stderr, "JIT: can't find deopt all idx");
                */
            }

            else {
                /* Not JITted; see if we can find the return address in the deopt table. */
                MVMint32 ret_offset = f->return_address - f->effective_bytecode;
                MVMint32 i;
                for (i = 0; i < f->spesh_cand->num_deopts * 2; i += 2) {
                    if (f->spesh_cand->deopts[i + 1] == ret_offset) {
                        /* Switch frame itself back to the original code. */
                        f->effective_bytecode    = f->static_info->body.bytecode;
                        f->effective_handlers    = f->static_info->body.handlers;

                        /* Re-create any frames needed if we're in an inline; if not,
                        * just update return address. */
                        if (f->spesh_cand->inlines)
                            uninline(tc, f, f->spesh_cand, ret_offset, f->spesh_cand->deopts[i], l);
                        else
                            f->return_address = f->effective_bytecode + f->spesh_cand->deopts[i];

                        /* No spesh cand/slots needed now. */
                        f->effective_spesh_slots = NULL;
                        f->spesh_cand            = NULL;

                        break;
                    }
                }
            }
        }
        l = f;
        f = f->caller;
    }
}