return process(&ev, session);
 }
 
-static void thread__comm_adjust(struct thread *self)
+static void thread__comm_adjust(struct thread *self, struct hists *hists)
 {
        char *comm = self->comm;
 
        if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
            (!symbol_conf.comm_list ||
             strlist__has_entry(symbol_conf.comm_list, comm))) {
-               unsigned int slen = strlen(comm);
+               u16 slen = strlen(comm);
 
-               if (slen > comms__col_width) {
-                       comms__col_width = slen;
-                       threads__col_width = slen + 6;
-               }
+               if (hists__new_col_len(hists, HISTC_COMM, slen))
+                       hists__set_col_len(hists, HISTC_THREAD, slen + 6);
        }
 }
 
-static int thread__set_comm_adjust(struct thread *self, const char *comm)
+static int thread__set_comm_adjust(struct thread *self, const char *comm,
+                                  struct hists *hists)
 {
        int ret = thread__set_comm(self, comm);
 
        if (ret)
                return ret;
 
-       thread__comm_adjust(self);
+       thread__comm_adjust(self, hists);
 
        return 0;
 }
 
        dump_printf(": %s:%d\n", self->comm.comm, self->comm.tid);
 
-       if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm)) {
+       if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm,
+                                                     &session->hists)) {
                dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
                return -1;
        }
                al->sym = NULL;
 }
 
-static void dso__calc_col_width(struct dso *self)
+static void dso__calc_col_width(struct dso *self, struct hists *hists)
 {
        if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
            (!symbol_conf.dso_list ||
             strlist__has_entry(symbol_conf.dso_list, self->name))) {
-               u16 slen = self->short_name_len;
-               if (verbose)
-                       slen = self->long_name_len;
-               if (dsos__col_width < slen)
-                       dsos__col_width = slen;
+               u16 slen = dso__name_len(self);
+               hists__new_col_len(hists, HISTC_DSO, slen);
        }
 
        self->slen_calculated = 1;
                 * sampled.
                 */
                if (!sort_dso.elide && !al->map->dso->slen_calculated)
-                       dso__calc_col_width(al->map->dso);
+                       dso__calc_col_width(al->map->dso, &session->hists);
 
                al->sym = map__find_symbol(al->map, al->addr, filter);
        } else {
                const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
 
-               if (dsos__col_width < unresolved_col_width &&
+               if (hists__col_len(&session->hists, HISTC_DSO) < unresolved_col_width &&
                    !symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
                    !symbol_conf.dso_list)
-                       dsos__col_width = unresolved_col_width;
+                       hists__set_col_len(&session->hists, HISTC_DSO,
+                                          unresolved_col_width);
        }
 
        if (symbol_conf.sym_list && al->sym &&
 
        .min_percent = 0.5
 };
 
+u16 hists__col_len(struct hists *self, enum hist_column col)
+{
+       return self->col_len[col];
+}
+
+void hists__set_col_len(struct hists *self, enum hist_column col, u16 len)
+{
+       self->col_len[col] = len;
+}
+
+bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len)
+{
+       if (len > hists__col_len(self, col)) {
+               hists__set_col_len(self, col, len);
+               return true;
+       }
+       return false;
+}
+
+static void hists__reset_col_len(struct hists *self)
+{
+       enum hist_column col;
+
+       for (col = 0; col < HISTC_NR_COLS; ++col)
+               hists__set_col_len(self, col, 0);
+}
+
+static void hists__calc_col_len(struct hists *self, struct hist_entry *h)
+{
+       u16 len;
+
+       if (h->ms.sym)
+               hists__new_col_len(self, HISTC_SYMBOL, h->ms.sym->namelen);
+
+       len = thread__comm_len(h->thread);
+       if (hists__new_col_len(self, HISTC_COMM, len))
+               hists__set_col_len(self, HISTC_THREAD, len + 6);
+
+       if (h->ms.map) {
+               len = dso__name_len(h->ms.map->dso);
+               hists__new_col_len(self, HISTC_DSO, len);
+       }
+}
+
 static void hist_entry__add_cpumode_period(struct hist_entry *self,
                                           unsigned int cpumode, u64 period)
 {
        return self;
 }
 
