return 0;
 }
 
+static void *hist_entry__zalloc(size_t size)
+{
+       return zalloc(size + sizeof(struct hist_entry));
+}
+
+static void hist_entry__free(void *ptr)
+{
+       free(ptr);
+}
+
+static struct hist_entry_ops default_ops = {
+       .new    = hist_entry__zalloc,
+       .free   = hist_entry__free,
+};
+
 static struct hist_entry *hist_entry__new(struct hist_entry *template,
                                          bool sample_self)
 {
+       struct hist_entry_ops *ops = template->ops;
        size_t callchain_size = 0;
        struct hist_entry *he;
        int err = 0;
 
+       if (!ops)
+               ops = template->ops = &default_ops;
+
        if (symbol_conf.use_callchain)
                callchain_size = sizeof(struct callchain_root);
 
-       he = zalloc(sizeof(*he) + callchain_size);
+       he = ops->new(callchain_size);
        if (he) {
                err = hist_entry__init(he, template, sample_self);
-               if (err)
-                       zfree(&he);
+               if (err) {
+                       ops->free(he);
+                       he = NULL;
+               }
        }
 
        return he;
 
 void hist_entry__delete(struct hist_entry *he)
 {
+       struct hist_entry_ops *ops = he->ops;
+
        thread__zput(he->thread);
        map__zput(he->ms.map);
 
        free_callchain(he->callchain);
        free(he->trace_output);
        free(he->raw_data);
-       free(he);
+       ops->free(he);
 }
 
 /*
 
        };
 };
 
+struct hist_entry_ops {
+       void    *(*new)(size_t size);
+       void    (*free)(void *ptr);
+};
+
 /**
  * struct hist_entry - histogram entry
  *
        void                    *trace_output;
        struct perf_hpp_list    *hpp_list;
        struct hist_entry       *parent_he;
+       struct hist_entry_ops   *ops;
        union {
                /* this is for hierarchical entry structure */
                struct {