Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

move global subprofdata into the runcore data for now. dump profile d…

…ata in the runcore's destroy callback.
  • Loading branch information...
commit f5358a86ce3c8aaf305783c6c84349b8e8eaaa2a 1 parent 22ad8af
@mlschroe mlschroe authored
View
63 include/parrot/runcore_subprof.h
@@ -15,6 +15,7 @@ typedef struct subprofile subprofile;
typedef struct callinfo callinfo;
typedef struct lineinfo lineinfo;
typedef struct subprofiledata subprofiledata;
+typedef struct subprof_runcore_t Parrot_subprof_runcore_t;
struct callinfo {
/* which sub we called */
@@ -29,13 +30,13 @@ struct callinfo {
struct lineinfo {
/* start op of this line */
- size_t op_offs;
+ size_t op_offs;
/* calls made from this line */
callinfo *calls;
/* number of ops executed in this line */
- UINTVAL ops;
+ UINTVAL ops;
/* number of CPU ticks spent in this line */
- UHUGEINTVAL ticks;
+ UHUGEINTVAL ticks;
};
struct subprofile {
@@ -51,11 +52,11 @@ struct subprofile {
/* first op of segment */
opcode_t *code_ops;
- INTVAL srcline;
+ INTVAL srcline;
char *srcfile;
lineinfo *lines;
- int nlines;
+ int nlines;
/* call chain info */
/* which sub called us */
@@ -66,8 +67,8 @@ struct subprofile {
PMC *ctx;
/* ops/ticks we need to distribute to the caller */
- UINTVAL callerops;
- UHUGEINTVAL callerticks;
+ UINTVAL callerops;
+ UHUGEINTVAL callerticks;
};
#define SUBPROF_TYPE_SUB 1
@@ -75,37 +76,46 @@ struct subprofile {
#define SUBPROF_TYPE_OPS 3
struct subprofiledata {
+ /* the interpreter we're profiling */
+ Interp *interp;
/* type of profile */
- int profile_type;
+ int profile_type;
/* the collected data, maps subpmc -> subprofile */
- Hash *sphash;
+ Hash *sphash;
/* the root call data */
- lineinfo rootline;
+ lineinfo rootline;
/* maps to expanded debug data */
- Hash *seg2debug;
+ Hash *seg2debug;
/* the current context */
- PMC *cursubpmc;
- PMC *curctx;
- subprofile *cursp;
+ PMC *cursubpmc;
+ PMC *curctx;
+ subprofile *cursp;
/* ticks are added at the end of the op */
UHUGEINTVAL *tickadd;
UHUGEINTVAL *tickadd2;
- UHUGEINTVAL starttick;
+ UHUGEINTVAL starttick;
};
+struct subprof_runcore_t {
+ STRING *name;
+ int id;
+ oplib_init_f opinit;
+ Parrot_runcore_runops_fn_t runops;
+ Parrot_runcore_destroy_fn_t destroy;
+ Parrot_runcore_prepare_fn_t prepare_run;
+ INTVAL flags;
-/* HEADERIZER BEGIN: src/runcore/subprof.c */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+ subprofiledata *spdata;
+};
-void dump_profile_data(PARROT_INTERP)
- __attribute__nonnull__(1);
-void mark_profile_data(PARROT_INTERP)
- __attribute__nonnull__(1);
+
+/* HEADERIZER BEGIN: src/runcore/subprof.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
void Parrot_runcore_subprof_hll_init(PARROT_INTERP)
__attribute__nonnull__(1);
@@ -116,10 +126,10 @@ void Parrot_runcore_subprof_ops_init(PARROT_INTERP)
void Parrot_runcore_subprof_sub_init(PARROT_INTERP)
__attribute__nonnull__(1);
-#define ASSERT_ARGS_dump_profile_data __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_mark_profile_data __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp))
+void runops_subprof_mark(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
#define ASSERT_ARGS_Parrot_runcore_subprof_hll_init \
__attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
@@ -129,6 +139,9 @@ void Parrot_runcore_subprof_sub_init(PARROT_INTERP)
#define ASSERT_ARGS_Parrot_runcore_subprof_sub_init \
__attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_runops_subprof_mark __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(runcore))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: src/runcore/subprof.c */
View
3  src/embed/api.c
@@ -190,7 +190,7 @@ Parrot_api_set_runcore(Parrot_PMC interp_pmc, ARGIN(const char * corename),
Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "fast"));
else if (STREQ(corename, "subprof_sub"))
Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "subprof_sub"));
- else if (STREQ(corename, "subprof_hll"))
+ else if (STREQ(corename, "subprof_hll") || STREQ(corename, "subprof"))
Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "subprof_hll"));
else if (STREQ(corename, "subprof_ops"))
Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "subprof_ops"));
@@ -318,7 +318,6 @@ Parrot_api_destroy_interpreter(Parrot_PMC interp_pmc)
if (_oldtop == NULL)
interp->lo_var_ptr = &_oldtop;
interp->api_jmp_buf = &env;
- dump_profile_data(interp);
Parrot_destroy(interp);
Parrot_x_exit(interp, 0);
/* Never reached, x_exit calls longjmp */
View
3  src/gc/mark_sweep.c
@@ -254,7 +254,8 @@ mark_interp(PARROT_INTERP)
if (!PMC_IS_NULL(interp->final_exception))
Parrot_gc_mark_PMC_alive(interp, interp->final_exception);
- mark_profile_data(interp);
+ if (interp->run_core)
+ runops_subprof_mark(interp, interp->run_core);
if (interp->parent_interpreter)
mark_interp(interp->parent_interpreter);
View
167 src/runcore/subprof.c
@@ -49,6 +49,10 @@ static void createlines(PARROT_INTERP,
__attribute__nonnull__(2)
__attribute__nonnull__(3);
+static void dump_profile_data(PARROT_INTERP, ARGIN(subprofiledata *spdata))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
PARROT_CAN_RETURN_NULL
static opcode_t * findlineannotations(PARROT_INTERP,
ARGIN(subprofiledata *spdata),
@@ -64,6 +68,15 @@ static void finishcallchain(PARROT_INTERP, ARGIN(subprofiledata *spdata))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static subprofiledata * get_subprofiledata(PARROT_INTERP,
+ ARGIN(Parrot_runcore_t *runcore),
+ int type)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
+static UHUGEINTVAL getticks(void);
static void popcallchain(PARROT_INTERP, ARGIN(subprofiledata *spdata))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
@@ -75,28 +88,36 @@ static void printspname(PARROT_INTERP,
__attribute__nonnull__(2)
__attribute__nonnull__(3);
+static void runops_subprof_destroy(PARROT_INTERP,
+ ARGIN(Parrot_runcore_t *runcore))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
static opcode_t * runops_subprof_hll_core(PARROT_INTERP,
- Parrot_runcore_t *runcore,
+ ARGIN(Parrot_runcore_t *runcore),
ARGIN(opcode_t *pc))
__attribute__nonnull__(1)
+ __attribute__nonnull__(2)
__attribute__nonnull__(3);
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
static opcode_t * runops_subprof_ops_core(PARROT_INTERP,
- Parrot_runcore_t *runcore,
+ ARGIN(Parrot_runcore_t *runcore),
ARGIN(opcode_t *pc))
__attribute__nonnull__(1)
+ __attribute__nonnull__(2)
__attribute__nonnull__(3);
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
static opcode_t * runops_subprof_sub_core(PARROT_INTERP,
- Parrot_runcore_t *runcore,
+ ARGIN(Parrot_runcore_t *runcore),
ARGIN(opcode_t *pc))
__attribute__nonnull__(1)
+ __attribute__nonnull__(2)
__attribute__nonnull__(3);
PARROT_CANNOT_RETURN_NULL
@@ -143,6 +164,9 @@ static lineinfo * sync_hll_linechange(PARROT_INTERP,
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(spdata) \
, PARROT_ASSERT_ARG(sp))
+#define ASSERT_ARGS_dump_profile_data __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(spdata))
#define ASSERT_ARGS_findlineannotations __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(spdata) \
@@ -151,6 +175,10 @@ static lineinfo * sync_hll_linechange(PARROT_INTERP,
#define ASSERT_ARGS_finishcallchain __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(spdata))
+#define ASSERT_ARGS_get_subprofiledata __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(runcore))
+#define ASSERT_ARGS_getticks __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_popcallchain __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(spdata))
@@ -158,14 +186,20 @@ static lineinfo * sync_hll_linechange(PARROT_INTERP,
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(spdata) \
, PARROT_ASSERT_ARG(sp))
+#define ASSERT_ARGS_runops_subprof_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(runcore))
#define ASSERT_ARGS_runops_subprof_hll_core __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(runcore) \
, PARROT_ASSERT_ARG(pc))
#define ASSERT_ARGS_runops_subprof_ops_core __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(runcore) \
, PARROT_ASSERT_ARG(pc))
#define ASSERT_ARGS_runops_subprof_sub_core __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(runcore) \
, PARROT_ASSERT_ARG(pc))
#define ASSERT_ARGS_sptodebug __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
@@ -189,8 +223,6 @@ static lineinfo * sync_hll_linechange(PARROT_INTERP,
/* HEADERIZER END: static */
-static subprofiledata _spdata;
-
/*
=item *C<static INTVAL *sptodebug(...)>
@@ -634,10 +666,9 @@ profile to stderr.
*/
-void
-dump_profile_data(PARROT_INTERP)
+static void
+dump_profile_data(PARROT_INTERP, ARGIN(subprofiledata *spdata))
{
- subprofiledata *spdata = &_spdata;
int h;
size_t off;
@@ -743,24 +774,16 @@ dump_profile_data(PARROT_INTERP)
fprintf(stderr, "\ntotals: %d %lld\n", totalops, totalticks);
}
-void
-mark_profile_data(PARROT_INTERP)
-{
- subprofiledata *spdata = &_spdata;
- if (!spdata->profile_type || !spdata->sphash)
- return;
- Parrot_hash_mark(interp, spdata->sphash);
-}
-
-
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
-static __inline__ UHUGEINTVAL getticks(void) {
+static __inline__ UHUGEINTVAL
+getticks(void) {
uint32_t lo, hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return (UHUGEINTVAL)hi << 32 | lo;
}
#else
-static UHUGEINTVAL getticks(void) {
+static UHUGEINTVAL
+getticks(void) {
return Parrot_hires_get_time();
}
#endif
@@ -845,6 +868,27 @@ sync_hll_linechange(PARROT_INTERP, ARGIN(subprofiledata *spdata), ARGIN_NULLOK(o
return li;
}
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static subprofiledata *
+get_subprofiledata(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), int type)
+{
+ Parrot_subprof_runcore_t *core = (Parrot_subprof_runcore_t *)runcore;
+ subprofiledata *spdata = core->spdata;
+ if (!spdata) {
+ spdata = (subprofiledata *)calloc(1, sizeof(subprofiledata));
+ spdata->profile_type = type;
+ spdata->interp = interp;
+ core->spdata = spdata;
+ }
+ if (spdata->profile_type != type)
+ Parrot_ex_throw_from_c_args(interp, NULL, 1, "illegal profile type change while profiling");
+ if (spdata->interp != interp)
+ Parrot_ex_throw_from_c_args(interp, NULL, 1, "illegal interpreter change while profiling");
+ return core->spdata;
+}
+
+
#ifdef code_start
# undef code_start
#endif
@@ -855,6 +899,24 @@ sync_hll_linechange(PARROT_INTERP, ARGIN(subprofiledata *spdata), ARGIN_NULLOK(o
#define code_start interp->code->base.data
#define code_end (interp->code->base.data + interp->code->base.size)
+/*
+=item C<static void runops_subprof_destroy(PARROT_INTERP, Parrot_runcore_t
+*runcore)>
+
+Destroy callback. We use it to print the profile data.
+
+*/
+
+static void
+runops_subprof_destroy(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
+{
+ Parrot_subprof_runcore_t *core = (Parrot_subprof_runcore_t *)runcore;
+ if (core->spdata) {
+ dump_profile_data(interp, core->spdata);
+ free(core->spdata);
+ core->spdata = NULL;
+ }
+}
/*
=item C<static opcode_t * runops_subprof_hll_core(PARROT_INTERP,
@@ -870,17 +932,12 @@ operations, with sub-level profiling and bounds checking enabled.
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
static opcode_t *
-runops_subprof_sub_core(PARROT_INTERP, SHIM(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
+runops_subprof_sub_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
{
- subprofiledata *spdata = &_spdata;
+ subprofiledata *spdata = get_subprofiledata(interp, runcore, SUBPROF_TYPE_SUB);
subprofile *sp = spdata->cursp;
PMC *ctx, *subpmc;
- if (spdata->profile_type && spdata->profile_type != SUBPROF_TYPE_SUB)
- Parrot_ex_throw_from_c_args(interp, NULL, 1,
- "illegal profile type change");
- spdata->profile_type = SUBPROF_TYPE_SUB;
-
while (pc) {
if (pc < code_start || pc >= code_end)
Parrot_ex_throw_from_c_args(interp, NULL, 1,
@@ -935,18 +992,18 @@ Registers the subprof_sub runcore with Parrot.
void
Parrot_runcore_subprof_sub_init(PARROT_INTERP)
{
- Parrot_runcore_t * const coredata = mem_gc_allocate_zeroed_typed(interp, Parrot_runcore_t);
+ Parrot_subprof_runcore_t * const coredata = mem_gc_allocate_zeroed_typed(interp, Parrot_subprof_runcore_t);
coredata->name = CONST_STRING(interp, "subprof_sub");
coredata->id = PARROT_SLOW_CORE;
coredata->opinit = PARROT_CORE_OPLIB_INIT;
coredata->runops = runops_subprof_sub_core;
coredata->prepare_run = NULL;
- coredata->destroy = NULL;
+ coredata->destroy = runops_subprof_destroy;
coredata->flags = 0;
PARROT_RUNCORE_FUNC_TABLE_SET(coredata);
- Parrot_runcore_register(interp, coredata);
+ Parrot_runcore_register(interp, (Parrot_runcore_t *)coredata);
}
@@ -966,20 +1023,15 @@ operations, with sub-level profiling and bounds checking enabled.
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
static opcode_t *
-runops_subprof_hll_core(PARROT_INTERP, SHIM(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
+runops_subprof_hll_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
{
- subprofiledata *spdata = &_spdata;
+ subprofiledata *spdata = get_subprofiledata(interp, runcore, SUBPROF_TYPE_HLL);
subprofile *sp = spdata->cursp;
PMC *ctx, *subpmc;
lineinfo *curline = sp ? sp->lines : 0;
opcode_t *startop = 0;
opcode_t *endop = 0; /* triggers pc >= endop below */
- if (spdata->profile_type && spdata->profile_type != SUBPROF_TYPE_HLL)
- Parrot_ex_throw_from_c_args(interp, NULL, 1,
- "illegal profile type change");
- spdata->profile_type = SUBPROF_TYPE_HLL;
-
while (pc) {
if (pc < code_start || pc >= code_end)
Parrot_ex_throw_from_c_args(interp, NULL, 1,
@@ -1073,18 +1125,18 @@ Registers the subprof_hll runcore with Parrot.
void
Parrot_runcore_subprof_hll_init(PARROT_INTERP)
{
- Parrot_runcore_t * const coredata = mem_gc_allocate_zeroed_typed(interp, Parrot_runcore_t);
+ Parrot_subprof_runcore_t * const coredata = mem_gc_allocate_zeroed_typed(interp, Parrot_subprof_runcore_t);
coredata->name = CONST_STRING(interp, "subprof_hll");
coredata->id = PARROT_SLOW_CORE;
coredata->opinit = PARROT_CORE_OPLIB_INIT;
coredata->runops = runops_subprof_hll_core;
coredata->prepare_run = NULL;
- coredata->destroy = NULL;
+ coredata->destroy = runops_subprof_destroy;
coredata->flags = 0;
PARROT_RUNCORE_FUNC_TABLE_SET(coredata);
- Parrot_runcore_register(interp, coredata);
+ Parrot_runcore_register(interp, (Parrot_runcore_t *)coredata);
}
@@ -1102,19 +1154,14 @@ operations, with sub-level profiling and bounds checking enabled.
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
static opcode_t *
-runops_subprof_ops_core(PARROT_INTERP, SHIM(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
+runops_subprof_ops_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
{
- PMC *ctx, *subpmc;
- subprofiledata *spdata = &_spdata;
+ subprofiledata *spdata = get_subprofiledata(interp, runcore, SUBPROF_TYPE_OPS);
subprofile *sp = spdata->cursp;
+ PMC *ctx, *subpmc;
opcode_t *startop = sp ? sp->code_ops + sp->subattrs->start_offs : 0;
UHUGEINTVAL tick;
- if (spdata->profile_type && spdata->profile_type != SUBPROF_TYPE_OPS)
- Parrot_ex_throw_from_c_args(interp, NULL, 1,
- "illegal profile type change");
- spdata->profile_type = SUBPROF_TYPE_OPS;
-
while (pc) {
if (pc < code_start || pc >= code_end)
Parrot_ex_throw_from_c_args(interp, NULL, 1,
@@ -1170,21 +1217,39 @@ Registers the subprof_ops runcore with Parrot.
void
Parrot_runcore_subprof_ops_init(PARROT_INTERP)
{
- Parrot_runcore_t * const coredata = mem_gc_allocate_zeroed_typed(interp, Parrot_runcore_t);
+ Parrot_subprof_runcore_t * const coredata = mem_gc_allocate_zeroed_typed(interp, Parrot_subprof_runcore_t);
coredata->name = CONST_STRING(interp, "subprof_ops");
coredata->id = PARROT_SLOW_CORE;
coredata->opinit = PARROT_CORE_OPLIB_INIT;
coredata->runops = runops_subprof_ops_core;
coredata->prepare_run = NULL;
- coredata->destroy = NULL;
+ coredata->destroy = runops_subprof_destroy;
coredata->flags = 0;
PARROT_RUNCORE_FUNC_TABLE_SET(coredata);
- Parrot_runcore_register(interp, coredata);
+ Parrot_runcore_register(interp, (Parrot_runcore_t *)coredata);
}
+
+void
+runops_subprof_mark(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
+{
+ Parrot_subprof_runcore_t *core;
+ subprofiledata *spdata;
+
+ if (runcore->destroy != runops_subprof_destroy)
+ return;
+ core = (Parrot_subprof_runcore_t *)runcore;
+ spdata = core->spdata;
+ if (!spdata || !spdata->profile_type || !spdata->sphash)
+ return;
+ Parrot_hash_mark(interp, spdata->sphash);
+}
+
+
+
/*
=back
Please sign in to comment.
Something went wrong with that request. Please try again.