Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
0733-erts-Fix-reduction-counting-in-binary-matc...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0733-erts-Fix-reduction-counting-in-binary-match-BIFs.patch of Package erlang
From c4239549ad9378ea6db30065ab1756c7d6724858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org> Date: Tue, 16 May 2023 11:21:33 +0200 Subject: [PATCH 2/2] erts: Fix reduction counting in binary match BIFs --- erts/emulator/beam/erl_bif_binary.c | 31 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c index 884cf792db..453a091b1e 100644 --- a/erts/emulator/beam/erl_bif_binary.c +++ b/erts/emulator/beam/erl_bif_binary.c @@ -646,7 +646,7 @@ static BFReturn ac_find_first_match(BinaryFindContext *ctx, byte *haystack) register Uint reds = *reductions; while (i < len) { - if (--reds == 0) { + if (reds == 0) { state->q = q; state->pos = i; state->len = len; @@ -655,6 +655,8 @@ static BFReturn ac_find_first_match(BinaryFindContext *ctx, byte *haystack) return BF_RESTART; } + reds--; + while (q->g[haystack[i]] == NULL && q->h != q) { q = q->h; } @@ -844,23 +846,22 @@ static BFReturn bm_find_first_match(BinaryFindContext *ctx, byte *haystack) Sint mem_read = len - needle_last - j; if (mem_read <= 0) { - return BF_NOT_FOUND; + return BF_NOT_FOUND; } - mem_read = MIN(mem_read, reds * MC_LOOP_FACTOR); + + /* Save at least one reduction for the loop below. */ + mem_read = MIN(mem_read, 1 + (reds - 1) * MC_LOOP_FACTOR); ASSERT(mem_read > 0); pos_pointer = memchr(&haystack[j + needle_last], needle[needle_last], mem_read); if (pos_pointer == NULL) { - reds -= mem_read / MC_LOOP_FACTOR; - j += mem_read; + reds -= mem_read / MC_LOOP_FACTOR; + j += mem_read; } else { - reds -= (pos_pointer - &haystack[j]) / MC_LOOP_FACTOR; - j = pos_pointer - haystack - needle_last; + reds -= (pos_pointer - &haystack[j]) / MC_LOOP_FACTOR; + j = pos_pointer - haystack - needle_last; } - // Ensure we have at least one reduction before entering the loop - ++reds; - for(;;) { if (j > len - blen) { *reductions = reds; @@ -934,7 +935,8 @@ static BFReturn bm_find_all_non_overlapping(BinaryFindContext *ctx, byte *haysta if(mem_read <= 0) { goto done; } - mem_read = MIN(mem_read, reds * MC_LOOP_FACTOR); + /* Save at least one reduction for the loop below. */ + mem_read = MIN(mem_read, 1 + (reds - 1) * MC_LOOP_FACTOR); ASSERT(mem_read > 0); pos_pointer = memchr(&haystack[j + needle_last], needle[needle_last], mem_read); if (pos_pointer == NULL) { @@ -944,8 +946,6 @@ static BFReturn bm_find_all_non_overlapping(BinaryFindContext *ctx, byte *haysta reds -= (pos_pointer - &haystack[j]) / MC_LOOP_FACTOR; j = pos_pointer - haystack - needle_last; } - // Ensure we have at least one reduction when resuming the loop - ++reds; } if (j > len - blen) { goto done; @@ -1463,7 +1463,6 @@ static BFReturn do_binary_find(Process *p, Eterm subject, BinaryFindContext **ct } erts_free_aligned_binary_bytes(temp_alloc); *res_term = THE_NON_VALUE; - BUMP_ALL_REDS(p); return BF_RESTART; } else { *res_term = ctx->found(p, subject, &ctx); @@ -1474,7 +1473,6 @@ static BFReturn do_binary_find(Process *p, Eterm subject, BinaryFindContext **ct if (is_first_call) { erts_set_gc_state(p, 0); } - BUMP_ALL_REDS(p); return BF_RESTART; } if (ctx->search->done != NULL) { @@ -1494,7 +1492,6 @@ static BFReturn do_binary_find(Process *p, Eterm subject, BinaryFindContext **ct if (is_first_call) { erts_set_gc_state(p, 0); } - BUMP_ALL_REDS(p); return BF_RESTART; } if (ctx->search->done != NULL) { @@ -1555,6 +1552,7 @@ binary_match(Process *p, Eterm arg1, Eterm arg2, Eterm arg3, Uint flags) case BF_OK: BIF_RET(result); case BF_RESTART: + BUMP_ALL_REDS(p); ASSERT(result == THE_NON_VALUE && ctx->trap_term != result && ctx->pat_term != result); BIF_TRAP3(&binary_find_trap_export, p, arg1, ctx->trap_term, ctx->pat_term); default: @@ -1616,6 +1614,7 @@ binary_split(Process *p, Eterm arg1, Eterm arg2, Eterm arg3) case BF_OK: BIF_RET(result); case BF_RESTART: + BUMP_ALL_REDS(p); ASSERT(result == THE_NON_VALUE && ctx->trap_term != result && ctx->pat_term != result); BIF_TRAP3(&binary_find_trap_export, p, arg1, ctx->trap_term, ctx->pat_term); default: -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor