From: Dmitry Volyntsev Date: Fri, 25 Oct 2019 13:20:37 +0000 (+0300) Subject: Optimizing njs_vm_clone() for speed. X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=962da26dc767d23d3f75033ddee7a51395797452;p=njs.git Optimizing njs_vm_clone() for speed. Postponing allocation of structures where possible. --- diff --git a/src/njs_builtin.c b/src/njs_builtin.c index 695e796f..83f90459 100644 --- a/src/njs_builtin.c +++ b/src/njs_builtin.c @@ -183,13 +183,34 @@ njs_builtin_objects_create(njs_vm_t *vm) njs_function_t *func; njs_vm_shared_t *shared; njs_lvlhsh_query_t lhq; + njs_regexp_pattern_t *pattern; njs_object_prototype_t *prototype; const njs_object_init_t *obj, **p; const njs_function_init_t *f; static const njs_str_t sandbox_key = njs_str("sandbox"); - shared = vm->shared; + shared = njs_mp_zalloc(vm->mem_pool, sizeof(njs_vm_shared_t)); + if (njs_slow_path(shared == NULL)) { + return NJS_ERROR; + } + + njs_lvlhsh_init(&shared->keywords_hash); + + ret = njs_lexer_keywords_init(vm->mem_pool, &shared->keywords_hash); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } + + njs_lvlhsh_init(&shared->values_hash); + + pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)", + njs_length("(?:)"), 0); + if (njs_slow_path(pattern == NULL)) { + return NJS_ERROR; + } + + shared->empty_regexp_pattern = pattern; ret = njs_object_hash_init(vm, &shared->array_instance_hash, &njs_array_instance_init); @@ -242,6 +263,8 @@ njs_builtin_objects_create(njs_vm_t *vm) return NJS_ERROR; } + njs_lvlhsh_init(&vm->modules_hash); + lhq.replace = 0; lhq.pool = vm->mem_pool; @@ -302,15 +325,14 @@ njs_builtin_objects_create(njs_vm_t *vm) } shared->prototypes[NJS_PROTOTYPE_REGEXP].regexp.pattern = - vm->shared->empty_regexp_pattern; + shared->empty_regexp_pattern; string_object = &shared->string_object; njs_lvlhsh_init(&string_object->hash); - string_object->shared_hash = vm->shared->string_instance_hash; + string_object->shared_hash = shared->string_instance_hash; string_object->type = NJS_OBJECT_STRING; string_object->shared = 1; string_object->extensible = 0; - string_object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_STRING].object; f = njs_native_constructors; func = shared->constructors; @@ -336,6 +358,8 @@ njs_builtin_objects_create(njs_vm_t *vm) func++; } + vm->shared = shared; + return NJS_OK; } @@ -471,7 +495,7 @@ njs_builtin_objects_clone(njs_vm_t *vm, njs_value_t *global) } vm->global_object = vm->shared->objects[0]; - vm->global_object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object; + vm->global_object.__proto__ = object_prototype; vm->global_object.shared = 0; njs_set_object(global, &vm->global_object); diff --git a/src/njs_extern.c b/src/njs_extern.c index a7d8d0b6..0850e8e3 100644 --- a/src/njs_extern.c +++ b/src/njs_extern.c @@ -171,12 +171,23 @@ njs_int_t njs_vm_external_create(njs_vm_t *vm, njs_value_t *ext_val, const njs_extern_t *proto, njs_external_ptr_t object) { - void *obj; + void *obj; + njs_arr_t *externals; if (njs_slow_path(proto == NULL)) { return NJS_ERROR; } + if (njs_slow_path(vm->external_objects == NULL)) { + externals = njs_arr_create(vm->mem_pool, 4, sizeof(void *)); + if (njs_slow_path(externals == NULL)) { + return NJS_ERROR; + } + + vm->external_objects = externals; + } + + obj = njs_arr_add(vm->external_objects); if (njs_slow_path(obj == NULL)) { return NJS_ERROR; diff --git a/src/njs_vm.c b/src/njs_vm.c index 422847d1..6ff811ad 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -22,11 +22,10 @@ const njs_str_t njs_entry_anonymous = njs_str("anonymous"); njs_vm_t * njs_vm_create(njs_vm_opt_t *options) { - njs_mp_t *mp; - njs_vm_t *vm; - njs_int_t ret; - njs_arr_t *debug; - njs_regexp_pattern_t *pattern; + njs_mp_t *mp; + njs_vm_t *vm; + njs_int_t ret; + njs_arr_t *debug; mp = njs_mp_fast_create(2 * njs_pagesize(), 128, 512, 16); if (njs_slow_path(mp == NULL)) { @@ -34,85 +33,62 @@ njs_vm_create(njs_vm_opt_t *options) } vm = njs_mp_zalign(mp, sizeof(njs_value_t), sizeof(njs_vm_t)); + if (njs_slow_path(vm == NULL)) { + return NULL; + } - if (njs_fast_path(vm != NULL)) { - vm->mem_pool = mp; - - ret = njs_regexp_init(vm); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } - - vm->options = *options; - - if (options->shared != NULL) { - vm->shared = options->shared; + vm->mem_pool = mp; - } else { - vm->shared = njs_mp_zalloc(mp, sizeof(njs_vm_shared_t)); - if (njs_slow_path(vm->shared == NULL)) { - return NULL; - } + ret = njs_regexp_init(vm); + if (njs_slow_path(ret != NJS_OK)) { + return NULL; + } - options->shared = vm->shared; + vm->options = *options; - njs_lvlhsh_init(&vm->shared->keywords_hash); + if (options->shared != NULL) { + vm->shared = options->shared; - ret = njs_lexer_keywords_init(mp, &vm->shared->keywords_hash); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } + } else { + ret = njs_builtin_objects_create(vm); + if (njs_slow_path(ret != NJS_OK)) { + return NULL; + } + } - njs_lvlhsh_init(&vm->shared->values_hash); + njs_lvlhsh_init(&vm->values_hash); - pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)", - njs_length("(?:)"), 0); - if (njs_slow_path(pattern == NULL)) { - return NULL; - } + vm->external = options->external; - vm->shared->empty_regexp_pattern = pattern; - - njs_lvlhsh_init(&vm->modules_hash); + vm->external_objects = njs_arr_create(vm->mem_pool, 4, sizeof(void *)); + if (njs_slow_path(vm->external_objects == NULL)) { + return NULL; + } - ret = njs_builtin_objects_create(vm); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } - } + njs_lvlhsh_init(&vm->externals_hash); + njs_lvlhsh_init(&vm->external_prototypes_hash); - njs_lvlhsh_init(&vm->values_hash); + vm->trace.level = NJS_LEVEL_TRACE; + vm->trace.size = 2048; + vm->trace.handler = njs_parser_trace_handler; + vm->trace.data = vm; - vm->external = options->external; + njs_set_undefined(&vm->retval); - vm->external_objects = njs_arr_create(vm->mem_pool, 4, sizeof(void *)); - if (njs_slow_path(vm->external_objects == NULL)) { + if (options->backtrace) { + debug = njs_arr_create(vm->mem_pool, 4, + sizeof(njs_function_debug_t)); + if (njs_slow_path(debug == NULL)) { return NULL; } - njs_lvlhsh_init(&vm->externals_hash); - njs_lvlhsh_init(&vm->external_prototypes_hash); - - vm->trace.level = NJS_LEVEL_TRACE; - vm->trace.size = 2048; - vm->trace.handler = njs_parser_trace_handler; - vm->trace.data = vm; - - if (options->backtrace) { - debug = njs_arr_create(vm->mem_pool, 4, - sizeof(njs_function_debug_t)); - if (njs_slow_path(debug == NULL)) { - return NULL; - } - - vm->debug = debug; - } + vm->debug = debug; + } - if (options->accumulative) { - ret = njs_vm_init(vm); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } + if (options->accumulative) { + ret = njs_vm_init(vm); + if (njs_slow_path(ret != NJS_OK)) { + return NULL; } } @@ -243,9 +219,7 @@ njs_vm_clone(njs_vm_t *vm, njs_external_ptr_t external) { njs_mp_t *nmp; njs_vm_t *nvm; - uint32_t items; njs_int_t ret; - njs_arr_t *externals; njs_thread_log_debug("CLONE:"); @@ -258,59 +232,24 @@ njs_vm_clone(njs_vm_t *vm, njs_external_ptr_t external) return NULL; } - nvm = njs_mp_zalign(nmp, sizeof(njs_value_t), sizeof(njs_vm_t)); - - if (njs_fast_path(nvm != NULL)) { - nvm->mem_pool = nmp; - - nvm->shared = vm->shared; - - nvm->trace = vm->trace; - nvm->trace.data = nvm; - - nvm->variables_hash = vm->variables_hash; - nvm->values_hash = vm->values_hash; - - nvm->modules = vm->modules; - nvm->modules_hash = vm->modules_hash; - - nvm->externals_hash = vm->externals_hash; - nvm->external_prototypes_hash = vm->external_prototypes_hash; - - items = vm->external_objects->items; - - externals = njs_arr_create(nvm->mem_pool, items + 4, sizeof(void *)); - if (njs_slow_path(externals == NULL)) { - return NULL; - } - - if (items > 0) { - memcpy(externals->start, vm->external_objects->start, - items * sizeof(void *)); - externals->items = items; - } - - nvm->external_objects = externals; - - nvm->options = vm->options; - - nvm->start = vm->start; - - nvm->external = external; + nvm = njs_mp_align(nmp, sizeof(njs_value_t), sizeof(njs_vm_t)); + if (njs_slow_path(nvm == NULL)) { + goto fail; + } - nvm->global_scope = vm->global_scope; - nvm->scope_size = vm->scope_size; + *nvm = *vm; - nvm->debug = vm->debug; + nvm->mem_pool = nmp; + nvm->trace.data = nvm; + nvm->external = external; - ret = njs_vm_init(nvm); - if (njs_slow_path(ret != NJS_OK)) { - goto fail; - } - - return nvm; + ret = njs_vm_init(nvm); + if (njs_slow_path(ret != NJS_OK)) { + goto fail; } + return nvm; + fail: njs_mp_destroy(nmp); @@ -325,7 +264,6 @@ njs_vm_init(njs_vm_t *vm) size_t size, scope_size; u_char *values; njs_int_t ret; - njs_arr_t *backtrace; njs_value_t *global; njs_frame_t *frame; @@ -353,10 +291,7 @@ njs_vm_init(njs_vm_t *vm) vm->scopes[NJS_SCOPE_GLOBAL] = (njs_value_t *) values; - if (vm->global_scope != 0) { - memcpy(values + NJS_INDEX_GLOBAL_OFFSET, vm->global_scope, - vm->scope_size); - } + memcpy(values + NJS_INDEX_GLOBAL_OFFSET, vm->global_scope, vm->scope_size); ret = njs_regexp_init(vm); if (njs_slow_path(ret != NJS_OK)) { @@ -373,20 +308,6 @@ njs_vm_init(njs_vm_t *vm) njs_lvlhsh_init(&vm->events_hash); njs_queue_init(&vm->posted_events); - if (vm->debug != NULL) { - backtrace = njs_arr_create(vm->mem_pool, 4, - sizeof(njs_backtrace_entry_t)); - if (njs_slow_path(backtrace == NULL)) { - return NJS_ERROR; - } - - vm->backtrace = backtrace; - } - - if (njs_is_null(&vm->retval)) { - njs_set_undefined(&vm->retval); - } - return NJS_OK; } @@ -1101,6 +1022,7 @@ njs_int_t njs_vm_add_backtrace_entry(njs_vm_t *vm, njs_frame_t *frame) { njs_int_t ret; + njs_arr_t *backtrace; njs_uint_t i; njs_function_t *function; njs_native_frame_t *native_frame; @@ -1108,6 +1030,16 @@ njs_vm_add_backtrace_entry(njs_vm_t *vm, njs_frame_t *frame) njs_function_lambda_t *lambda; njs_backtrace_entry_t *be; + if (njs_slow_path(vm->backtrace == NULL)) { + backtrace = njs_arr_create(vm->mem_pool, 4, + sizeof(njs_backtrace_entry_t)); + if (njs_slow_path(backtrace == NULL)) { + return NJS_ERROR; + } + + vm->backtrace = backtrace; + } + native_frame = &frame->native; function = native_frame->function; diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 0527a9cd..caeb24d7 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -896,7 +896,7 @@ error: if (catch != NULL) { pc = catch; - if (vm->debug != NULL) { + if (vm->backtrace != NULL) { njs_arr_reset(vm->backtrace); }