Branch: Tag:

2015-06-04

2015-06-04 15:29:30 by Martin Karlgren <marty@roxen.com>

count_memory: return early when visiting non-internal things and lookahead < 0.

This avoids allocating entries in the mc_marker hash table for each referred
thing of e.g. a mapping or multiset. Seems to improve performance by a factor
8-10 when doing Pike.count_memory (-1, m) where m is a relatively large mapping.

5241:    * recurses through REF_TYPE_INTERNAL references. Note that most    * fields in mc_marker aren't used. */   { -  struct mc_marker *ref_to = find_mc_marker (thing); -  int ref_from_flags; -  +     assert (mc_pass);    assert (mc_lookahead < 0);   #ifdef PIKE_DEBUG    assert (mc_ref_from != (void *) (ptrdiff_t) -1);   #endif    -  +  int ref_from_flags; +     ref_from_flags = mc_ref_from->flags;    assert (ref_from_flags & MC_FLAG_INTERNAL);    assert (!(ref_from_flags & MC_FLAG_INT_VISITED));    -  + #ifndef MEMORY_COUNT_DEBUG +  if (!(ref_type & REF_TYPE_INTERNAL)) { +  /* Return before lookup (or much worse, allocation) in the +  mc_marker hash table. The only reason to allocate a marker in +  this case is, AFAICS, to get the tracing right with +  MEMORY_COUNT_DEBUG enabled. That case is handled below. */ +  return; +  } + #endif +  +  struct mc_marker *ref_to = find_mc_marker (thing); +     if (!ref_to) {    ref_to = my_make_mc_marker (thing, visit_fn, extra);    MC_DEBUG_MSG (ref_to, "got new thing");
5267:    else    MC_DEBUG_MSG (ref_to, "got old thing");    + #ifdef MEMORY_COUNT_DEBUG    if (!(ref_type & REF_TYPE_INTERNAL)) {    MC_DEBUG_MSG (ref_to, "ignored non-internal ref");    return;    } -  + #endif       ref_to->int_refs++;    MC_DEBUG_MSG (ref_to, "added really internal ref");