Re: Two observations using GDB 13 snapshot

Eli Zaretskii via Gdb-patches
2023-01-04T18:10:53Z

> Date: Tue, 3 Jan 2023 16:34:53 -0500
> Cc: tom@tromey.com, gdb-patches@sourceware.org, luis.machado@arm.com
> From: Simon Marchi <simark@simark.ca>
>
> > In terms of the code, may be worth trying TOLOWER from
> > include/safe-ctype.h instead of tolower()
>
> The tolower call is inside strcasecmp, we don't call tolower directly:
>
> #0 0x77c348d5 in msvcrt!__crtLCMapStringA ()
> from C:\WINDOWS\system32\msvcrt.dll
> #1 0x77c348cd in msvcrt!__crtLCMapStringA ()
> from C:\WINDOWS\system32\msvcrt.dll
> #2 0x77c30045 in wmktemp () from C:\WINDOWS\system32\msvcrt.dll
> #3 0x77c1c992 in tolower () from C:\WINDOWS\system32\msvcrt.dll
> #4 0x77c462a1 in stricmp () from C:\WINDOWS\system32\msvcrt.dll
> #5 0x005107d3 in strcasecmp (__s2=<optimized out>, __s1=<optimized out>)
> at d:/usr/include/strings.h:92
> #6 cooked_index_entry::operator< (this=<optimized out>, other=...)
> at ./dwarf2/cooked-index.h:150
>
> It would be interesting to change that strcasecmp call to strcmp, just
> to see if it makes an impact on the performance. Whether or not that
> would be correct is another thing, but it would help see if that
> strcasecmp / tolower call is really at fault here.

Looks like indeed strcasecmp is the culprit. With the patch below,
which replaces strcasecmp with a simple case-insensitive comparison
that only works with ASCII, the phase of reading symbols from gdb.exe
goes down to just 6 seconds, which is basically the same time as with
GDB 12.

--- gdb/dwarf2/cooked-index.h~0 2022-12-17 03:47:12.000000000 +0200
+++ gdb/dwarf2/cooked-index.h 2023-01-04 20:00:04.052250000 +0200
@@ -35,6 +35,8 @@
#include "dwarf2/tag.h"
#include "gdbsupport/range-chain.h"

+#define my_tolower(c) (('A' <= (c) && (c) <= 'Z') ? ((c) - 'A' + 'a') : (c))
+
struct dwarf2_per_cu_data;

/* Flags that describe an entry in the index. */
@@ -147,7 +149,20 @@ struct cooked_index_entry : public alloc
entries. */
bool operator< (const cooked_index_entry &other) const
{
+#if 0
return strcasecmp (canonical, other.canonical) < 0;
+#else
+ const unsigned char *s1 = (unsigned char *)canonical, *s2 = (unsigned char *)other.canonical;
+
+ while (my_tolower(*s1) == my_tolower(*s2))
+ {
+ if (*s1 == 0)
+ return false;
+ s1++;
+ s2++;
+ }
+ return (int)my_tolower(*s1) < (int)my_tolower(*s2);
+#endif
}

/* The name as it appears in DWARF. This always points into one of