-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdumpstat.c
164 lines (147 loc) · 4.02 KB
/
dumpstat.c
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include "std.h"
#include "dumpstat.h"
#include "comm.h"
#include "file.h"
/*
* Write statistics about objects on file.
*/
static int sumSizes (mapping_t *, mapping_node_t *, void *);
static int svalue_size (svalue_t *);
static int sumSizes (mapping_t * m, mapping_node_t * elt, void * tp)
{
int *t = (int *)tp;
*t += (svalue_size(&elt->values[0]) + svalue_size(&elt->values[1]));
*t += sizeof(mapping_node_t);
return 0;
}
int depth = 0;
static int svalue_size (svalue_t * v)
{
int i, total;
switch (v->type) {
case T_OBJECT:
case T_REAL:
case T_NUMBER:
return 0;
case T_STRING:
return (strlen(v->u.string) + 1);
case T_ARRAY:
case T_CLASS:
if (++depth > 100)
return 0;
/* first svalue is stored inside the array struct */
total = sizeof(array_t) - sizeof(svalue_t);
for (i = 0; i < v->u.arr->size; i++) {
total += svalue_size(&v->u.arr->item[i]) + sizeof(svalue_t);
}
depth--;
return total;
case T_MAPPING:
if (++depth > 100)
return 0;
total = sizeof(mapping_t);
mapTraverse(v->u.map, sumSizes, &total);
depth--;
return total;
case T_FUNCTION:
{
svalue_t tmp;
tmp.type = T_ARRAY;
tmp.u.arr = v->u.fp->hdr.args;
if (++depth > 100)
return 0;
if (tmp.u.arr)
total = sizeof(funptr_hdr_t) + svalue_size(&tmp);
else
total = sizeof(funptr_hdr_t);
switch (v->u.fp->hdr.type) {
case FP_EFUN:
total += sizeof(efun_ptr_t);
break;
case FP_LOCAL | FP_NOT_BINDABLE:
total += sizeof(local_ptr_t);
break;
case FP_SIMUL:
total += sizeof(simul_ptr_t);
break;
case FP_FUNCTIONAL:
case FP_FUNCTIONAL | FP_NOT_BINDABLE:
total += sizeof(functional_t);
break;
}
depth--;
return total;
}
#ifndef NO_BUFFER_TYPE
case T_BUFFER:
/* first byte is stored inside the buffer struct */
return sizeof(buffer_t) + v->u.buf->size - 1;
#endif
default:
//some freed value or a reference (!) to one (in all my test cases
//anyway), it will be removed by reclaim_objects later, Wodan
//fatal("Illegal type: %d\n", v->type);
;
}
/* NOTREACHED */
return 0;
}
int data_size (object_t * ob)
{
int total = 0, i;
if (ob->prog) {
for (i = 0; i < ob->prog->num_variables_total; i++) {
depth = 0;
total += svalue_size(&ob->variables[i]) + sizeof(svalue_t);
}
}
return total;
}
void dumpstat (const char * tfn)
{
FILE *f;
object_t *ob;
const char *fn;
#ifdef F_SET_HIDE
int display_hidden;
#endif
fn = check_valid_path(tfn, current_object, "dumpallobj", 1);
if (!fn) {
error("Invalid path '/%s' for writing.\n", tfn);
return;
}
f = fopen(fn, "w");
if (!f) {
error("Unable to open '/%s' for writing.\n", fn);
return;
}
#ifdef F_SET_HIDE
display_hidden = -1;
#endif
for (ob = obj_list; ob; ob = ob->next_all) {
int tmp;
#ifdef F_SET_HIDE
if (ob->flags & O_HIDDEN) {
if (display_hidden == -1)
display_hidden = valid_hide(current_object);
if (!display_hidden)
continue;
}
#endif
/* FIXME */
if (ob->prog && (ob->prog->ref == 1 || !(ob->flags & O_CLONE)))
tmp = ob->prog->total_size;
else
tmp = 0;
fprintf(f, "%-20s %ld ref %2d %s %s (%d)\n", ob->obname,
tmp + data_size(ob) + sizeof(object_t), ob->ref,
ob->flags & O_HEART_BEAT ? "HB" : " ",
#ifndef NO_ENVIRONMENT
ob->super ? ob->super->obname : "--",
#else
"--",
#endif
/* ob->cpu */ 0);
}
fclose(f);
}