diff options
author | Sverker Eriksson <sverker@erlang.org> | 2021-05-06 12:15:05 +0200 |
---|---|---|
committer | Sverker Eriksson <sverker@erlang.org> | 2021-05-06 12:16:23 +0200 |
commit | a7d4b1a7867ec23edc2c4a41c965b83cfc6afdcb (patch) | |
tree | 517faa16b98f7ac5093a077021c915d89ea05c44 /erts | |
parent | c3784253e168e4f7acf301015e5461eacf884e4e (diff) | |
parent | ae9b51e15c2f879741679e52f9b3b498195c49e2 (diff) | |
download | erlang-a7d4b1a7867ec23edc2c4a41c965b83cfc6afdcb.tar.gz |
Merge 'sverker/22/ets-matchspec-stack-bug/OTP-17379'
forward to OTP-23.3.1
as 'sverker/23/ets-matchspec-stack-bug/OTP-17379'
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/erl_db_util.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 2087e1c337..658ac44824 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -3837,6 +3837,7 @@ dmc_array(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text, { int all_constant = 1; int textpos = DMC_STACK_NUM(*text); + int preventive_bumps = 0; Uint i; /* @@ -3856,13 +3857,35 @@ dmc_array(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text, if (!c && all_constant) { all_constant = 0; if (i < nelems - 1) { + /* Revert preventive stack bumps as they will now be done again + * for real by do_emit_constant() */ + context->stack_used -= preventive_bumps; + dmc_rearrange_constants(context, text, textpos, p + i + 1, nelems - i - 1); } - } else if (c && !all_constant) { - do_emit_constant(context, text, p[i]); + } else if (c) { + if (all_constant) { + /* + * OTP-17379: + * All constants so far, but do preventive stack bumps + * as the constants may later be converted to matchPushC + * by dmc_rearrange_constants above. + * Otherwise dmc_expr() may do incorrect stack depth estimation + * when it emits instructions for the first non-constant. + */ + ++context->stack_used; + ++preventive_bumps; + } + else { + do_emit_constant(context, text, p[i]); + } } } + if (all_constant) { + /* Preventive stack bumps not needed */ + context->stack_used -= preventive_bumps; + } *constant = all_constant; return retOk; } |