Ejemplo n.º 1
0
Archivo: facts.c Proyecto: nanis/MoarVM
/* Looks up a wval and adds information based on it. */
static void wval_facts(MVMThreadContext *tc, MVMSpeshGraph *g, MVMuint16 tgt_orig,
                       MVMuint16 tgt_i, MVMuint16 dep, MVMint64 idx) {
    MVMCompUnit *cu = g->sf->body.cu;
    if (dep < cu->body.num_scs) {
        MVMSerializationContext *sc = MVM_sc_get_sc(tc, cu, dep);
        if (sc)
            object_facts(tc, g, tgt_orig, tgt_i, MVM_sc_get_object(tc, sc, idx));
    }
}
Ejemplo n.º 2
0
/* Dumps a basic block. */
static void dump_bb(MVMThreadContext *tc, DumpStr *ds, MVMSpeshGraph *g, MVMSpeshBB *bb,
                    SpeshGraphSizeStats *stats, InlineIndexStack *inline_stack) {
    MVMSpeshIns *cur_ins;
    MVMint64     i;
    MVMint32     size = 0;

    /* Heading. */
    appendf(ds, "  BB %d (%p):\n", bb->idx, bb);

    if (bb->inlined) {
        append(ds, "    Inlined\n");
    }

    {
        /* Also, we have a line number */
        MVMBytecodeAnnotation *bbba = MVM_bytecode_resolve_annotation(tc, &g->sf->body, bb->initial_pc);
        MVMuint32 line_number;
        if (bbba) {
            line_number = bbba->line_number;
            MVM_free(bbba);
        } else {
            line_number = -1;
        }
        appendf(ds, "    line: %d (pc %d)\n", line_number, bb->initial_pc);
    }

    /* Instructions. */
    append(ds, "    Instructions:\n");
    cur_ins = bb->first_ins;
    while (cur_ins) {
        MVMSpeshAnn *ann = cur_ins->annotations;
        MVMuint32 line_number;
        MVMuint32 pop_inlines = 0;
        MVMuint32 num_comments = 0;

        while (ann) {
            /* These four annotations carry a deopt index that we can find a
             * corresponding line number for */
            if (ann->type == MVM_SPESH_ANN_DEOPT_ONE_INS
                || ann->type == MVM_SPESH_ANN_DEOPT_ALL_INS
                || ann->type == MVM_SPESH_ANN_DEOPT_INLINE
                || ann->type == MVM_SPESH_ANN_DEOPT_OSR) {
                MVMBytecodeAnnotation *ba = MVM_bytecode_resolve_annotation(tc, &g->sf->body, g->deopt_addrs[2 * ann->data.deopt_idx]);
                if (ba) {
                    line_number = ba->line_number;
                    MVM_free(ba);
                } else {
                    line_number = -1;
                }
            }
            switch (ann->type) {
                case MVM_SPESH_ANN_FH_START:
                    appendf(ds, "      [Annotation: FH Start (%d)]\n",
                        ann->data.frame_handler_index);
                    break;
                case MVM_SPESH_ANN_FH_END:
                    appendf(ds, "      [Annotation: FH End (%d)]\n",
                        ann->data.frame_handler_index);
                    break;
                case MVM_SPESH_ANN_FH_GOTO:
                    appendf(ds, "      [Annotation: FH Goto (%d)]\n",
                        ann->data.frame_handler_index);
                    break;
                case MVM_SPESH_ANN_DEOPT_ONE_INS:
                    appendf(ds, "      [Annotation: INS Deopt One (idx %d -> pc %d; line %d)]\n",
                        ann->data.deopt_idx, g->deopt_addrs[2 * ann->data.deopt_idx], line_number);
                    break;
                case MVM_SPESH_ANN_DEOPT_ALL_INS:
                    appendf(ds, "      [Annotation: INS Deopt All (idx %d -> pc %d; line %d)]\n",
                        ann->data.deopt_idx, g->deopt_addrs[2 * ann->data.deopt_idx], line_number);
                    break;
                case MVM_SPESH_ANN_INLINE_START:
                    appendf(ds, "      [Annotation: Inline Start (%d)]\n",
                        ann->data.inline_idx);
                    push_inline(tc, inline_stack, ann->data.inline_idx);
                    break;
                case MVM_SPESH_ANN_INLINE_END:
                    appendf(ds, "      [Annotation: Inline End (%d)]\n",
                        ann->data.inline_idx);
                    pop_inlines++;
                    break;
                case MVM_SPESH_ANN_DEOPT_INLINE:
                    appendf(ds, "      [Annotation: INS Deopt Inline (idx %d -> pc %d; line %d)]\n",
                        ann->data.deopt_idx, g->deopt_addrs[2 * ann->data.deopt_idx], line_number);
                    break;
                case MVM_SPESH_ANN_DEOPT_OSR:
                    appendf(ds, "      [Annotation: INS Deopt OSR (idx %d -> pc %d); line %d]\n",
                        ann->data.deopt_idx, g->deopt_addrs[2 * ann->data.deopt_idx], line_number);
                    break;
                case MVM_SPESH_ANN_LINENO: {
                    char *cstr;
                    MVMCompUnit *cu = get_current_cu(tc, g, inline_stack);
                    if (cu->body.num_strings < ann->data.lineno.filename_string_index) {
                        appendf(ds, "      [Annotation: Line Number: <out of bounds>:%d]\n",
                        ann->data.lineno.line_number);
                    }
                    else {
                        cstr = MVM_string_utf8_encode_C_string(tc,
                            MVM_cu_string(tc, get_current_cu(tc, g, inline_stack),
                            ann->data.lineno.filename_string_index));
                        appendf(ds, "      [Annotation: Line Number: %s:%d]\n",
                            cstr, ann->data.lineno.line_number);
                        MVM_free(cstr);
                    }
                    break;
                }
                case MVM_SPESH_ANN_LOGGED:
                    appendf(ds, "      [Annotation: Logged (bytecode offset %d)]\n",
                        ann->data.bytecode_offset);
                    break;
                case MVM_SPESH_ANN_DEOPT_SYNTH:
                    appendf(ds, "      [Annotation: INS Deopt Synth (idx %d)]\n",
                        ann->data.deopt_idx);
                    break;
                case MVM_SPESH_ANN_COMMENT:
                    num_comments++;
                    break;
                default:
                    appendf(ds, "      [Annotation: %d (unknown)]\n", ann->type);
            }
            ann = ann->next;
        }
        while (pop_inlines--)
            pop_inline(tc, inline_stack);

        if (num_comments > 1) {
            ann = cur_ins->annotations;
            while (ann) {
                if (ann->type == MVM_SPESH_ANN_COMMENT) {
                    appendf(ds, "      # %s\n", ann->data.comment);
                }
                ann = ann->next;
            }
        }

        appendf(ds, "      %-15s ", cur_ins->info->name);
        if (cur_ins->info->opcode == MVM_SSA_PHI) {
            for (i = 0; i < cur_ins->info->num_operands; i++) {
                MVMint16 orig = cur_ins->operands[i].reg.orig;
                MVMint16 regi = cur_ins->operands[i].reg.i;
                if (i)
                    append(ds, ", ");
                if (orig < 10) append(ds, " ");
                if (regi < 10) append(ds, " ");
                appendf(ds, "r%d(%d)", orig, regi);
            }
        }
        else {
            /* Count the opcode itself */
            size += 2;
            for (i = 0; i < cur_ins->info->num_operands; i++) {
                if (i)
                    append(ds, ", ");
                switch (cur_ins->info->operands[i] & MVM_operand_rw_mask) {
                    case MVM_operand_read_reg:
                    case MVM_operand_write_reg: {
                        MVMint16 orig = cur_ins->operands[i].reg.orig;
                        MVMint16 regi = cur_ins->operands[i].reg.i;
                        if (orig < 10) append(ds, " ");
                        if (regi < 10) append(ds, " ");
                        appendf(ds, "r%d(%d)", orig, regi);
                        size += 4;
                        break;
                    }
                    case MVM_operand_read_lex:
                    case MVM_operand_write_lex: {
                        MVMStaticFrameBody *cursor = &g->sf->body;
                        MVMuint32 ascension;
                        appendf(ds, "lex(idx=%d,outers=%d", cur_ins->operands[i].lex.idx,
                            cur_ins->operands[i].lex.outers);
                        for (ascension = 0;
                                ascension < cur_ins->operands[i].lex.outers;
                                ascension++, cursor = &cursor->outer->body) { };
                        if (cursor->fully_deserialized) {
                            if (cur_ins->operands[i].lex.idx < cursor->num_lexicals) {
                                char *cstr = MVM_string_utf8_encode_C_string(tc, cursor->lexical_names_list[cur_ins->operands[i].lex.idx]->key);
                                appendf(ds, ",%s)", cstr);
                                MVM_free(cstr);
                            } else {
                                append(ds, ",<out of bounds>)");
                            }
                        } else {
                            append(ds, ",<pending deserialization>)");
                        }
                        size += 4;
                        break;
                    }
                    case MVM_operand_literal: {
                        MVMuint32 type = cur_ins->info->operands[i] & MVM_operand_type_mask;
                        switch (type) {
                        case MVM_operand_ins: {
                            MVMint32 bb_idx = cur_ins->operands[i].ins_bb->idx;
                            if (bb_idx < 100) append(ds, " ");
                            if (bb_idx < 10)  append(ds, " ");
                            appendf(ds, "BB(%d)", bb_idx);
                            size += 4;
                            break;
                        }
                        case MVM_operand_int8:
                            appendf(ds, "liti8(%"PRId8")", cur_ins->operands[i].lit_i8);
                            size += 2;
                            break;
                        case MVM_operand_int16:
                            appendf(ds, "liti16(%"PRId16")", cur_ins->operands[i].lit_i16);
                            size += 2;
                            break;
                        case MVM_operand_int32:
                            appendf(ds, "liti32(%"PRId32")", cur_ins->operands[i].lit_i32);
                            size += 4;
                            break;
                        case MVM_operand_uint32:
                            appendf(ds, "litui32(%"PRIu32")", cur_ins->operands[i].lit_ui32);
                            size += 4;
                            break;
                        case MVM_operand_int64:
                            appendf(ds, "liti64(%"PRId64")", cur_ins->operands[i].lit_i64);
                            size += 8;
                            break;
                        case MVM_operand_num32:
                            appendf(ds, "litn32(%f)", cur_ins->operands[i].lit_n32);
                            size += 4;
                            break;
                        case MVM_operand_num64:
                            appendf(ds, "litn64(%g)", cur_ins->operands[i].lit_n64);
                            size += 8;
                            break;
                        case MVM_operand_str: {
                            char *cstr = MVM_string_utf8_encode_C_string(tc,
                                MVM_cu_string(tc, g->sf->body.cu, cur_ins->operands[i].lit_str_idx));
                            appendf(ds, "lits(%s)", cstr);
                            MVM_free(cstr);
                            size += 8;
                            break;
                        }
                        case MVM_operand_callsite: {
                            MVMCallsite *callsite = g->sf->body.cu->body.callsites[cur_ins->operands[i].callsite_idx];
                            appendf(ds, "callsite(%p, %d arg, %d pos, %s, %s)",
                                    callsite,
                                    callsite->arg_count, callsite->num_pos,
                                    callsite->has_flattening ? "flattening" : "nonflattening",
                                    callsite->is_interned ? "interned" : "noninterned");
                            size += 2;
                            break;

                        }
                        case MVM_operand_spesh_slot:
                            appendf(ds, "sslot(%"PRId16")", cur_ins->operands[i].lit_i16);
                            size += 2;
                            break;
                        case MVM_operand_coderef: {
                            MVMCodeBody *body = &((MVMCode*)g->sf->body.cu->body.coderefs[cur_ins->operands[i].coderef_idx])->body;
                            MVMBytecodeAnnotation *anno = MVM_bytecode_resolve_annotation(tc, &body->sf->body, 0);

                            append(ds, "coderef(");

                            if (anno) {
                                char *filestr = MVM_string_utf8_encode_C_string(tc,
                                    MVM_cu_string(tc, g->sf->body.cu, anno->filename_string_heap_index));
                                appendf(ds, "%s:%d%s)", filestr, anno->line_number, body->outer ? " (closure)" : "");
                                MVM_free(filestr);
                            } else {
                                append(ds, "??\?)");
                            }

                            size += 2;

                            MVM_free(anno);
                            break;
                        }
                        default:
                            append(ds, "<nyi(lit)>");
                        }
                        break;
                    }
                    default:
                        append(ds, "<nyi>");
                }
            }
            if (cur_ins->info->opcode == MVM_OP_wval || cur_ins->info->opcode == MVM_OP_wval_wide) {
                /* We can try to find out what the debug_name of this thing is. */
                MVMint16 dep = cur_ins->operands[1].lit_i16;
                MVMint64 idx;
                MVMCollectable *result = NULL;
                MVMSerializationContext *sc;
                char *debug_name = NULL;
                const char *repr_name = NULL;
                if (cur_ins->info->opcode == MVM_OP_wval) {
                    idx = cur_ins->operands[2].lit_i16;
                } else {
                    idx = cur_ins->operands[2].lit_i64;
                }
                sc = MVM_sc_get_sc(tc, g->sf->body.cu, dep);
                if (sc)
                    result = (MVMCollectable *)MVM_sc_try_get_object(tc, sc, idx);
                if (result) {
                    if (result->flags & MVM_CF_STABLE) {
                        debug_name = MVM_6model_get_stable_debug_name(tc, (MVMSTable *)result);
                        repr_name  = ((MVMSTable *)result)->REPR->name;
                    } else {
                        debug_name = MVM_6model_get_debug_name(tc, (MVMObject *)result);
                        repr_name  = REPR(result)->name;
                    }
                    if (debug_name) {
                        appendf(ds, " (%s: %s)", repr_name, debug_name);
                    } else {
                        appendf(ds, " (%s: ?)", repr_name);
                    }
                } else {
                    appendf(ds, " (not deserialized)");
                }
            }
        }
        if (num_comments == 1) {
            ann = cur_ins->annotations;
            while (ann) {
                if (ann->type == MVM_SPESH_ANN_COMMENT) {
                    appendf(ds, "  # %s", ann->data.comment);
                    break;
                }
                ann = ann->next;
            }
        }
        append(ds, "\n");
        cur_ins = cur_ins->next;
    }

    if (stats) {
        if (bb->inlined)
            stats->inlined_size += size;
        stats->total_size += size;
    }

    /* Predecessors and successors. */
    append(ds, "    Successors: ");
    for (i = 0; i < bb->num_succ; i++)
        appendf(ds, (i == 0 ? "%d" : ", %d"), bb->succ[i]->idx);
    append(ds, "\n    Predecessors: ");
    for (i = 0; i < bb->num_pred; i++)
        appendf(ds, (i == 0 ? "%d" : ", %d"), bb->pred[i]->idx);
    append(ds, "\n    Dominance children: ");
    for (i = 0; i < bb->num_children; i++)
        appendf(ds, (i == 0 ? "%d" : ", %d"), bb->children[i]->idx);
    append(ds, "\n\n");
}