1 /* runcore_profiling.h
2  *  Copyright (C) 2001-2012, Parrot Foundation.
3  *  Overview:
4  *     Functions and macros to dispatch opcodes.
5  */
6 
7 #ifndef PARROT_RUNCORE_PROFILING_H_GUARD
8 #define PARROT_RUNCORE_PROFILING_H_GUARD
9 
10 struct         profiling_runcore_t;
11 typedef struct profiling_runcore_t Parrot_profiling_runcore_t;
12 
13 #include "parrot/parrot.h"
14 #include "parrot/op.h"
15 #include "parrot/runcore_api.h"
16 
17 /* make a #define that will hold an INTVAL and a pointer */
18 #if PTR_SIZE == INTVAL_SIZE
19 #  define PPROF_DATA INTVAL
20 #else
21 #  define PPROF_DATA HUGEINTVAL
22 #endif
23 
24 typedef enum Parrot_profiling_flags {
25     PROFILING_EXIT_CHECK_FLAG         = 1 << 0,
26     PROFILING_FIRST_LOOP_FLAG         = 1 << 1,
27     PROFILING_HAVE_PRINTED_CLI_FLAG   = 1 << 2,
28     PROFILING_REPORT_ANNOTATIONS_FLAG = 1 << 3,
29     PROFILING_CANONICAL_OUTPUT_FLAG   = 1 << 4
30 } Parrot_profiling_flags;
31 
32 typedef enum Parrot_profiling_line {
33     PPROF_LINE_CONTEXT_SWITCH,
34     PPROF_LINE_OP,
35     PPROF_LINE_ANNOTATION,
36     PPROF_LINE_VERSION,
37     PPROF_LINE_CLI,
38     PPROF_LINE_END_OF_RUNLOOP
39 } Parrot_profiling_line;
40 
41 typedef void (*profiling_store_fn)  (PARROT_INTERP, ARGIN(Parrot_profiling_runcore_t*),
42                                         ARGIN(PPROF_DATA*), ARGIN_NULLOK(Parrot_profiling_line));
43 typedef void (*profiling_init_fn)   (PARROT_INTERP, ARGIN(Parrot_profiling_runcore_t*));
44 typedef void (*profiling_destroy_fn)(PARROT_INTERP, ARGIN(Parrot_profiling_runcore_t*));
45 
46 #define RUNCORE_init(i, r) \
47     ((r)->output.init    ? (r)->output.init((i), (r))            : (void)NULL)
48 #define RUNCORE_store(i, r, d, l) \
49     ((r)->output.store   ? (r)->output.store((i), (r), (d), (l)) : (void)NULL)
50 #define RUNCORE_destroy(i, r) \
51     ((r)->output.destroy ? (r)->output.destroy((i), (r))         : (void)NULL)
52 
53 typedef enum Parrot_profiling_datatype {
54 
55     /* context switch */
56     PPROF_DATA_NAMESPACE = 0,
57     PPROF_DATA_FILENAME  = 1,
58     PPROF_DATA_SUB_ADDR  = 2,
59     PPROF_DATA_CTX_ADDR  = 3,
60 
61     /* op */
62     PPROF_DATA_LINE   = 0,
63     PPROF_DATA_TIME   = 1,
64     PPROF_DATA_OPNAME = 2,
65 
66     /* annotation */
67     PPROF_DATA_ANNOTATION_NAME  = 0,
68     PPROF_DATA_ANNOTATION_VALUE = 1,
69 
70     PPROF_DATA_VERSION = 0,
71 
72     PPROF_DATA_CLI = 0,
73 
74     PPROF_DATA_MAX = 3
75 } Parrot_profiling_datatype;
76 
77 typedef struct profiling_output_t {
78     profiling_init_fn    init;
79     profiling_store_fn   store;
80     profiling_destroy_fn destroy;
81 } Parrot_profiling_output;
82 
83 struct profiling_runcore_t {
84     STRING                      *name;
85     int                          id;
86     oplib_init_f                 opinit;
87     Parrot_runcore_runops_fn_t   runops;
88     Parrot_runcore_destroy_fn_t  destroy;
89     Parrot_runcore_prepare_fn_t  prepare_run;
90     INTVAL                       flags;
91 
92     /* end of common members */
93     Parrot_profiling_output output;
94     UHUGEINTVAL     runcore_start;
95     UHUGEINTVAL     op_start;
96     UHUGEINTVAL     op_finish;
97     UHUGEINTVAL     runcore_finish;
98     INTVAL          profiling_flags;
99     INTVAL          runloop_count;
100     FILE           *profile_fd;
101     STRING         *profile_filename;
102     PMC            *prev_sub;
103     Parrot_Context *prev_ctx;
104     UINTVAL         time_size;  /* how big is the following array */
105     UHUGEINTVAL    *time;       /* time spent between DO_OP and start/end of a runcore */
106     Hash           *line_cache; /* hash for caching pc -> line mapping */
107 };
108 
109 #define Profiling_flag_SET(runcore, flag) \
110     ((runcore)->profiling_flags |= flag)
111 #define Profiling_flag_TEST(runcore, flag) \
112     ((runcore)->profiling_flags & flag)
113 #define Profiling_flag_CLEAR(runcore, flag) \
114     ((runcore)->profiling_flags &= ~(flag))
115 
116 #define Profiling_exit_check_TEST(o) \
117     Profiling_flag_TEST(o, PROFILING_EXIT_CHECK_FLAG)
118 #define Profiling_exit_check_SET(o) \
119     Profiling_flag_SET(o, PROFILING_EXIT_CHECK_FLAG)
120 #define Profiling_exit_check_CLEAR(o) \
121     Profiling_flag_CLEAR(o, PROFILING_EXIT_CHECK_FLAG)
122 
123 #define Profiling_first_loop_TEST(o) \
124     Profiling_flag_TEST(o, PROFILING_FIRST_LOOP_FLAG)
125 #define Profiling_first_loop_SET(o) \
126     Profiling_flag_SET(o, PROFILING_FIRST_LOOP_FLAG)
127 #define Profiling_first_loop_CLEAR(o) \
128     Profiling_flag_CLEAR(o, PROFILING_FIRST_LOOP_FLAG)
129 
130 #define Profiling_have_printed_cli_TEST(o) \
131     Profiling_flag_TEST(o, PROFILING_HAVE_PRINTED_CLI_FLAG)
132 #define Profiling_have_printed_cli_SET(o) \
133     Profiling_flag_SET(o, PROFILING_HAVE_PRINTED_CLI_FLAG)
134 #define Profiling_have_printed_cli_CLEAR(o) \
135     Profiling_flag_CLEAR(o, PROFILING_HAVE_PRINTED_CLI_FLAG)
136 
137 #define Profiling_report_annotations_TEST(o) \
138     Profiling_flag_TEST(o, PROFILING_REPORT_ANNOTATIONS_FLAG)
139 #define Profiling_report_annotations_SET(o) \
140     Profiling_flag_SET(o, PROFILING_REPORT_ANNOTATIONS_FLAG)
141 #define Profiling_report_annotations_CLEAR(o) \
142     Profiling_flag_CLEAR(o, PROFILING_REPORT_ANNOTATIONS_FLAG)
143 
144 #define Profiling_canonical_output_TEST(o) \
145     Profiling_flag_TEST(o, PROFILING_CANONICAL_OUTPUT_FLAG)
146 #define Profiling_canonical_output_SET(o) \
147     Profiling_flag_SET(o, PROFILING_CANONICAL_OUTPUT_FLAG)
148 #define Profiling_canonical_output_CLEAR(o) \
149     Profiling_flag_CLEAR(o, PROFILING_CANONICAL_OUTPUT_FLAG)
150 
151 /* HEADERIZER BEGIN: src/runcore/profiling.c */
152 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
153 
154 void Parrot_runcore_profiling_init(PARROT_INTERP)
155         __attribute__nonnull__(1);
156 
157 #define ASSERT_ARGS_Parrot_runcore_profiling_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
158        PARROT_ASSERT_ARG(interp))
159 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
160 /* HEADERIZER END: src/runcore/profiling.c */
161 
162 #endif /* PARROT_RUNCORE_PROFILING_H_GUARD */
163 
164 /*
165  * Local variables:
166  *   c-file-style: "parrot"
167  * End:
168  * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
169  */
170