diff --git a/src/profiler/configuration.c b/src/profiler/configuration.c index 7fbf68c0ca..b427ed453c 100644 --- a/src/profiler/configuration.c +++ b/src/profiler/configuration.c @@ -1,5 +1,6 @@ #include "moar.h" +#define CONFPROG_UNUSED_ENTRYPOINT 1 #define OUTPUT_LOTS_OF_JUNK 1 @@ -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"); @@ -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 */ @@ -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); @@ -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)); @@ -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; diff --git a/src/profiler/configuration.h b/src/profiler/configuration.h index b9b0c8c009..a95b6130b0 100644 --- a/src/profiler/configuration.h +++ b/src/profiler/configuration.h @@ -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; @@ -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); diff --git a/src/profiler/heapsnapshot.c b/src/profiler/heapsnapshot.c index b301181c35..ee1bee4d0c 100644 --- a/src/profiler/heapsnapshot.c +++ b/src/profiler/heapsnapshot.c @@ -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++; } } diff --git a/tools/compile_confprog.p6 b/tools/compile_confprog.p6 index 563f9c3507..f22eceaa82 100644 --- a/tools/compile_confprog.p6 +++ b/tools/compile_confprog.p6 @@ -81,6 +81,7 @@ grammar ConfProg { | 'profiler_dynamic' | 'spesh' | 'jit' + | 'heapsnapshot' ] \s* ":" } @@ -147,6 +148,10 @@ grammar ConfProg { '(' \s* \s* ')' } + regex one_expression: { + '(' ( | )* %% [\s* ',' \s*] ')' + } + proto regex postfixish { * } regex postfixish: { '.' @@ -235,6 +240,8 @@ my %prefix-to-op = < >; class ConfProgActions { + has %.labels; + method prefixop($/) { make $/.Str } method compop($/) { say $/.Str; make %op-to-op{$/.Str} } @@ -294,6 +301,34 @@ class ConfProgActions { make $result; } + method one_expression:($/) { + use Data::Dump::Tree::ExtraRoles; + + my @positionals; + my @nameds; + my $matchddt = Data::Dump::Tree.new; + $matchddt does DDTR::MatchDetails; + $matchddt.dump: $/; + + for @0 { + with . { + @positionals.push: .ast; + } + orwith . { + die "named arguments in functioncall NYI"; + @nameds.push: .ast; + } + } + + my $result = Op.new( + op => "call", + children => [ + flat $.Str, + @positionals, @nameds + ]); + make $result; + } + method statement:($/) { make Label.new( name => $.Str, @@ -301,10 +336,17 @@ class ConfProgActions { ); } method statement: