aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-08-18 08:27:51 +0200
committerBjörn Gustavsson <[email protected]>2017-08-23 05:57:39 +0200
commit0848894878ef90b1c6d81e4a6e2741508d0b99f5 (patch)
treec3852f78520af8802d251fc2147a5a0b1b0c77f5 /erts/emulator/beam
parent8f2646de9a74d82d8527782bdb58584c60e99742 (diff)
downloadotp-0848894878ef90b1c6d81e4a6e2741508d0b99f5.tar.gz
otp-0848894878ef90b1c6d81e4a6e2741508d0b99f5.tar.bz2
otp-0848894878ef90b1c6d81e4a6e2741508d0b99f5.zip
Pack instructions using 'q', 'c', and 's'
Update the pack engine to safely push literal operands to the pack stack and to safely pop them back to another code address. That will allow packing of more instructions.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/beam_load.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 98701db558..982f998ae3 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -2495,16 +2495,32 @@ load_code(LoaderState* stp)
* The packing engine.
*/
if (opc[stp->specific_op].pack[0]) {
- char* prog; /* Program for packing engine. */
- BeamInstr stack[8]; /* Stack. */
- BeamInstr* sp = stack; /* Points to next free position. */
- BeamInstr packed = 0; /* Accumulator for packed operations. */
+ char* prog; /* Program for packing engine. */
+ struct pack_stack {
+ BeamInstr instr;
+ LiteralPatch* patch;
+ } stack[8]; /* Stack. */
+ struct pack_stack* sp = stack; /* Points to next free position. */
+ BeamInstr packed = 0; /* Accumulator for packed operations. */
for (prog = opc[stp->specific_op].pack; *prog; prog++) {
switch (*prog) {
case 'g': /* Get instruction; push on stack. */
- *sp++ = code[--ci];
- break;
+ {
+ LiteralPatch* lp;
+
+ ci--;
+ sp->instr = code[ci];
+ sp->patch = 0;
+ for (lp = stp->literal_patches; lp && lp->pos > ci-MAX_OPARGS; lp = lp->next) {
+ if (lp->pos == ci) {
+ sp->patch = lp;
+ break;
+ }
+ }
+ sp++;
+ }
+ break;
case 'i': /* Initialize packing accumulator. */
packed = code[--ci];
break;
@@ -2520,10 +2536,17 @@ load_code(LoaderState* stp)
break;
#endif
case 'p': /* Put instruction (from stack). */
- code[ci++] = *--sp;
+ --sp;
+ code[ci] = sp->instr;
+ if (sp->patch) {
+ sp->patch->pos = ci;
+ }
+ ci++;
break;
case 'P': /* Put packed operands. */
- *sp++ = packed;
+ sp->instr = packed;
+ sp->patch = 0;
+ sp++;
packed = 0;
break;
default: