Skip to content

Commit a7d4b1a

Browse files
committed
Merge 'sverker/22/ets-matchspec-stack-bug/OTP-17379'
forward to OTP-23.3.1 as 'sverker/23/ets-matchspec-stack-bug/OTP-17379'
2 parents c378425 + ae9b51e commit a7d4b1a

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

erts/emulator/beam/erl_db_util.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3837,6 +3837,7 @@ dmc_array(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text,
38373837
{
38383838
int all_constant = 1;
38393839
int textpos = DMC_STACK_NUM(*text);
3840+
int preventive_bumps = 0;
38403841
Uint i;
38413842

38423843
/*
@@ -3856,13 +3857,35 @@ dmc_array(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text,
38563857
if (!c && all_constant) {
38573858
all_constant = 0;
38583859
if (i < nelems - 1) {
3860+
/* Revert preventive stack bumps as they will now be done again
3861+
* for real by do_emit_constant() */
3862+
context->stack_used -= preventive_bumps;
3863+
38593864
dmc_rearrange_constants(context, text, textpos,
38603865
p + i + 1, nelems - i - 1);
38613866
}
3862-
} else if (c && !all_constant) {
3863-
do_emit_constant(context, text, p[i]);
3867+
} else if (c) {
3868+
if (all_constant) {
3869+
/*
3870+
* OTP-17379:
3871+
* All constants so far, but do preventive stack bumps
3872+
* as the constants may later be converted to matchPushC
3873+
* by dmc_rearrange_constants above.
3874+
* Otherwise dmc_expr() may do incorrect stack depth estimation
3875+
* when it emits instructions for the first non-constant.
3876+
*/
3877+
++context->stack_used;
3878+
++preventive_bumps;
3879+
}
3880+
else {
3881+
do_emit_constant(context, text, p[i]);
3882+
}
38643883
}
38653884
}
3885+
if (all_constant) {
3886+
/* Preventive stack bumps not needed */
3887+
context->stack_used -= preventive_bumps;
3888+
}
38663889
*constant = all_constant;
38673890
return retOk;
38683891
}

lib/stdlib/test/ets_SUITE.erl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@
4141
-export([foldl_ordered/1, foldr_ordered/1, foldl/1, foldr/1, fold_empty/1]).
4242
-export([t_delete_object/1, t_init_table/1, t_whitebox/1,
4343
select_bound_chunk/1, t_delete_all_objects/1, t_test_ms/1,
44-
t_select_delete/1,t_select_replace/1,t_select_replace_next_bug/1,t_ets_dets/1]).
44+
t_select_delete/1,t_select_replace/1,t_select_replace_next_bug/1,
45+
t_select_pam_stack_overflow_bug/1,
46+
t_ets_dets/1]).
4547
-export([t_insert_list/1, t_insert_list_bag/1, t_insert_list_duplicate_bag/1,
4648
t_insert_list_set/1, t_insert_list_delete_set/1,
4749
t_insert_list_parallel/1, t_insert_list_delete_parallel/1,
@@ -147,6 +149,7 @@ all() ->
147149
t_init_table, t_whitebox, t_delete_all_objects,
148150
t_test_ms, t_select_delete, t_select_replace,
149151
t_select_replace_next_bug,
152+
t_select_pam_stack_overflow_bug,
150153
t_ets_dets, memory, t_select_reverse, t_bucket_disappears,
151154
t_named_select, select_fixtab_owner_change,
152155
select_fail, t_insert_new, t_repair_continuation,
@@ -1897,6 +1900,15 @@ t_select_replace_next_bug(Config) when is_list(Config) ->
18971900
ets:delete(T).
18981901

18991902

1903+
%% OTP-17379
1904+
t_select_pam_stack_overflow_bug(Config) ->
1905+
T = ets:new(k, []),
1906+
ets:insert(T,[{x,17}]),
1907+
[{x,18}] = ets:select(T,[{{x,17}, [], [{{{element,1,'$_'},{const,18}}}]}]),
1908+
ets:delete(T),
1909+
ok.
1910+
1911+
19001912
%% Test that partly bound keys gives faster matches.
19011913
partly_bound(Config) when is_list(Config) ->
19021914
case os:type() of

0 commit comments

Comments
 (0)