1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
/* You may distribute under the terms of either the GNU General Public License
* or the Artistic License (the same terms as Perl itself)
*
* (C) Paul Evans, 2018 -- leonerd@leonerd.org.uk
*/
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
static char *sv_typename(U8 svt)
{
switch(svt) {
case SVt_NULL:
return "NULL";
case SVt_IV:
case SVt_NV:
case SVt_PV:
case SVt_PVIV:
case SVt_PVNV:
case SVt_PVMG:
#if PERL_VERSION < 12
/* SVt_RV was removed after 5.10 */
case SVt_RV:
#endif
return "SCALAR";
#if PERL_VERSION >= 12
/* SVt_REGEXP was added in perl 5.12 */
case SVt_REGEXP:
return "REGEXP";
#endif
case SVt_PVGV:
return "GLOB";
case SVt_PVAV:
return "ARRAY";
case SVt_PVHV:
return "HASH";
case SVt_PVCV:
return "CODE";
case SVt_PVFM:
return "FORMAT";
case SVt_PVIO:
return "IO";
#if PERL_VERSION >= 20
/* SVt_INVLIST was added in perl 5.20 */
case SVt_INVLIST:
return "INVLIST";
#endif
default:
return "UNKNOWN";
}
}
MODULE = Net::Prometheus::PerlCollector PACKAGE = Net::Prometheus::PerlCollector
void
count_heap(detail)
int detail
INIT:
SV *arena;
STRLEN arenas = 0, svs = 0;
HV *svs_by_type = NULL, *svs_by_class = NULL;
PPCODE:
if(detail)
svs_by_type = newHV();
if(detail > 1)
svs_by_class = newHV();
for(arena = PL_sv_arenaroot; arena; arena = (SV *)SvANY(arena)) {
const SV *arenaend = &arena[SvREFCNT(arena)];
SV *sv;
arenas++;
for(sv = arena + 1; sv < arenaend; sv++)
if(SvTYPE(sv) != 0xFF && SvREFCNT(sv)) {
svs++;
if(svs_by_type) {
char *type = sv_typename(SvTYPE(sv));
SV **countp = hv_fetch(svs_by_type, type, strlen(type), 1);
sv_setiv(*countp, SvIOK(*countp) ? SvIV(*countp) + 1 : 1);
if(svs_by_class && SvOBJECT(sv)) {
char *class = HvNAME(SvSTASH(sv));
SV **countp = hv_fetch(svs_by_class, class, strlen(class), 1);
sv_setiv(*countp, SvIOK(*countp) ? SvIV(*countp) + 1 : 1);
}
}
}
}
EXTEND(SP, 4);
mPUSHu(arenas);
mPUSHu(svs);
if(svs_by_type)
mPUSHs(newRV_noinc((SV *)svs_by_type));
if(svs_by_class)
mPUSHs(newRV_noinc((SV *)svs_by_class));
XSRETURN(2 + !!svs_by_type + !!svs_by_class);
|