aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/msg_instrs.tab
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-11-16 13:11:35 +0100
committerGitHub <[email protected]>2017-11-16 13:11:35 +0100
commit68dd05500dcad280417a2479f32fb6f7894ae712 (patch)
treee4bda059dea8ee0d3c3d94b635dae8423518a63a /erts/emulator/beam/msg_instrs.tab
parentf1bee5747a39adde2e8bab666d19c99a0069f5a9 (diff)
parent3679444fb654e9cba1252c6df0be5170e5388639 (diff)
downloadotp-68dd05500dcad280417a2479f32fb6f7894ae712.tar.gz
otp-68dd05500dcad280417a2479f32fb6f7894ae712.tar.bz2
otp-68dd05500dcad280417a2479f32fb6f7894ae712.zip
Merge pull request #1626 from bjorng/bjorn/erts/fix-receive-opt/ERL-511
Fix broken receive mark after an exception OTP-14782
Diffstat (limited to 'erts/emulator/beam/msg_instrs.tab')
-rw-r--r--erts/emulator/beam/msg_instrs.tab21
1 files changed, 9 insertions, 12 deletions
diff --git a/erts/emulator/beam/msg_instrs.tab b/erts/emulator/beam/msg_instrs.tab
index 8055a8616f..d6d4d2fb49 100644
--- a/erts/emulator/beam/msg_instrs.tab
+++ b/erts/emulator/beam/msg_instrs.tab
@@ -43,27 +43,23 @@
// *
// */
-recv_mark(Dest) {
+i_recv_mark() {
/*
- * Save the current position in message buffer and the
- * the label for the loop_rec/2 instruction for the
- * the receive statement.
+ * Save the current position in message buffer.
*/
- $SET_REL_I(c_p->msg.mark, $Dest);
c_p->msg.saved_last = c_p->msg.last;
}
i_recv_set() {
/*
- * If the mark is valid (points to the loop_rec/2
- * instruction that follows), we know that the saved
- * position points to the first message that could
- * possibly be matched out.
+ * If c_p->msg.saved_last is non-zero, it points to the first
+ * message that could possibly be matched out.
*
- * If the mark is invalid, we do nothing, meaning that
- * we will look through all messages in the message queue.
+ * If c_p->msg.saved_last is zero, it means that it was invalidated
+ * because another receive was executed before this i_recv_set()
+ * instruction was reached.
*/
- if (c_p->msg.mark == (BeamInstr *) ($NEXT_INSTRUCTION)) {
+ if (c_p->msg.saved_last) {
c_p->msg.save = c_p->msg.saved_last;
}
SET_I($NEXT_INSTRUCTION);
@@ -131,6 +127,7 @@ i_loop_rec(Dest) {
ASSERT(HTOP == c_p->htop && E == c_p->stop);
/* TODO: Add DTrace probe for this bad message situation? */
UNLINK_MESSAGE(c_p, msgp);
+ c_p->msg.saved_last = 0; /* Better safe than sorry. */
msgp->next = NULL;
erts_cleanup_messages(msgp);
goto loop_rec__;