From: Dmitry Volyntsev Date: Tue, 6 Aug 2019 15:46:50 +0000 (+0300) Subject: Simplified njs_property_query() API by eliminating pq->shared. X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=852eb44b6e60ed9c2a1a71f3e081512f40c2a194;p=njs.git Simplified njs_property_query() API by eliminating pq->shared. Making copy of shared property in object's hash at the first access. It simplifies njs_property_query() API and speeds up next access to the property. --- diff --git a/src/njs_builtin.c b/src/njs_builtin.c index cd6928d2..6fc311a4 100644 --- a/src/njs_builtin.c +++ b/src/njs_builtin.c @@ -1172,7 +1172,7 @@ njs_process_object_argv(njs_vm_t *vm, njs_value_t *process, lhq.value = prop; lhq.key_hash = NJS_ARGV_HASH; lhq.key = njs_str_value("argv"); - lhq.replace = 0; + lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; @@ -1270,7 +1270,7 @@ njs_process_object_env(njs_vm_t *vm, njs_value_t *process, njs_set_object(&prop->value, env); - lhq.replace = 0; + lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; lhq.value = prop; diff --git a/src/njs_function.c b/src/njs_function.c index d0dd394d..f0d835af 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -815,13 +815,11 @@ njs_function_property_prototype_create(njs_vm_t *vm, njs_value_t *value) njs_function_t *function; prototype = njs_object_alloc(vm); - if (njs_slow_path(prototype == NULL)) { return NULL; } function = njs_function_value_copy(vm, value); - if (njs_slow_path(function == NULL)) { return NULL; } diff --git a/src/njs_object.c b/src/njs_object.c index 420f9e63..fce9e7a0 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -1611,9 +1611,9 @@ njs_value_t * njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_object_t *prototype) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_prop_t *prop; + njs_lvlhsh_query_t lhq; static const njs_value_t proto_string = njs_string("prototype"); @@ -1629,7 +1629,7 @@ njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash, lhq.value = prop; lhq.key_hash = NJS_PROTOTYPE_HASH; lhq.key = njs_str_value("prototype"); - lhq.replace = 0; + lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; diff --git a/src/njs_object.h b/src/njs_object.h index 3cc4c74d..4d4fd6cc 100644 --- a/src/njs_object.h +++ b/src/njs_object.h @@ -62,7 +62,6 @@ njs_int_t njs_object_prop_define(njs_vm_t *vm, njs_value_t *object, njs_value_t *name, njs_value_t *value); njs_int_t njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, njs_value_t *value, njs_value_t *setval); -njs_int_t njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq); const char *njs_prop_type_string(njs_object_prop_type_t type); extern const njs_object_init_t njs_object_constructor_init; diff --git a/src/njs_object_prop.c b/src/njs_object_prop.c index 14b2e648..c659bccf 100644 --- a/src/njs_object_prop.c +++ b/src/njs_object_prop.c @@ -156,14 +156,6 @@ njs_object_prop_define(njs_vm_t *vm, njs_value_t *object, /* Updating existing prop. */ - if (njs_slow_path(pq.shared)) { - ret = njs_prop_private_copy(vm, &pq); - - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - prev = pq.lhq.value; switch (prev->type) { @@ -458,6 +450,7 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, prop = pq.lhq.value; switch (prop->type) { + case NJS_METHOD: case NJS_PROPERTY: break; @@ -471,19 +464,6 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, break; - case NJS_METHOD: - if (pq.shared) { - ret = njs_prop_private_copy(vm, &pq); - - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - prop = pq.lhq.value; - } - - break; - default: njs_type_error(vm, "unexpected property type: %s", njs_prop_type_string(prop->type)); @@ -615,76 +595,6 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, } -njs_int_t -njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq) -{ - njs_int_t ret; - njs_function_t *function; - njs_object_prop_t *prop, *shared, *name; - njs_lvlhsh_query_t lhq; - - static const njs_value_t name_string = njs_string("name"); - - prop = njs_mp_align(vm->mem_pool, sizeof(njs_value_t), - sizeof(njs_object_prop_t)); - if (njs_slow_path(prop == NULL)) { - njs_memory_error(vm); - return NJS_ERROR; - } - - shared = pq->lhq.value; - *prop = *shared; - - pq->lhq.replace = 0; - pq->lhq.value = prop; - pq->lhq.pool = vm->mem_pool; - - ret = njs_lvlhsh_insert(&pq->prototype->hash, &pq->lhq); - if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); - return NJS_ERROR; - } - - if (!njs_is_function(&prop->value)) { - return NJS_OK; - } - - function = njs_function_value_copy(vm, &prop->value); - if (njs_slow_path(function == NULL)) { - return NJS_ERROR; - } - - if (function->ctor) { - function->object.shared_hash = vm->shared->function_instance_hash; - - } else { - function->object.shared_hash = vm->shared->arrow_instance_hash; - } - - name = njs_object_prop_alloc(vm, &name_string, &prop->name, 0); - if (njs_slow_path(name == NULL)) { - return NJS_ERROR; - } - - name->configurable = 1; - - lhq.key_hash = NJS_NAME_HASH; - lhq.key = njs_str_value("name"); - lhq.replace = 0; - lhq.value = name; - lhq.proto = &njs_object_hash_proto; - lhq.pool = vm->mem_pool; - - ret = njs_lvlhsh_insert(&function->object.hash, &lhq); - if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); - return NJS_ERROR; - } - - return NJS_OK; -} - - const char * njs_prop_type_string(njs_object_prop_type_t type) { diff --git a/src/njs_value.c b/src/njs_value.c index 4dd57e7d..536e0799 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -11,6 +11,7 @@ static njs_int_t njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_object_t *object, const njs_value_t *key); +static njs_int_t njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq); static njs_int_t njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_array_t *array, uint32_t index); static njs_int_t njs_string_property_query(njs_vm_t *vm, @@ -659,9 +660,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, ret = njs_lvlhsh_find(&proto->shared_hash, &pq->lhq); if (ret == NJS_OK) { - pq->shared = 1; - - return ret; + return njs_prop_private_copy(vm, pq); } } @@ -678,6 +677,76 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, } +static njs_int_t +njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq) +{ + njs_int_t ret; + njs_function_t *function; + njs_object_prop_t *prop, *shared, *name; + njs_lvlhsh_query_t lhq; + + static const njs_value_t name_string = njs_string("name"); + + prop = njs_mp_align(vm->mem_pool, sizeof(njs_value_t), + sizeof(njs_object_prop_t)); + if (njs_slow_path(prop == NULL)) { + njs_memory_error(vm); + return NJS_ERROR; + } + + shared = pq->lhq.value; + *prop = *shared; + + pq->lhq.replace = 0; + pq->lhq.value = prop; + pq->lhq.pool = vm->mem_pool; + + ret = njs_lvlhsh_insert(&pq->prototype->hash, &pq->lhq); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); + return NJS_ERROR; + } + + if (!njs_is_function(&prop->value)) { + return NJS_OK; + } + + function = njs_function_value_copy(vm, &prop->value); + if (njs_slow_path(function == NULL)) { + return NJS_ERROR; + } + + if (function->ctor) { + function->object.shared_hash = vm->shared->function_instance_hash; + + } else { + function->object.shared_hash = vm->shared->arrow_instance_hash; + } + + name = njs_object_prop_alloc(vm, &name_string, &prop->name, 0); + if (njs_slow_path(name == NULL)) { + return NJS_ERROR; + } + + name->configurable = 1; + + lhq.key_hash = NJS_NAME_HASH; + lhq.key = njs_str_value("name"); + lhq.replace = 0; + lhq.value = name; + lhq.proto = &njs_object_hash_proto; + lhq.pool = vm->mem_pool; + + ret = njs_lvlhsh_insert(&function->object.hash, &lhq); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "lvlhsh insert failed"); + return NJS_ERROR; + } + + return NJS_OK; +} + + static njs_int_t njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_array_t *array, uint32_t index) @@ -931,18 +1000,6 @@ njs_value_property(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, switch (prop->type) { case NJS_METHOD: - if (pq.shared) { - ret = njs_prop_private_copy(vm, &pq); - - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - prop = pq.lhq.value; - } - - /* Fall through. */ - case NJS_PROPERTY: if (njs_is_data_descriptor(prop)) { *retval = prop->value; @@ -1052,11 +1109,6 @@ njs_value_property_set(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, switch (prop->type) { case NJS_PROPERTY: case NJS_METHOD: - if (njs_slow_path(pq.shared)) { - shared = prop; - break; - } - goto found; case NJS_PROPERTY_REF: diff --git a/src/njs_value.h b/src/njs_value.h index 1896f00b..91184c47 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -352,7 +352,6 @@ typedef struct { njs_object_t *prototype; njs_object_prop_t *own_whiteout; uint8_t query; - uint8_t shared; uint8_t own; } njs_property_query_t; @@ -799,7 +798,6 @@ njs_set_object_value(njs_value_t *value, njs_object_value_t *object_value) (pq)->lhq.value = NULL; \ (pq)->own_whiteout = NULL; \ (pq)->query = _query; \ - (pq)->shared = 0; \ (pq)->own = _own; \ } while (0) diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 80323e70..272e7573 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -1224,7 +1224,7 @@ static njs_jump_off_t njs_vmcode_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key) { njs_jump_off_t ret; - njs_object_prop_t *prop, *whipeout; + njs_object_prop_t *prop; njs_property_query_t pq; njs_property_query_init(&pq, NJS_PROPERTY_QUERY_DELETE, 1); @@ -1242,32 +1242,19 @@ njs_vmcode_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key) return NJS_ERROR; } - if (njs_slow_path(pq.shared)) { - whipeout = njs_mp_align(vm->mem_pool, sizeof(njs_value_t), - sizeof(njs_object_prop_t)); - if (njs_slow_path(whipeout == NULL)) { - njs_memory_error(vm); - return NJS_ERROR; - } - - njs_set_invalid(&whipeout->value); - whipeout->name = prop->name; - whipeout->type = NJS_WHITEOUT; - - pq.lhq.replace = 0; - pq.lhq.value = whipeout; - pq.lhq.pool = vm->mem_pool; + switch (prop->type) { + case NJS_PROPERTY_HANDLER: + if (njs_is_external(value)) { + ret = prop->value.data.u.prop_handler(vm, value, NULL, NULL); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } - ret = njs_lvlhsh_insert(&pq.prototype->hash, &pq.lhq); - if (njs_slow_path(ret != NJS_OK)) { - njs_internal_error(vm, "lvlhsh insert failed"); - return NJS_ERROR; + goto done; } - break; - } + /* Fall through. */ - switch (prop->type) { case NJS_PROPERTY: case NJS_METHOD: break; @@ -1276,14 +1263,6 @@ njs_vmcode_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key) njs_set_invalid(prop->value.data.u.value); goto done; - case NJS_PROPERTY_HANDLER: - ret = prop->value.data.u.prop_handler(vm, value, NULL, NULL); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - goto done; - default: njs_internal_error(vm, "unexpected property type \"%s\" " "while deleting",