-static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry)
+static void hists__inc_nr_entries(struct hists *self, struct hist_entry *h)
 {
-       if (entry->filtered)
-               return;
-       if (entry->ms.sym && self->max_sym_namelen < entry->ms.sym->namelen)
-               self->max_sym_namelen = entry->ms.sym->namelen;
-       ++self->nr_entries;
+       if (!h->filtered) {
+               hists__calc_col_len(self, h);
+               ++self->nr_entries;
+       }
 }
 
 static u8 symbol__parent_filter(const struct symbol *parent)
        tmp = RB_ROOT;
        next = rb_first(&self->entries);
        self->nr_entries = 0;
-       self->max_sym_namelen = 0;
+       hists__reset_col_len(self);
 
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
        next = rb_first(&self->entries);
 
        self->nr_entries = 0;
-       self->max_sym_namelen = 0;
+       hists__reset_col_len(self);
 
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
 }
 
 int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
-                        struct hists *pair_hists, bool show_displacement,
-                        long displacement, bool color, u64 session_total)
+                        struct hists *hists, struct hists *pair_hists,
+                        bool show_displacement, long displacement,
+                        bool color, u64 session_total)
 {
        struct sort_entry *se;
        u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
 
                ret += snprintf(s + ret, size - ret, "%s", sep ?: "  ");
                ret += se->se_snprintf(self, s + ret, size - ret,
-                                      se->se_width ? *se->se_width : 0);
+                                      hists__col_len(hists, se->se_width_idx));
        }
 
        return ret;
 }
 
-int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
-                       bool show_displacement, long displacement, FILE *fp,
-                       u64 session_total)
+int hist_entry__fprintf(struct hist_entry *self, struct hists *hists,
+                       struct hists *pair_hists, bool show_displacement,
+                       long displacement, FILE *fp, u64 session_total)
 {
        char bf[512];
-       hist_entry__snprintf(self, bf, sizeof(bf), pair_hists,
+       hist_entry__snprintf(self, bf, sizeof(bf), hists, pair_hists,
                             show_displacement, displacement,
                             true, session_total);
        return fprintf(fp, "%s\n", bf);
 }
 
-static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
+static size_t hist_entry__fprintf_callchain(struct hist_entry *self,
+                                           struct hists *hists, FILE *fp,
                                            u64 session_total)
 {
        int left_margin = 0;
        if (sort__first_dimension == SORT_COMM) {
                struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
                                                         typeof(*se), list);
-               left_margin = se->se_width ? *se->se_width : 0;
+               left_margin = hists__col_len(hists, se->se_width_idx);
                left_margin -= thread__comm_len(self->thread);
        }
 
                        continue;
                }
                width = strlen(se->se_header);
-               if (se->se_width) {
-                       if (symbol_conf.col_width_list_str) {
-                               if (col_width) {
-                                       *se->se_width = atoi(col_width);
-                                       col_width = strchr(col_width, ',');
-                                       if (col_width)
-                                               ++col_width;
-                               }
+               if (symbol_conf.col_width_list_str) {
+                       if (col_width) {
+                               hists__set_col_len(self, se->se_width_idx,
+                                                  atoi(col_width));
+                               col_width = strchr(col_width, ',');
+                               if (col_width)
+                                       ++col_width;
                        }
-                       width = *se->se_width = max(*se->se_width, width);
                }
+               if (!hists__new_col_len(self, se->se_width_idx, width))
+                       width = hists__col_len(self, se->se_width_idx);
                fprintf(fp, "  %*s", width, se->se_header);
        }
        fprintf(fp, "\n");
                        continue;
 
                fprintf(fp, "  ");
-               if (se->se_width)
-                       width = *se->se_width;
-               else
+               width = hists__col_len(self, se->se_width_idx);
+               if (width == 0)
                        width = strlen(se->se_header);
                for (i = 0; i < width; i++)
                        fprintf(fp, ".");
                                displacement = 0;
                        ++position;
                }
