]> git.kaiwu.me - njs.git/commitdiff
Optimized inlining of njs_values_strict_equal().
authorValentin Bartenev <vbart@nginx.com>
Thu, 11 Jul 2019 13:10:33 +0000 (16:10 +0300)
committerValentin Bartenev <vbart@nginx.com>
Thu, 11 Jul 2019 13:10:33 +0000 (16:10 +0300)
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.

njs/njs_string.c
njs/njs_string.h
njs/njs_value.c
njs/njs_value.h

index b6a21a542d47a0d76f84217d5c5336a8f71038fe..050f25fef07043d88e993a72c869d9376d460087 100644 (file)
@@ -689,7 +689,7 @@ njs_string_instance_length(njs_vm_t *vm, njs_value_t *value,
 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, const njs_value_t *v2)
     }
 
     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, const njs_value_t *v2)
             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;
     }
index b8426ae9f90e184c3210c868a4a80fa81cd205c3..6f47db1a9a23a48ccd9f444e71e4a0f63b6a4a3c 100644 (file)
@@ -168,7 +168,6 @@ njs_ret_t njs_string_validate(njs_vm_t *vm, njs_string_prop_t *string,
 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);
index 511720a69df6079a41de6759ac2b68b16da91d16..16207a5a417732eaf95386a42d4121bd3487744f 100644 (file)
@@ -91,77 +91,6 @@ 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)
-{
-    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"
index e7025cbbe16c08bf57a9b883694eff89ad030f94..c614630d3f17a99c63fa1b0917eba69a89fd41a1 100644 (file)
@@ -685,8 +685,6 @@ njs_set_object_value(njs_value_t *value, njs_object_value_t *object_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_vm_t *vm, const njs_value_t *value,
 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;