Changeset: 0999d205de17 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0999d205de17
Modified Files:
gdk/gdk_string.c
Branch: default
Log Message:
Speed up GDKstrFromStr a little by providing branch prediction annotations.
diffs (234 lines):
diff --git a/gdk/gdk_string.c b/gdk/gdk_string.c
--- a/gdk/gdk_string.c
+++ b/gdk/gdk_string.c
@@ -176,6 +176,29 @@ strLocate(Heap *h, const char *v)
return 0;
}
+#ifdef __GNUC__
+/* __builtin_expect returns its first argument; it is expected to be
+ * equal to the second argument */
+#define unlikely(expr) __builtin_expect((expr) != 0, 0)
+#define likely(expr) __builtin_expect((expr) != 0, 1)
+#else
+#define unlikely(expr) (expr)
+#define likely(expr) (expr)
+#endif
+
+/*
+ * UTF-8 encoding is as follows:
+ * U-00000000 - U-0000007F: 0xxxxxxx
+ * U-00000080 - U-000007FF: 110zzzzx 10xxxxxx
+ * U-00000800 - U-0000FFFF: 1110zzzz 10zxxxxx 10xxxxxx
+ * U-00010000 - U-0010FFFF: 11110zzz 10zzxxxx 10xxxxxx 10xxxxxx
+ *
+ * To be correctly coded UTF-8, the sequence should be the shortest
+ * possible encoding of the value being encoded. This means that at
+ * least one of the z bits must be non-zero. Also note that the four
+ * byte sequence can encode more than is allowed and that the values
+ * U+D800..U+DFFF are not allowed to be encoded.
+ */
static inline gdk_return
checkUTF8(const char *v)
{
@@ -185,11 +208,6 @@ checkUTF8(const char *v)
* unlikely to succeed, i.e. the ones that lead to a return of
* GDK_FAIL, as being expected to return 0 using the
* __builtin_expect function. */
-#ifndef __GNUC__
- /* __builtin_expect returns its first argument; it is expected
- * to be equal to the second argument */
-#define __builtin_expect(expr, expect) (expr)
-#endif
if (v[0] != '\200' || v[1] != '\0') {
/* check that string is correctly encoded UTF-8 */
for (size_t i = 0; v[i]; i++) {
@@ -199,27 +217,27 @@ checkUTF8(const char *v)
if ((v[i] & 0x80) == 0) {
;
} else if ((v[i] & 0xE0) == 0xC0) {
- if (__builtin_expect((v[i] & 0x1E) == 0, 0))
+ if (unlikely((v[i] & 0x1E) == 0))
return GDK_FAIL;
- if (__builtin_expect((v[++i] & 0xC0) != 0x80,
0))
+ if (unlikely((v[++i] & 0xC0) != 0x80))
return GDK_FAIL;
} else if ((v[i] & 0xF0) == 0xE0) {
- if (__builtin_expect((v[++i] & 0xC0) != 0x80,
0))
+ if (unlikely((v[++i] & 0xC0) != 0x80))
return GDK_FAIL;
if ((v[i] & 0x0F) == 0) {
- if (__builtin_expect((v[++i] & 0xE0) !=
0xA0, 0))
+ if (unlikely((v[++i] & 0xE0) != 0xA0))
return GDK_FAIL;
- } else if (__builtin_expect((v[++i] & 0xC0) !=
0x80, 0))
+ } else if (unlikely((v[++i] & 0xC0) != 0x80))
return GDK_FAIL;
} else if ((v[i] & 0xF8) == 0xF0) {
- if (__builtin_expect((v[i+1] & 0x07) == 0 &&
- (v[i+2] & 0x30) == 0, 0))
+ if (unlikely((v[i+1] & 0x07) == 0 &&
+ (v[i+2] & 0x30) == 0))
return GDK_FAIL;
- if (__builtin_expect((v[++i] & 0xC0) != 0x80,
0))
+ if (unlikely((v[++i] & 0xC0) != 0x80))
return GDK_FAIL;
- if (__builtin_expect((v[++i] & 0xC0) != 0x80,
0))
+ if (unlikely((v[++i] & 0xC0) != 0x80))
return GDK_FAIL;
- if (__builtin_expect((v[++i] & 0xC0) != 0x80,
0))
+ if (unlikely((v[++i] & 0xC0) != 0x80))
return GDK_FAIL;
} else {
return GDK_FAIL;
@@ -367,29 +385,6 @@ strPut(BAT *b, var_t *dst, const void *V
* the input is correct UTF-8.
*/
-/*
- UTF-8 encoding is as follows:
-U-00000000 - U-0000007F: 0xxxxxxx
-U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
-U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
-U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
-U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
-*/
-/* To be correctly coded UTF-8, the sequence should be the shortest
- * possible encoding of the value being encoded. This means that for
- * an encoding of length n+1 (1 <= n <= 5), at least one of the bits
- * in utf8chkmsk[n] should be non-zero (else the encoding could be
- * shorter). */
-static int utf8chkmsk[] = {
- 0x0000007f,
- 0x00000780,
- 0x0000f800,
- 0x001f0000,
- 0x03e00000,
- 0x7c000000,
-};
-
ssize_t
GDKstrFromStr(unsigned char *restrict dst, const unsigned char *restrict src,
ssize_t len)
{
@@ -424,7 +419,7 @@ GDKstrFromStr(unsigned char *restrict ds
cur++;
c = mult08(c) + base08(*cur);
if (num08(cur[1])) {
- if (c > 037) {
+ if (unlikely(c > 037)) {
/* octal
* escape
* sequence
@@ -455,7 +450,7 @@ GDKstrFromStr(unsigned char *restrict ds
case 'U':
/* \u with four hexadecimal digits or
* \U with eight hexadecimal digits */
- if (n > 0) {
+ if (unlikely(n > 0)) {
/* not when in the middle of a
* UTF-8 sequence */
goto notutf8;
@@ -463,15 +458,15 @@ GDKstrFromStr(unsigned char *restrict ds
c = 0;
for (n = *cur == 'U' ? 8 : 4; n > 0; n--) {
cur++;
- if (!num16(*cur)) {
+ if (unlikely(!num16(*cur))) {
GDKerror("not a Unicode code
point escape\n");
return -1;
}
c = c << 4 | base16(*cur);
}
/* n == 0 now */
- if (c == 0 || c > 0x10FFFF ||
- (c & 0xFFF800) == 0xD800) {
+ if (unlikely(c == 0 || c > 0x10FFFF ||
+ (c & 0xFFF800) == 0xD800)) {
GDKerror("illegal Unicode code
point\n");
return -1;
}
@@ -531,7 +526,7 @@ GDKstrFromStr(unsigned char *restrict ds
#if 0
} else if (c == quote && cur[1] == quote) {
assert(c != 0);
- if (n > 0)
+ if (unlikely(n > 0))
goto notutf8;
*p++ = quote;
cur++;
@@ -542,7 +537,7 @@ GDKstrFromStr(unsigned char *restrict ds
if (n > 0) {
/* we're still expecting follow-up bytes in a
* UTF-8 sequence */
- if ((c & 0xC0) != 0x80) {
+ if (unlikely((c & 0xC0) != 0x80)) {
/* incorrect UTF-8 sequence: byte is
* not 10xxxxxx */
goto notutf8;
@@ -551,44 +546,44 @@ GDKstrFromStr(unsigned char *restrict ds
n--;
if (n == 0) {
/* this was the last byte in the sequence */
- if ((utf8char & mask) == 0) {
+ if (unlikely((utf8char & mask) == 0)) {
/* incorrect UTF-8 sequence:
* not shortest possible */
goto notutf8;
}
- if (utf8char > 0x10FFFF) {
+ if (unlikely(utf8char > 0x10FFFF)) {
/* incorrect UTF-8 sequence:
* value too large */
goto notutf8;
}
- if ((utf8char & 0x1FFF800) == 0xD800) {
+ if (unlikely((utf8char & 0x1FFF800) == 0xD800))
{
/* incorrect UTF-8 sequence:
* low or high surrogate
* encoded as UTF-8 */
goto notutf8;
}
}
- } else if (c >= 0x80) {
- int m;
-
- /* start of multi-byte UTF-8 character */
- for (n = 0, m = 0x40; c & m; n++, m >>= 1)
- ;
- /* n now is number of 10xxxxxx bytes that
- * should follow */
- if (n == 0 || n >= 4) {
- /* incorrect UTF-8 sequence */
- /* n==0: c == 10xxxxxx */
- /* n>=4: c == 11111xxx */
- goto notutf8;
- }
- mask = utf8chkmsk[n];
- /* collect the Unicode code point in utf8char */
- utf8char = c & ~(0xFFC0 >> n); /* remove non-x bits */
+ } else if ((c & 0x80) == 0) {
+ ;
+ } else if ((c & 0xE0) == 0xC0) {
+ n = 1;
+ mask = 0x007F;
+ utf8char = c & 0x1F;
+ } else if ((c & 0xF0) == 0xE0) {
+ n = 1;
+ mask = 0x0780;
+ utf8char = c & 0x0F;
+ } else if ((c & 0xF8) == 0xF0) {
+ n = 1;
+ mask = 0xF800;
+ utf8char = c & 0x07;
+ } else {
+ /* incorrect UTF-8 sequence */
+ goto notutf8;
}
*p++ = c;
}
- if (n > 0) {
+ if (unlikely(n > 0)) {
/* incomplete UTF-8 sequence */
goto notutf8;
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list