From: Dmitry Volyntsev Date: Wed, 4 Oct 2023 01:09:06 +0000 (-0700) Subject: Improved memory footprint of RegExp.prototype.replace(). X-Git-Tag: 0.8.2~11 X-Git-Url: http://www.kaiwu.me/postgresql/commit/static/gitweb.js?a=commitdiff_plain;h=26390a94096eb6ef38503d35033959e985457547;p=njs.git Improved memory footprint of RegExp.prototype.replace(). --- diff --git a/src/njs_flathsh.c b/src/njs_flathsh.c index 224dd39d..c823c466 100644 --- a/src/njs_flathsh.c +++ b/src/njs_flathsh.c @@ -162,6 +162,15 @@ njs_flathsh_new(njs_flathsh_query_t *fhq) } +void +njs_flathsh_destroy(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) +{ + njs_flathsh_free(fhq, njs_flathsh_chunk(fh->slot)); + + fh->slot = NULL; +} + + static njs_flathsh_descr_t * njs_flathsh_alloc(njs_flathsh_query_t *fhq, size_t hash_size, size_t elts_size) { diff --git a/src/njs_flathsh.h b/src/njs_flathsh.h index b3d39d20..d347bb81 100644 --- a/src/njs_flathsh.h +++ b/src/njs_flathsh.h @@ -130,6 +130,7 @@ NJS_EXPORT njs_flathsh_elt_t *njs_flathsh_add_elt(njs_flathsh_t *fh, njs_flathsh_query_t *fhq); NJS_EXPORT njs_flathsh_descr_t *njs_flathsh_new(njs_flathsh_query_t *fhq); +NJS_EXPORT void njs_flathsh_destroy(njs_flathsh_t *fh, njs_flathsh_query_t *fhq); /* Temporary backward compatibility .*/ diff --git a/src/njs_regexp.c b/src/njs_regexp.c index 30368f57..47a32375 100644 --- a/src/njs_regexp.c +++ b/src/njs_regexp.c @@ -1182,6 +1182,50 @@ done: } +static void +njs_regexp_exec_result_free(njs_vm_t *vm, njs_array_t *result) +{ + njs_uint_t n; + njs_value_t *start; + njs_flathsh_t *hash; + njs_object_prop_t *prop; + njs_lvlhsh_each_t lhe; + njs_lvlhsh_query_t lhq; + + if (result->object.fast_array) { + start = result->start; + + for (n = 0; n < result->length; n++) { + if (start[n].short_string.size == NJS_STRING_LONG) { + njs_mp_free(vm->mem_pool, start[n].long_string.data); + } + } + } + + njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto); + + hash = &result->object.hash; + + for ( ;; ) { + prop = njs_flathsh_each(hash, &lhe); + + if (prop == NULL) { + break; + } + + njs_mp_free(vm->mem_pool, prop); + } + + + lhq.pool = vm->mem_pool; + lhq.proto = &njs_object_hash_proto; + + njs_flathsh_destroy(hash, &lhq); + + njs_array_destroy(vm, result); +} + + njs_int_t njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) @@ -1497,6 +1541,10 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, arguments, ncaptures, &groups, replace, retval); + if (njs_object_slots(r)) { + njs_regexp_exec_result_free(vm, njs_array(r)); + } + } else { ret = njs_array_expand(vm, array, 0, njs_is_defined(&groups) ? 3 : 2); @@ -1517,6 +1565,8 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, arguments, n, retval); } + njs_array_destroy(vm, array); + if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; }