From 8067992954f9b882ffd7332ee669a254c000f1b2 Mon Sep 17 00:00:00 2001 From: Andrew Bennett Date: Fri, 18 Sep 2015 09:38:46 -0600 Subject: erts: Minor refactor for binary find BIF backend * Use NULL instead of THE_NON_VALUE for non-Eterm variable. * Add BinaryFindState_bignum struct to avoid unnecessary type casting. --- erts/emulator/beam/erl_bif_binary.c | 109 ++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 54 deletions(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c index 9f72b8c0ac..b1ebf0327e 100644 --- a/erts/emulator/beam/erl_bif_binary.c +++ b/erts/emulator/beam/erl_bif_binary.c @@ -531,21 +531,23 @@ static void ac_init_find_all(ACFindAllState *state, ACTrie *act, Sint startpos, state->out = NULL; } -static void ac_restore_find_all(ACFindAllState *state, char *buff) +static void ac_restore_find_all(ACFindAllState *state, + const ACFindAllState *src) { - memcpy(state,buff,sizeof(ACFindAllState)); + memcpy(state, src, sizeof(ACFindAllState)); if (state->allocated > 0) { state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) * (state->allocated)); - memcpy(state->out,buff+sizeof(ACFindAllState),sizeof(FindallData)*state->m); + memcpy(state->out, src+1, sizeof(FindallData)*state->m); } else { state->out = NULL; } } -static void ac_serialize_find_all(ACFindAllState *state, char *buff) +static void ac_serialize_find_all(const ACFindAllState *state, + ACFindAllState *dst) { - memcpy(buff,state,sizeof(ACFindAllState)); - memcpy(buff+sizeof(ACFindAllState),state->out,sizeof(FindallData)*state->m); + memcpy(dst, state, sizeof(ACFindAllState)); + memcpy(dst+1, state->out, sizeof(FindallData)*state->m); } static void ac_clean_find_all(ACFindAllState *state) @@ -805,24 +807,24 @@ static void bm_init_find_all(BMFindAllState *state, Sint startpos, Uint len) state->out = NULL; } -static void bm_restore_find_all(BMFindAllState *state, char *buff) +static void bm_restore_find_all(BMFindAllState *state, + const BMFindAllState *src) { - memcpy(state,buff,sizeof(BMFindAllState)); + memcpy(state, src, sizeof(BMFindAllState)); if (state->allocated > 0) { state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) * (state->allocated)); - memcpy(state->out,buff+sizeof(BMFindAllState), - sizeof(FindallData)*state->m); + memcpy(state->out, src+1, sizeof(FindallData)*state->m); } else { state->out = NULL; } } -static void bm_serialize_find_all(BMFindAllState *state, char *buff) +static void bm_serialize_find_all(const BMFindAllState *state, + BMFindAllState *dst) { - memcpy(buff,state,sizeof(BMFindAllState)); - memcpy(buff+sizeof(BMFindAllState),state->out, - sizeof(FindallData)*state->m); + memcpy(dst, state, sizeof(BMFindAllState)); + memcpy(dst+1, state->out, sizeof(FindallData)*state->m); } static void bm_clean_find_all(BMFindAllState *state) @@ -1032,6 +1034,17 @@ typedef struct BinaryFindState { Eterm (*global_result) (Process *, Eterm, struct BinaryFindState *, FindallData *, Uint); } BinaryFindState; +typedef struct BinaryFindState_bignum { + Eterm bignum_hdr; + BinaryFindState bfs; + union { + BMFindFirstState bmffs; + BMFindAllState bmfas; + ACFindFirstState acffs; + ACFindAllState acfas; + } data; +} BinaryFindState_bignum; + #define SIZEOF_BINARY_FIND_STATE(S) \ (sizeof(BinaryFindState)+sizeof(S)) @@ -1197,7 +1210,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar byte *bytes; Uint bitoffs, bitsize; byte *temp_alloc = NULL; - char *state_ptr = NULL; + BinaryFindState_bignum *state_ptr = NULL; ERTS_GET_BINARY_BYTES(subject, bytes, bitoffs, bitsize); if (bitsize != 0) { @@ -1207,17 +1220,14 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar bytes = erts_get_aligned_binary_bytes(subject, &temp_alloc); } if (state_term != NIL) { - state_ptr = (char *)(big_val(state_term)); - state_ptr += sizeof(Eterm); - bfs = (BinaryFindState *)(state_ptr); - state_ptr += sizeof(BinaryFindState); + state_ptr = (BinaryFindState_bignum *)(big_val(state_term)); + bfs = &(state_ptr->bfs); } if (bfs->flags & BINARY_FIND_ALL) { if (bfs->type == am_bm) { BMData *bm; Sint pos; - Eterm *hp; BMFindAllState state; Uint reds = get_reds(p, BM_LOOP_FACTOR); Uint save_reds = reds; @@ -1229,7 +1239,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar if (state_term == NIL) { bm_init_find_all(&state, bfs->hsstart, bfs->hsend); } else { - bm_restore_find_all(&state, state_ptr); + bm_restore_find_all(&state, &(state_ptr->data.bmfas)); } pos = bm_find_all_non_overlapping(&state, bm, bytes, &reds); @@ -1242,12 +1252,11 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar #ifdef HARDDEBUG erts_printf("Trap bm!\n"); #endif - hp = HAlloc(p, x+1); - hp[0] = make_pos_bignum_header(x); - state_ptr = (char *)(hp); - memcpy((void *)(state_ptr+sizeof(Eterm)), bfs, sizeof(BinaryFindState)); - bm_serialize_find_all(&state, state_ptr+sizeof(Eterm)+sizeof(BinaryFindState)); - *res_term = make_big(hp); + state_ptr = (BinaryFindState_bignum*) HAlloc(p, x+1); + state_ptr->bignum_hdr = make_pos_bignum_header(x); + memcpy(&state_ptr->bfs, bfs, sizeof(BinaryFindState)); + bm_serialize_find_all(&state, &state_ptr->data.bmfas); + *res_term = make_big(&state_ptr->bignum_hdr); erts_free_aligned_binary_bytes(temp_alloc); bm_clean_find_all(&state); return DO_BIN_MATCH_RESTART; @@ -1262,7 +1271,6 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar ACTrie *act; int acr; ACFindAllState state; - Eterm *hp; Uint reds = get_reds(p, AC_LOOP_FACTOR); Uint save_reds = reds; @@ -1273,7 +1281,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar if (state_term == NIL) { ac_init_find_all(&state, act, bfs->hsstart, bfs->hsend); } else { - ac_restore_find_all(&state, state_ptr); + ac_restore_find_all(&state, &(state_ptr->data.acfas)); } acr = ac_find_all_non_overlapping(&state, bytes, &reds); if (acr == AC_NOT_FOUND) { @@ -1285,12 +1293,11 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar #ifdef HARDDEBUG erts_printf("Trap ac!\n"); #endif - hp = HAlloc(p, x+1); - hp[0] = make_pos_bignum_header(x); - state_ptr = (char *)(hp); - memcpy((void *)(state_ptr+sizeof(Eterm)), bfs, sizeof(BinaryFindState)); - ac_serialize_find_all(&state, state_ptr+sizeof(Eterm)+sizeof(BinaryFindState)); - *res_term = make_big(hp); + state_ptr = (BinaryFindState_bignum*) HAlloc(p, x+1); + state_ptr->bignum_hdr = make_pos_bignum_header(x); + memcpy(&state_ptr->bfs, bfs, sizeof(BinaryFindState)); + ac_serialize_find_all(&state, &state_ptr->data.acfas); + *res_term = make_big(&state_ptr->bignum_hdr); erts_free_aligned_binary_bytes(temp_alloc); ac_clean_find_all(&state); return DO_BIN_MATCH_RESTART; @@ -1306,7 +1313,6 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar if (bfs->type == am_bm) { BMData *bm; Sint pos; - Eterm *hp; BMFindFirstState state; Uint reds = get_reds(p, BM_LOOP_FACTOR); Uint save_reds = reds; @@ -1318,7 +1324,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar if (state_term == NIL) { bm_init_find_first_match(&state, bfs->hsstart, bfs->hsend); } else { - memcpy((void *)(&state), (const void *)(state_ptr), sizeof(BMFindFirstState)); + memcpy(&state, &state_ptr->data.bmffs, sizeof(BMFindFirstState)); } #ifdef HARDDEBUG @@ -1335,13 +1341,11 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar #ifdef HARDDEBUG erts_printf("Trap bm!\n"); #endif - hp = HAlloc(p, x+1); - hp[0] = make_pos_bignum_header(x); - state_ptr = (char *)(hp); - memcpy((void *)(state_ptr+sizeof(Eterm)), bfs, sizeof(BinaryFindState)); - memcpy((void *)(state_ptr+sizeof(Eterm)+sizeof(BinaryFindState)), - (const void *)(&state), sizeof(BMFindFirstState)); - *res_term = make_big(hp); + state_ptr = (BinaryFindState_bignum*) HAlloc(p, x+1); + state_ptr->bignum_hdr = make_pos_bignum_header(x); + memcpy(&state_ptr->bfs, bfs, sizeof(BinaryFindState)); + memcpy(&state_ptr->data.acffs, &state, sizeof(BMFindFirstState)); + *res_term = make_big(&state_ptr->bignum_hdr); erts_free_aligned_binary_bytes(temp_alloc); return DO_BIN_MATCH_RESTART; } else { @@ -1355,7 +1359,6 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar Uint pos, rlen; int acr; ACFindFirstState state; - Eterm *hp; Uint reds = get_reds(p, AC_LOOP_FACTOR); Uint save_reds = reds; @@ -1366,7 +1369,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar if (state_term == NIL) { ac_init_find_first_match(&state, act, bfs->hsstart, bfs->hsend); } else { - memcpy((void *)(&state), (const void *)(state_ptr), sizeof(ACFindFirstState)); + memcpy(&state, &state_ptr->data.acffs, sizeof(ACFindFirstState)); } acr = ac_find_first_match(&state, bytes, &pos, &rlen, &reds); if (acr == AC_NOT_FOUND) { @@ -1378,13 +1381,11 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar #ifdef HARDDEBUG erts_printf("Trap ac!\n"); #endif - hp = HAlloc(p, x+1); - hp[0] = make_pos_bignum_header(x); - state_ptr = (char *)(hp); - memcpy((void *)(state_ptr+sizeof(Eterm)), bfs, sizeof(BinaryFindState)); - memcpy((void *)(state_ptr+sizeof(Eterm)+sizeof(BinaryFindState)), - (const void *)(&state), sizeof(ACFindFirstState)); - *res_term = make_big(hp); + state_ptr = (BinaryFindState_bignum*) HAlloc(p, x+1); + state_ptr->bignum_hdr = make_pos_bignum_header(x); + memcpy(&state_ptr->bfs, bfs, sizeof(BinaryFindState)); + memcpy(&state_ptr->data.acffs, &state, sizeof(ACFindFirstState)); + *res_term = make_big(&state_ptr->bignum_hdr); erts_free_aligned_binary_bytes(temp_alloc); return DO_BIN_MATCH_RESTART; } else { @@ -1763,7 +1764,7 @@ static BIF_RETTYPE binary_find_trap(BIF_ALIST_3) int runres; Eterm result; Binary *bin = ((ProcBin *) binary_val(BIF_ARG_3))->val; - runres = do_binary_find(BIF_P, BIF_ARG_1, THE_NON_VALUE, bin, BIF_ARG_2, &result); + runres = do_binary_find(BIF_P, BIF_ARG_1, NULL, bin, BIF_ARG_2, &result); if (runres == DO_BIN_MATCH_OK) { BIF_RET(result); } else { -- cgit v1.2.3