pike.git / src / gc.c

version» Context lines:

pike.git/src/gc.c:4608:    * we leave MC_PASS_MARK_EXTERNAL, thus we avoid the work to go    * through the externals clear the flag for the next round. */   #define MC_FLAG_EXT_TOGGLE 0x40      /* The value of IS_EXTERNAL is meaningless when MC_FLAG_INTERNAL is set. */   #define IS_EXTERNAL(M) \    (((M)->flags ^ mc_ext_toggle_bias) & MC_FLAG_EXT_TOGGLE)      #define INIT_CLEARED_EXTERNAL(M) do { \    struct mc_marker *_m = (M); \ +  debug_malloc_touch_named(_m, "INIT_CLEARED_EXTERNAL"); \    if (mc_ext_toggle_bias) _m->flags |= MC_FLAG_EXT_TOGGLE; \    } while (0)   #define FLAG_EXTERNAL(M) do { \    struct mc_marker *_m = (M); \ -  +  debug_malloc_touch_named(_m, "FLAG_EXTERNAL"); \    assert (!IS_EXTERNAL (_m)); \    _m->flags ^= MC_FLAG_EXT_TOGGLE; \    } while (0)   #define TOGGLE_EXT_FLAGS() do { \    mc_ext_toggle_bias ^= MC_FLAG_EXT_TOGGLE; \    } while (0)      struct mc_marker   {    struct mc_marker *hash_next; /* Used by PTR_HASH_ALLOC. */
pike.git/src/gc.c:4737:      #define DL_IS_EMPTY(LIST) (LIST.dl_next == &LIST)      #define DL_ADD_LAST(LIST, M) do { \    struct mc_marker *_m = (M); \    struct mc_marker *_list_prev = LIST.dl_prev; \    DO_IF_DEBUG ( \    assert (_m->dl_prev == (void *) (ptrdiff_t) -1); \    assert (_m->dl_next == (void *) (ptrdiff_t) -1); \    ); \ +  debug_malloc_touch_named(_m, "DL_ADD_LAST (_m)"); \ +  debug_malloc_touch_named(_list_prev, "DL_ADD_LAST (_list_prev)"); \    _m->dl_prev = _list_prev; \    _m->dl_next = &LIST; \    LIST.dl_prev = _list_prev->dl_next = _m; \    } while (0)      #define DL_REMOVE(M) do { \    struct mc_marker *_m = (M); \    struct mc_marker *_list_prev = _m->dl_prev; \    struct mc_marker *_list_next = _m->dl_next; \    assert (_m->dl_prev != (void *) (ptrdiff_t) -1); \    assert (_m->dl_next != (void *) (ptrdiff_t) -1); \ -  +  debug_malloc_touch_named(_m, "DL_REMOVE (_m)"); \ +  debug_malloc_touch_named(_list_prev, "DL_REMOVE (_list_prev)"); \ +  debug_malloc_touch_named(_list_next, "DL_REMOVE (_list_next)"); \    _list_prev->dl_next = _list_next; \    _list_next->dl_prev = _list_prev; \    DO_IF_DEBUG (_m->dl_prev = _m->dl_next = (void *) (ptrdiff_t) -1); \    } while (0)      #define DL_MOVE(FROM_LIST, TO_LIST) do { \    if (FROM_LIST.dl_next != &FROM_LIST) { \    struct mc_marker *to_list_last = TO_LIST.dl_prev; \ -  +  debug_malloc_touch_named(&FROM_LIST, "DL_MOVE (FROM_LIST"); \ +  debug_malloc_touch_named(&TO_LIST, "DL_MOVE (TO_LIST)"); \ +  debug_malloc_touch_named(to_list_last, "DL_MOVE (to_list_last)"); \    TO_LIST.dl_prev = FROM_LIST.dl_prev; \    to_list_last->dl_next = FROM_LIST.dl_next; \    FROM_LIST.dl_prev->dl_next = &TO_LIST; \    FROM_LIST.dl_next->dl_prev = to_list_last; \    FROM_LIST.dl_prev = FROM_LIST.dl_next = &FROM_LIST; \    } \    } while (0)      #define DL_MAKE_EMPTY(LIST) do { \    LIST.dl_prev = LIST.dl_next = &LIST; \
pike.git/src/gc.c:4789: Inside #if defined(MEMORY_COUNT_DEBUG)
   else fputs ("[", stderr);    describe_mc_marker (m);    fprintf (stderr, "] %s\n", msg);    }    else if (mc_ref_from != (void *) (ptrdiff_t) -1) {    fputs ("{", stderr);    describe_mc_marker (mc_ref_from);    fprintf (stderr, "} %s\n", msg);    }   } + #define MC_DEBUG_MSG(m, msg) MC_DEBUG_MSG(debug_malloc_pass_named(m, TOSTR(msg)), msg)   #else   #define MC_DEBUG_MSG(m, msg) do {} while (0)   #endif      /* The following is a standard binary heap priority queue implemented    * using an array. C.f. http://www.sbhatnagar.com/SourceCode/pqueue.html. */      /* Note: 1-based indexing is used in mc_work_queue to avoid    * off-by-ones in the binary arithmetic. */   static struct mc_marker **mc_work_queue = NULL;
