Skip to content

Commit

Permalink
add heapsnapshot support to confprog
Browse files Browse the repository at this point in the history
  • Loading branch information
timo committed May 27, 2019
1 parent 3ec073f commit a1154bc
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 17 deletions.
62 changes: 60 additions & 2 deletions src/profiler/configuration.c
@@ -1,5 +1,6 @@
#include "moar.h"

#define CONFPROG_UNUSED_ENTRYPOINT 1

#define OUTPUT_LOTS_OF_JUNK 1

Expand Down Expand Up @@ -386,6 +387,7 @@ void MVM_confprog_install(MVMThreadContext *tc, MVMObject *bytecode, MVMObject *
MVMuint64 bytecode_size;
MVMuint8 *array_contents;
MVMConfigurationProgram *confprog;
MVMint16 entrypoint_array[MVM_PROGRAM_ENTRYPOINT_COUNT];

CHECK_CONC(bytecode, VMArray, "the bytecode");
CHECK_CONC(string_array, VMArray, "the string heap");
Expand Down Expand Up @@ -429,25 +431,45 @@ void MVM_confprog_install(MVMThreadContext *tc, MVMObject *bytecode, MVMObject *
{
MVMObject *arr = entrypoints;
MVMArrayREPRData *reprdata = (MVMArrayREPRData *)STABLE(arr)->REPR_data;
MVMuint64 index;
MVMuint64 count;

if (reprdata->slot_type != MVM_ARRAY_I64) {
MVM_exception_throw_adhoc(tc, "installconfprog requires the entrypoints array to be a native array of 64-bit integers (got a %s)",
MVM_6model_get_debug_name(tc, bytecode));
}

count = MVM_repr_elems(tc, arr);

memset(entrypoint_array, 0, sizeof(entrypoint_array));

junkprint(stderr, "copying over %d entrypoints\n", count);

for (index = 0; index < count && index < MVM_PROGRAM_ENTRYPOINT_COUNT; index++) {
entrypoint_array[index] = MVM_repr_at_pos_i(tc, arr, index);
junkprint(stderr, " - %d == %d\n", index, entrypoint_array[index]);
}
}

confprog = MVM_calloc(sizeof(MVMConfigurationProgram), 1);

fprintf(stderr, "copying %d (%x) bytecode entries\n", bytecode_size, bytecode_size);
confprog->bytecode = MVM_malloc(bytecode_size);
memcpy(confprog->bytecode, array_contents, bytecode_size);

memcpy(confprog->entrypoints, entrypoint_array, sizeof(entrypoint_array));

confprog->bytecode_length = bytecode_size;

confprog->string_heap = string_array;

MVM_confprog_validate(tc, confprog);

MVM_confprog_run(tc, confprog, tc->instance->VMNull, 0);
tc->instance->confprog = confprog;
}

MVMuint8 MVM_confprog_has_entrypoint(MVMThreadContext *tc, MVMuint8 entrypoint) {
return tc->instance->confprog && entrypoint < MVM_PROGRAM_ENTRYPOINT_COUNT && tc->instance->confprog->entrypoints[entrypoint] != CONFPROG_UNUSED_ENTRYPOINT;
}

/* Stolen from interp.c */
Expand All @@ -462,10 +484,21 @@ void MVM_confprog_install(MVMThreadContext *tc, MVMObject *bytecode, MVMObject *
MVMint64 MVM_confprog_run(MVMThreadContext *tc, void *subject, MVMuint8 entrypoint, MVMint64 initial_feature_value) {
MVMConfigurationProgram *prog = tc->instance->confprog;
MVMuint8 *cur_op;
MVMuint8 *last_op;
MVMint64 result;

MVMuint8 *bytecode_start;

CPRegister *reg_base = MVM_calloc(prog->reg_count + 1, sizeof(CPRegister));

cur_op = prog->bytecode;
reg_base[REGISTER_FEATURE_TOGGLE].i64 = initial_feature_value;

bytecode_start = prog->bytecode;
cur_op = bytecode_start + prog->entrypoints[entrypoint];
last_op = bytecode_start + prog->bytecode_length;

junkprint(stderr, "running confprog for entrypoint %d (at position %d)\n", entrypoint, prog->entrypoints[entrypoint]);
junkprint(stderr, "confprog is 0x%x (%d) bytes big", last_op - bytecode_start, last_op - bytecode_start);

runloop: {
MVMuint16 ins = *((MVMuint16 *)cur_op);
Expand All @@ -487,6 +520,10 @@ MVMint64 MVM_confprog_run(MVMThreadContext *tc, void *subject, MVMuint8 entrypoi
junkprint(stderr, "const_i64 %d\n", MVM_BC_get_I64(cur_op, 2));
cur_op += 10;
goto NEXT;
OP(const_n64):
GET_REG(cur_op, 0).n64 = MVM_BC_get_N64(cur_op, 2);
cur_op += 10;
goto NEXT;
OP(const_i64_16):
GET_REG(cur_op, 0).i64 = GET_I16(cur_op, 2);
junkprint(stderr, "const_i64_16 %d into %d\n", GET_I16(cur_op, 2), GET_UI16(cur_op, 0));
Expand Down Expand Up @@ -583,6 +620,27 @@ MVMint64 MVM_confprog_run(MVMThreadContext *tc, void *subject, MVMuint8 entrypoi
MVM_coerce_smart_stringify(tc, obj, res);
goto NEXT;
}
OP(gt_n):
GET_REG(cur_op, 0).i64 = GET_REG(cur_op, 2).n64 > GET_REG(cur_op, 4).n64;
cur_op += 6;
goto NEXT;
OP(rand_n):
GET_REG(cur_op, 0).n64 = MVM_proc_rand_n(tc);
cur_op += 2;
goto NEXT;
OP(goto):
cur_op = bytecode_start + GET_UI32(cur_op, 0);
goto NEXT;
OP(if_i):
if (GET_REG(cur_op, 0).i64)
cur_op = bytecode_start + GET_UI32(cur_op, 2);
else
cur_op += 6;
goto NEXT;
OP(exit): {
MVMint64 exit_code = GET_REG(cur_op, 0).i64;
goto finish_main_loop;
}
default:
fprintf(stderr, "operation %s (%d, 0x%x) NYI\n", MVM_op_get_op(ins)->name, ins, ins);
goto finish_main_loop;
Expand Down
10 changes: 9 additions & 1 deletion src/profiler/configuration.h
Expand Up @@ -2,8 +2,15 @@
#define MVM_PROGRAM_ENTRYPOINT_PROFILER_DYNAMIC 1
#define MVM_PROGRAM_ENTRYPOINT_SPESH 2
#define MVM_PROGRAM_ENTRYPOINT_JIT 3
#define MVM_PROGRAM_ENTRYPOINT_HEAPSNAPSHOT 4

#define MVM_PROGRAM_ENTRYPOINT_COUNT 4
#define MVM_PROGRAM_ENTRYPOINT_COUNT 5

#define MVM_CONFPROG_SF_RESULT_TO_BE_DETERMINED 0
#define MVM_CONFPROG_SF_RESULT_NEVER 1
#define MVM_CONFPROG_SF_RESULT_DYNAMIC_SUGGEST_NO 2
#define MVM_CONFPROG_SF_RESULT_DYNAMIC_SUGGEST_YES 3
#define MVM_CONFPROG_SF_RESULT_ALWAYS 4

struct MVMConfigurationProgramEntryPoint {
MVMuint32 offset;
Expand All @@ -22,6 +29,7 @@ struct MVMConfigurationProgram {
MVMint16 entrypoints[MVM_PROGRAM_ENTRYPOINT_COUNT];
};

MVMuint8 MVM_confprog_has_entrypoint(MVMThreadContext *tc, MVMuint8 entrypoint);
MVMint64 MVM_confprog_run(MVMThreadContext *tc, void *subject, MVMuint8 entrypoint, MVMint64 initial_feature_value);
void MVM_confprog_mark(MVMThreadContext *tc, MVMGCWorklist *worklist, MVMHeapSnapshotState *snapshot);
void MVM_confprog_install(MVMThreadContext *tc, MVMObject *bytecode, MVMObject *string_array, MVMObject *entrypoints);
23 changes: 18 additions & 5 deletions src/profiler/heapsnapshot.c
Expand Up @@ -925,14 +925,27 @@ void finish_collection_to_filehandle(MVMThreadContext *tc, MVMHeapSnapshotCollec
void MVM_profile_heap_take_snapshot(MVMThreadContext *tc) {
if (MVM_profile_heap_profiling(tc)) {
MVMHeapSnapshotCollection *col = tc->instance->heap_snapshots;
col->snapshot = MVM_calloc(1, sizeof(MVMHeapSnapshot));
MVMint64 do_heapsnapshot = 1;

record_snapshot(tc, col, col->snapshot);
fprintf(stderr, "checking for confprog on entrypoint %d\n", MVM_PROGRAM_ENTRYPOINT_HEAPSNAPSHOT);
if (MVM_confprog_has_entrypoint(tc, MVM_PROGRAM_ENTRYPOINT_HEAPSNAPSHOT)) {
do_heapsnapshot = MVM_confprog_run(tc, NULL, MVM_PROGRAM_ENTRYPOINT_HEAPSNAPSHOT, do_heapsnapshot);
}

if (do_heapsnapshot) {
col->snapshot = MVM_calloc(1, sizeof(MVMHeapSnapshot));

fprintf(stderr, "doing snapshot\n");
record_snapshot(tc, col, col->snapshot);

snapshot_to_filehandle(tc, col);
fflush(col->fh);
snapshot_to_filehandle(tc, col);
fflush(col->fh);

destroy_current_heap_snapshot(tc);
destroy_current_heap_snapshot(tc);
}
else {
fprintf(stderr, "not doing snapshot\n");
}
col->snapshot_idx++;
}
}
Expand Down

0 comments on commit a1154bc

Please sign in to comment.