aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2016-04-01 14:03:51 +0200
committerBjörn Gustavsson <bjorn@erlang.org>2016-04-06 15:55:29 +0200
commitec26a0c56cb6e28cc5a35ef72116275e5eeef823 (patch)
tree9731b718e21457bac2517ef7258de76f5cf3dcc5 /erts/emulator
parent4b507534f27c343fe2b53f07bbe52e94c81e381f (diff)
downloadotp-ec26a0c56cb6e28cc5a35ef72116275e5eeef823.tar.gz
otp-ec26a0c56cb6e28cc5a35ef72116275e5eeef823.tar.bz2
otp-ec26a0c56cb6e28cc5a35ef72116275e5eeef823.zip
Refactor calls to transform_engine()
We used to set last_op_next and last_op to NULL just in case. Setting last_op_next to causes a rescan of the instructions to find the last instruction in the chain, so we would want to avoid that unless really necessary.
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/beam_load.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 16cbdbffea..2f2b433999 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -2028,11 +2028,7 @@ load_code(LoaderState* stp)
ASSERT(arity == last_op->arity);
do_transform:
- if (stp->genop == NULL) {
- last_op_next = NULL;
- goto get_next_instr;
- }
-
+ ASSERT(stp->genop != NULL);
if (gen_opc[stp->genop->op].transform != -1) {
int need;
tmp_op = stp->genop;
@@ -2045,25 +2041,34 @@ load_code(LoaderState* stp)
}
switch (transform_engine(stp)) {
case TE_FAIL:
- last_op_next = NULL;
- last_op = NULL;
+ /*
+ * No transformation found. stp->genop != NULL and
+ * last_op_next is still valid. Go ahead and load
+ * the instruction.
+ */
break;
case TE_OK:
+ /*
+ * Some transformation was applied. last_op_next is
+ * no longer valid and stp->genop may be NULL.
+ * Try to transform again.
+ */
+ if (stp->genop == NULL) {
+ last_op_next = &stp->genop;
+ goto get_next_instr;
+ }
last_op_next = NULL;
- last_op = NULL;
goto do_transform;
case TE_SHORT_WINDOW:
- last_op_next = NULL;
- last_op = NULL;
+ /*
+ * No transformation applied. stp->genop != NULL and
+ * last_op_next is still valid. Fetch a new instruction
+ * before trying the transformation again.
+ */
goto get_next_instr;
}
}
- if (stp->genop == NULL) {
- last_op_next = NULL;
- goto get_next_instr;
- }
-
/*
* From the collected generic instruction, find the specific
* instruction.
@@ -2584,7 +2589,10 @@ load_code(LoaderState* stp)
{
GenOp* next = stp->genop->next;
FREE_GENOP(stp, stp->genop);
- stp->genop = next;
+ if ((stp->genop = next) == NULL) {
+ last_op_next = &stp->genop;
+ goto get_next_instr;
+ }
goto do_transform;
}
}