aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2022-06-21 13:03:35 +0200
committerbfredl <bjorn.linse@gmail.com>2022-06-21 18:40:35 +0200
commita9442c532e9af45fc5c79d0207ab837cb715941f (patch)
treeba4edafcdf0794250a6e63725233c12e15cb3d29
parent1dad288432d398dc1e4b5bbf1d72db7a488eb341 (diff)
downloadrneovim-a9442c532e9af45fc5c79d0207ab837cb715941f.tar.gz
rneovim-a9442c532e9af45fc5c79d0207ab837cb715941f.tar.bz2
rneovim-a9442c532e9af45fc5c79d0207ab837cb715941f.zip
perf(highlight): allocate permanent names in an arena for fun and cache locality
-rw-r--r--src/nvim/api/private/helpers.c5
-rw-r--r--src/nvim/highlight_group.c33
-rw-r--r--src/nvim/memory.c8
3 files changed, 23 insertions, 23 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 693d946088..9cadef0385 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -686,10 +686,7 @@ Dictionary arena_dict(Arena *arena, size_t max_size)
String arena_string(Arena *arena, String str)
{
if (str.size) {
- char *mem = arena_alloc(arena, str.size + 1, false);
- memcpy(mem, str.data, str.size);
- mem[str.size] = NUL;
- return cbuf_as_string(mem, str.size);
+ return cbuf_as_string(arena_memdupz(arena, str.data, str.size), str.size);
} else {
return (String)STRING_INIT;
}
diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c
index e68181b4fc..93d6e65040 100644
--- a/src/nvim/highlight_group.c
+++ b/src/nvim/highlight_group.c
@@ -30,6 +30,9 @@
// builtin |highlight-groups|
static garray_T highlight_ga = GA_EMPTY_INIT_VALUE;
+// arena for object with same lifetime as highlight_ga (aka hl_table)
+Arena highlight_arena = ARENA_EMPTY;
+
Map(cstr_t, int) highlight_unames = MAP_INIT;
/// The "term", "cterm" and "gui" arguments can be any combination of the
@@ -1287,13 +1290,9 @@ void do_highlight(const char *line, const bool forceit, const bool init)
#if defined(EXITFREE)
void free_highlight(void)
{
- for (int i = 0; i < highlight_ga.ga_len; i++) {
- highlight_clear(i);
- xfree(hl_table[i].sg_name);
- xfree(hl_table[i].sg_name_u);
- }
ga_clear(&highlight_ga);
map_destroy(cstr_t, int)(&highlight_unames);
+ arena_mem_free(arena_finish(&highlight_arena), NULL);
}
#endif
@@ -1722,7 +1721,7 @@ int syn_check_group(const char *name, size_t len)
}
int id = syn_name2id_len((char_u *)name, len);
if (id == 0) { // doesn't exist yet
- return syn_add_group(vim_strnsave((char_u *)name, len));
+ return syn_add_group(name, len);
}
return id;
}
@@ -1732,17 +1731,15 @@ int syn_check_group(const char *name, size_t len)
/// @param name must be an allocated string, it will be consumed.
/// @return 0 for failure, else the allocated group id
/// @see syn_check_group
-static int syn_add_group(char_u *name)
+static int syn_add_group(const char *name, size_t len)
{
- char_u *p;
-
// Check that the name is ASCII letters, digits and underscore.
- for (p = name; *p != NUL; p++) {
- if (!vim_isprintc(*p)) {
+ for (size_t i = 0; i < len; i++) {
+ int c = (int8_t)name[i];
+ if (!vim_isprintc(c)) {
emsg(_("E669: Unprintable character in group name"));
- xfree(name);
return 0;
- } else if (!ASCII_ISALNUM(*p) && *p != '_') {
+ } else if (!ASCII_ISALNUM(c) && c != '_') {
// This is an error, but since there previously was no check only give a warning.
msg_source(HL_ATTR(HLF_W));
msg(_("W18: Invalid character in group name"));
@@ -1758,16 +1755,13 @@ static int syn_add_group(char_u *name)
if (highlight_ga.ga_len >= MAX_HL_ID) {
emsg(_("E849: Too many highlight and syntax groups"));
- xfree(name);
return 0;
}
- char *const name_up = (char *)vim_strsave_up(name);
-
// Append another syntax_highlight entry.
HlGroup *hlgp = GA_APPEND_VIA_PTR(HlGroup, &highlight_ga);
memset(hlgp, 0, sizeof(*hlgp));
- hlgp->sg_name = name;
+ hlgp->sg_name = (char_u *)arena_memdupz(&highlight_arena, name, len);
hlgp->sg_rgb_bg = -1;
hlgp->sg_rgb_fg = -1;
hlgp->sg_rgb_sp = -1;
@@ -1775,11 +1769,12 @@ static int syn_add_group(char_u *name)
hlgp->sg_rgb_fg_idx = kColorIdxNone;
hlgp->sg_rgb_sp_idx = kColorIdxNone;
hlgp->sg_blend = -1;
- hlgp->sg_name_u = name_up;
+ hlgp->sg_name_u = arena_memdupz(&highlight_arena, name, len);
+ vim_strup((char_u *)hlgp->sg_name_u);
int id = highlight_ga.ga_len; // ID is index plus one
- map_put(cstr_t, int)(&highlight_unames, name_up, id);
+ map_put(cstr_t, int)(&highlight_unames, hlgp->sg_name_u, id);
return id;
}
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 9d02b83e5f..a615802b36 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -605,6 +605,14 @@ void arena_mem_free(ArenaMem mem, ArenaMem *reuse_blk)
}
}
+char *arena_memdupz(Arena *arena, const char *buf, size_t size)
+{
+ char *mem = arena_alloc(arena, size + 1, false);
+ memcpy(mem, buf, size);
+ mem[size] = NUL;
+ return mem;
+}
+
#if defined(EXITFREE)
# include "nvim/buffer.h"