aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_load.c
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-03-25 13:10:30 +0100
committerBjörn Gustavsson <[email protected]>2015-04-13 12:37:55 +0200
commit9b940b12210500e615ea05b447b0e1be34e70d39 (patch)
tree2592ce44da307877a30d2ff0ea2e13c368aa83b8 /erts/emulator/beam/beam_load.c
parent5f1e301dfec48fccbf865a8b54af5908bebb77c4 (diff)
downloadotp-9b940b12210500e615ea05b447b0e1be34e70d39.tar.gz
otp-9b940b12210500e615ea05b447b0e1be34e70d39.tar.bz2
otp-9b940b12210500e615ea05b447b0e1be34e70d39.zip
Pre-compute hash values for the general get_map_elements instruction
See the previous commit for justification and use cases.
Diffstat (limited to 'erts/emulator/beam/beam_load.c')
-rw-r--r--erts/emulator/beam/beam_load.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index ee319d0a78..8d7beb4eb4 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -4219,6 +4219,47 @@ gen_get_map_element(LoaderState* stp, GenOpArg Fail, GenOpArg Src,
}
static GenOp*
+gen_get_map_elements(LoaderState* stp, GenOpArg Fail, GenOpArg Src,
+ GenOpArg Size, GenOpArg* Rest)
+{
+ GenOp* op;
+ Uint32 hx;
+ Uint i;
+ GenOpArg* dst;
+#ifdef DEBUG
+ int good_hash;
+#endif
+
+ ASSERT(Size.type == TAG_u);
+
+ NEW_GENOP(stp, op);
+ op->op = genop_i_get_map_elements_3;
+ GENOP_ARITY(op, 3 + 3*(Size.val/2));
+ op->next = NULL;
+ op->a[0] = Fail;
+ op->a[1] = Src;
+ op->a[2].type = TAG_u;
+ op->a[2].val = 3*(Size.val/2);
+
+ dst = op->a+3;
+ for (i = 0; i < Size.val / 2; i++) {
+ dst[0] = Rest[2*i];
+ dst[1] = Rest[2*i+1];
+#ifdef DEBUG
+ good_hash =
+#endif
+ hash_genop_arg(stp, dst[0], &hx);
+#ifdef DEBUG
+ ASSERT(good_hash);
+#endif
+ dst[2].type = TAG_u;
+ dst[2].val = (BeamInstr) hx;
+ dst += 3;
+ }
+ return op;
+}
+
+static GenOp*
gen_has_map_fields(LoaderState* stp, GenOpArg Fail, GenOpArg Src,
GenOpArg Size, GenOpArg* Rest)
{