Browse Source

Add DUK_OPT_EXTSTR_FREE() macro hook

pull/92/head
Sami Vaarala 10 years ago
parent
commit
429fb1e2ea
  1. 8
      src/duk_features.h.in
  2. 3
      src/duk_heap.h
  3. 33
      src/duk_heap_alloc.c
  4. 13
      src/duk_heap_markandsweep.c
  5. 5
      src/duk_hstring.h

8
src/duk_features.h.in

@ -2521,16 +2521,20 @@ typedef FILE duk_file;
*/
#undef DUK_USE_HSTRING_EXTDATA
#undef DUK_USE_EXTSTR_INTERN_CHECK
#if defined(DUK_OPT_EXTERNAL_STRINGS)
#define DUK_USE_HSTRING_EXTDATA
#endif
#undef DUK_USE_EXTSTR_INTERN_CHECK
#if defined(DUK_OPT_EXTERNAL_STRINGS) && defined(DUK_OPT_EXTSTR_INTERN_CHECK)
#define DUK_USE_EXTSTR_INTERN_CHECK(ptr,len) DUK_OPT_EXTSTR_INTERN_CHECK((ptr), (len))
#endif
#undef DUK_USE_EXTSTR_FREE
#if defined(DUK_OPT_EXTERNAL_STRINGS) && defined(DUK_OPT_EXTSTR_FREE)
#define DUK_USE_EXTSTR_FREE(ptr) DUK_OPT_EXTSTR_FREE((ptr))
#endif
/*
* Lightweight functions
*/

3
src/duk_heap.h

@ -402,6 +402,9 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
void *alloc_udata,
duk_fatal_function fatal_func);
DUK_INTERNAL_DECL void duk_heap_free(duk_heap *heap);
DUK_INTERNAL_DECL void duk_free_hobject_inner(duk_heap *heap, duk_hobject *h);
DUK_INTERNAL_DECL void duk_free_hbuffer_inner(duk_heap *heap, duk_hbuffer *h);
DUK_INTERNAL_DECL void duk_free_hstring_inner(duk_heap *heap, duk_hstring *h);
DUK_INTERNAL_DECL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr);
DUK_INTERNAL_DECL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);

33
src/duk_heap_alloc.c

@ -21,7 +21,7 @@
* been already dealt with.
*/
DUK_LOCAL void duk__free_hobject_inner(duk_heap *heap, duk_hobject *h) {
DUK_INTERNAL void duk_free_hobject_inner(duk_heap *heap, duk_hobject *h) {
DUK_ASSERT(heap != NULL);
DUK_ASSERT(h != NULL);
@ -52,7 +52,7 @@ DUK_LOCAL void duk__free_hobject_inner(duk_heap *heap, duk_hobject *h) {
}
}
DUK_LOCAL void duk__free_hbuffer_inner(duk_heap *heap, duk_hbuffer *h) {
DUK_INTERNAL void duk_free_hbuffer_inner(duk_heap *heap, duk_hbuffer *h) {
DUK_ASSERT(heap != NULL);
DUK_ASSERT(h != NULL);
@ -63,6 +63,22 @@ DUK_LOCAL void duk__free_hbuffer_inner(duk_heap *heap, duk_hbuffer *h) {
}
}
DUK_INTERNAL void duk_free_hstring_inner(duk_heap *heap, duk_hstring *h) {
DUK_ASSERT(heap != NULL);
DUK_ASSERT(h != NULL);
DUK_UNREF(heap);
DUK_UNREF(h);
#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_FREE)
if (DUK_HSTRING_HAS_EXTDATA(h)) {
DUK_DDD(DUK_DDDPRINT("free extstr: hstring %!O, extdata: %p",
h, DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h)));
DUK_USE_EXTSTR_FREE((const void *) DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h));
}
#endif
}
DUK_INTERNAL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr) {
DUK_ASSERT(heap);
DUK_ASSERT(hdr);
@ -71,13 +87,13 @@ DUK_INTERNAL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr) {
switch ((int) DUK_HEAPHDR_GET_TYPE(hdr)) {
case DUK_HTYPE_STRING:
/* no inner refs to free */
duk_free_hstring_inner(heap, (duk_hstring *) hdr);
break;
case DUK_HTYPE_OBJECT:
duk__free_hobject_inner(heap, (duk_hobject *) hdr);
duk_free_hobject_inner(heap, (duk_hobject *) hdr);
break;
case DUK_HTYPE_BUFFER:
duk__free_hbuffer_inner(heap, (duk_hbuffer *) hdr);
duk_free_hbuffer_inner(heap, (duk_hbuffer *) hdr);
break;
default:
DUK_UNREACHABLE();
@ -165,11 +181,14 @@ DUK_LOCAL void duk__free_stringtable(duk_heap *heap) {
#else
e = heap->strtable[i];
#endif
if (e == DUK_STRTAB_DELETED_MARKER(heap)) {
if (e == NULL || e == DUK_STRTAB_DELETED_MARKER(heap)) {
continue;
}
DUK_ASSERT(e != NULL);
/* strings may have inner refs (extdata) in some cases */
duk_free_hstring_inner(heap, (duk_hstring *) e);
/* strings have no inner allocations so free directly */
DUK_DDD(DUK_DDDPRINT("FINALFREE (string): %!iO",
(duk_heaphdr *) e));
DUK_FREE(heap, e);

13
src/duk_heap_markandsweep.c

@ -558,12 +558,13 @@ DUK_LOCAL void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep
heap->strtable[i] = DUK_STRTAB_DELETED_MARKER(heap);
#endif
/* then free */
#if 1
DUK_FREE(heap, (duk_heaphdr *) h); /* no inner refs/allocs, just free directly */
#else
duk_heap_free_heaphdr_raw(heap, (duk_heaphdr *) h); /* this would be OK but unnecessary */
#endif
/* free inner references (these exist e.g. when external
* strings are enabled)
*/
duk_free_hstring_inner(heap, (duk_hstring *) h);
/* finally free the struct itself */
DUK_FREE(heap, (duk_heaphdr *) h);
}
#ifdef DUK_USE_DEBUG

5
src/duk_hstring.h

@ -102,8 +102,11 @@
#endif
#if defined(DUK_USE_HSTRING_EXTDATA)
#define DUK_HSTRING_GET_EXTDATA(x) \
((x)->extdata)
#define DUK_HSTRING_GET_DATA(x) \
(DUK_HSTRING_HAS_EXTDATA((x)) ? ((duk_hstring_external *) (x))->extdata : ((const duk_uint8_t *) ((x) + 1)))
(DUK_HSTRING_HAS_EXTDATA((x)) ? \
DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) (x)) : ((const duk_uint8_t *) ((x) + 1)))
#else
#define DUK_HSTRING_GET_DATA(x) \
((const duk_uint8_t *) ((x) + 1))

Loading…
Cancel
Save