From: Igor Sysoev Date: Mon, 24 Oct 2016 11:12:12 +0000 (+0300) Subject: Array creation and reallocation optimizations. X-Git-Tag: 0.1.4~2 X-Git-Url: http://git.kaiwu.me/sitemap.xml?a=commitdiff_plain;h=d64fbffcccfbe77bd0b99be1a8fb31c797dd0340;p=njs.git Array creation and reallocation optimizations. --- diff --git a/njs/njs_array.c b/njs/njs_array.c index c93d6c1f..aa8f9e68 100644 --- a/njs/njs_array.c +++ b/njs/njs_array.c @@ -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_array_t *array, uint32_t prepend, } } - 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, njs_value_t *args, nxt_uint_t nargs, 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 --git a/njs/njs_disassembler.c b/njs/njs_disassembler.c index de69d611..2b4e0bda 100644 --- a/njs/njs_disassembler.c +++ b/njs/njs_disassembler.c @@ -197,8 +197,9 @@ njs_disassemble(u_char *start, u_char *end) 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 --git a/njs/njs_generator.c b/njs/njs_generator.c index e0bf18b1..dce4601d 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -1510,15 +1510,11 @@ njs_generate_array(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node) 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 --git a/njs/njs_parser.c b/njs/njs_parser.c index bb42bd55..f500fbd3 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -1885,6 +1885,7 @@ njs_parser_array(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj) } if (token == NJS_TOKEN_COMMA) { + obj->ctor = 1; index++; continue; } @@ -1942,11 +1943,11 @@ njs_parser_array(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj) 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 --git a/njs/njs_vm.c b/njs/njs_vm.c index 2b8ae555..5090653a 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -366,7 +366,7 @@ njs_vmcode_object(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) 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_t *invld1, njs_value_t *invld2) 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, njs_property_query_t *pq, } } + 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, njs_value_t *object, 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, njs_value_t *object, njs_value_t *value) 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])) {