aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_emu.c
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2010-11-11 08:23:55 +0100
committerBjörn Gustavsson <[email protected]>2011-01-17 15:23:42 +0100
commit824a481d5f38c748cd6efcb83cba0b8d26b88768 (patch)
treeb516c2028042df57c05bb66faf7d6b3202950bb7 /erts/emulator/beam/beam_emu.c
parente4a4632ed173f22642a2b67316b6decbc91b2a5b (diff)
downloadotp-824a481d5f38c748cd6efcb83cba0b8d26b88768.tar.gz
otp-824a481d5f38c748cd6efcb83cba0b8d26b88768.tar.bz2
otp-824a481d5f38c748cd6efcb83cba0b8d26b88768.zip
Optimize creation of tuples
Combine the put_tuple/2 and all following put/1 instructions to one i_put_tuple/2 instruction. In general, that will reduce the number of instruction words by 50 percent. Measurements seem to indicate that the speed is about the same.
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r--erts/emulator/beam/beam_emu.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 82925fda2c..e36ac1f1e6 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -525,6 +525,11 @@ extern int count_instructions;
SWAPIN; \
} while (0)
+#define PutTuple(Dst, Arity) \
+ do { \
+ Dst = make_tuple(HTOP); \
+ pt_arity = (Arity); \
+ } while (0)
/*
* Check that we haven't used the reductions and jump to function pointed to by
@@ -732,15 +737,6 @@ extern int count_instructions;
(Dest) = (* (Eterm *) EXPAND_POINTER(tmp_arg1)); \
} while (0)
-#define PutTuple(Arity, Src, Dest) \
- ASSERT(is_arity_value(Arity)); \
- Dest = make_tuple(HTOP); \
- HTOP[0] = (Arity); \
- HTOP[1] = (Src); \
- HTOP += 2
-
-#define Put(Word) *HTOP++ = (Word)
-
#define EqualImmed(X, Y, Action) if (X != Y) { Action; }
#define IsFloat(Src, Fail) if (is_not_float(Src)) { Fail; }
@@ -1155,6 +1151,8 @@ void process_main(void)
Uint temp_bits; /* Temporary used by BsSkipBits2 & BsGetInteger2 */
+ Eterm pt_arity; /* Used by do_put_tuple */
+
ERL_BITS_DECLARE_STATEP; /* Has to be last declaration */
@@ -1924,6 +1922,32 @@ void process_main(void)
Goto(*I);
}
+ do_put_tuple: {
+ Eterm* hp = HTOP;
+
+ *hp++ = make_arityval(pt_arity);
+
+ do {
+ Eterm term = *I++;
+ switch (term & _TAG_IMMED1_MASK) {
+ case (R_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER:
+ *hp++ = r(0);
+ break;
+ case (X_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER:
+ *hp++ = x(term >> _TAG_IMMED1_SIZE);
+ break;
+ case (Y_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER:
+ *hp++ = y(term >> _TAG_IMMED1_SIZE);
+ break;
+ default:
+ *hp++ = term;
+ break;
+ }
+ } while (--pt_arity != 0);
+ HTOP = hp;
+ Goto(*I);
+ }
+
/*
* All guards with zero arguments have special instructions:
* self/0