[svn:parrot] r44071 - in trunk: include/parrot src/runcore
cotto at svn.parrot.org
cotto at svn.parrot.org
Wed Feb 17 07:41:56 UTC 2010
Author: cotto
Date: Wed Feb 17 07:41:56 2010
New Revision: 44071
URL: https://trac.parrot.org/parrot/changeset/44071
Log:
[profiling] break some repeated code into a separate function and attempt some general cleanup
Modified:
trunk/include/parrot/runcore_profiling.h
trunk/src/runcore/profiling.c
Modified: trunk/include/parrot/runcore_profiling.h
==============================================================================
--- trunk/include/parrot/runcore_profiling.h Wed Feb 17 07:20:56 2010 (r44070)
+++ trunk/include/parrot/runcore_profiling.h Wed Feb 17 07:41:56 2010 (r44071)
@@ -40,7 +40,7 @@
PPROF_LINE_END_OF_RUNLOOP
} Parrot_profiling_line;
-typedef void (*profiling_output_fn)(ARGIN(Parrot_profiling_runcore_t*), ARGIN_NULLOK(Parrot_profiling_line));
+typedef void (*profiling_output_fn)(ARGIN(Parrot_profiling_runcore_t*), ARGIN(PPROF_DATA*), ARGIN_NULLOK(Parrot_profiling_line));
typedef profiling_output_fn Parrot_profiling_output_fn;
typedef enum Parrot_profiling_datatype {
@@ -92,7 +92,6 @@
UINTVAL time_size; /* how big is the following array */
UHUGEINTVAL *time; /* time spent between DO_OP and start/end of a runcore */
Hash *line_cache; /* hash for caching pc -> line mapping */
- PPROF_DATA pprof_data[PPROF_DATA_MAX+1]; /* array for storage of one line of profiling data */
};
#define Profiling_flag_SET(runcore, flag) \
Modified: trunk/src/runcore/profiling.c
==============================================================================
--- trunk/src/runcore/profiling.c Wed Feb 17 07:20:56 2010 (r44070)
+++ trunk/src/runcore/profiling.c Wed Feb 17 07:41:56 2010 (r44071)
@@ -34,7 +34,7 @@
#endif
#define PPROF_VERSION 2
-#define MAX_NAMESPACE_DEPTH 32
+#define MAX_NS_DEPTH 32
#define code_start interp->code->base.data
#define code_end (interp->code->base.data + interp->code->base.size)
@@ -44,6 +44,10 @@
/* HEADERIZER BEGIN: static */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+static void add_bogus_parent_runloop(
+ ARGIN(Parrot_profiling_runcore_t * runcore))
+ __attribute__nonnull__(1);
+
PARROT_CAN_RETURN_NULL
static void * init_profiling_core(PARROT_INTERP,
ARGIN(Parrot_profiling_runcore_t *runcore),
@@ -54,13 +58,17 @@
static void record_values_ascii_pprof(
ARGIN(Parrot_profiling_runcore_t * runcore),
+ ARGIN(PPROF_DATA *pprof_data),
ARGIN_NULLOK(Parrot_profiling_line type))
- __attribute__nonnull__(1);
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
static void record_values_none(
ARGIN(Parrot_profiling_runcore_t * runcore),
+ ARGIN(PPROF_DATA *pprof_data),
ARGIN_NULLOK(Parrot_profiling_line type))
- __attribute__nonnull__(1);
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
@@ -71,14 +79,18 @@
__attribute__nonnull__(2)
__attribute__nonnull__(3);
+#define ASSERT_ARGS_add_bogus_parent_runloop __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(runcore))
#define ASSERT_ARGS_init_profiling_core __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(runcore) \
, PARROT_ASSERT_ARG(pc))
#define ASSERT_ARGS_record_values_ascii_pprof __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(runcore))
+ PARROT_ASSERT_ARG(runcore) \
+ , PARROT_ASSERT_ARG(pprof_data))
#define ASSERT_ARGS_record_values_none __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(runcore))
+ PARROT_ASSERT_ARG(runcore) \
+ , PARROT_ASSERT_ARG(pprof_data))
#define ASSERT_ARGS_runops_profiling_core __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(runcore) \
@@ -148,8 +160,7 @@
runcore->level = 0;
runcore->time_size = 32;
runcore->line_cache = parrot_new_pointer_hash(interp);
- runcore->time = mem_allocate_n_typed(runcore->time_size,
- UHUGEINTVAL);
+ runcore->time = mem_allocate_n_typed(runcore->time_size, UHUGEINTVAL);
/* figure out what format the output should be in */
output_cstr = Parrot_getenv(interp, CONST_STRING(interp, "PARROT_PROFILING_OUTPUT"));
@@ -250,10 +261,10 @@
{
ASSERT_ARGS(runops_profiling_core)
- PMC *preop_sub, *argv;
- opcode_t *preop_pc;
- STRING *unknown_file = CONST_STRING(interp, "<unknown file>");
- UHUGEINTVAL op_time;
+ PMC *argv;
+ opcode_t *preop_pc;
+ UHUGEINTVAL op_time;
+ PPROF_DATA pprof_data[PPROF_DATA_MAX + 1];
runcore->runcore_start = Parrot_hires_get_time();
@@ -262,9 +273,7 @@
if (runcore->level >= runcore->time_size) {
runcore->time_size *= 2;
- runcore->time =
- mem_realloc_n_typed(runcore->time, runcore->time_size + 1,
- UHUGEINTVAL);
+ runcore->time = mem_realloc_n_typed(runcore->time, runcore->time_size + 1, UHUGEINTVAL);
}
/* store the time between DO_OP and the start of this runcore in this
@@ -278,22 +287,19 @@
/* argv isn't initialized until after :init (etc) subs are executed */
if (argv && !Profiling_have_printed_cli_TEST(runcore)) {
- PMC *iglobals = interp->iglobals;
- PMC *executable = VTABLE_get_pmc_keyed_int(interp, iglobals,
- IGLOBALS_EXECUTABLE);
- STRING *space = CONST_STRING(interp, " ");
- STRING *cli_args = Parrot_str_join(interp, space, argv);
- STRING *cli_str;
char *cli_cstr;
+ STRING *space, *cli_args, *cli_exe, *cli_str;
+ PMC *exe_name = VTABLE_get_pmc_keyed_int(interp, interp->iglobals, IGLOBALS_EXECUTABLE);
- cli_str = Parrot_str_concat(interp, VTABLE_get_string(interp,
- executable), space, 0);
- cli_str = Parrot_str_concat(interp, cli_str, cli_args, 0);
+ space = CONST_STRING(interp, " ");
+ cli_args = Parrot_str_join(interp, space, argv);
+ cli_exe = VTABLE_get_string(interp, exe_name);
+ cli_str = Parrot_sprintf_c(interp, "%Ss %Ss", cli_exe, cli_args);
cli_cstr = Parrot_str_to_cstring(interp, cli_str);
/* CLI line won't reflect any options passed to the parrot binary. */
- runcore->pprof_data[PPROF_DATA_CLI] = (PPROF_DATA) cli_cstr;
- runcore->output_fn(runcore, PPROF_LINE_CLI);
+ pprof_data[PPROF_DATA_CLI] = (PPROF_DATA) cli_cstr;
+ runcore->output_fn(runcore, pprof_data, PPROF_LINE_CLI);
Parrot_str_free_cstring(cli_cstr);
@@ -302,23 +308,12 @@
if (Profiling_first_loop_TEST(runcore)) {
- runcore->pprof_data[PPROF_DATA_VERSION] = (PPROF_DATA) PPROF_VERSION;
- runcore->output_fn(runcore, PPROF_LINE_VERSION);
+ Profiling_first_loop_CLEAR(runcore);
- /* make all separate runloops appear to come from a single source */
- runcore->pprof_data[PPROF_DATA_NAMESPACE] = (PPROF_DATA) "main";
- runcore->pprof_data[PPROF_DATA_FILENAME] = (PPROF_DATA) "no_file";
- runcore->pprof_data[PPROF_DATA_SUB_ADDR] = 1;
- runcore->pprof_data[PPROF_DATA_CTX_ADDR] = 1;
- runcore->output_fn(runcore, PPROF_LINE_CONTEXT_SWITCH);
-
- runcore->pprof_data[PPROF_DATA_LINE] = runcore->runloop_count;
- runcore->pprof_data[PPROF_DATA_TIME] = 0;
- runcore->pprof_data[PPROF_DATA_OPNAME] = (PPROF_DATA) "noop";
- runcore->output_fn(runcore, PPROF_LINE_OP);
+ pprof_data[PPROF_DATA_VERSION] = (PPROF_DATA) PPROF_VERSION;
+ runcore->output_fn(runcore, pprof_data, PPROF_LINE_VERSION);
- runcore->runloop_count++;
- Profiling_first_loop_CLEAR(runcore);
+ add_bogus_parent_runloop(runcore);
}
while (pc) {
@@ -333,7 +328,6 @@
preop_ctx_pmc = CURRENT_CONTEXT(interp);
preop_ctx = PMC_data_typed(preop_ctx_pmc, Parrot_Context*);
preop_ctx->current_pc = pc;
- preop_sub = preop_ctx->current_sub;
preop_pc = pc;
runcore->level++;
@@ -363,7 +357,7 @@
if (preop_ctx->current_sub) {
STRING *sub_name, *full_ns, *ns_separator, *preop_filename;
char *full_ns_cstr, *filename_cstr;
- STRING *ns_names[MAX_NAMESPACE_DEPTH];
+ STRING *ns_names[MAX_NS_DEPTH];
PMC *ns = preop_ctx->current_namespace;
INTVAL i;
@@ -376,7 +370,7 @@
full_ns = Parrot_str_new(interp, "", 0);
ns_separator = Parrot_str_new(interp, ";", 1);
- i = MAX_NAMESPACE_DEPTH - 1;
+ i = MAX_NS_DEPTH - 1;
for (;ns ; i--) {
if (i < 0) {
/* should probably warn about truncated namespace here */
@@ -388,7 +382,7 @@
i++;
i++; /* the root namespace has an empty name, so ignore it */
- for (;i < MAX_NAMESPACE_DEPTH; i++) {
+ for (;i < MAX_NS_DEPTH; i++) {
full_ns = Parrot_str_concat(interp, full_ns, ns_names[i], 0);
full_ns = Parrot_str_concat(interp, full_ns, ns_separator, 0);
}
@@ -397,11 +391,11 @@
full_ns = Parrot_str_concat(interp, full_ns, sub_name, 0);
full_ns_cstr = Parrot_str_to_cstring(interp, full_ns);
- runcore->pprof_data[PPROF_DATA_NAMESPACE] = (PPROF_DATA) full_ns_cstr;
- runcore->pprof_data[PPROF_DATA_FILENAME] = (PPROF_DATA) filename_cstr;
- runcore->pprof_data[PPROF_DATA_SUB_ADDR] = (PPROF_DATA) preop_ctx->current_sub;
- runcore->pprof_data[PPROF_DATA_CTX_ADDR] = (PPROF_DATA) preop_ctx;
- runcore->output_fn(runcore, PPROF_LINE_CONTEXT_SWITCH);
+ pprof_data[PPROF_DATA_NAMESPACE] = (PPROF_DATA) full_ns_cstr;
+ pprof_data[PPROF_DATA_FILENAME] = (PPROF_DATA) filename_cstr;
+ pprof_data[PPROF_DATA_SUB_ADDR] = (PPROF_DATA) preop_ctx->current_sub;
+ pprof_data[PPROF_DATA_CTX_ADDR] = (PPROF_DATA) preop_ctx;
+ runcore->output_fn(runcore, pprof_data, PPROF_LINE_CONTEXT_SWITCH);
Parrot_str_free_cstring(full_ns_cstr);
Parrot_str_free_cstring(filename_cstr);
@@ -429,7 +423,6 @@
if (!PMC_IS_NULL(annot)) {
- /* this is probably pessimal but it's just a poc at this point */
PMC *iter = VTABLE_get_iter(interp, annot);
while (VTABLE_get_bool(interp, iter)) {
@@ -438,9 +431,9 @@
char *key_cstr = Parrot_str_to_cstring(interp, key);
char *val_cstr = Parrot_str_to_cstring(interp, val);
- runcore->pprof_data[PPROF_DATA_ANNOTATION_NAME] = (PPROF_DATA) key_cstr;
- runcore->pprof_data[PPROF_DATA_ANNOTATION_VALUE] = (PPROF_DATA) val_cstr;
- runcore->output_fn(runcore, PPROF_LINE_ANNOTATION);
+ pprof_data[PPROF_DATA_ANNOTATION_NAME] = (PPROF_DATA) key_cstr;
+ pprof_data[PPROF_DATA_ANNOTATION_VALUE] = (PPROF_DATA) val_cstr;
+ runcore->output_fn(runcore, pprof_data, PPROF_LINE_ANNOTATION);
Parrot_str_free_cstring(key_cstr);
Parrot_str_free_cstring(val_cstr);
@@ -448,30 +441,18 @@
}
}
- runcore->pprof_data[PPROF_DATA_LINE] = preop_line;
- runcore->pprof_data[PPROF_DATA_TIME] = op_time;
- runcore->pprof_data[PPROF_DATA_OPNAME] =
- (PPROF_DATA)(interp->op_info_table)[*preop_pc].name;
- runcore->output_fn(runcore, PPROF_LINE_OP);
+ pprof_data[PPROF_DATA_LINE] = preop_line;
+ pprof_data[PPROF_DATA_TIME] = op_time;
+ pprof_data[PPROF_DATA_OPNAME] = (PPROF_DATA)(interp->op_info_table)[*preop_pc].name;
+ runcore->output_fn(runcore, pprof_data, PPROF_LINE_OP);
}
/* make it easy to tell separate runloops apart */
if (runcore->level == 0) {
- runcore->output_fn(runcore, PPROF_LINE_END_OF_RUNLOOP);
- /* make all separate runloops appear to come from a single source */
- runcore->pprof_data[PPROF_DATA_NAMESPACE] = (PPROF_DATA) "main";
- runcore->pprof_data[PPROF_DATA_FILENAME] = (PPROF_DATA) "no_file";
- runcore->pprof_data[PPROF_DATA_SUB_ADDR] = 1;
- runcore->pprof_data[PPROF_DATA_CTX_ADDR] = 1;
- runcore->output_fn(runcore, PPROF_LINE_CONTEXT_SWITCH);
-
- runcore->pprof_data[PPROF_DATA_LINE] = runcore->runloop_count;
- runcore->pprof_data[PPROF_DATA_TIME] = 0;
- runcore->pprof_data[PPROF_DATA_OPNAME] = (PPROF_DATA) "noop";
- runcore->output_fn(runcore, PPROF_LINE_OP);
+ runcore->output_fn(runcore, pprof_data, PPROF_LINE_END_OF_RUNLOOP);
- runcore->runloop_count++;
+ add_bogus_parent_runloop(runcore);
}
Profiling_exit_check_SET(runcore);
@@ -481,8 +462,45 @@
/*
+=item C<static void add_bogus_parent_runloop(Parrot_profiling_runcore_t *
+runcore)>
+
+Record profiling information for a bogus parent runloop. Parrot program
+generally have several runloops, so a little trickery is needed to profile them
+all as a single program. This is accomplished by having a fake sub named
+'main' which has no cost in itself but which appears to call all top-level
+runloops as children.
+
+=cut
+
+*/
+
+static void
+add_bogus_parent_runloop(ARGIN(Parrot_profiling_runcore_t * runcore))
+{
+ ASSERT_ARGS(add_bogus_parent_runloop)
+
+ PPROF_DATA pprof_data[PPROF_DATA_MAX+1];
+
+ /* make all separate runloops appear to come from a single source */
+ pprof_data[PPROF_DATA_NAMESPACE] = (PPROF_DATA) "main";
+ pprof_data[PPROF_DATA_FILENAME] = (PPROF_DATA) "no_file";
+ pprof_data[PPROF_DATA_SUB_ADDR] = 1;
+ pprof_data[PPROF_DATA_CTX_ADDR] = 1;
+ runcore->output_fn(runcore, pprof_data, PPROF_LINE_CONTEXT_SWITCH);
+
+ pprof_data[PPROF_DATA_LINE] = runcore->runloop_count;
+ pprof_data[PPROF_DATA_TIME] = 0;
+ pprof_data[PPROF_DATA_OPNAME] = (PPROF_DATA) "noop";
+ runcore->output_fn(runcore, pprof_data, PPROF_LINE_OP);
+
+ runcore->runloop_count++;
+}
+
+/*
+
=item C<static void record_values_ascii_pprof(Parrot_profiling_runcore_t *
-runcore, Parrot_profiling_line type)>
+runcore, PPROF_DATA *pprof_data, Parrot_profiling_line type)>
Record profiling data to a filehandle in a human-readable format.
@@ -492,17 +510,17 @@
static void
record_values_ascii_pprof(ARGIN(Parrot_profiling_runcore_t * runcore),
-ARGIN_NULLOK(Parrot_profiling_line type))
+ARGIN(PPROF_DATA *pprof_data), ARGIN_NULLOK(Parrot_profiling_line type))
{
ASSERT_ARGS(record_values_ascii_pprof)
switch (type) {
case PPROF_LINE_CONTEXT_SWITCH:
{
- char *pd_namespace = (char *) runcore->pprof_data[PPROF_DATA_NAMESPACE];
- char *pd_filename = (char *) runcore->pprof_data[PPROF_DATA_FILENAME];
- void *sub_addr = (void *) runcore->pprof_data[PPROF_DATA_SUB_ADDR];
- void *ctx_addr = (void *) runcore->pprof_data[PPROF_DATA_CTX_ADDR];
+ char *pd_namespace = (char *) pprof_data[PPROF_DATA_NAMESPACE];
+ char *pd_filename = (char *) pprof_data[PPROF_DATA_FILENAME];
+ void *sub_addr = (void *) pprof_data[PPROF_DATA_SUB_ADDR];
+ void *ctx_addr = (void *) pprof_data[PPROF_DATA_CTX_ADDR];
fprintf(runcore->profile_fd,
"CS:{x{ns:%s}x}{x{file:%s}x}{x{sub:%p}x}{x{ctx:%p}x}\n",
pd_namespace, pd_filename, sub_addr, ctx_addr);
@@ -511,9 +529,9 @@
case PPROF_LINE_OP:
{
- PPROF_DATA line = (PPROF_DATA) runcore->pprof_data[PPROF_DATA_LINE];
- PPROF_DATA time = (PPROF_DATA) runcore->pprof_data[PPROF_DATA_TIME];
- char *opname = (char *) runcore->pprof_data[PPROF_DATA_OPNAME];
+ PPROF_DATA line = (PPROF_DATA) pprof_data[PPROF_DATA_LINE];
+ PPROF_DATA time = (PPROF_DATA) pprof_data[PPROF_DATA_TIME];
+ char *opname = (char *) pprof_data[PPROF_DATA_OPNAME];
fprintf(runcore->profile_fd, "OP:{x{line:%d}x}{x{time:%d}x}{x{op:%s}x}\n",
(int) line, (int) time, opname);
}
@@ -521,21 +539,17 @@
case PPROF_LINE_ANNOTATION:
{
- char *name = (char *) runcore->pprof_data[PPROF_DATA_ANNOTATION_NAME];
- char *value = (char *) runcore->pprof_data[PPROF_DATA_ANNOTATION_VALUE];
+ char *name = (char *) pprof_data[PPROF_DATA_ANNOTATION_NAME];
+ char *value = (char *) pprof_data[PPROF_DATA_ANNOTATION_VALUE];
fprintf(runcore->profile_fd, "AN:{x{name:%s}x}{x{value:%s}x}\n", name, value);
}
case PPROF_LINE_CLI:
- {
- char *cli = (char *) runcore->pprof_data[PPROF_DATA_CLI];
- fprintf(runcore->profile_fd, "CLI: %s\n", cli);
- }
+ fprintf(runcore->profile_fd, "CLI: %s\n", (char *) pprof_data[PPROF_DATA_CLI]);
break;
case PPROF_LINE_VERSION:
- fprintf(runcore->profile_fd, "VERSION:%d\n",
- (int) runcore->pprof_data[PPROF_DATA_VERSION]);
+ fprintf(runcore->profile_fd, "VERSION:%d\n", (int) pprof_data[PPROF_DATA_VERSION]);
break;
case PPROF_LINE_END_OF_RUNLOOP:
@@ -550,7 +564,7 @@
/*
=item C<static void record_values_none(Parrot_profiling_runcore_t * runcore,
-Parrot_profiling_line type)>
+PPROF_DATA *pprof_data, Parrot_profiling_line type)>
Accept data but don't actually write it anywhere.
@@ -560,10 +574,11 @@
static void
record_values_none(ARGIN(Parrot_profiling_runcore_t * runcore),
-ARGIN_NULLOK(Parrot_profiling_line type))
+ARGIN(PPROF_DATA *pprof_data), ARGIN_NULLOK(Parrot_profiling_line type))
{
ASSERT_ARGS(record_values_none)
UNUSED(runcore);
+ UNUSED(pprof_data);
UNUSED(type);
}
More information about the parrot-commits
mailing list