static int process_sample_event(event_t *event, struct perf_session *session)
 {
        struct addr_location al;
+       struct sample_data data;
 
-       dump_printf("(IP, %d): %d: %#Lx\n", event->header.misc,
-                   event->ip.pid, event->ip.ip);
-
-       if (event__preprocess_sample(event, session, &al, NULL) < 0) {
+       if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) {
                pr_warning("problem processing %d event, skipping it.\n",
                           event->header.type);
                return -1;
 
        struct addr_location al;
        struct sample_data data = { .period = 1, };
 
-       dump_printf("(IP, %d): %d: %#Lx\n", event->header.misc,
-                   event->ip.pid, event->ip.ip);
-
-       if (event__preprocess_sample(event, session, &al, NULL) < 0) {
+       if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) {
                pr_warning("problem processing %d event, skipping it.\n",
                           event->header.type);
                return -1;
        if (al.filtered || al.sym == NULL)
                return 0;
 
-       event__parse_sample(event, session->sample_type, &data);
-
        if (hists__add_entry(&session->hists, &al, data.period)) {
                pr_warning("problem incrementing symbol period, skipping event\n");
                return -1;
 
        struct addr_location al;
        struct perf_event_attr *attr;
 
-       event__parse_sample(event, session->sample_type, &data);
-
-       dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld cpu:%d\n",
-                   event->header.misc, data.pid, data.tid, data.ip,
-                   data.period, data.cpu);
-
-       if (session->sample_type & PERF_SAMPLE_CALLCHAIN) {
-               unsigned int i;
-
-               dump_printf("... chain: nr:%Lu\n", data.callchain->nr);
-
-               if (!ip_callchain__valid(data.callchain, event)) {
-                       pr_debug("call-chain problem with event, "
-                                "skipping it.\n");
-                       return 0;
-               }
-
-               if (dump_trace) {
-                       for (i = 0; i < data.callchain->nr; i++)
-                               dump_printf("..... %2d: %016Lx\n",
-                                           i, data.callchain->ips[i]);
-               }
-       }
-
-       if (event__preprocess_sample(event, session, &al, NULL) < 0) {
+       if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) {
                fprintf(stderr, "problem processing %d event, skipping it.\n",
                        event->header.type);
                return -1;
 
        u64 ip = self->ip.ip;
        struct sym_entry *syme;
        struct addr_location al;
+       struct sample_data data;
        struct machine *machine;
        u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 
        if (self->header.misc & PERF_RECORD_MISC_EXACT_IP)
                exact_samples++;
 
-       if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
+       if (event__preprocess_sample(self, session, &al, &data,
+                                    symbol_filter) < 0 ||
            al.filtered)
                return;
 
 
 #include "util.h"
 #include "callchain.h"
 
-bool ip_callchain__valid(struct ip_callchain *chain, event_t *event)
+bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event)
 {
        unsigned int chain_size = event->header.size;
        chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
 
 int append_chain(struct callchain_node *root, struct ip_callchain *chain,
                 struct map_symbol *syms);
 
-bool ip_callchain__valid(struct ip_callchain *chain, event_t *event);
+bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event);
 #endif /* __PERF_CALLCHAIN_H */
 
 }
 
 int event__preprocess_sample(const event_t *self, struct perf_session *session,
-                            struct addr_location *al, symbol_filter_t filter)
+                            struct addr_location *al, struct sample_data *data,
+                            symbol_filter_t filter)
 {
        u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
-       struct thread *thread = perf_session__findnew(session, self->ip.pid);
+       struct thread *thread;
+
+       event__parse_sample(self, session->sample_type, data);
+
+       dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld cpu:%d\n",
+                   self->header.misc, data->pid, data->tid, data->ip,
+                   data->period, data->cpu);
+
+       if (session->sample_type & PERF_SAMPLE_CALLCHAIN) {
+               unsigned int i;
+
+               dump_printf("... chain: nr:%Lu\n", data->callchain->nr);
 
+               if (!ip_callchain__valid(data->callchain, self)) {
+                       pr_debug("call-chain problem with event, "
+                                "skipping it.\n");
+                       goto out_filtered;
+               }
+
+               if (dump_trace) {
+                       for (i = 0; i < data->callchain->nr; i++)
+                               dump_printf("..... %2d: %016Lx\n",
+                                           i, data->callchain->ips[i]);
+               }
+       }
+       thread = perf_session__findnew(session, self->ip.pid);
        if (thread == NULL)
                return -1;
 
        return 0;
 }
 
-int event__parse_sample(event_t *event, u64 type, struct sample_data *data)
+int event__parse_sample(const event_t *event, u64 type, struct sample_data *data)
 {
-       u64 *array = event->sample.array;
+       const u64 *array = event->sample.array;
 
        if (type & PERF_SAMPLE_IP) {
                data->ip = event->ip.ip;
 
 
 struct addr_location;
 int event__preprocess_sample(const event_t *self, struct perf_session *session,
-                            struct addr_location *al, symbol_filter_t filter);
-int event__parse_sample(event_t *event, u64 type, struct sample_data *data);
+                            struct addr_location *al, struct sample_data *data,
+                            symbol_filter_t filter);
+int event__parse_sample(const event_t *event, u64 type, struct sample_data *data);
 
 extern const char *event__name[];