mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
refactor(drawline): avoid xmalloc/xfree cycles on each screenline
This commit is contained in:
parent
3128cff6b1
commit
74581ec7eb
@ -101,7 +101,6 @@ typedef struct {
|
|||||||
int n_attr; ///< chars with special attr
|
int n_attr; ///< chars with special attr
|
||||||
char *p_extra; ///< string of extra chars, plus NUL, only used
|
char *p_extra; ///< string of extra chars, plus NUL, only used
|
||||||
///< when c_extra and c_final are NUL
|
///< when c_extra and c_final are NUL
|
||||||
char *p_extra_free; ///< p_extra buffer that needs to be freed
|
|
||||||
int extra_attr; ///< attributes for p_extra
|
int extra_attr; ///< attributes for p_extra
|
||||||
int c_extra; ///< extra chars, all the same
|
int c_extra; ///< extra chars, all the same
|
||||||
int c_final; ///< final char, mandatory if set
|
int c_final; ///< final char, mandatory if set
|
||||||
@ -113,7 +112,6 @@ typedef struct {
|
|||||||
// saved "extra" items for when draw_state becomes WL_LINE (again)
|
// saved "extra" items for when draw_state becomes WL_LINE (again)
|
||||||
int saved_n_extra;
|
int saved_n_extra;
|
||||||
char *saved_p_extra;
|
char *saved_p_extra;
|
||||||
char *saved_p_extra_free;
|
|
||||||
bool saved_extra_for_extmark;
|
bool saved_extra_for_extmark;
|
||||||
int saved_c_extra;
|
int saved_c_extra;
|
||||||
int saved_c_final;
|
int saved_c_final;
|
||||||
@ -147,6 +145,27 @@ typedef struct {
|
|||||||
# include "drawline.c.generated.h"
|
# include "drawline.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static char *extra_buf = NULL;
|
||||||
|
static size_t extra_buf_size = 0;
|
||||||
|
|
||||||
|
static char *get_extra_buf(size_t size)
|
||||||
|
{
|
||||||
|
size = MAX(size, 64);
|
||||||
|
if (extra_buf_size < size) {
|
||||||
|
xfree(extra_buf);
|
||||||
|
extra_buf = xmalloc(size);
|
||||||
|
extra_buf_size = size;
|
||||||
|
}
|
||||||
|
return extra_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EXITFREE
|
||||||
|
void drawline_free_all_mem(void)
|
||||||
|
{
|
||||||
|
xfree(extra_buf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Advance **color_cols
|
/// Advance **color_cols
|
||||||
///
|
///
|
||||||
/// @return true when there are columns to draw.
|
/// @return true when there are columns to draw.
|
||||||
@ -349,6 +368,8 @@ static bool use_cursor_line_highlight(win_T *wp, linenr_T lnum)
|
|||||||
&& (wp->w_p_culopt_flags & CULOPT_NBR);
|
&& (wp->w_p_culopt_flags & CULOPT_NBR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char fdc_buf[MB_MAXCHAR * 10 + 1];
|
||||||
|
|
||||||
/// Setup for drawing the 'foldcolumn', if there is one.
|
/// Setup for drawing the 'foldcolumn', if there is one.
|
||||||
static void handle_foldcolumn(win_T *wp, winlinevars_T *wlv)
|
static void handle_foldcolumn(win_T *wp, winlinevars_T *wlv)
|
||||||
{
|
{
|
||||||
@ -357,13 +378,11 @@ static void handle_foldcolumn(win_T *wp, winlinevars_T *wlv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a buffer, "wlv->extra[]" may already be in use.
|
// Use a separate buffer as `extra_buf` might be in use.
|
||||||
xfree(wlv->p_extra_free);
|
wlv->n_extra = (int)fill_foldcolumn(fdc_buf, wp, wlv->foldinfo, wlv->lnum,
|
||||||
wlv->p_extra_free = xmalloc(MAX_MCO * (size_t)fdc + 1);
|
|
||||||
wlv->n_extra = (int)fill_foldcolumn(wlv->p_extra_free, wp, wlv->foldinfo, wlv->lnum,
|
|
||||||
&wlv->n_closing);
|
&wlv->n_closing);
|
||||||
wlv->p_extra_free[wlv->n_extra] = NUL;
|
fdc_buf[wlv->n_extra] = NUL;
|
||||||
wlv->p_extra = wlv->p_extra_free;
|
wlv->p_extra = fdc_buf;
|
||||||
wlv->c_extra = NUL;
|
wlv->c_extra = NUL;
|
||||||
wlv->c_final = NUL;
|
wlv->c_final = NUL;
|
||||||
if (use_cursor_line_highlight(wp, wlv->lnum)) {
|
if (use_cursor_line_highlight(wp, wlv->lnum)) {
|
||||||
@ -393,7 +412,7 @@ size_t fill_foldcolumn(char *p, win_T *wp, foldinfo_T foldinfo, linenr_T lnum, i
|
|||||||
int len = 0;
|
int len = 0;
|
||||||
bool closed = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
|
bool closed = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
|
||||||
// Init to all spaces.
|
// Init to all spaces.
|
||||||
memset(p, ' ', MAX_MCO * (size_t)fdc + 1);
|
memset(p, ' ', MB_MAXCHAR * (size_t)fdc + 1);
|
||||||
|
|
||||||
level = foldinfo.fi_level;
|
level = foldinfo.fi_level;
|
||||||
|
|
||||||
@ -991,9 +1010,6 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra)
|
|||||||
wlv->draw_state = WL_START;
|
wlv->draw_state = WL_START;
|
||||||
wlv->saved_n_extra = wlv->n_extra;
|
wlv->saved_n_extra = wlv->n_extra;
|
||||||
wlv->saved_p_extra = wlv->p_extra;
|
wlv->saved_p_extra = wlv->p_extra;
|
||||||
xfree(wlv->saved_p_extra_free);
|
|
||||||
wlv->saved_p_extra_free = wlv->p_extra_free;
|
|
||||||
wlv->p_extra_free = NULL;
|
|
||||||
wlv->saved_extra_for_extmark = wlv->extra_for_extmark;
|
wlv->saved_extra_for_extmark = wlv->extra_for_extmark;
|
||||||
wlv->saved_c_extra = wlv->c_extra;
|
wlv->saved_c_extra = wlv->c_extra;
|
||||||
wlv->saved_c_final = wlv->c_final;
|
wlv->saved_c_final = wlv->c_final;
|
||||||
@ -1014,9 +1030,6 @@ static void win_line_continue(winlinevars_T *wlv)
|
|||||||
wlv->c_extra = wlv->saved_c_extra;
|
wlv->c_extra = wlv->saved_c_extra;
|
||||||
wlv->c_final = wlv->saved_c_final;
|
wlv->c_final = wlv->saved_c_final;
|
||||||
wlv->p_extra = wlv->saved_p_extra;
|
wlv->p_extra = wlv->saved_p_extra;
|
||||||
xfree(wlv->p_extra_free);
|
|
||||||
wlv->p_extra_free = wlv->saved_p_extra_free;
|
|
||||||
wlv->saved_p_extra_free = NULL;
|
|
||||||
wlv->extra_for_extmark = wlv->saved_extra_for_extmark;
|
wlv->extra_for_extmark = wlv->saved_extra_for_extmark;
|
||||||
wlv->char_attr = wlv->saved_char_attr;
|
wlv->char_attr = wlv->saved_char_attr;
|
||||||
} else {
|
} else {
|
||||||
@ -1111,6 +1124,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
|
|
||||||
char buf_fold[FOLD_TEXT_LEN]; // Hold value returned by get_foldtext
|
char buf_fold[FOLD_TEXT_LEN]; // Hold value returned by get_foldtext
|
||||||
VirtText fold_vt = VIRTTEXT_EMPTY;
|
VirtText fold_vt = VIRTTEXT_EMPTY;
|
||||||
|
char *foldtext_free = NULL;
|
||||||
|
|
||||||
// 'cursorlineopt' has "screenline" and cursor is in this line
|
// 'cursorlineopt' has "screenline" and cursor is in this line
|
||||||
bool cul_screenline = false;
|
bool cul_screenline = false;
|
||||||
@ -1908,8 +1922,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
wlv.n_extra = (int)strlen(wlv.p_extra);
|
wlv.n_extra = (int)strlen(wlv.p_extra);
|
||||||
|
|
||||||
if (wlv.p_extra != buf_fold) {
|
if (wlv.p_extra != buf_fold) {
|
||||||
xfree(wlv.p_extra_free);
|
foldtext_free = wlv.p_extra;
|
||||||
wlv.p_extra_free = wlv.p_extra;
|
|
||||||
}
|
}
|
||||||
wlv.c_extra = NUL;
|
wlv.c_extra = NUL;
|
||||||
wlv.c_final = NUL;
|
wlv.c_final = NUL;
|
||||||
@ -2415,11 +2428,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
len += wlv.n_extra - tab_len;
|
len += wlv.n_extra - tab_len;
|
||||||
}
|
}
|
||||||
c = wp->w_p_lcs_chars.tab1;
|
c = wp->w_p_lcs_chars.tab1;
|
||||||
p = xmalloc((size_t)len + 1);
|
p = get_extra_buf((size_t)len + 1);
|
||||||
memset(p, ' ', (size_t)len);
|
memset(p, ' ', (size_t)len);
|
||||||
p[len] = NUL;
|
p[len] = NUL;
|
||||||
xfree(wlv.p_extra_free);
|
wlv.p_extra = p;
|
||||||
wlv.p_extra_free = p;
|
|
||||||
for (int i = 0; i < tab_len; i++) {
|
for (int i = 0; i < tab_len; i++) {
|
||||||
if (*p == NUL) {
|
if (*p == NUL) {
|
||||||
tab_len = i;
|
tab_len = i;
|
||||||
@ -2434,7 +2446,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
p += utf_char2bytes(lcs, p);
|
p += utf_char2bytes(lcs, p);
|
||||||
wlv.n_extra += utf_char2len(lcs) - (saved_nextra > 0 ? 1 : 0);
|
wlv.n_extra += utf_char2len(lcs) - (saved_nextra > 0 ? 1 : 0);
|
||||||
}
|
}
|
||||||
wlv.p_extra = wlv.p_extra_free;
|
|
||||||
|
|
||||||
// n_extra will be increased by FIX_FOX_BOGUSCOLS
|
// n_extra will be increased by FIX_FOX_BOGUSCOLS
|
||||||
// macro below, so need to adjust for that here
|
// macro below, so need to adjust for that here
|
||||||
@ -2533,14 +2544,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
c = (uint8_t)(*wlv.p_extra);
|
c = (uint8_t)(*wlv.p_extra);
|
||||||
p = xmalloc((size_t)wlv.n_extra + 1);
|
p = get_extra_buf((size_t)wlv.n_extra + 1);
|
||||||
memset(p, ' ', (size_t)wlv.n_extra);
|
memset(p, ' ', (size_t)wlv.n_extra);
|
||||||
strncpy(p, // NOLINT(runtime/printf)
|
strncpy(p, // NOLINT(runtime/printf)
|
||||||
wlv.p_extra + 1,
|
wlv.p_extra + 1,
|
||||||
(size_t)strlen(wlv.p_extra) - 1);
|
(size_t)strlen(wlv.p_extra) - 1);
|
||||||
p[wlv.n_extra] = NUL;
|
p[wlv.n_extra] = NUL;
|
||||||
xfree(wlv.p_extra_free);
|
wlv.p_extra = p;
|
||||||
wlv.p_extra_free = wlv.p_extra = p;
|
|
||||||
} else {
|
} else {
|
||||||
wlv.n_extra = byte2cells(c) - 1;
|
wlv.n_extra = byte2cells(c) - 1;
|
||||||
c = (uint8_t)(*wlv.p_extra++);
|
c = (uint8_t)(*wlv.p_extra++);
|
||||||
@ -3141,8 +3151,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
|||||||
|
|
||||||
clear_virttext(&fold_vt);
|
clear_virttext(&fold_vt);
|
||||||
kv_destroy(virt_lines);
|
kv_destroy(virt_lines);
|
||||||
xfree(wlv.p_extra_free);
|
xfree(foldtext_free);
|
||||||
xfree(wlv.saved_p_extra_free);
|
|
||||||
return wlv.row;
|
return wlv.row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "nvim/buffer_updates.h"
|
#include "nvim/buffer_updates.h"
|
||||||
#include "nvim/context.h"
|
#include "nvim/context.h"
|
||||||
#include "nvim/decoration_provider.h"
|
#include "nvim/decoration_provider.h"
|
||||||
|
#include "nvim/drawline.h"
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/gettext.h"
|
#include "nvim/gettext.h"
|
||||||
#include "nvim/globals.h"
|
#include "nvim/globals.h"
|
||||||
@ -818,6 +819,7 @@ void free_all_mem(void)
|
|||||||
check_quickfix_busy();
|
check_quickfix_busy();
|
||||||
|
|
||||||
decor_free_all_mem();
|
decor_free_all_mem();
|
||||||
|
drawline_free_all_mem();
|
||||||
|
|
||||||
ui_free_all_mem();
|
ui_free_all_mem();
|
||||||
nlua_free_all_mem();
|
nlua_free_all_mem();
|
||||||
|
Loading…
Reference in New Issue
Block a user