]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | /* |
2 | * Debug dumping of duk_heap. | |
3 | */ | |
4 | ||
5 | #include "duk_internal.h" | |
6 | ||
7 | #ifdef DUK_USE_DEBUG | |
8 | ||
9 | #if 0 /*unused*/ | |
10 | DUK_LOCAL void duk__sanitize_snippet(char *buf, duk_size_t buf_size, duk_hstring *str) { | |
11 | duk_size_t i; | |
12 | duk_size_t nchars; | |
13 | duk_size_t maxchars; | |
14 | duk_uint8_t *data; | |
15 | ||
16 | DUK_MEMZERO(buf, buf_size); | |
17 | ||
18 | maxchars = (duk_size_t) (buf_size - 1); | |
19 | data = DUK_HSTRING_GET_DATA(str); | |
20 | nchars = ((duk_size_t) str->blen < maxchars ? (duk_size_t) str->blen : maxchars); | |
21 | for (i = 0; i < nchars; i++) { | |
22 | duk_small_int_t c = (duk_small_int_t) data[i]; | |
23 | if (c < 0x20 || c > 0x7e) { | |
24 | c = '.'; | |
25 | } | |
26 | buf[i] = (char) c; | |
27 | } | |
28 | } | |
29 | #endif | |
30 | ||
31 | #if 0 | |
32 | DUK_LOCAL const char *duk__get_heap_type_string(duk_heaphdr *hdr) { | |
33 | switch (DUK_HEAPHDR_GET_TYPE(hdr)) { | |
34 | case DUK_HTYPE_STRING: | |
35 | return "string"; | |
36 | case DUK_HTYPE_OBJECT: | |
37 | return "object"; | |
38 | case DUK_HTYPE_BUFFER: | |
39 | return "buffer"; | |
40 | default: | |
41 | return "???"; | |
42 | } | |
43 | } | |
44 | #endif | |
45 | ||
46 | #if 0 | |
47 | DUK_LOCAL void duk__dump_indented(duk_heaphdr *obj, int index) { | |
48 | DUK_UNREF(obj); | |
49 | DUK_UNREF(index); | |
50 | DUK_UNREF(duk__get_heap_type_string); | |
51 | ||
52 | #ifdef DUK_USE_REFERENCE_COUNTING | |
53 | DUK_D(DUK_DPRINT(" [%ld]: %p %s (flags: 0x%08lx, ref: %ld) -> %!O", | |
54 | (long) index, | |
55 | (void *) obj, | |
56 | (const char *) duk__get_heap_type_string(obj), | |
57 | (unsigned long) DUK_HEAPHDR_GET_FLAGS(obj), | |
58 | (long) DUK_HEAPHDR_GET_REFCOUNT(obj), | |
59 | (duk_heaphdr *) obj)); | |
60 | #else | |
61 | DUK_D(DUK_DPRINT(" [%ld]: %p %s (flags: 0x%08lx) -> %!O", | |
62 | (long) index, | |
63 | (void *) obj, | |
64 | (const char *) duk__get_heap_type_string(obj), | |
65 | (unsigned long) DUK_HEAPHDR_GET_FLAGS(obj), | |
66 | (duk_heaphdr *) obj)); | |
67 | #endif | |
68 | } | |
69 | #endif | |
70 | ||
71 | #if 0 /*unused*/ | |
72 | DUK_LOCAL void duk__dump_heaphdr_list(duk_heap *heap, duk_heaphdr *root, const char *name) { | |
73 | duk_int_t count; | |
74 | duk_heaphdr *curr; | |
75 | ||
76 | DUK_UNREF(heap); | |
77 | DUK_UNREF(name); | |
78 | ||
79 | count = 0; | |
80 | curr = root; | |
81 | while (curr) { | |
82 | count++; | |
83 | curr = DUK_HEAPHDR_GET_NEXT(curr); | |
84 | } | |
85 | ||
86 | DUK_D(DUK_DPRINT("%s, %ld objects", (const char *) name, (long) count)); | |
87 | ||
88 | count = 0; | |
89 | curr = root; | |
90 | while (curr) { | |
91 | count++; | |
92 | duk__dump_indented(curr, count); | |
93 | curr = DUK_HEAPHDR_GET_NEXT(curr); | |
94 | } | |
95 | } | |
96 | #endif | |
97 | ||
98 | #if 0 /*unused*/ | |
99 | DUK_LOCAL void duk__dump_stringtable(duk_heap *heap) { | |
100 | duk_uint_fast32_t i; | |
101 | char buf[64+1]; | |
102 | ||
103 | DUK_D(DUK_DPRINT("stringtable %p, used %ld, size %ld, load %ld%%", | |
104 | (void *) heap->strtable, | |
105 | (long) heap->st_used, | |
106 | (long) heap->st_size, | |
107 | (long) (((double) heap->st_used) / ((double) heap->st_size) * 100.0))); | |
108 | ||
109 | for (i = 0; i < (duk_uint_fast32_t) heap->st_size; i++) { | |
110 | duk_hstring *e = heap->strtable[i]; | |
111 | ||
112 | if (!e) { | |
113 | DUK_D(DUK_DPRINT(" [%ld]: NULL", (long) i)); | |
114 | } else if (e == DUK_STRTAB_DELETED_MARKER(heap)) { | |
115 | DUK_D(DUK_DPRINT(" [%ld]: DELETED", (long) i)); | |
116 | } else { | |
117 | duk__sanitize_snippet(buf, sizeof(buf), e); | |
118 | ||
119 | #ifdef DUK_USE_REFERENCE_COUNTING | |
120 | DUK_D(DUK_DPRINT(" [%ld]: %p (flags: 0x%08lx, ref: %ld) '%s', strhash=0x%08lx, blen=%ld, clen=%ld, " | |
121 | "arridx=%ld, internal=%ld, reserved_word=%ld, strict_reserved_word=%ld, eval_or_arguments=%ld", | |
122 | (long) i, | |
123 | (void *) e, | |
124 | (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) e), | |
125 | (long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) e), | |
126 | (const char *) buf, | |
127 | (unsigned long) e->hash, | |
128 | (long) e->blen, | |
129 | (long) e->clen, | |
130 | (long) (DUK_HSTRING_HAS_ARRIDX(e) ? 1 : 0), | |
131 | (long) (DUK_HSTRING_HAS_INTERNAL(e) ? 1 : 0), | |
132 | (long) (DUK_HSTRING_HAS_RESERVED_WORD(e) ? 1 : 0), | |
133 | (long) (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(e) ? 1 : 0), | |
134 | (long) (DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(e) ? 1 : 0))); | |
135 | #else | |
136 | DUK_D(DUK_DPRINT(" [%ld]: %p (flags: 0x%08lx) '%s', strhash=0x%08lx, blen=%ld, clen=%ld, " | |
137 | "arridx=%ld, internal=%ld, reserved_word=%ld, strict_reserved_word=%ld, eval_or_arguments=%ld", | |
138 | (long) i, | |
139 | (void *) e, | |
140 | (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) e), | |
141 | (const char *) buf, | |
142 | (long) e->hash, | |
143 | (long) e->blen, | |
144 | (long) e->clen, | |
145 | (long) (DUK_HSTRING_HAS_ARRIDX(e) ? 1 : 0), | |
146 | (long) (DUK_HSTRING_HAS_INTERNAL(e) ? 1 : 0), | |
147 | (long) (DUK_HSTRING_HAS_RESERVED_WORD(e) ? 1 : 0), | |
148 | (long) (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(e) ? 1 : 0), | |
149 | (long) (DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(e) ? 1 : 0))); | |
150 | #endif | |
151 | } | |
152 | } | |
153 | } | |
154 | #endif | |
155 | ||
156 | #if 0 /*unused*/ | |
157 | DUK_LOCAL void duk__dump_strcache(duk_heap *heap) { | |
158 | duk_uint_fast32_t i; | |
159 | char buf[64+1]; | |
160 | ||
161 | DUK_D(DUK_DPRINT("stringcache")); | |
162 | ||
163 | for (i = 0; i < (duk_uint_fast32_t) DUK_HEAP_STRCACHE_SIZE; i++) { | |
164 | duk_strcache *c = &heap->strcache[i]; | |
165 | if (!c->h) { | |
166 | DUK_D(DUK_DPRINT(" [%ld]: bidx=%ld, cidx=%ld, str=NULL", | |
167 | (long) i, (long) c->bidx, (long) c->cidx)); | |
168 | } else { | |
169 | duk__sanitize_snippet(buf, sizeof(buf), c->h); | |
170 | DUK_D(DUK_DPRINT(" [%ld]: bidx=%ld cidx=%ld str=%s", | |
171 | (long) i, (long) c->bidx, (long) c->cidx, (const char *) buf)); | |
172 | } | |
173 | } | |
174 | } | |
175 | #endif | |
176 | ||
177 | #if 0 /*unused*/ | |
178 | DUK_INTERNAL void duk_debug_dump_heap(duk_heap *heap) { | |
179 | char buf[64+1]; | |
180 | ||
181 | DUK_D(DUK_DPRINT("=== heap %p ===", (void *) heap)); | |
182 | DUK_D(DUK_DPRINT(" flags: 0x%08lx", (unsigned long) heap->flags)); | |
183 | ||
184 | /* Note: there is no standard formatter for function pointers */ | |
185 | #ifdef DUK_USE_GCC_PRAGMAS | |
186 | #pragma GCC diagnostic push | |
187 | #pragma GCC diagnostic ignored "-pedantic" | |
188 | #endif | |
189 | duk_debug_format_funcptr(buf, sizeof(buf), (duk_uint8_t *) &heap->alloc_func, sizeof(heap->alloc_func)); | |
190 | DUK_D(DUK_DPRINT(" alloc_func: %s", (const char *) buf)); | |
191 | duk_debug_format_funcptr(buf, sizeof(buf), (duk_uint8_t *) &heap->realloc_func, sizeof(heap->realloc_func)); | |
192 | DUK_D(DUK_DPRINT(" realloc_func: %s", (const char *) buf)); | |
193 | duk_debug_format_funcptr(buf, sizeof(buf), (duk_uint8_t *) &heap->free_func, sizeof(heap->free_func)); | |
194 | DUK_D(DUK_DPRINT(" free_func: %s", (const char *) buf)); | |
195 | duk_debug_format_funcptr(buf, sizeof(buf), (duk_uint8_t *) &heap->fatal_func, sizeof(heap->fatal_func)); | |
196 | DUK_D(DUK_DPRINT(" fatal_func: %s", (const char *) buf)); | |
197 | #ifdef DUK_USE_GCC_PRAGMAS | |
198 | #pragma GCC diagnostic pop | |
199 | #endif | |
200 | ||
201 | DUK_D(DUK_DPRINT(" heap_udata: %p", (void *) heap->heap_udata)); | |
202 | ||
203 | #ifdef DUK_USE_MARK_AND_SWEEP | |
204 | #ifdef DUK_USE_VOLUNTARY_GC | |
205 | DUK_D(DUK_DPRINT(" mark-and-sweep trig counter: %ld", (long) heap->mark_and_sweep_trigger_counter)); | |
206 | #endif | |
207 | DUK_D(DUK_DPRINT(" mark-and-sweep rec depth: %ld", (long) heap->mark_and_sweep_recursion_depth)); | |
208 | DUK_D(DUK_DPRINT(" mark-and-sweep base flags: 0x%08lx", (unsigned long) heap->mark_and_sweep_base_flags)); | |
209 | #endif | |
210 | ||
211 | DUK_D(DUK_DPRINT(" lj.jmpbuf_ptr: %p", (void *) heap->lj.jmpbuf_ptr)); | |
212 | DUK_D(DUK_DPRINT(" lj.type: %ld", (long) heap->lj.type)); | |
213 | DUK_D(DUK_DPRINT(" lj.value1: %!T", (duk_tval *) &heap->lj.value1)); | |
214 | DUK_D(DUK_DPRINT(" lj.value2: %!T", (duk_tval *) &heap->lj.value2)); | |
215 | DUK_D(DUK_DPRINT(" lj.iserror: %ld", (long) heap->lj.iserror)); | |
216 | ||
217 | DUK_D(DUK_DPRINT(" handling_error: %ld", (long) heap->handling_error)); | |
218 | ||
219 | DUK_D(DUK_DPRINT(" heap_thread: %!@O", (duk_heaphdr *) heap->heap_thread)); | |
220 | DUK_D(DUK_DPRINT(" curr_thread: %!@O", (duk_heaphdr *) heap->curr_thread)); | |
221 | DUK_D(DUK_DPRINT(" heap_object: %!@O", (duk_heaphdr *) heap->heap_object)); | |
222 | ||
223 | DUK_D(DUK_DPRINT(" call_recursion_depth: %ld", (long) heap->call_recursion_depth)); | |
224 | DUK_D(DUK_DPRINT(" call_recursion_limit: %ld", (long) heap->call_recursion_limit)); | |
225 | ||
226 | DUK_D(DUK_DPRINT(" hash_seed: 0x%08lx", (unsigned long) heap->hash_seed)); | |
227 | DUK_D(DUK_DPRINT(" rnd_state: 0x%08lx", (unsigned long) heap->rnd_state)); | |
228 | ||
229 | duk__dump_strcache(heap); | |
230 | ||
231 | duk__dump_heaphdr_list(heap, heap->heap_allocated, "heap allocated"); | |
232 | ||
233 | #ifdef DUK_USE_REFERENCE_COUNTING | |
234 | duk__dump_heaphdr_list(heap, heap->refzero_list, "refcounting refzero list"); | |
235 | #endif | |
236 | ||
237 | #ifdef DUK_USE_MARK_AND_SWEEP | |
238 | duk__dump_heaphdr_list(heap, heap->finalize_list, "mark-and-sweep finalize list"); | |
239 | #endif | |
240 | ||
241 | duk__dump_stringtable(heap); | |
242 | ||
243 | /* heap->strs: not worth dumping */ | |
244 | } | |
245 | #endif | |
246 | ||
247 | #endif /* DUK_USE_DEBUG */ |