diff --git a/src/njs.h b/src/njs.h index 38819ecfd..4e1c844e7 100644 --- a/src/njs.h +++ b/src/njs.h @@ -290,6 +290,8 @@ typedef njs_int_t (*njs_iterator_handler_t)(njs_vm_t *vm, NJS_EXPORT void njs_vm_opt_init(njs_vm_opt_t *options); +NJS_EXPORT njs_vm_t *njs_vm_create_parent(njs_vm_opt_t *options, + njs_vm_t *vm_parent); NJS_EXPORT njs_vm_t *njs_vm_create(njs_vm_opt_t *options); NJS_EXPORT void njs_vm_destroy(njs_vm_t *vm); diff --git a/src/njs_atom.h b/src/njs_atom.h index 9ece3a20e..fa8283101 100644 --- a/src/njs_atom.h +++ b/src/njs_atom.h @@ -35,5 +35,6 @@ void njs_atom_hash_init(void); extern njs_atom_values_t njs_atom; extern njs_flathsh_t njs_atom_hash; +extern uint32_t njs_atom_hash_atom_id; #endif /* _NJS_ATOM_H_INCLUDED_ */ diff --git a/src/njs_builtin.c b/src/njs_builtin.c index 754cf84bb..e69793002 100644 --- a/src/njs_builtin.c +++ b/src/njs_builtin.c @@ -108,7 +108,7 @@ njs_object_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_int_t -njs_builtin_objects_create(njs_vm_t *vm) +njs_builtin_objects_create(njs_vm_t *vm, njs_vm_t *vm_parent) { njs_int_t ret, index; njs_uint_t i; @@ -127,10 +127,31 @@ njs_builtin_objects_create(njs_vm_t *vm) vm->shared = shared; njs_lvlhsh_init(&shared->keywords_hash); + njs_lvlhsh_init(&shared->values_hash); njs_atom_hash_init(); + if (vm_parent == NULL) { + /* njs_lvlhsh_init(&vm->atom_hash_shared); // done by zalign */ + + ret = njs_flathsh_alloc_copy(vm->mem_pool, &vm->atom_hash, + &njs_atom_hash); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } + vm->atom_hash_mem_pool = vm->mem_pool; + vm->atom_hash_atom_id = njs_atom_hash_atom_id; + + } else { + vm->atom_hash_shared = vm_parent->atom_hash_shared; + + vm->atom_hash = vm_parent->atom_hash; + vm->atom_hash_mem_pool = vm_parent->mem_pool; + vm->atom_hash_atom_id = vm_parent->atom_hash_atom_id; + + } + pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)", njs_length("(?:)"), 0); if (njs_slow_path(pattern == NULL)) { diff --git a/src/njs_flathsh.c b/src/njs_flathsh.c index c823c4660..c48fec4fd 100644 --- a/src/njs_flathsh.c +++ b/src/njs_flathsh.c @@ -573,3 +573,31 @@ njs_flathsh_each(const njs_flathsh_t *fh, njs_flathsh_each_t *fhe) return NULL; } + + +njs_int_t +njs_flathsh_alloc_copy(njs_mp_t *mp, njs_flathsh_t *to, njs_flathsh_t *from) +{ + void *from_chunk, *to_chunk; + uint32_t from_size; + njs_flathsh_descr_t *from_descr; + + from_descr = from->slot; + + from_size = sizeof(uint32_t) * (from_descr->hash_mask + 1ul) + + sizeof(njs_flathsh_descr_t) + + sizeof(njs_flathsh_elt_t) * from_descr->elts_size; + + to_chunk = njs_mp_alloc(mp, from_size); + if (njs_slow_path(to_chunk == NULL)) { + return NJS_ERROR; + } + + from_chunk = njs_flathsh_chunk(from_descr); + + memcpy(to_chunk, from_chunk, from_size); + + to->slot = (char *)to_chunk + ((char *)from_descr - (char *)from_chunk); + + return NJS_OK; +} diff --git a/src/njs_flathsh.h b/src/njs_flathsh.h index d347bb813..a69792314 100644 --- a/src/njs_flathsh.h +++ b/src/njs_flathsh.h @@ -132,6 +132,9 @@ NJS_EXPORT njs_flathsh_elt_t *njs_flathsh_add_elt(njs_flathsh_t *fh, 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); +NJS_EXPORT njs_int_t njs_flathsh_alloc_copy(njs_mp_t *mp, njs_flathsh_t *to, + njs_flathsh_t *from); + /* Temporary backward compatibility .*/ diff --git a/src/njs_main.h b/src/njs_main.h index 09a0d1dcb..8715f4ac3 100644 --- a/src/njs_main.h +++ b/src/njs_main.h @@ -25,11 +25,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include diff --git a/src/njs_vm.c b/src/njs_vm.c index 4c6c0bbd5..ea04157fa 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -29,7 +29,7 @@ njs_vm_opt_init(njs_vm_opt_t *options) njs_vm_t * -njs_vm_create(njs_vm_opt_t *options) +njs_vm_create_parent(njs_vm_opt_t *options, njs_vm_t *vm_parent) { njs_mp_t *mp; njs_vm_t *vm; @@ -62,12 +62,14 @@ njs_vm_create(njs_vm_opt_t *options) vm->shared = options->shared; } else { - ret = njs_builtin_objects_create(vm); + ret = njs_builtin_objects_create(vm, vm_parent); if (njs_slow_path(ret != NJS_OK)) { return NULL; } } +//vm->is_cloned = 0; //?? + vm->external = options->external; vm->spare_stack_size = options->max_stack_size; @@ -148,6 +150,13 @@ njs_vm_create(njs_vm_opt_t *options) } +njs_vm_t * +njs_vm_create(njs_vm_opt_t *options) +{ + return njs_vm_create_parent(options, NULL); +} + + njs_int_t njs_vm_ctor_push(njs_vm_t *vm) { @@ -408,6 +417,13 @@ njs_vm_clone(njs_vm_t *vm, njs_external_ptr_t external) nvm->trace.data = nvm; nvm->external = external; + nvm->atom_hash_shared = vm->atom_hash; + + njs_lvlhsh_init(&nvm->atom_hash); + nvm->atom_hash_mem_pool = nvm->mem_pool; + nvm->atom_hash_atom_id = vm->atom_hash_atom_id; +//?? nvm->is_clone = 1; + ret = njs_vm_runtime_init(nvm); if (njs_slow_path(ret != NJS_OK)) { goto fail; diff --git a/src/njs_vm.h b/src/njs_vm.h index 6d09caf8f..c4cd12510 100644 --- a/src/njs_vm.h +++ b/src/njs_vm.h @@ -128,6 +128,11 @@ struct njs_vm_s { njs_native_frame_t *top_frame; njs_frame_t *active_frame; + njs_lvlhsh_t atom_hash_shared; + njs_lvlhsh_t atom_hash; + njs_mp_t *atom_hash_mem_pool; + uint32_t atom_hash_atom_id; + njs_lvlhsh_t keywords_hash; njs_lvlhsh_t values_hash; @@ -243,7 +248,7 @@ void njs_vm_constructors_init(njs_vm_t *vm); njs_value_t njs_vm_exception(njs_vm_t *vm); void njs_vm_scopes_restore(njs_vm_t *vm, njs_native_frame_t *frame); -njs_int_t njs_builtin_objects_create(njs_vm_t *vm); +njs_int_t njs_builtin_objects_create(njs_vm_t *vm, njs_vm_t *vm_parent); njs_int_t njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function, njs_str_t *name);