[njs] Array creation and reallocation optimizations.
Igor Sysoev
igor at sysoev.ru
Mon Oct 24 12:03:50 UTC 2016
details: http://hg.nginx.org/njs/rev/bf848210269c
branches:
changeset: 212:bf848210269c
user: Igor Sysoev <igor at sysoev.ru>
date: Mon Oct 24 14:12:12 2016 +0300
description:
Array creation and reallocation optimizations.
diffstat:
njs/njs_array.c | 35 ++++++++++-------------------------
njs/njs_disassembler.c | 5 +++--
njs/njs_generator.c | 6 +-----
njs/njs_parser.c | 5 +++--
njs/njs_vm.c | 41 ++++++++++++++++++++++++++++++-----------
5 files changed, 47 insertions(+), 45 deletions(-)
diffs (213 lines):
diff -r cec366d97854 -r bf848210269c njs/njs_array.c
--- a/njs/njs_array.c Sat Oct 22 20:24:32 2016 +0300
+++ b/njs/njs_array.c Mon Oct 24 14:12:12 2016 +0300
@@ -184,8 +184,7 @@ njs_ret_t
njs_array_realloc(njs_vm_t *vm, njs_array_t *array, uint32_t prepend,
uint32_t size)
{
- nxt_uint_t n;
- njs_value_t *value, *old;
+ njs_value_t *start, *old;
if (size != array->size) {
if (size < 16) {
@@ -196,35 +195,21 @@ njs_array_realloc(njs_vm_t *vm, njs_arra
}
}
- value = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t),
+ start = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t),
(prepend + size) * sizeof(njs_value_t));
- if (nxt_slow_path(value == NULL)) {
+ if (nxt_slow_path(start == NULL)) {
return NXT_ERROR;
}
- old = array->data;
- array->data = value;
-
- while (prepend != 0) {
- njs_set_invalid(value);
- value++;
- prepend--;
- }
-
- memcpy(value, array->start, array->size * sizeof(njs_value_t));
-
- array->start = value;
- n = array->size;
array->size = size;
- value += n;
- size -= n;
+ old = array->data;
+ array->data = start;
+ start += prepend;
- while (size != 0) {
- njs_set_invalid(value);
- value++;
- size--;
- }
+ memcpy(start, array->start, array->length * sizeof(njs_value_t));
+
+ array->start = start;
nxt_mem_cache_free(vm->mem_cache_pool, old);
@@ -515,7 +500,7 @@ njs_array_prototype_unshift(njs_vm_t *vm
if (n != 0) {
if ((intptr_t) n > (array->start - array->data)) {
- ret = njs_array_realloc(vm, array, n, array->size);
+ ret = njs_array_realloc(vm, array, n, 0);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}
diff -r cec366d97854 -r bf848210269c njs/njs_disassembler.c
--- a/njs/njs_disassembler.c Sat Oct 22 20:24:32 2016 +0300
+++ b/njs/njs_disassembler.c Mon Oct 24 14:12:12 2016 +0300
@@ -197,8 +197,9 @@ njs_disassemble(u_char *start, u_char *e
if (operation == njs_vmcode_array) {
array = (njs_vmcode_array_t *) p;
- printf("%05zd ARRAY %04zX %zd\n",
- p - start, (size_t) array->retval, (size_t) array->length);
+ printf("%05zd ARRAY %04zX %zd%s\n",
+ p - start, (size_t) array->retval, (size_t) array->length,
+ array->code.ctor ? " INIT" : "");
p += sizeof(njs_vmcode_array_t);
diff -r cec366d97854 -r bf848210269c njs/njs_generator.c
--- a/njs/njs_generator.c Sat Oct 22 20:24:32 2016 +0300
+++ b/njs/njs_generator.c Mon Oct 24 14:12:12 2016 +0300
@@ -1510,15 +1510,11 @@ njs_generate_array(njs_vm_t *vm, njs_par
array->code.operation = njs_vmcode_array;
array->code.operands = NJS_VMCODE_1OPERAND;
array->code.retval = NJS_VMCODE_RETVAL;
+ array->code.ctor = node->ctor;
array->retval = node->index;
array->length = node->u.length;
- if (node->left == NULL) {
- return NXT_OK;
- }
-
/* Initialize array. */
-
return njs_generator(vm, parser, node->left);
}
diff -r cec366d97854 -r bf848210269c njs/njs_parser.c
--- a/njs/njs_parser.c Sat Oct 22 20:24:32 2016 +0300
+++ b/njs/njs_parser.c Mon Oct 24 14:12:12 2016 +0300
@@ -1885,6 +1885,7 @@ njs_parser_array(njs_vm_t *vm, njs_parse
}
if (token == NJS_TOKEN_COMMA) {
+ obj->ctor = 1;
index++;
continue;
}
@@ -1942,11 +1943,11 @@ njs_parser_array(njs_vm_t *vm, njs_parse
stmt->left = left;
stmt->right = assign;
- parser->code_size += sizeof(njs_vmcode_2addr_t);
parser->node = stmt;
-
left = stmt;
+ obj->ctor = 0;
+
if (token == NJS_TOKEN_CLOSE_BRACKET) {
break;
}
diff -r cec366d97854 -r bf848210269c njs/njs_vm.c
--- a/njs/njs_vm.c Sat Oct 22 20:24:32 2016 +0300
+++ b/njs/njs_vm.c Mon Oct 24 14:12:12 2016 +0300
@@ -366,7 +366,7 @@ njs_vmcode_object(njs_vm_t *vm, njs_valu
njs_ret_t
njs_vmcode_array(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
{
- uint32_t size;
+ uint32_t length;
njs_array_t *array;
njs_value_t *value;
njs_vmcode_array_t *code;
@@ -376,14 +376,22 @@ njs_vmcode_array(njs_vm_t *vm, njs_value
array = njs_array_alloc(vm, code->length, NJS_ARRAY_SPARE);
if (nxt_fast_path(array != NULL)) {
- size = array->size;
- value = array->start;
-
- do {
- njs_set_invalid(value);
- value++;
- size--;
- } while (size != 0);
+
+ if (code->code.ctor) {
+ /* Array of the form [,,,], [1,,]. */
+ value = array->start;
+ length = array->length;
+
+ do {
+ njs_set_invalid(value);
+ value++;
+ length--;
+ } while (length != 0);
+
+ } else {
+ /* Array of the form [], [,,1], [1,2,3]. */
+ array->length = 0;
+ }
vm->retval.data.u.array = array;
vm->retval.type = NJS_ARRAY;
@@ -1039,7 +1047,9 @@ static njs_ret_t
njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq,
njs_value_t *object, int32_t index)
{
+ size_t size;
njs_ret_t ret;
+ njs_value_t *value;
njs_array_t *array;
array = object->data.u.array;
@@ -1057,6 +1067,15 @@ njs_array_property_query(njs_vm_t *vm, n
}
}
+ value = &array->start[array->length];
+ size = index - array->length;
+
+ while (size != 0) {
+ njs_set_invalid(value);
+ value++;
+ size--;
+ }
+
array->length = index + 1;
}
@@ -1182,7 +1201,7 @@ njs_vmcode_property_foreach(njs_vm_t *vm
next->lhe.proto = &njs_object_hash_proto;
next->index = -1;
- if (njs_is_array(object) && object->data.u.array->size != 0) {
+ if (njs_is_array(object) && object->data.u.array->length != 0) {
next->index = 0;
}
@@ -1222,7 +1241,7 @@ njs_vmcode_property_next(njs_vm_t *vm, n
if (next->index >= 0) {
array = object->data.u.array;
- while ((uint32_t) next->index < array->size) {
+ while ((uint32_t) next->index < array->length) {
n = next->index++;
if (njs_is_valid(&array->start[n])) {
More information about the nginx-devel
mailing list