-               ret += hist_entry__fprintf(h, pair, show_displacement,
+               ret += hist_entry__fprintf(h, self, pair, show_displacement,
                                           displacement, fp, self->stats.total_period);
 
                if (symbol_conf.use_callchain)
-                       ret += hist_entry__fprintf_callchain(h, fp, self->stats.total_period);
-
+                       ret += hist_entry__fprintf_callchain(h, self, fp,
+                                                            self->stats.total_period);
                if (h->ms.map == NULL && verbose > 1) {
                        __map_groups__fprintf_maps(&h->thread->mg,
                                                   MAP__FUNCTION, verbose, fp);
        self->stats.total_period += h->period;
        self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
 
-       if (h->ms.sym && self->max_sym_namelen < h->ms.sym->namelen)
-               self->max_sym_namelen = h->ms.sym->namelen;
+       hists__calc_col_len(self, h);
 }
 
 void hists__filter_by_dso(struct hists *self, const struct dso *dso)
 
        self->nr_entries = self->stats.total_period = 0;
        self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
-       self->max_sym_namelen = 0;
+       hists__reset_col_len(self);
 
        for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
 
        self->nr_entries = self->stats.total_period = 0;
        self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
-       self->max_sym_namelen = 0;
+       hists__reset_col_len(self);
 
        for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
 
        u32 nr_unknown_events;
 };
 
+enum hist_column {
+       HISTC_SYMBOL,
+       HISTC_DSO,
+       HISTC_THREAD,
+       HISTC_COMM,
+       HISTC_PARENT,
+       HISTC_CPU,
+       HISTC_NR_COLS, /* Last entry */
+};
+
 struct hists {
        struct rb_node          rb_node;
        struct rb_root          entries;
        u64                     config;
        u64                     event_stream;
        u32                     type;
-       u32                     max_sym_namelen;
+       u16                     col_len[HISTC_NR_COLS];
 };
 
 struct hist_entry *__hists__add_entry(struct hists *self,
                                      struct symbol *parent, u64 period);
 extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
 extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
-int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
-                       bool show_displacement, long displacement, FILE *fp,
-                       u64 total);
+int hist_entry__fprintf(struct hist_entry *self, struct hists *hists,
+                       struct hists *pair_hists, bool show_displacement,
+                       long displacement, FILE *fp, u64 total);
 int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
-                        struct hists *pair_hists, bool show_displacement,
-                        long displacement, bool color, u64 total);
+                        struct hists *hists, struct hists *pair_hists,
+                        bool show_displacement, long displacement,
+                        bool color, u64 total);
 void hist_entry__free(struct hist_entry *);
 
 void hists__output_resort(struct hists *self);
 void hists__filter_by_dso(struct hists *self, const struct dso *dso);
 void hists__filter_by_thread(struct hists *self, const struct thread *thread);
 
