pike.git / src / gc.c

version» Context lines:

pike.git/src/gc.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: gc.c,v 1.330 2008/10/12 21:49:56 mast Exp $ + || $Id: gc.c,v 1.331 2008/10/12 22:41:16 mast Exp $   */      #include "global.h"      struct callback *gc_evaluator_callback=0;      #include "array.h"   #include "multiset.h"   #include "mapping.h"   #include "object.h"
pike.git/src/gc.c:4947:    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    *! +  *! In brief, if you call @expr{Pike.count_memory(0,x)@} you get back +  *! the number of bytes @expr{x@} occupies in memory. +  *! +  *! The detailed story is a bit longer: +  *!    *! This function calculates the number of bytes that all @[things]    *! occupy. Or put another way, it calculates the number of bytes that    *! would be freed if all those things would lose their references at    *! the same time, i.e. not only the memory in the things themselves,    *! but also in all the things that are directly and indirectly    *! referenced from those things and not from anywhere else.    *!    *! The memory counted is only that which is directly occupied by the    *! things in question, including any overallocation for mappings,    *! multisets and arrays. Other memory overhead that they give rise to
pike.git/src/gc.c:5002:    *! higher than zero to this function.    *!    *! Note that @expr{pike_cycle_depth@} can also be set to zero to    *! effectively stop the lookahead from continuing through the object.    *! That can be useful to put in objects you know have global    *! references, to speed up the traversal.    *!    *! @param options    *! If this is an integer, it specifies the maximum lookahead    *! distance. -1 counts only the memory of the given @[things], -  *! without following any references, 0 extends the count to all +  *! without following any references. 0 extends the count to all    *! their referenced things as long as there are no cycles (except -  *! if @expr{pike_cycle_depth@} is found in objects - see above), 1 +  *! if @expr{pike_cycle_depth@} is found in objects - see above). 1    *! makes it cover cycles of length 1 (e.g. a thing points to    *! itself), 2 handles cycles of length 2 (e.g. where two things    *! point at each other), and so on.    *!    *! However, the lookahead is by default blocked by programs, i.e.    *! it never follows references emanating from programs. That since    *! programs seldom are part of dynamic data structures, and they    *! also typically contain numerous references to global data which    *! would add a lot of work to the lookahead search.    *!    *! To control the search in more detail, @[options] can be a    *! mapping instead:    *!    *! @mapping    *! @member int lookahead    *! The maximum lookahead distance, as described above. Defaults    *! to 0 if missing. -  +  *!    *! @member int block_arrays    *! @member int block_mappings    *! @member int block_multisets    *! @member int block_objects    *! @member int block_programs    *! When any of these are given with a nonzero value, the    *! corresponding type is blocked when lookahead references are    *! followed. They are unblocked if the flag is given with a    *! zero value. Only programs are blocked by default. -  +  *! +  *! These blocks are only active during the lookahead, so +  *! blocked things are still recursed and memory counted if they +  *! are given as arguments or only got internal references. +  *!    *! @member int block_pike_cycle_depth    *! Do not heed @expr{pike_cycle_depth@} values found in    *! objects. This is implicit if the lookahead is negative. -  +  *!    *! @member int return_count    *! Return the number of things that memory was counted for,    *! instead of the byte count. (This is the same number    *! @expr{internal@} contains if @expr{collect_stats@} is set.) -  +  *!    *! @member int collect_internals    *! If this is nonzero then its value is replaced with an array    *! that contains the things that memory was counted for. -  +  *!    *! @member int collect_externals    *! If set then the value is replaced with an array containing    *! the things that were visited but turned out to have external    *! references (within the limited lookahead). -  +  *!    *! @member int collect_direct_externals    *! If set then the value is replaced with an array containing    *! the things found during the lookahead that (appears to) have    *! direct external references. This list is a subset of the    *! @expr{collect_externals@} list. It is useful if you get    *! unexpected global references to your data structure which    *! you want to track down. -  +  *!    *! @member int collect_stats    *! If this is nonzero then the mapping is extended with more    *! elements containing statistics from the search; see below.    *! @endmapping    *!    *! When the @expr{collect_stats@} flag is set, the mapping is    *! extended with these elements:    *!    *! @mapping    *! @member int internal    *! Number of things that were marked internal and hence memory    *! counted. It includes the things given as arguments. -  +  *!    *! @member int cyclic    *! Number of things that were marked internal only after    *! resolving cycles. -  +  *!    *! @member int external    *! Number of things that were visited through the lookahead but    *! were found to be external. -  +  *!    *! @member int visits    *! Number of times things were visited in total. This figure    *! includes visits to various internal things that aren't    *! visible from the pike level, so it might be larger than what    *! is apparently motivated by the numbers above. -  +  *!    *! @member int revisits    *! Number of times the same things were revisited. This can    *! occur in the lookahead when a thing is encountered through a    *! shorter path than the one it first got visited through. It    *! also occurs in resolved cycles. Like @expr{visits@}, this    *! count can include things that aren't visible from pike. -  +  *!    *! @member int rounds    *! Number of search rounds. This is usually 1 or 2. More rounds    *! are necessary only when blocked types turn out to be    *! (acyclic) internal, so that they need to be counted and    *! recursed anyway. -  +  *!    *! @member int work_queue_alloc    *! The number of elements that was allocated to store the work    *! queue which is used to keep track of the things to visit    *! during the lookahead. This is usually bigger than the    *! maximum number of things the queue actually held. -  +  *!    *! @member int size    *! The memory occupied by the internal things. This is the same    *! as the normal return value, but it's put here too for    *! convenience.    *! @endmapping    *!    *! @param things    *! One or more things to count memory size for. Only things passed    *! by reference are allowed, except for functions which are    *! forbidden because a meaningful size calculation can't be done
pike.git/src/gc.c:5124:    *! The result of @expr{Pike.count_memory(0,a,b)@} might be larger    *! than the sum of @expr{Pike.count_memory(0,a)@} and    *! @expr{Pike.count_memory(0,b)@} since @expr{a@} and @expr{b@}    *! together might reference things that aren't referenced from    *! anywhere else.    *!    *! @note    *! It's possible that a string that is referenced still isn't    *! counted, because strings are always shared in Pike and the same    *! string might be in use in some unrelated part of the program. -  *! -  *! @note -  *! Things (normally programs) that are blocked in the lookahead -  *! search are still recursed and memory counted properly if they are -  *! given as arguments or only got internal references. +     */   void f_count_memory (INT32 args)   {    struct svalue *collect_internal = NULL;    unsigned count_internal, count_cyclic, count_visited;    unsigned count_visits, count_revisits, count_rounds;    int collect_stats = 0, return_count = 0;       if (args < 1)    SIMPLE_TOO_FEW_ARGS_ERROR ("count_memory", 1);