aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-09-09 12:01:14 +0200
committerBjörn Gustavsson <[email protected]>2017-09-14 10:16:15 +0200
commit6f45ff73583aa7d0352b8a16df78872f47defd35 (patch)
tree8bcc05bfdc6bbf1a3cbd4c1a240cb4eed6eaf353
parenta8e391f3baf2cfbcfa57e46d4cfe95c089921100 (diff)
downloadotp-6f45ff73583aa7d0352b8a16df78872f47defd35.tar.gz
otp-6f45ff73583aa7d0352b8a16df78872f47defd35.tar.bz2
otp-6f45ff73583aa7d0352b8a16df78872f47defd35.zip
Optimize i_select_tuple_arity2 and is_select_lins
Don't save a pointer to the default failure label. That could relieve register pressure. Instead, if we'll need to signal an error in i_select_tuple_arity2, delay to the execution phase. That should be a clear win because i_select_tuple_arity2 very rarely fails because of the term being selected is not a tuple.
-rw-r--r--erts/emulator/beam/select_instrs.tab43
1 files changed, 16 insertions, 27 deletions
diff --git a/erts/emulator/beam/select_instrs.tab b/erts/emulator/beam/select_instrs.tab
index 4a8d9cce96..f5ce5d5a32 100644
--- a/erts/emulator/beam/select_instrs.tab
+++ b/erts/emulator/beam/select_instrs.tab
@@ -75,66 +75,55 @@ select_val_bins.select(Fail, NumElements) {
$JUMP($Fail);
}
-i_select_tuple_arity2 := select_val2.src.ta_fail.execute;
-i_select_val2 := select_val2.src.fail.execute;
+i_select_tuple_arity2 := select_val2.src.get_arity.execute;
+i_select_val2 := select_val2.src.execute;
select_val2.head() {
Eterm select_val2;
- BeamInstr* select_fail;
}
select_val2.src(Src) {
select_val2 = $Src;
}
-select_val2.ta_fail(Fail) {
- select_fail = &$Fail;
- if (is_not_tuple(select_val2)) {
- $FAIL(*select_fail);
+select_val2.get_arity() {
+ if (ERTS_LIKELY(is_tuple(select_val2))) {
+ select_val2 = *tuple_val(select_val2);
+ } else {
+ select_val2 = NIL;
}
- select_val2 = *tuple_val(select_val2);
-}
-
-select_val2.fail(Fail) {
- select_fail = &$Fail;
}
-select_val2.execute(T1, T2, D1, D2) {
+select_val2.execute(Fail, T1, T2, D1, D2) {
if (select_val2 == $T1) {
$JUMP($D1);
} else if (select_val2 == $T2) {
$JUMP($D2);
} else {
- $FAIL(*select_fail);
+ $FAIL($Fail);
}
}
-i_select_tuple_arity := select_val_lin.fetch.ta_fail.execute;
-i_select_val_lins := select_val_lin.fetch.fail.execute;
+i_select_tuple_arity := select_val_lin.fetch.get_arity.execute;
+i_select_val_lins := select_val_lin.fetch.execute;
select_val_lin.head() {
Eterm select_val;
- BeamInstr* select_fail;
}
select_val_lin.fetch(Src) {
select_val = $Src;
}
-select_val_lin.ta_fail(Fail) {
- select_fail = &$Fail;
- if (is_tuple(select_val)) {
+select_val_lin.get_arity() {
+ if (ERTS_LIKELY(is_tuple(select_val))) {
select_val = *tuple_val(select_val);
} else {
- $JUMP(*select_fail);
+ select_val = NIL;
}
}
-select_val_lin.fail(Fail) {
- select_fail = &$Fail;
-}
-
-select_val_lin.execute(N) {
+select_val_lin.execute(Fail, N) {
BeamInstr* vs = $NEXT_INSTRUCTION;
int ix = 0;
@@ -155,7 +144,7 @@ select_val_lin.execute(N) {
Eterm offset = jump_tab[ix];
$JUMP(offset);
} else {
- $JUMP(*select_fail);
+ $JUMP($Fail);
}
}