File 0026-erts-Minor-refactor-for-binary-find-BIF-backend.patch of Package erlang

From 8067992954f9b882ffd7332ee669a254c000f1b2 Mon Sep 17 00:00:00 2001
From: Andrew Bennett <potatosaladx@gmail.com>
Date: Fri, 18 Sep 2015 09:38:46 -0600
Subject: [PATCH 6/6] 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(-)

diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index 9f72b8c..b1ebf03 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 {
-- 
2.1.4

openSUSE Build Service is sponsored by