pike.git/src/gc.c:4835:       if (mc_wq_used == 1) return NULL;       m = mc_work_queue[1];    m->queuepos = MAX_UINT32;       if (--mc_wq_used > 1) {    struct mc_marker *n, *last = mc_work_queue[mc_wq_used];    int last_la_count = last->la_count;    unsigned pos = 1; +  debug_malloc_touch_named(last, "last");       while (pos <= mc_wq_used / 2) {    unsigned child_pos = 2 * pos;       if (child_pos < mc_wq_used &&    mc_work_queue[child_pos]->la_count <    mc_work_queue[child_pos + 1]->la_count)    child_pos++;    if (mc_work_queue[child_pos]->la_count <= last_la_count)    break;    -  +  debug_malloc_touch_named(mc_work_queue[pos], "mc_work_queue[pos]");    n = mc_work_queue[pos] = mc_work_queue[child_pos];    n->queuepos = pos; -  +  debug_malloc_touch_named(n, "n");    pos = child_pos;    }    -  +  debug_malloc_touch_named(mc_work_queue[pos], "mc_work_queue[pos] = last");    mc_work_queue[pos] = last;    last->queuepos = pos;    }       CHECK_WQ();       return m;   }      static void mc_wq_enqueue (struct mc_marker *m)
pike.git/src/gc.c:4902:    move_svalue (&throw_value, --Pike_sp);    mc_wq_size /= 2;    return;    }    mc_work_queue = p;    }    pos = mc_wq_used++;    }       while (pos > 1 && (n = mc_work_queue[pos / 2])->la_count < m_la_count) { +  debug_malloc_touch_named(n, "n"); +  debug_malloc_touch_named(mc_work_queue[pos], "mc_work_queue[pos]");    mc_work_queue[pos] = n;    n->queuepos = pos;    pos /= 2;    } -  +  debug_malloc_touch_named(mc_work_queue[pos], "mc_work_queue[pos] = m"); +  debug_malloc_touch_named(m, "m");    mc_work_queue[pos] = m;    m->queuepos = pos;       CHECK_WQ();   }      static struct svalue pike_cycle_depth_str = SVALUE_INIT_FREE;      static int mc_cycle_depth_from_obj (struct object *o)   {
pike.git/src/gc.c:4979:    if (mc_block_strings > 0 &&    visit_fn == (visit_thing_fn *) &visit_string) {   #ifdef MEMORY_COUNT_DEBUG    ref_to = find_mc_marker (thing);   #endif    MC_DEBUG_MSG (ref_to, "ignored string");    return;    }       ref_to = find_mc_marker (thing); +  debug_malloc_touch_named(ref_to, "ref_to");    ref_from_flags = mc_ref_from->flags;       /* Create mc_marker if necessary. */       if (!ref_to) {    ref_to = my_make_mc_marker (thing, visit_fn, extra); -  +  debug_malloc_touch(ref_to);    MC_DEBUG_MSG (ref_to, "visiting new thing");    assert (!(ref_from_flags & (MC_FLAG_INT_VISITED | MC_FLAG_LA_VISITED)));    ref_to_la_count = old_la_count = 0;    }    else if (ref_to->flags & MC_FLAG_INTERNAL) {    /* Ignore refs to internal things. Can't treat them like other    * things anyway since the int_refs aren't valid for the starting    * points. */    MC_DEBUG_MSG (ref_to, "ignored internal");    assert (ref_to->la_count != ((unsigned INT16) -1) >> 1);
pike.git/src/gc.c:5295:   {   }      PMOD_EXPORT int mc_count_bytes (void *thing)   {    if (mc_pass == MC_PASS_LOOKAHEAD) {    struct mc_marker *m = find_mc_marker (thing);   #ifdef PIKE_DEBUG    if (!m) Pike_fatal ("mc_marker not found for %p.\n", thing);   #endif +  MC_DEBUG_MSG(m, "mc_count_bytes (LA)");    if ((m->flags & (MC_FLAG_INTERNAL|MC_FLAG_INT_VISITED)) == MC_FLAG_INTERNAL)    return 1;    }    return 0;   }      /*! @decl int count_memory (int|mapping(string:int) options, @    *! array|multiset|mapping|object|program|string|type|int... things)    *! @appears Pike.count_memory    *!
pike.git/src/gc.c:5662:    move_svalue (s, &s2);    }       if (find_mc_marker (s->u.ptr)) {    /* The user passed the same thing several times. Ignore it. */    }       else {    struct mc_marker *m =    my_make_mc_marker (s->u.ptr, visit_fn_from_type[TYPEOF(*s)], NULL); +  debug_malloc_touch(m);    m->flags |= MC_FLAG_INTERNAL;    if (!mc_block_pike_cycle_depth && TYPEOF(*s) == T_OBJECT) {    int cycle_depth = mc_cycle_depth_from_obj (s->u.object);    if (TYPEOF(throw_value) != PIKE_T_FREE) {    free(mc_work_queue);    mc_work_queue = NULL;    stop_mc();    throw_severity = THROW_ERROR;    pike_throw();    }
pike.git/src/gc.c:6078:    struct mc_marker *ref_to = find_mc_marker(dst);    if (ref_to) {    /* Already visited or queued for visiting. */    return;    }       ref_to = my_make_mc_marker(dst, visit_dst, extra);    ref_to->la_count = 0; /* initialize just so the queue doesn't order on    uninitialized memory (... valgrind) */    +  MC_DEBUG_MSG(ref_to, "identify_loop_visit_ref()"); +     if (type != PIKE_T_UNKNOWN) {    /* NB: low_mapping_insert() for object indices may throw errors    * if eg lfun::`==() throws an error. We therefore instead    * use the raw pointers as indices instead.    */    struct svalue s;    SET_SVAL(s, PIKE_T_INT, NUMBER_NUMBER, integer, (INT_TYPE)(ptrdiff_t)dst);    mc_wq_enqueue(ref_to);    low_mapping_insert(identify_loop_reverse, &s, Pike_sp-1, 0);    } else {