aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2016-12-28 18:23:06 +0100
committerRickard Green <[email protected]>2017-01-12 15:22:26 +0100
commit6bcdd45abd97134fddfb5b0307b1d256337b0c67 (patch)
tree7d3bdbe9e08ff9f046463ff95580d6489bface18
parenta3cccab21df2f18eeb38de0f28fb70480f3676d2 (diff)
downloadotp-6bcdd45abd97134fddfb5b0307b1d256337b0c67.tar.gz
otp-6bcdd45abd97134fddfb5b0307b1d256337b0c67.tar.bz2
otp-6bcdd45abd97134fddfb5b0307b1d256337b0c67.zip
Reduction counting on non-tail return
-rw-r--r--erts/emulator/beam/beam_emu.c21
-rw-r--r--erts/emulator/beam/erl_vm.h2
-rw-r--r--erts/emulator/test/nif_SUITE.erl2
3 files changed, 19 insertions, 6 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index c554bd73b6..bb77dbd955 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -633,21 +633,34 @@ void** beam_ops;
y[4] = xt4; \
} while (0)
+#define DispatchReturn \
+do { \
+ if (FCALLS > 0 || FCALLS > neg_o_reds) { \
+ FCALLS--; \
+ Goto(*I); \
+ } \
+ else { \
+ c_p->current = NULL; \
+ c_p->arity = 1; \
+ goto context_switch3; \
+ } \
+} while (0)
+
#define MoveReturn(Src) \
x(0) = (Src); \
I = c_p->cp; \
ASSERT(VALID_INSTR(*c_p->cp)); \
c_p->cp = 0; \
CHECK_TERM(r(0)); \
- Goto(*I)
+ DispatchReturn
#define DeallocateReturn(Deallocate) \
do { \
int words_to_pop = (Deallocate); \
- SET_I((BeamInstr *) cp_val(*E)); \
+ SET_I((BeamInstr *) cp_val(*E)); \
E = ADD_BYTE_OFFSET(E, words_to_pop); \
CHECK_TERM(r(0)); \
- Goto(*I); \
+ DispatchReturn; \
} while (0)
#define MoveDeallocateReturn(Src, Deallocate) \
@@ -1681,7 +1694,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array)
c_p->cp = 0;
CHECK_TERM(r(0));
HEAP_SPACE_VERIFIED(0);
- Goto(*I);
+ DispatchReturn;
}
/*
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index 93cfe08105..d88cafc5bf 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -36,7 +36,7 @@
#define EMULATOR "BEAM"
#define SEQ_TRACE 1
-#define CONTEXT_REDS 2000 /* Swap process out after this number */
+#define CONTEXT_REDS 4000 /* Swap process out after this number */
#define MAX_ARG 255 /* Max number of arguments allowed */
#define MAX_REG 1024 /* Max number of x(N) registers used */
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 0d3910b2e2..36d512e388 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -1689,7 +1689,7 @@ consume_timeslice(Config) when is_list(Config) ->
consume_timeslice_test(Config) when is_list(Config) ->
ensure_lib_loaded(Config),
- CONTEXT_REDS = 2000,
+ CONTEXT_REDS = 4000,
Me = self(),
Go = make_ref(),
RedDiff = make_ref(),