diff options
author | Havoc Pennington <hp@redhat.com> | 2004-11-13 07:07:47 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2004-11-13 07:07:47 +0000 |
commit | 1b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98 (patch) | |
tree | 8876649d553dbae0d210340e614ab5ba3da1cf87 /dbus | |
parent | aa1294405e5440306a9d1ce1f6c4e86f8793e9b8 (diff) |
2004-11-13 Havoc Pennington <hp@redhat.com>
* test/glib/test-profile.c: fix this thing up a bit
* dbus/dbus-message.c (dbus_message_new_empty_header): increase
preallocation sizes by a fair bit; not sure if this will be an
overall performance win or not, but it does reduce reallocs.
* dbus/dbus-string.c (set_length, reallocate_for_length): ignore
the test hack that forced constant realloc if asserts are
disabled, so we can profile sanely. Sprinkle in some
_DBUS_UNLIKELY() which are probably pointless, but before I
noticed the real performance problem I put them in.
(_dbus_string_validate_utf8): micro-optimize this thing a little
bit, though callgrind says it didn't help; then special-case
ascii, which did help a lot; then be sure we detect nul bytes as
invalid, which is a bugfix.
(align_length_then_lengthen): add some more _DBUS_UNLIKELY
superstition; use memset to nul the padding instead of a manual
loop.
(_dbus_string_get_length): inline this as a
macro; it showed up in the profile because it's used for loop
tests and so forth
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/dbus-message.c | 4 | ||||
-rw-r--r-- | dbus/dbus-string.c | 90 | ||||
-rw-r--r-- | dbus/dbus-string.h | 10 |
3 files changed, 74 insertions, 30 deletions
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index df0ade26..0b3b1bf2 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -493,11 +493,13 @@ get_type_alignment (int type) case DBUS_TYPE_ARRAY: _dbus_assert_not_reached ("passed an ARRAY type to get_type_alignment()"); + alignment = 0; /* quiet gcc */ break; case DBUS_TYPE_INVALID: default: _dbus_assert_not_reached ("passed an invalid or unknown type to get_type_alignment()"); + alignment = 0; /* quiet gcc */ break; } @@ -1355,7 +1357,7 @@ dbus_message_new_empty_header (void) ++i; } - if (!_dbus_string_init_preallocated (&message->header, 64)) + if (!_dbus_string_init_preallocated (&message->header, 256)) { dbus_free (message); return NULL; diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 7381dab2..75d22103 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -380,20 +380,28 @@ reallocate_for_length (DBusRealString *real, new_allocated = real->allocated * 2; /* if you change the code just above here, run the tests without - * the following before you commit + * the following assert-only hack before you commit */ + /* This is keyed off asserts in addition to tests so when you + * disable asserts to profile, you don't get this destroyer + * of profiles. + */ +#ifdef DBUS_DISABLE_ASSERT +#else #ifdef DBUS_BUILD_TESTS new_allocated = 0; /* ensure a realloc every time so that we go * through all malloc failure codepaths */ -#endif - +#endif /* DBUS_BUILD_TESTS */ +#endif /* !DBUS_DISABLE_ASSERT */ + /* But be sure we always alloc at least space for the new length */ - new_allocated = MAX (new_allocated, new_length + ALLOCATION_PADDING); + new_allocated = MAX (new_allocated, + new_length + ALLOCATION_PADDING); _dbus_assert (new_allocated >= real->allocated); /* code relies on this */ new_str = dbus_realloc (real->str - real->align_offset, new_allocated); - if (new_str == NULL) + if (_DBUS_UNLIKELY (new_str == NULL)) return FALSE; real->str = new_str + real->align_offset; @@ -410,15 +418,15 @@ set_length (DBusRealString *real, /* Note, we are setting the length not including nul termination */ /* exceeding max length is the same as failure to allocate memory */ - if (new_length > real->max_length) + if (_DBUS_UNLIKELY (new_length > real->max_length)) return FALSE; else if (new_length > (real->allocated - ALLOCATION_PADDING) && - !reallocate_for_length (real, new_length)) + _DBUS_UNLIKELY (!reallocate_for_length (real, new_length))) return FALSE; else { real->len = new_length; - real->str[real->len] = '\0'; + real->str[new_length] = '\0'; return TRUE; } } @@ -780,6 +788,8 @@ _dbus_string_copy_to_buffer (const DBusString *str, buffer[avail_len-1] = '\0'; } +/* Only have the function if we don't have the macro */ +#ifndef _dbus_string_get_length /** * Gets the length of a string (not including nul termination). * @@ -792,6 +802,7 @@ _dbus_string_get_length (const DBusString *str) return real->len; } +#endif /* !_dbus_string_get_length */ /** * Makes a string longer by the given number of bytes. Checks whether @@ -812,7 +823,7 @@ _dbus_string_lengthen (DBusString *str, DBUS_STRING_PREAMBLE (str); _dbus_assert (additional_length >= 0); - if (additional_length > real->max_length - real->len) + if (_DBUS_UNLIKELY (additional_length > real->max_length - real->len)) return FALSE; /* would overflow */ return set_length (real, @@ -869,7 +880,7 @@ align_length_then_lengthen (DBusString *str, _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */ new_len = _DBUS_ALIGN_VALUE (real->len, alignment); - if (new_len > (unsigned long) real->max_length - then_lengthen_by) + if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length - then_lengthen_by)) return FALSE; new_len += then_lengthen_by; @@ -879,21 +890,17 @@ align_length_then_lengthen (DBusString *str, if (delta == 0) return TRUE; - if (!set_length (real, new_len)) + if (_DBUS_UNLIKELY (!set_length (real, new_len))) return FALSE; /* delta == padding + then_lengthen_by * new_len == old_len + padding + then_lengthen_by + * nul the padding if we had to add any padding */ if (then_lengthen_by < delta) { - unsigned int i; - i = new_len - delta; - while (i < (new_len - then_lengthen_by)) - { - real->str[i] = '\0'; - ++i; - } + memset (&real->str[new_len - delta], '\0', + delta - then_lengthen_by); } return TRUE; @@ -1509,8 +1516,11 @@ _dbus_string_replace_len (const DBusString *source, Len = 6; \ Mask = 0x01; \ } \ - else \ - Len = -1; + else \ + { \ + Len = 0; \ + Mask = 0; \ + } /** * computes length of a unicode character in UTF-8 @@ -1590,7 +1600,7 @@ _dbus_string_get_unichar (const DBusString *str, c = *p; UTF8_COMPUTE (c, mask, len); - if (len == -1) + if (len == 0) return; UTF8_GET (result, p, i, mask, len); @@ -2431,29 +2441,51 @@ _dbus_string_validate_utf8 (const DBusString *str, while (p < end) { - int i, mask = 0, char_len; + int i, mask, char_len; dbus_unichar_t result; - unsigned char c = (unsigned char) *p; + + const unsigned char c = (unsigned char) *p; + + if (c == 0) /* nul bytes not OK */ + break; + + /* Special-case ASCII; this makes us go a lot faster in + * D-BUS profiles where we are typically validating + * function names and such. We have to know that + * all following checks will pass for ASCII though, + * comments follow ... + */ + if (c < 128) + { + ++p; + continue; + } UTF8_COMPUTE (c, mask, char_len); - if (_DBUS_UNLIKELY (char_len == -1)) + if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */ break; /* check that the expected number of bytes exists in the remaining length */ - if (_DBUS_UNLIKELY ((end - p) < char_len)) + if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */ break; UTF8_GET (result, p, i, mask, char_len); - if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* Check for overlong UTF-8 */ + /* Check for overlong UTF-8 */ + if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */ break; - - if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) +#if 0 + /* The UNICODE_VALID check below will catch this */ + if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */ break; +#endif - if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) + if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */ break; + + /* UNICODE_VALID should have caught it */ + _dbus_assert (result != (dbus_unichar_t)-1); p += char_len; } diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index 1a0236d4..cf526e43 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -49,6 +49,13 @@ struct DBusString unsigned int dummy8 : 3; /**< placeholder */ }; +/* Unless we want to run all the assertions in the function, + * inline this thing, it shows up high in the profile + */ +#ifdef DBUS_DISABLE_ASSERT +#define _dbus_string_get_length(s) ((s)->dummy2) +#endif + dbus_bool_t _dbus_string_init (DBusString *str); void _dbus_string_init_const (DBusString *str, const char *value); @@ -91,7 +98,10 @@ dbus_bool_t _dbus_string_copy_data_len (const DBusString *str, void _dbus_string_copy_to_buffer (const DBusString *str, char *buffer, int len); +#ifndef _dbus_string_get_length int _dbus_string_get_length (const DBusString *str); +#endif /* !_dbus_string_get_length */ + dbus_bool_t _dbus_string_lengthen (DBusString *str, int additional_length); void _dbus_string_shorten (DBusString *str, |