diff options
author | Erlang/OTP <[email protected]> | 2010-03-22 14:51:35 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2010-03-22 15:56:43 +0100 |
commit | a4b4d36cdbbd692123443a1d3f19f1c452963201 (patch) | |
tree | 218002c4a2b38f69eb67d6388c8034820812fd47 /erts/emulator/beam/erl_arith.c | |
parent | 835dba95f810cc925ac856171014b9dbea8c90be (diff) | |
parent | 24095d93fb28bdd60abe771a426e39c6ff0f72c7 (diff) | |
download | otp-a4b4d36cdbbd692123443a1d3f19f1c452963201.tar.gz otp-a4b4d36cdbbd692123443a1d3f19f1c452963201.tar.bz2 otp-a4b4d36cdbbd692123443a1d3f19f1c452963201.zip |
Merge branch 'pan/otp_8332_halfword' into dev
* pan/otp_8332_halfword:
Teach testcase in driver_suite the new prototype for driver_async
wx: Correct usage of driver callbacks from wx thread
Adopt the new (R13B04) Nif functionality to the halfword codebase
Support monitoring and demonitoring from driver threads
Fix further test-suite problems
Correct the VM to work for more test suites
Teach {wordsize,internal|external} to system_info/1
Make tracing and distribution work
Turn on instruction packing in the loader and virtual machine
Add the BeamInstr data type for loaded BEAM code
Fix the BEAM dissambler for the half-word emulator
Store pointers to heap data in 32-bit words
Add a custom mmap wrapper to force heaps into the lower address range
Fit all heap data into the 32-bit address range
Diffstat (limited to 'erts/emulator/beam/erl_arith.c')
-rw-r--r-- | erts/emulator/beam/erl_arith.c | 107 |
1 files changed, 62 insertions, 45 deletions
diff --git a/erts/emulator/beam/erl_arith.c b/erts/emulator/beam/erl_arith.c index 126ec7cc73..64fad9fe0e 100644 --- a/erts/emulator/beam/erl_arith.c +++ b/erts/emulator/beam/erl_arith.c @@ -41,6 +41,16 @@ # define MAX(x, y) (((x) > (y)) ? (x) : (y)) #endif +#if !HEAP_ON_C_STACK +# define DECLARE_TMP(VariableName,N,P) \ + Eterm *VariableName = ((ERTS_PROC_GET_SCHDATA(P)->erl_arith_tmp_heap) + (2 * N)) +#else +# define DECLARE_TMP(VariableName,N,P) \ + Eterm VariableName[2] +#endif +# define ARG_IS_NOT_TMP(Arg,Tmp) ((Arg) != make_big((Tmp))) + + static Eterm shift(Process* p, Eterm arg1, Eterm arg2, int right); static ERTS_INLINE void maybe_shrink(Process* p, Eterm* hp, Eterm res, Uint alloc) @@ -169,7 +179,7 @@ shift(Process* p, Eterm arg1, Eterm arg2, int right) { Sint i; Sint ires; - Eterm tmp_big1[2]; + DECLARE_TMP(tmp_big1,0,p); Eterm* bigp; Uint need; @@ -312,8 +322,8 @@ BIF_RETTYPE bnot_1(BIF_ALIST_1) Eterm erts_mixed_plus(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm res; Eterm hdr; FloatDef f1, f2; @@ -458,8 +468,8 @@ erts_mixed_plus(Process* p, Eterm arg1, Eterm arg2) Eterm erts_mixed_minus(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm hdr; Eterm res; FloatDef f1, f2; @@ -602,8 +612,8 @@ erts_mixed_minus(Process* p, Eterm arg1, Eterm arg2) Eterm erts_mixed_times(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm hdr; Eterm res; FloatDef f1, f2; @@ -627,8 +637,8 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2) } else if (arg2 == SMALL_ONE) { return(arg1); } else { - Eterm big_res[3]; - + DeclareTmpHeap(big_res,3,p); + UseTmpHeap(3,p); /* * The following code is optimized for the case that * result is small (which should be the most common case @@ -636,6 +646,7 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2) */ res = small_times(signed_val(arg1), signed_val(arg2), big_res); if (is_small(res)) { + UnUseTmpHeap(3,p); return res; } else { /* @@ -657,6 +668,7 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2) if (arity > 1) { *hp = big_res[2]; } + UnUseTmpHeap(3,p); return res; } } @@ -915,8 +927,8 @@ erts_mixed_div(Process* p, Eterm arg1, Eterm arg2) Eterm erts_int_div(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); int ires; switch (NUMBER_CODE(arg1, arg2)) { @@ -967,8 +979,8 @@ erts_int_div(Process* p, Eterm arg1, Eterm arg2) Eterm erts_int_rem(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); int ires; switch (NUMBER_CODE(arg1, arg2)) { @@ -979,7 +991,8 @@ erts_int_rem(Process* p, Eterm arg1, Eterm arg2) if (arg1 != make_small(MIN_SMALL)) { return arg1; } else { - Eterm tmp = small_to_big(signed_val(arg1), tmp_big1); + Eterm tmp; + tmp = small_to_big(signed_val(arg1), tmp_big1); if ((ires = big_ucomp(tmp, arg2)) == 0) { return SMALL_ZERO; } else { @@ -1013,8 +1026,8 @@ erts_int_rem(Process* p, Eterm arg1, Eterm arg2) Eterm erts_band(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm* hp; int need; @@ -1041,8 +1054,8 @@ Eterm erts_band(Process* p, Eterm arg1, Eterm arg2) Eterm erts_bor(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm* hp; int need; @@ -1069,8 +1082,8 @@ Eterm erts_bor(Process* p, Eterm arg1, Eterm arg2) Eterm erts_bxor(Process* p, Eterm arg1, Eterm arg2) { - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm* hp; int need; @@ -1148,8 +1161,8 @@ erts_gc_mixed_plus(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm res; Eterm hdr; FloatDef f1, f2; @@ -1237,10 +1250,10 @@ erts_gc_mixed_plus(Process* p, Eterm* reg, Uint live) need_heap = BIG_NEED_SIZE(sz); if (ERTS_NEED_GC(p, need_heap)) { erts_garbage_collect(p, need_heap, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } @@ -1316,8 +1329,8 @@ erts_gc_mixed_minus(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm hdr; Eterm res; FloatDef f1, f2; @@ -1394,10 +1407,10 @@ erts_gc_mixed_minus(Process* p, Eterm* reg, Uint live) need_heap = BIG_NEED_SIZE(sz); if (ERTS_NEED_GC(p, need_heap)) { erts_garbage_collect(p, need_heap, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } @@ -1482,8 +1495,8 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); Eterm hdr; Eterm res; FloatDef f1, f2; @@ -1509,7 +1522,8 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) } else if (arg2 == SMALL_ONE) { return(arg1); } else { - Eterm big_res[3]; + DeclareTmpHeap(big_res,3,p); + UseTmpHeap(3,p); /* * The following code is optimized for the case that @@ -1519,6 +1533,7 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) res = small_times(signed_val(arg1), signed_val(arg2), big_res); if (is_small(res)) { + UnUseTmpHeap(3,p); return res; } else { /* @@ -1546,6 +1561,7 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) if (arity > 1) { *hp = big_res[2]; } + UnUseTmpHeap(3,p); return res; } } @@ -1609,17 +1625,17 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live) need_heap = BIG_NEED_SIZE(sz); if (ERTS_NEED_GC(p, need_heap)) { erts_garbage_collect(p, need_heap, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } hp = p->htop; p->htop += need_heap; res = big_times(arg1, arg2, hp); - trim_heap(p, hp, res); + trim_heap(p, hp, res); /* * Note that the result must be big in this case, since @@ -1828,8 +1844,8 @@ erts_gc_int_div(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); int ires; arg1 = reg[live]; @@ -1866,10 +1882,10 @@ erts_gc_int_div(Process* p, Eterm* reg, Uint live) need = BIG_NEED_SIZE(i-ires+1) + BIG_NEED_SIZE(i); if (ERTS_NEED_GC(p, need)) { erts_garbage_collect(p, need, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } @@ -1894,8 +1910,8 @@ erts_gc_int_rem(Process* p, Eterm* reg, Uint live) { Eterm arg1; Eterm arg2; - Eterm tmp_big1[2]; - Eterm tmp_big2[2]; + DECLARE_TMP(tmp_big1,0,p); + DECLARE_TMP(tmp_big2,1,p); int ires; arg1 = reg[live]; @@ -1908,7 +1924,8 @@ erts_gc_int_rem(Process* p, Eterm* reg, Uint live) if (arg1 != make_small(MIN_SMALL)) { return arg1; } else { - Eterm tmp = small_to_big(signed_val(arg1), tmp_big1); + Eterm tmp; + tmp = small_to_big(signed_val(arg1), tmp_big1); if ((ires = big_ucomp(tmp, arg2)) == 0) { return SMALL_ZERO; } else { @@ -1928,10 +1945,10 @@ erts_gc_int_rem(Process* p, Eterm* reg, Uint live) if (ERTS_NEED_GC(p, need)) { erts_garbage_collect(p, need, reg, live+2); - if (arg1 != make_big(tmp_big1)) { + if (ARG_IS_NOT_TMP(arg1,tmp_big1)) { arg1 = reg[live]; } - if (arg2 != make_big(tmp_big2)) { + if (ARG_IS_NOT_TMP(arg2,tmp_big2)) { arg2 = reg[live+1]; } } @@ -1956,8 +1973,8 @@ Eterm erts_gc_##func(Process* p, Eterm* reg, Uint live) \ { \ Eterm arg1; \ Eterm arg2; \ - Eterm tmp_big1[2]; \ - Eterm tmp_big2[2]; \ + DECLARE_TMP(tmp_big1,0,p); \ + DECLARE_TMP(tmp_big2,1,p); \ Eterm* hp; \ int need; \ \ |