From e1da232d721c1a228f5bfdcae94ef80b88fa0364 Mon Sep 17 00:00:00 2001
Date: Tue, 21 Aug 2018 18:43:57 -0400
Subject: [PATCH] Optimize the order of struct members
- Reorder members to reduce padding and wasted RAM, most noticeable on x64
- Put links first so foo->next is a simple dereference
- Shrink pairnum to a short (ncurses uses a short for this as well)
- Replace rex_flags with a bool called ignore_case. This prevents using an
entire word boundary in x64.
- long is an unreliable type, replace it with int.
---
src/color.c | 5 ++-
src/nano.h | 125 ++++++++++++++++++++++++++-------------------------
src/rcfile.c | 12 ++---
3 files changed, 73 insertions(+), 69 deletions(-)
diff --git a/src/color.c b/src/color.c
index 036b4d45..c56d4d7a 100644
--- a/src/color.c
+++ b/src/color.c
@@ -272,14 +272,15 @@ void color_update(void)
/* If a syntax was found, compile its specified regexes (which have
* already been checked for validity when they were read in). */
for (ink = openfile->colorstrings; ink != NULL; ink = ink->next) {
+ int rex_flags = NANO_REG_EXTENDED | ((ink->ignore_case) ? REG_ICASE : 0);
if (ink->start == NULL) {
ink->start = (regex_t *)nmalloc(sizeof(regex_t));
- regcomp(ink->start, fixbounds(ink->start_regex), ink->rex_flags);
+ regcomp(ink->start, fixbounds(ink->start_regex), rex_flags);
}
if (ink->end_regex != NULL && ink->end == NULL) {
ink->end = (regex_t *)nmalloc(sizeof(regex_t));
- regcomp(ink->end, fixbounds(ink->end_regex), ink->rex_flags);
+ regcomp(ink->end, fixbounds(ink->end_regex), rex_flags);
}
}
}
diff --git a/src/nano.h b/src/nano.h
index c0779801..8c51234b 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -184,19 +184,8 @@ typedef enum {
/* Structure types. */
#ifdef ENABLE_COLOR
typedef struct colortype {
- short fg;
- /* This syntax's foreground color. */
- short bg;
- /* This syntax's background color. */
- bool bright;
- /* Is this color A_BOLD? */
- int pairnum;
- /* The color pair number used for this foreground color and
- * background color. */
- int attributes;
- /* Pair number and brightness composed into ready-to-use attributes. */
- int rex_flags;
- /* The regex compilation flags (with or without REG_ICASE). */
+ struct colortype *next;
+ /* Next set of colors. */
char *start_regex;
/* The start (or all) of the regex string. */
regex_t *start;
@@ -205,20 +194,33 @@ typedef struct colortype {
/* The end (if any) of the regex string. */
regex_t *end;
/* The compiled end (if any) of the regex string. */
- struct colortype *next;
- /* Next set of colors. */
int id;
/* Basic id for assigning to lines later. */
+ int attributes;
+ /* Pair number and brightness composed into ready-to-use attributes. */
+ short fg;
+ /* This syntax's foreground color. */
+ short bg;
+ /* This syntax's background color. */
+ short pairnum;
+ /* The color pair number used for this foreground color and
+ * background color. */
+ bool ignore_case;
+ /* Whether this ignores case. */
+ bool bright;
+ /* Whether this is A_BOLD. */
} colortype;
typedef struct regexlisttype {
- char *full_regex;
- /* A regex string to match things that imply a certain syntax. */
struct regexlisttype *next;
/* The next regex. */
+ char *full_regex;
+ /* A regex string to match things that imply a certain syntax. */
} regexlisttype;
typedef struct syntaxtype {
+ struct syntaxtype *next;
+ /* Next syntax. */
char *name;
/* The name of this syntax. */
regexlisttype *extensions;
@@ -237,11 +239,13 @@ typedef struct syntaxtype {
/* The colors and their regexes used in this syntax. */
int nmultis;
/* How many multiline regex strings this syntax has. */
- struct syntaxtype *next;
- /* Next syntax. */
} syntaxtype;
typedef struct lintstruct {
+ struct lintstruct *next;
+ /* Next error. */
+ struct lintstruct *prev;
+ /* Previous error. */
ssize_t lineno;
/* Line number of the error. */
ssize_t colno;
@@ -250,10 +254,6 @@ typedef struct lintstruct {
/* Error message text. */
char *filename;
/* Filename. */
- struct lintstruct *next;
- /* Next error. */
- struct lintstruct *prev;
- /* Previous error. */
} lintstruct;
/* Flags that indicate how a multiline regex applies to a line. */
@@ -273,14 +273,14 @@ typedef struct lintstruct {
/* More structure types. */
typedef struct filestruct {
- char *data;
- /* The text of this line. */
- ssize_t lineno;
- /* The number of this line. */
struct filestruct *next;
/* Next node. */
struct filestruct *prev;
/* Previous node. */
+ char *data;
+ /* The text of this line. */
+ ssize_t lineno;
+ /* The number of this line. */
#ifdef ENABLE_COLOR
short *multidata;
/* Array of which multi-line regexes apply to this line. */
@@ -307,19 +307,25 @@ typedef struct partition {
#ifndef NANO_TINY
typedef struct undo_group {
+ struct undo_group *next;
ssize_t top_line;
/* First line of group. */
ssize_t bottom_line;
/* Last line of group. */
char **indentations;
/* String data used to restore the affected lines; one per line. */
- struct undo_group *next;
} undo_group;
typedef struct undo {
+ struct undo *next;
+ /* A pointer to the undo item of the preceding action. */
ssize_t lineno;
+
undo_type type;
/* What type of undo this was. */
+ int xflags;
+ /* Some flag data we need. */
+
size_t begin;
/* Where did this action begin or end. */
char *strdata;
@@ -328,8 +334,6 @@ typedef struct undo {
/* The file size before the action. */
size_t newsize;
/* The file size after the action. */
- int xflags;
- /* Some flag data we need. */
undo_group *grouping;
/* Undo info specific to groups of lines. */
@@ -342,24 +346,29 @@ typedef struct undo {
/* Mostly the line number of the current line; sometimes something else. */
size_t mark_begin_x;
/* The x position corresponding to the above line number. */
- struct undo *next;
- /* A pointer to the undo item of the preceding action. */
+
} undo;
#endif /* !NANO_TINY */
#ifdef ENABLE_HISTORIES
typedef struct poshiststruct {
+ struct poshiststruct *next;
char *filename;
/* The file. */
ssize_t lineno;
/* Line number we left off on. */
ssize_t xno;
/* x position in the file we left off on. */
- struct poshiststruct *next;
} poshiststruct;
#endif
typedef struct openfilestruct {
+#ifdef ENABLE_MULTIBUFFER
+ struct openfilestruct *next;
+ /* The next open file, if any. */
+ struct openfilestruct *prev;
+ /* The preceding open file, if any. */
+#endif
char *filename;
/* The file's name. */
filestruct *fileage;
@@ -381,19 +390,19 @@ typedef struct openfilestruct {
/* The file's x position we would like. */
ssize_t current_y;
/* The file's y-coordinate position. */
- bool modified;
- /* Whether the file has been modified. */
struct stat *current_stat;
/* The file's current stat information. */
+#ifdef ENABLE_COLOR
+ syntaxtype *syntax;
+ /* The syntax struct for this file, if any. */
+ colortype *colorstrings;
+ /* The file's associated colors. */
+#endif
#ifndef NANO_TINY
filestruct *mark;
/* The line in the file where the mark is set; NULL if not set. */
size_t mark_x;
/* The mark's x position in the above line. */
- mark_type kind_of_mark;
- /* Whether it is a soft (with Shift) or a hard mark. */
- file_format fmt;
- /* The file's format -- Unix or DOS or Mac or mixed. */
undo *undotop;
/* The top of the undo list. */
undo *current_undo;
@@ -404,35 +413,29 @@ typedef struct openfilestruct {
/* The type of the last action the user performed. */
char *lock_filename;
/* The path of the lockfile, if we created one. */
+ mark_type kind_of_mark;
+ /* Whether it is a soft (with Shift) or a hard mark. */
+ file_format fmt;
+ /* The file's format -- Unix or DOS or Mac or mixed. */
#endif
-#ifdef ENABLE_COLOR
- syntaxtype *syntax;
- /* The syntax struct for this file, if any. */
- colortype *colorstrings;
- /* The file's associated colors. */
-#endif
-#ifdef ENABLE_MULTIBUFFER
- struct openfilestruct *next;
- /* The next open file, if any. */
- struct openfilestruct *prev;
- /* The preceding open file, if any. */
-#endif
+ bool modified;
+ /* Whether the file has been modified. */
} openfilestruct;
#ifdef ENABLE_NANORC
typedef struct rcoption {
const char *name;
/* The name of the rcfile option. */
- long flag;
+ int flag;
/* The flag associated with it, if any. */
} rcoption;
#endif
typedef struct sc {
+ struct sc *next;
+ /* Next in the list. */
const char *keystr;
/* The string that describes a keystroke, like "^C" or "M-R". */
- bool meta;
- /* Whether this is a Meta keystroke. */
int keycode;
/* The integer that, together with meta, identifies the keystroke. */
int menus;
@@ -450,15 +453,19 @@ typedef struct sc {
char *expansion;
/* The string of keycodes to which this shortcut is expanded. */
#endif
- struct sc *next;
- /* Next in the list. */
+ bool meta;
+ /* Whether this is a Meta keystroke. */
} sc;
typedef struct subnfunc {
+ struct subnfunc *next;
+ /* Next item in the list. */
void (*func)(void);
/* The actual function to call. */
int menus;
/* In what menus this function applies. */
+ int toggle;
+ /* If this is a toggle, which toggle to affect. */
const char *desc;
/* The function's short description, for example "Where Is". */
#ifdef ENABLE_HELP
@@ -470,16 +477,12 @@ typedef struct subnfunc {
#endif
bool viewok;
/* Is this function allowed when in view mode? */
- long toggle;
- /* If this is a toggle, which toggle to affect. */
- struct subnfunc *next;
- /* Next item in the list. */
} subnfunc;
#ifdef ENABLE_WORDCOMPLETION
typedef struct completion_word {
- char *word;
struct completion_word *next;
+ char *word;
} completion_word;
#endif
diff --git a/src/rcfile.c b/src/rcfile.c
index 08de4d67..98d0723e 100644
--- a/src/rcfile.c
+++ b/src/rcfile.c
@@ -629,13 +629,13 @@ bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright)
}
/* Parse the color string in the line at ptr, and add it to the current
- * file's associated colors. rex_flags are the regex compilation flags
- * to use, excluding or including REG_ICASE for case (in)sensitivity. */
-void parse_colors(char *ptr, int rex_flags)
+ * file's associated colors. */
+static void parse_colors(char *ptr, bool ignore_case)
{
short fg, bg;
bool bright;
char *item;
+ int rex_flags = NANO_REG_EXTENDED | ((ignore_case) ? REG_ICASE : 0);
if (!opensyntax) {
rcfile_error(N_("A '%s' command requires a preceding 'syntax' command"),
@@ -698,7 +698,7 @@ void parse_colors(char *ptr, int rex_flags)
newcolor->fg = fg;
newcolor->bg = bg;
newcolor->bright = bright;
- newcolor->rex_flags = rex_flags;
+ newcolor->ignore_case = ignore_case;
newcolor->start_regex = mallocstrcpy(NULL, item);
newcolor->start = NULL;
@@ -980,9 +980,9 @@ void parse_rcfile(FILE *rcstream, bool syntax_only)
;
#endif
else if (strcasecmp(keyword, "color") == 0)
- parse_colors(ptr, NANO_REG_EXTENDED);
+ parse_colors(ptr, FALSE);
else if (strcasecmp(keyword, "icolor") == 0)
- parse_colors(ptr, NANO_REG_EXTENDED | REG_ICASE);
+ parse_colors(ptr, TRUE);
else if (strcasecmp(keyword, "linter") == 0)
pick_up_name("linter", ptr, &live_syntax->linter);
else if (syntax_only && (strcasecmp(keyword, "set") == 0 ||
--
2.18.0