+u16 hists__col_len(struct hists *self, enum hist_column col);
+void hists__set_col_len(struct hists *self, enum hist_column col, u16 len);
+bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len);
+
 #ifdef NO_NEWT_SUPPORT
 static inline int hists__browse(struct hists *self __used,
                                const char *helpline __used,
 
 }
 
 static size_t hist_entry__append_browser(struct hist_entry *self,
-                                        newtComponent tree, u64 total)
+                                        newtComponent tree,
+                                        struct hists *hists)
 {
        char s[256];
        size_t ret;
        if (symbol_conf.exclude_other && !self->parent)
                return 0;
 
-       ret = hist_entry__snprintf(self, s, sizeof(s), NULL,
-                                  false, 0, false, total);
+       ret = hist_entry__snprintf(self, s, sizeof(s), hists, NULL,
+                                  false, 0, false, hists->stats.total_period);
        if (symbol_conf.use_callchain) {
                int indexes[2];
 
                if (h->filtered)
                        continue;
 
-               len = hist_entry__append_browser(h, self->tree, hists->stats.total_period);
+               len = hist_entry__append_browser(h, self->tree, hists);
                if (len > max_len)
                        max_len = len;
                if (symbol_conf.use_callchain)
 
 #include "sort.h"
+#include "hist.h"
 
 regex_t                parent_regex;
 const char     default_parent_pattern[] = "^sys_|^do_page_fault";
 
 enum sort_type sort__first_dimension;
 
-unsigned int dsos__col_width;
-unsigned int comms__col_width;
-unsigned int threads__col_width;
-unsigned int cpus__col_width;
-static unsigned int parent_symbol__col_width;
 char * field_sep;
 
 LIST_HEAD(hist_entry__sort_list);
        .se_header      = "Command:  Pid",
        .se_cmp         = sort__thread_cmp,
        .se_snprintf    = hist_entry__thread_snprintf,
-       .se_width       = &threads__col_width,
+       .se_width_idx   = HISTC_THREAD,
 };
 
 struct sort_entry sort_comm = {
        .se_cmp         = sort__comm_cmp,
        .se_collapse    = sort__comm_collapse,
        .se_snprintf    = hist_entry__comm_snprintf,
-       .se_width       = &comms__col_width,
+       .se_width_idx   = HISTC_COMM,
 };
 
 struct sort_entry sort_dso = {
        .se_header      = "Shared Object",
        .se_cmp         = sort__dso_cmp,
        .se_snprintf    = hist_entry__dso_snprintf,
-       .se_width       = &dsos__col_width,
+       .se_width_idx   = HISTC_DSO,
 };
 
 struct sort_entry sort_sym = {
        .se_header      = "Symbol",
        .se_cmp         = sort__sym_cmp,
        .se_snprintf    = hist_entry__sym_snprintf,
+       .se_width_idx   = HISTC_SYMBOL,
 };
 
 struct sort_entry sort_parent = {
        .se_header      = "Parent symbol",
        .se_cmp         = sort__parent_cmp,
        .se_snprintf    = hist_entry__parent_snprintf,
-       .se_width       = &parent_symbol__col_width,
+       .se_width_idx   = HISTC_PARENT,
 };
  
 struct sort_entry sort_cpu = {
        .se_header      = "CPU",
        .se_cmp         = sort__cpu_cmp,
        .se_snprintf    = hist_entry__cpu_snprintf,
-       .se_width       = &cpus__col_width,
+       .se_width_idx   = HISTC_CPU,
 };
 
 struct sort_dimension {
 
 extern struct sort_entry sort_dso;
 extern struct sort_entry sort_sym;
 extern struct sort_entry sort_parent;
-extern unsigned int dsos__col_width;
-extern unsigned int comms__col_width;
-extern unsigned int threads__col_width;
-extern unsigned int cpus__col_width;
 extern enum sort_type sort__first_dimension;
 
 struct hist_entry {
        int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
        int     (*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
                               unsigned int width);
-       unsigned int *se_width;
+       u8      se_width_idx;
        bool    elide;
 };
 
 
 #include <fcntl.h>
 #include <unistd.h>
 #include "build-id.h"
+#include "debug.h"
 #include "symbol.h"
 #include "strlist.h"
 
        .try_vmlinux_path = true,
 };
 
+int dso__name_len(const struct dso *self)
+{
+       if (verbose)
+               return self->long_name_len;
+
+       return self->short_name_len;
+}
+
 bool dso__loaded(const struct dso *self, enum map_type type)
 {
        return self->loaded & (1 << type);
 
 struct dso *dso__new_kernel(const char *name);
 void dso__delete(struct dso *self);
 
+int dso__name_len(const struct dso *self);
+
 bool dso__loaded(const struct dso *self, enum map_type type);
 bool dso__sorted_by_name(const struct dso *self, enum map_type type);