Ejemplo n.º 1
0
MVMObject * references_str(MVMThreadContext *tc, MVMHeapSnapshot *s) {
    /* Produces ; separated sequences of:
     *   kind,idx,to
     * All of which are integers.
     */
    MVMObject *result;
    size_t buffer_size = 10 * s->num_references;
    size_t buffer_pos  = 0;
    char *buffer       = MVM_malloc(buffer_size);

    MVMuint64 i;
    for (i = 0; i < s->num_references; i++) {
        char tmp[128];
        int item_chars = snprintf(tmp, 128, "%"PRIu64",%"PRIu64",%"PRIu64";",
            s->references[i].description & ((1 << MVM_SNAPSHOT_REF_KIND_BITS) - 1),
            s->references[i].description >> MVM_SNAPSHOT_REF_KIND_BITS,
            s->references[i].collectable_index);
        if (item_chars < 0)
            MVM_panic(1, "Failed to save reference in heap snapshot");
        if (buffer_pos + item_chars >= buffer_size) {
            buffer_size += 4096;
            buffer = MVM_realloc(buffer, buffer_size);
        }
        memcpy(buffer + buffer_pos, tmp, item_chars);
        buffer_pos += item_chars;
    }
    if (buffer_pos > 1)
        buffer[buffer_pos - 1] = 0; /* Cut off the trailing ; for ease of parsing */
    buffer[buffer_pos] = 0;

    result = box_s(tc, vmstr(tc, buffer));
    MVM_free(buffer);
    return result;
}
Ejemplo n.º 2
0
MVMObject * types_str(MVMThreadContext *tc, MVMHeapSnapshotCollection *col) {
    /* Produces ; separated sequences of:
     *   repr_string_index,type_name_string_index
     * Both of which are integers.
     */
     MVMObject *result;
     size_t buffer_size = 10 * col->num_types;
     size_t buffer_pos  = 0;
     char *buffer       = MVM_malloc(buffer_size);

     MVMuint64 i;
     for (i = 0; i < col->num_types; i++) {
         char tmp[256];
         int item_chars = snprintf(tmp, 256,
            "%"PRIu64",%"PRIu64";",
            col->types[i].repr_name,
            col->types[i].type_name);
         if (item_chars < 0)
             MVM_panic(1, "Failed to save type in heap snapshot");
         if (buffer_pos + item_chars >= buffer_size) {
             buffer_size += 4096;
             buffer = MVM_realloc(buffer, buffer_size);
         }
         memcpy(buffer + buffer_pos, tmp, item_chars);
         buffer_pos += item_chars;
     }
    if (buffer_pos > 1)
        buffer[buffer_pos - 1] = 0; /* Cut off the trailing ; for ease of parsing */
     buffer[buffer_pos] = 0;

     result = box_s(tc, vmstr(tc, buffer));
     MVM_free(buffer);
     return result;
}
Ejemplo n.º 3
0
MVMObject * collectables_str(MVMThreadContext *tc, MVMHeapSnapshot *s) {
    /* Produces ; separated sequences of:
     *   kind,type_or_frame_index,collectable_size,unmanaged_size,refs_start,num_refs
     * All of which are integers.
     */
     MVMObject *result;
     size_t buffer_size = 20 * s->num_collectables;
     size_t buffer_pos  = 0;
     char *buffer       = MVM_malloc(buffer_size);

     MVMuint64 i;
     for (i = 0; i < s->num_collectables; i++) {
         char tmp[256];
         int item_chars = snprintf(tmp, 256,
            "%"PRIu16",%"PRId32",%"PRIu16",%"PRIu64",%"PRIu64",%"PRIu32";",
            s->collectables[i].kind,
            s->collectables[i].type_or_frame_index,
            s->collectables[i].collectable_size,
            s->collectables[i].unmanaged_size,
            s->collectables[i].num_refs ? s->collectables[i].refs_start : (MVMuint64)0,
            s->collectables[i].num_refs);
         if (item_chars < 0)
             MVM_panic(1, "Failed to save collectable in heap snapshot");
         if (buffer_pos + item_chars >= buffer_size) {
             buffer_size += 4096;
             buffer = MVM_realloc(buffer, buffer_size);
         }
         memcpy(buffer + buffer_pos, tmp, item_chars);
         buffer_pos += item_chars;
     }
    if (buffer_pos > 1)
        buffer[buffer_pos - 1] = 0; /* Cut off the trailing ; for ease of parsing */
     buffer[buffer_pos] = 0;

     result = box_s(tc, vmstr(tc, buffer));
     MVM_free(buffer);
     return result;
}
Ejemplo n.º 4
0
/* Dumps a call graph node. */
static MVMObject * dump_call_graph_node(MVMThreadContext *tc, ProfDumpStrs *pds,
                                        const MVMProfileCallNode *pcn) {
    MVMObject *node_hash  = new_hash(tc);
    MVMuint32  i;

    /* Let's see if we're dealing with a native call or a regular moar call */
    if (pcn->sf) {
        /* Try to resolve the code filename and line number. */
        MVMBytecodeAnnotation *annot = MVM_bytecode_resolve_annotation(tc,
            &(pcn->sf->body), 0);
        MVMint32 fshi = annot ? (MVMint32)annot->filename_string_heap_index : -1;

        /* Add name of code object. */
        MVM_repr_bind_key_o(tc, node_hash, pds->name,
            box_s(tc, pcn->sf->body.name));

        /* Add line number and file name. */
        if (fshi >= 0 && fshi < pcn->sf->body.cu->body.num_strings)
            MVM_repr_bind_key_o(tc, node_hash, pds->file,
                box_s(tc, MVM_cu_string(tc, pcn->sf->body.cu, fshi)));
        else if (pcn->sf->body.cu->body.filename)
            MVM_repr_bind_key_o(tc, node_hash, pds->file,
                box_s(tc, pcn->sf->body.cu->body.filename));
        else
            MVM_repr_bind_key_o(tc, node_hash, pds->file,
                box_s(tc, tc->instance->str_consts.empty));
        MVM_repr_bind_key_o(tc, node_hash, pds->line,
            box_i(tc, annot ? (MVMint32)annot->line_number : -1));
        MVM_free(annot);

        /* Use static frame memory address to get a unique ID. */
        MVM_repr_bind_key_o(tc, node_hash, pds->id,
            box_i(tc, (MVMint64)pcn->sf));
    } else {
        MVMString *function_name_string =
            MVM_string_utf8_c8_decode(tc, tc->instance->VMString,
                                      pcn->native_target_name, strlen(pcn->native_target_name));

        MVM_repr_bind_key_o(tc, node_hash, pds->name,
            box_s(tc, function_name_string));
        MVM_repr_bind_key_o(tc, node_hash, pds->file,
            box_s(tc, pds->native_lib));

        MVM_repr_bind_key_o(tc, node_hash, pds->line,
            box_i(tc, -2));

        /* Use the address of the name string as unique ID. a hack, but oh well. */
        MVM_repr_bind_key_o(tc, node_hash, pds->id,
            box_i(tc, (MVMint64)pcn->native_target_name));
    }

    /* Entry counts. */
    if (pcn->total_entries)
        MVM_repr_bind_key_o(tc, node_hash, pds->entries,
            box_i(tc, pcn->total_entries));
    if (pcn->specialized_entries)
        MVM_repr_bind_key_o(tc, node_hash, pds->spesh_entries,
            box_i(tc, pcn->specialized_entries));
    if (pcn->jit_entries)
        MVM_repr_bind_key_o(tc, node_hash, pds->jit_entries,
            box_i(tc, pcn->jit_entries));
    if (pcn->inlined_entries)
        MVM_repr_bind_key_o(tc, node_hash, pds->inlined_entries,
            box_i(tc, pcn->inlined_entries));

    /* Total (inclusive) time. */
    MVM_repr_bind_key_o(tc, node_hash, pds->inclusive_time,
        box_i(tc, pcn->total_time / 1000));

    /* OSR and deopt counts. */
    if (pcn->osr_count)
        MVM_repr_bind_key_o(tc, node_hash, pds->osr,
            box_i(tc, pcn->osr_count));
    if (pcn->deopt_one_count)
        MVM_repr_bind_key_o(tc, node_hash, pds->deopt_one,
            box_i(tc, pcn->deopt_one_count));
    if (pcn->deopt_all_count)
        MVM_repr_bind_key_o(tc, node_hash, pds->deopt_all,
            box_i(tc, pcn->deopt_all_count));

    /* Visit successors in the call graph, dumping them and working out the
     * exclusive time. */
    if (pcn->num_succ) {
        MVMObject *callees        = new_array(tc);
        MVMuint64  exclusive_time = pcn->total_time;
        for (i = 0; i < pcn->num_succ; i++) {
            MVM_repr_push_o(tc, callees,
                dump_call_graph_node(tc, pds, pcn->succ[i]));
            exclusive_time -= pcn->succ[i]->total_time;
        }
        MVM_repr_bind_key_o(tc, node_hash, pds->exclusive_time,
            box_i(tc, exclusive_time / 1000));
        MVM_repr_bind_key_o(tc, node_hash, pds->callees, callees);
    }
    else {
        MVM_repr_bind_key_o(tc, node_hash, pds->exclusive_time,
            box_i(tc, pcn->total_time / 1000));
    }

    if (pcn->num_alloc) {
        /* Emit allocations. */
        MVMObject *alloc_list = new_array(tc);
        MVM_repr_bind_key_o(tc, node_hash, pds->allocations, alloc_list);
        for (i = 0; i < pcn->num_alloc; i++) {
            MVMObject *alloc_info = new_hash(tc);
            MVMProfileAllocationCount *alloc = &pcn->alloc[i];

            MVMObject *type       = pcn->alloc[i].type;

            MVM_repr_bind_key_o(tc, alloc_info, pds->id, box_i(tc, (MVMint64)type));
            MVM_repr_bind_key_o(tc, alloc_info, pds->type, type);
            if (alloc->allocations_spesh)
                MVM_repr_bind_key_o(tc, alloc_info, pds->spesh,
                    box_i(tc, alloc->allocations_spesh));
            if (alloc->allocations_jit)
                MVM_repr_bind_key_o(tc, alloc_info, pds->jit,
                    box_i(tc, alloc->allocations_jit));
            MVM_repr_bind_key_o(tc, alloc_info, pds->count,
                box_i(tc, alloc->allocations_interp
                          + alloc->allocations_spesh
                          + alloc->allocations_jit));
            MVM_repr_push_o(tc, alloc_list, alloc_info);
        }
    }

    return node_hash;
}