aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/instrs.tab
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/instrs.tab')
-rw-r--r--erts/emulator/beam/instrs.tab138
1 files changed, 77 insertions, 61 deletions
diff --git a/erts/emulator/beam/instrs.tab b/erts/emulator/beam/instrs.tab
index 1af01e53bd..c17d1a8f69 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,18 +114,14 @@ move_call_last(Src, CallDest, Deallocate) {
}
i_call_only(CallDest) {
- $DISPATCH($CallDest);
+ $DISPATCH_REL($CallDest);
}
-i_move_call_only(CallDest, Src) {
+move_call_only(Src, CallDest) {
x(0) = $Src;
$i_call_only($CallDest);
}
-move_call_only(Src, CallDest) {
- $i_move_call_only($CallDest, $Src);
-}
-
DISPATCHX(Dest) {
//| -no_next
DTRACE_GLOBAL_CALL_FROM_EXPORT(c_p, $Dest);
@@ -156,10 +159,10 @@ i_move_call_ext_last(Dest, StackOffset, Src) {
$i_call_ext_last($Dest, $StackOffset);
}
-APPLY(I, Deallocate) {
+APPLY(I, Deallocate, Next) {
//| -no_next
HEAVY_SWAPOUT;
- next = apply(c_p, r(0), x(1), x(2), reg, $I, $Deallocate);
+ $Next = apply(c_p, reg, $I, $Deallocate);
HEAVY_SWAPIN;
}
@@ -170,59 +173,63 @@ HANDLE_APPLY_ERROR() {
i_apply() {
BeamInstr *next;
- $APPLY(NULL, 0);
- if (next != NULL) {
- $i_call(next);
+ $APPLY(NULL, 0, next);
+ if (ERTS_LIKELY(next != NULL)) {
+ SET_CP(c_p, $NEXT_INSTRUCTION);
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
i_apply_last(Deallocate) {
BeamInstr *next;
- $APPLY(I, $Deallocate);
- if (next != NULL) {
- $i_call_last(next, $Deallocate);
+ $APPLY(I, $Deallocate, next);
+ if (ERTS_LIKELY(next != NULL)) {
+ $deallocate($Deallocate);
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
i_apply_only() {
BeamInstr *next;
- $APPLY(I, 0);
- if (next != NULL) {
- $i_call_only(next);
+ $APPLY(I, 0, next);
+ if (ERTS_LIKELY(next != NULL)) {
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
-FIXED_APPLY(Arity, I, Deallocate) {
+FIXED_APPLY(Arity, I, Deallocate, Next) {
//| -no_next
HEAVY_SWAPOUT;
- next = fixed_apply(c_p, reg, $Arity, $I, $Deallocate);
+ $Next = fixed_apply(c_p, reg, $Arity, $I, $Deallocate);
HEAVY_SWAPIN;
}
apply(Arity) {
BeamInstr *next;
- $FIXED_APPLY($Arity, NULL, 0);
- if (next != NULL) {
- $i_call(next);
+ $FIXED_APPLY($Arity, NULL, 0, next);
+ if (ERTS_LIKELY(next != NULL)) {
+ SET_CP(c_p, $NEXT_INSTRUCTION);
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
apply_last(Arity, Deallocate) {
BeamInstr *next;
- $FIXED_APPLY($Arity, I, $Deallocate);
- if (next != NULL) {
- $i_call_last(next, $Deallocate);
+ $FIXED_APPLY($Arity, I, $Deallocate, next);
+ if (ERTS_LIKELY(next != NULL)) {
+ $deallocate($Deallocate);
+ $DISPATCH_ABS(next);
}
$HANDLE_APPLY_ERROR();
}
-APPLY_FUN() {
+APPLY_FUN(Next) {
HEAVY_SWAPOUT;
- next = apply_fun(c_p, r(0), x(1), reg);
+ $Next = apply_fun(c_p, r(0), x(1), reg);
HEAVY_SWAPIN;
}
@@ -237,8 +244,8 @@ DISPATCH_FUN(I) {
i_apply_fun() {
BeamInstr *next;
- $APPLY_FUN();
- if (next != NULL) {
+ $APPLY_FUN(next);
+ if (ERTS_LIKELY(next != NULL)) {
SET_CP(c_p, $NEXT_INSTRUCTION);
$DISPATCH_FUN(next);
}
@@ -247,8 +254,8 @@ i_apply_fun() {
i_apply_fun_last(Deallocate) {
BeamInstr *next;
- $APPLY_FUN();
- if (next != NULL) {
+ $APPLY_FUN(next);
+ if (ERTS_LIKELY(next != NULL)) {
$deallocate($Deallocate);
$DISPATCH_FUN(next);
}
@@ -257,24 +264,24 @@ i_apply_fun_last(Deallocate) {
i_apply_fun_only() {
BeamInstr *next;
- $APPLY_FUN();
- if (next != NULL) {
+ $APPLY_FUN(next);
+ if (ERTS_LIKELY(next != NULL)) {
$DISPATCH_FUN(next);
}
$HANDLE_APPLY_FUN_ERROR();
}
-CALL_FUN(Fun) {
+CALL_FUN(Fun, Next) {
//| -no_next
HEAVY_SWAPOUT;
- next = call_fun(c_p, $Fun, reg, THE_NON_VALUE);
+ $Next = call_fun(c_p, $Fun, reg, THE_NON_VALUE);
HEAVY_SWAPIN;
}
i_call_fun(Fun) {
BeamInstr *next;
- $CALL_FUN($Fun);
- if (next != NULL) {
+ $CALL_FUN($Fun, next);
+ if (ERTS_LIKELY(next != NULL)) {
SET_CP(c_p, $NEXT_INSTRUCTION);
$DISPATCH_FUN(next);
}
@@ -283,8 +290,8 @@ i_call_fun(Fun) {
i_call_fun_last(Fun, Deallocate) {
BeamInstr *next;
- $CALL_FUN($Fun);
- if (next != NULL) {
+ $CALL_FUN($Fun, next);
+ if (ERTS_LIKELY(next != NULL)) {
$deallocate($Deallocate);
$DISPATCH_FUN(next);
}
@@ -368,7 +375,6 @@ i_element := element_group.fetch.execute;
element_group.head() {
- Eterm element_index;
Eterm element_tuple;
}
@@ -377,8 +383,8 @@ element_group.fetch(Src) {
}
element_group.execute(Fail, Index, Dst) {
- element_index = $Index;
- if (is_small(element_index) && is_tuple(element_tuple)) {
+ Eterm element_index = $Index;
+ if (ERTS_LIKELY(is_small(element_index) && is_tuple(element_tuple))) {
Eterm* tp = tuple_val(element_tuple);
if ((signed_val(element_index) >= 1) &&
@@ -402,7 +408,7 @@ fast_element_group.fetch(Src) {
}
fast_element_group.execute(Fail, Index, Dst) {
- if (is_tuple(fast_element_tuple)) {
+ if (ERTS_LIKELY(is_tuple(fast_element_tuple))) {
Eterm* tp = tuple_val(fast_element_tuple);
Eterm pos = $Index; /* Untagged integer >= 1 */
if (pos <= arityval(*tp)) {
@@ -564,6 +570,7 @@ i_put_tuple.fill(Arity) {
}
} while (--arity != 0);
HTOP = hp;
+ ASSERT(VALID_INSTR(* (Eterm *)I));
Goto(*I);
}
@@ -735,9 +742,10 @@ is_reference(Fail, Src) {
}
is_tagged_tuple(Fail, Src, Arityval, Tag) {
- if (!(BEAM_IS_TUPLE($Src) &&
- (tuple_val($Src))[0] == $Arityval &&
- (tuple_val($Src))[1] == $Tag)) {
+ Eterm term = $Src;
+ if (!(BEAM_IS_TUPLE(term) &&
+ (tuple_val(term))[0] == $Arityval &&
+ (tuple_val(term))[1] == $Tag)) {
$FAIL($Fail);
}
}
@@ -749,7 +757,8 @@ is_tuple(Fail, Src) {
}
is_tuple_of_arity(Fail, Src, Arityval) {
- if (!(BEAM_IS_TUPLE($Src) && *tuple_val($Src) == $Arityval)) {
+ Eterm term = $Src;
+ if (!(BEAM_IS_TUPLE(term) && *tuple_val(term) == $Arityval)) {
$FAIL($Fail);
}
}
@@ -779,7 +788,8 @@ is_eq_exact(Fail, X, Y) {
}
i_is_eq_exact_literal(Fail, Src, Literal) {
- if (!eq($Src, $Literal)) {
+ Eterm src = $Src;
+ if (is_immed(src) || !eq(src, $Literal)) {
$FAIL($Fail);
}
}
@@ -791,7 +801,8 @@ is_ne_exact(Fail, X, Y) {
}
i_is_ne_exact_literal(Fail, Src, Literal) {
- if (eq($Src, $Literal)) {
+ Eterm src = $Src;
+ if (!is_immed(src) && eq(src, $Literal)) {
$FAIL($Fail);
}
}
@@ -821,12 +832,14 @@ badmatch(Src) {
c_p->fvalue = $Src;
c_p->freason = BADMATCH;
goto find_func_info;
+ //| -no_next;
}
case_end(Src) {
c_p->fvalue = $Src;
c_p->freason = EXC_CASE_CLAUSE;
goto find_func_info;
+ //| -no_next;
}
if_end() {
@@ -846,8 +859,7 @@ catch(Y, Fail) {
}
catch_end(Y) {
- c_p->catches--;
- make_blank($Y);
+ $try_end($Y);
if (is_non_value(r(0))) {
c_p->fvalue = NIL;
if (x(1) == am_throw) {
@@ -877,12 +889,15 @@ catch_end(Y) {
try_end(Y) {
c_p->catches--;
make_blank($Y);
- if (is_non_value(r(0))) {
- c_p->fvalue = NIL;
- r(0) = x(1);
- x(1) = x(2);
- x(2) = x(3);
- }
+}
+
+try_case(Y) {
+ $try_end($Y);
+ ASSERT(is_non_value(r(0)));
+ c_p->fvalue = NIL;
+ r(0) = x(1);
+ x(1) = x(2);
+ x(2) = x(3);
}
try_case_end(Src) {
@@ -906,5 +921,6 @@ i_raise() {
c_p->freason = PRIMARY_EXCEPTION(s->freason);
}
goto find_func_info;
+ //| -no_next
}