aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/instrs.tab
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-09-02 14:35:39 +0200
committerBjörn Gustavsson <[email protected]>2017-09-13 12:20:56 +0200
commit8650d6d811bb99490e1a75cbbab684a673a950ba (patch)
tree39924f5d0b31516b7e1d54e0755a6e7cc47c2b78 /erts/emulator/beam/instrs.tab
parentbffbd4fb504e9551fc7feb9177ef0a2394c00cae (diff)
downloadotp-8650d6d811bb99490e1a75cbbab684a673a950ba.tar.gz
otp-8650d6d811bb99490e1a75cbbab684a673a950ba.tar.bz2
otp-8650d6d811bb99490e1a75cbbab684a673a950ba.zip
Refactor instructions to support relative jumps
Introduce new macros that can be used for relative jumps and use them consistently. Test that everything works by using a non-zero constant JUMP_OFFSET. The loader subtracts JUMP_OFFSET from loaded labels, and all instructions that use 'f' operands add it back.
Diffstat (limited to 'erts/emulator/beam/instrs.tab')
-rw-r--r--erts/emulator/beam/instrs.tab32
1 files changed, 22 insertions, 10 deletions
diff --git a/erts/emulator/beam/instrs.tab b/erts/emulator/beam/instrs.tab
index 690bd3a848..7ea9dee299 100644
--- a/erts/emulator/beam/instrs.tab
+++ b/erts/emulator/beam/instrs.tab
@@ -78,7 +78,14 @@ move_deallocate_return(Src, Deallocate) {
// Call instructions
-DISPATCH(CallDest) {
+DISPATCH_REL(CallDest) {
+ //| -no_next
+ $SET_I_REL($CallDest);
+ DTRACE_LOCAL_CALL(c_p, erts_code_to_codemfa(I));
+ Dispatch();
+}
+
+DISPATCH_ABS(CallDest) {
//| -no_next
SET_I((BeamInstr *) $CallDest);
DTRACE_LOCAL_CALL(c_p, erts_code_to_codemfa(I));
@@ -87,18 +94,18 @@ DISPATCH(CallDest) {
i_call(CallDest) {
SET_CP(c_p, $NEXT_INSTRUCTION);
- $DISPATCH($CallDest);
+ $DISPATCH_REL($CallDest);
}
move_call(Src, CallDest) {
x(0) = $Src;
SET_CP(c_p, $NEXT_INSTRUCTION);
- $DISPATCH($CallDest);
+ $DISPATCH_REL($CallDest);
}
i_call_last(CallDest, Deallocate) {
$deallocate($Deallocate);
- $DISPATCH($CallDest);
+ $DISPATCH_REL($CallDest);
}
move_call_last(Src, CallDest, Deallocate) {
@@ -107,7 +114,7 @@ move_call_last(Src, CallDest, Deallocate) {
}
i_call_only(CallDest) {
- $DISPATCH($CallDest);
+ $DISPATCH_REL($CallDest);
}
move_call_only(Src, CallDest) {
@@ -168,7 +175,8 @@ i_apply() {
BeamInstr *next;
$APPLY(NULL, 0, next);
if (ERTS_LIKELY(next != NULL)) {
- $i_call(next);
+ SET_CP(c_p, $NEXT_INSTRUCTION);
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
@@ -177,7 +185,8 @@ i_apply_last(Deallocate) {
BeamInstr *next;
$APPLY(I, $Deallocate, next);
if (ERTS_LIKELY(next != NULL)) {
- $i_call_last(next, $Deallocate);
+ $deallocate($Deallocate);
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
@@ -186,7 +195,7 @@ i_apply_only() {
BeamInstr *next;
$APPLY(I, 0, next);
if (ERTS_LIKELY(next != NULL)) {
- $i_call_only(next);
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
@@ -202,7 +211,8 @@ apply(Arity) {
BeamInstr *next;
$FIXED_APPLY($Arity, NULL, 0, next);
if (ERTS_LIKELY(next != NULL)) {
- $i_call(next);
+ SET_CP(c_p, $NEXT_INSTRUCTION);
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
@@ -211,7 +221,8 @@ apply_last(Arity, Deallocate) {
BeamInstr *next;
$FIXED_APPLY($Arity, I, $Deallocate, next);
if (ERTS_LIKELY(next != NULL)) {
- $i_call_last(next, $Deallocate);
+ $deallocate($Deallocate);
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
@@ -560,6 +571,7 @@ i_put_tuple.fill(Arity) {
}
} while (--arity != 0);
HTOP = hp;
+ ASSERT(VALID_INSTR(* (Eterm *)I));
Goto(*I);
}