[njs] Optimizing njs_vm_clone() for speed.
Dmitry Volyntsev
xeioex at nginx.com
Fri Oct 25 13:20:50 UTC 2019
details: https://hg.nginx.org/njs/rev/7e7d0dac4572
branches:
changeset: 1202:7e7d0dac4572
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Fri Oct 25 16:20:37 2019 +0300
description:
Optimizing njs_vm_clone() for speed.
Postponing allocation of structures where possible.
diffstat:
src/njs_builtin.c | 34 ++++++-
src/njs_extern.c | 13 ++-
src/njs_vm.c | 224 ++++++++++++++++++-----------------------------------
src/njs_vmcode.c | 2 +-
4 files changed, 120 insertions(+), 153 deletions(-)
diffs (427 lines):
diff -r d849bf348b0d -r 7e7d0dac4572 src/njs_builtin.c
--- a/src/njs_builtin.c Thu Oct 24 16:17:17 2019 +0300
+++ b/src/njs_builtin.c Fri Oct 25 16:20:37 2019 +0300
@@ -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,
}
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 -r d849bf348b0d -r 7e7d0dac4572 src/njs_extern.c
--- a/src/njs_extern.c Thu Oct 24 16:17:17 2019 +0300
+++ b/src/njs_extern.c Fri Oct 25 16:20:37 2019 +0300
@@ -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 -r d849bf348b0d -r 7e7d0dac4572 src/njs_vm.c
--- a/src/njs_vm.c Thu Oct 24 16:17:17 2019 +0300
+++ b/src/njs_vm.c Fri Oct 25 16:20:37 2019 +0300
@@ -22,11 +22,10 @@ const njs_str_t njs_entry_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,86 +33,63 @@ 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;
+ 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;
+
+ } else {
+ ret = njs_builtin_objects_create(vm);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NULL;
+ }
+ }
+
+ njs_lvlhsh_init(&vm->values_hash);
- ret = njs_regexp_init(vm);
- if (njs_slow_path(ret != NJS_OK)) {
+ vm->external = options->external;
+
+ vm->external_objects = njs_arr_create(vm->mem_pool, 4, sizeof(void *));
+ if (njs_slow_path(vm->external_objects == 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;
+
+ njs_set_undefined(&vm->retval);
+
+ 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->options = *options;
-
- if (options->shared != NULL) {
- vm->shared = options->shared;
-
- } else {
- vm->shared = njs_mp_zalloc(mp, sizeof(njs_vm_shared_t));
- if (njs_slow_path(vm->shared == NULL)) {
- return NULL;
- }
-
- options->shared = vm->shared;
-
- njs_lvlhsh_init(&vm->shared->keywords_hash);
-
- ret = njs_lexer_keywords_init(mp, &vm->shared->keywords_hash);
- if (njs_slow_path(ret != NJS_OK)) {
- return NULL;
- }
-
- njs_lvlhsh_init(&vm->shared->values_hash);
-
- pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)",
- njs_length("(?:)"), 0);
- if (njs_slow_path(pattern == NULL)) {
- return NULL;
- }
-
- vm->shared->empty_regexp_pattern = pattern;
-
- njs_lvlhsh_init(&vm->modules_hash);
+ vm->debug = debug;
+ }
- ret = njs_builtin_objects_create(vm);
- if (njs_slow_path(ret != NJS_OK)) {
- return NULL;
- }
- }
-
- njs_lvlhsh_init(&vm->values_hash);
-
- vm->external = options->external;
-
- vm->external_objects = njs_arr_create(vm->mem_pool, 4, sizeof(void *));
- if (njs_slow_path(vm->external_objects == NULL)) {
+ if (options->accumulative) {
+ ret = njs_vm_init(vm);
+ if (njs_slow_path(ret != NJS_OK)) {
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;
- }
-
- if (options->accumulative) {
- ret = njs_vm_init(vm);
- if (njs_slow_path(ret != NJS_OK)) {
- return NULL;
- }
- }
}
return vm;
@@ -243,9 +219,7 @@ njs_vm_clone(njs_vm_t *vm, njs_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,58 +232,23 @@ njs_vm_clone(njs_vm_t *vm, njs_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 = njs_mp_align(nmp, sizeof(njs_value_t), sizeof(njs_vm_t));
+ if (njs_slow_path(nvm == NULL)) {
+ goto fail;
+ }
- 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;
- }
+ *nvm = *vm;
- 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->mem_pool = nmp;
+ nvm->trace.data = nvm;
+ nvm->external = external;
- nvm->external = external;
-
- nvm->global_scope = vm->global_scope;
- nvm->scope_size = vm->scope_size;
-
- nvm->debug = vm->debug;
+ ret = njs_vm_init(nvm);
+ if (njs_slow_path(ret != NJS_OK)) {
+ goto fail;
+ }
- ret = njs_vm_init(nvm);
- if (njs_slow_path(ret != NJS_OK)) {
- goto fail;
- }
-
- return nvm;
- }
+ return nvm;
fail:
@@ -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_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 -r d849bf348b0d -r 7e7d0dac4572 src/njs_vmcode.c
--- a/src/njs_vmcode.c Thu Oct 24 16:17:17 2019 +0300
+++ b/src/njs_vmcode.c Fri Oct 25 16:20:37 2019 +0300
@@ -896,7 +896,7 @@ error:
if (catch != NULL) {
pc = catch;
- if (vm->debug != NULL) {
+ if (vm->backtrace != NULL) {
njs_arr_reset(vm->backtrace);
}
More information about the nginx-devel
mailing list