Use local variables in hash calc to avoid aliasing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
diff --git a/src/hashsig.c b/src/hashsig.c
index ab8d8b3..a11c4be 100644
--- a/src/hashsig.c
+++ b/src/hashsig.c
@@ -43,8 +43,8 @@ struct git_hashsig {
int considered;
};
-#define HEAP_LCHILD_OF(I) (((I)*2)+1)
-#define HEAP_RCHILD_OF(I) (((I)*2)+2)
+#define HEAP_LCHILD_OF(I) (((I)<<1)+1)
+#define HEAP_RCHILD_OF(I) (((I)<<1)+2)
#define HEAP_PARENT_OF(I) (((I)-1)>>1)
static void hashsig_heap_init(hashsig_heap *h, hashsig_cmp cmp)
@@ -152,8 +152,9 @@ static void hashsig_initial_window(
hashsig_in_progress *prog)
{
hashsig_state state, shift_n;
- int win_len;
+ int win_len, saw_lf = prog->saw_lf;
const char *scan, *end;
+ char *window = &prog->window[0];
/* init until we have processed at least HASHSIG_HASH_WINDOW data */
@@ -170,7 +171,7 @@ static void hashsig_initial_window(
while (scan < end && win_len < HASHSIG_HASH_WINDOW) {
char ch = *scan++;
- if (!hashsig_include_char(ch, sig->opt, &prog->saw_lf))
+ if (!hashsig_include_char(ch, sig->opt, &saw_lf))
continue;
state = (state * HASHSIG_HASH_SHIFT + ch) & HASHSIG_HASH_MASK;
@@ -180,7 +181,7 @@ static void hashsig_initial_window(
else
shift_n = (shift_n * HASHSIG_HASH_SHIFT) & HASHSIG_HASH_MASK;
- prog->window[win_len++] = ch;
+ window[win_len++] = ch;
}
/* insert initial hash if we just finished */
@@ -194,6 +195,7 @@ static void hashsig_initial_window(
prog->state = state;
prog->win_len = win_len;
prog->shift_n = shift_n;
+ prog->saw_lf = saw_lf;
*data = scan;
}
@@ -206,22 +208,26 @@ static int hashsig_add_hashes(
{
const char *scan = data, *end = data + size;
hashsig_state state, shift_n, rmv;
+ int win_pos, saw_lf;
+ char *window = &prog->window[0];
if (prog->win_len < HASHSIG_HASH_WINDOW)
hashsig_initial_window(sig, &scan, size, prog);
state = prog->state;
shift_n = prog->shift_n;
+ saw_lf = prog->saw_lf;
+ win_pos = prog->win_pos;
/* advance window, adding new chars and removing old */
for (; scan < end; ++scan) {
char ch = *scan;
- if (!hashsig_include_char(ch, sig->opt, &prog->saw_lf))
+ if (!hashsig_include_char(ch, sig->opt, &saw_lf))
continue;
- rmv = shift_n * prog->window[prog->win_pos];
+ rmv = shift_n * window[win_pos];
state = (state - rmv) & HASHSIG_HASH_MASK;
state = (state * HASHSIG_HASH_SHIFT) & HASHSIG_HASH_MASK;
@@ -231,11 +237,13 @@ static int hashsig_add_hashes(
hashsig_heap_insert(&sig->maxs, (hashsig_t)state);
sig->considered++;
- prog->window[prog->win_pos] = ch;
- prog->win_pos = (prog->win_pos + 1) % HASHSIG_HASH_WINDOW;
+ window[win_pos] = ch;
+ win_pos = (win_pos + 1) % HASHSIG_HASH_WINDOW;
}
- prog->state = state;
+ prog->state = state;
+ prog->saw_lf = saw_lf;
+ prog->win_pos = win_pos;
return 0;
}
@@ -296,7 +304,7 @@ int git_hashsig_create_fromfile(
const char *path,
git_hashsig_option_t opts)
{
- char buf[4096];
+ char buf[0x1000];
ssize_t buflen = 0;
int error = 0, fd;
hashsig_in_progress prog = HASHSIG_IN_PROGRESS_INIT;