[njs] Optimized inlining of njs_values_strict_equal().
Valentin Bartenev
vbart at nginx.com
Thu Jul 11 13:11:11 UTC 2019
details: https://hg.nginx.org/njs/rev/ea18aa7693da
branches:
changeset: 1041:ea18aa7693da
user: Valentin Bartenev <vbart at nginx.com>
date: Thu Jul 11 16:10:33 2019 +0300
description:
Optimized inlining of njs_values_strict_equal().
This function is often called inside loops and basically it does only a few cmp
instructions that can be inlined.
The more complex part related to comparing of two strings is functionally
identical to njs_string_eq(), but contains an optimization that avoids memcmp()
when strings have different lengths. This optimization has been merged into
njs_string_eq().
No functional changes.
diffstat:
njs/njs_string.c | 24 ++++++++++++++++++-
njs/njs_string.h | 1 -
njs/njs_value.c | 71 --------------------------------------------------------
njs/njs_value.h | 29 +++++++++++++++++++++-
4 files changed, 50 insertions(+), 75 deletions(-)
diffs (186 lines):
diff -r b5f72739c00e -r ea18aa7693da njs/njs_string.c
--- a/njs/njs_string.c Thu Jul 11 15:42:33 2019 +0300
+++ b/njs/njs_string.c Thu Jul 11 16:10:33 2019 +0300
@@ -689,7 +689,7 @@ njs_string_instance_length(njs_vm_t *vm,
nxt_bool_t
njs_string_eq(const njs_value_t *v1, const njs_value_t *v2)
{
- size_t size;
+ size_t size, length1, length2;
const u_char *start1, *start2;
size = v1->short_string.size;
@@ -699,6 +699,17 @@ njs_string_eq(const njs_value_t *v1, con
}
if (size != NJS_STRING_LONG) {
+ length1 = v1->short_string.length;
+ length2 = v2->short_string.length;
+
+ /*
+ * Using full memcmp() comparison if at least one string
+ * is a Byte string.
+ */
+ if (length1 != 0 && length2 != 0 && length1 != length2) {
+ return 0;
+ }
+
start1 = v1->short_string.start;
start2 = v2->short_string.start;
@@ -709,6 +720,17 @@ njs_string_eq(const njs_value_t *v1, con
return 0;
}
+ length1 = v1->long_string.data->length;
+ length2 = v2->long_string.data->length;
+
+ /*
+ * Using full memcmp() comparison if at least one string
+ * is a Byte string.
+ */
+ if (length1 != 0 && length2 != 0 && length1 != length2) {
+ return 0;
+ }
+
start1 = v1->long_string.data->start;
start2 = v2->long_string.data->start;
}
diff -r b5f72739c00e -r ea18aa7693da njs/njs_string.h
--- a/njs/njs_string.h Thu Jul 11 15:42:33 2019 +0300
+++ b/njs/njs_string.h Thu Jul 11 16:10:33 2019 +0300
@@ -168,7 +168,6 @@ njs_ret_t njs_string_validate(njs_vm_t *
size_t njs_string_prop(njs_string_prop_t *string, const njs_value_t *value);
njs_ret_t njs_string_constructor(njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, njs_index_t unused);
-nxt_bool_t njs_string_eq(const njs_value_t *val1, const njs_value_t *val2);
nxt_int_t njs_string_cmp(const njs_value_t *val1, const njs_value_t *val2);
void njs_string_slice_string_prop(njs_string_prop_t *dst,
const njs_string_prop_t *string, const njs_slice_prop_t *slice);
diff -r b5f72739c00e -r ea18aa7693da njs/njs_value.c
--- a/njs/njs_value.c Thu Jul 11 15:42:33 2019 +0300
+++ b/njs/njs_value.c Thu Jul 11 16:10:33 2019 +0300
@@ -91,77 +91,6 @@ njs_value_release(njs_vm_t *vm, njs_valu
}
-nxt_bool_t
-njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2)
-{
- size_t size, length1, length2;
- const u_char *start1, *start2;
-
- if (val1->type != val2->type) {
- return 0;
- }
-
- if (njs_is_numeric(val1)) {
-
- if (njs_is_undefined(val1)) {
- return 1;
- }
-
- /* Infinities are handled correctly by comparision. */
- return (njs_number(val1) == njs_number(val2));
- }
-
- if (njs_is_string(val1)) {
- size = val1->short_string.size;
-
- if (size != val2->short_string.size) {
- return 0;
- }
-
- if (size != NJS_STRING_LONG) {
- length1 = val1->short_string.length;
- length2 = val2->short_string.length;
-
- /*
- * Using full memcmp() comparison if at least one string
- * is a Byte string.
- */
- if (length1 != 0 && length2 != 0 && length1 != length2) {
- return 0;
- }
-
- start1 = val1->short_string.start;
- start2 = val2->short_string.start;
-
- } else {
- size = val1->long_string.size;
-
- if (size != val2->long_string.size) {
- return 0;
- }
-
- length1 = val1->long_string.data->length;
- length2 = val2->long_string.data->length;
-
- /*
- * Using full memcmp() comparison if at least one string
- * is a Byte string.
- */
- if (length1 != 0 && length2 != 0 && length1 != length2) {
- return 0;
- }
-
- start1 = val1->long_string.data->start;
- start2 = val2->long_string.data->start;
- }
-
- return (memcmp(start1, start2, size) == 0);
- }
-
- return (njs_object(val1) == njs_object(val2));
-}
-
-
/*
* A hint value is 0 for numbers and 1 for strings. The value chooses
* method calls order specified by ECMAScript 5.1: "valueOf", "toString"
diff -r b5f72739c00e -r ea18aa7693da njs/njs_value.h
--- a/njs/njs_value.h Thu Jul 11 15:42:33 2019 +0300
+++ b/njs/njs_value.h Thu Jul 11 16:10:33 2019 +0300
@@ -685,8 +685,6 @@ njs_set_object_value(njs_value_t *value,
void njs_value_retain(njs_value_t *value);
void njs_value_release(njs_vm_t *vm, njs_value_t *value);
-nxt_bool_t njs_values_strict_equal(const njs_value_t *val1,
- const njs_value_t *val2);
njs_ret_t njs_value_to_primitive(njs_vm_t *vm, njs_value_t *value,
nxt_uint_t hint);
njs_array_t *njs_value_enumerate(njs_vm_t *vm, const njs_value_t *value,
@@ -696,6 +694,33 @@ njs_array_t *njs_value_own_enumerate(njs
const char *njs_type_string(njs_value_type_t type);
const char *njs_arg_type_string(uint8_t arg);
+nxt_bool_t njs_string_eq(const njs_value_t *v1, const njs_value_t *v2);
+
+
+nxt_inline nxt_bool_t
+njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2)
+{
+ if (val1->type != val2->type) {
+ return 0;
+ }
+
+ if (njs_is_numeric(val1)) {
+
+ if (njs_is_undefined(val1)) {
+ return 1;
+ }
+
+ /* Infinities are handled correctly by comparision. */
+ return (njs_number(val1) == njs_number(val2));
+ }
+
+ if (njs_is_string(val1)) {
+ return njs_string_eq(val1, val2);
+ }
+
+ return (njs_object(val1) == njs_object(val2));
+}
+
extern const njs_value_t njs_value_null;
extern const njs_value_t njs_value_undefined;
More information about the nginx-devel
mailing list