aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/atom.names1
-rw-r--r--erts/emulator/beam/bif.c14
-rw-r--r--erts/emulator/beam/big.c12
-rw-r--r--erts/emulator/beam/erl_gc.c26
-rw-r--r--erts/emulator/beam/erl_proc_sig_queue.c1
-rw-r--r--erts/emulator/beam/erl_proc_sig_queue.h3
-rw-r--r--erts/emulator/test/big_SUITE.erl18
7 files changed, 36 insertions, 39 deletions
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index a14f22b19e..291bc95604 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -546,6 +546,7 @@ atom reload
atom rem
atom report_errors
atom reset
+atom reset_seq_trace
atom restart
atom return_from
atom return_to
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 015c051cc1..04498332b0 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -4490,11 +4490,12 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
ERTS_TRACER_CLEAR(&old_seq_tracer);
BIF_RET(ret);
- } else if (BIF_ARG_1 == make_small(1)) {
+ } else if (BIF_ARG_1 == am_reset_seq_trace) {
int i, max;
- erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erts_thr_progress_block();
+ erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_thr_progress_block();
+
max = erts_ptab_max(&erts_proc);
for (i = 0; i < max; i++) {
Process *p = erts_pix2proc(i);
@@ -4506,13 +4507,14 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
#endif
p->seq_trace_clock = 0;
p->seq_trace_lastcnt = 0;
-
+ erts_proc_lock(p, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_MSGQ);
erts_proc_sig_clear_seq_trace_tokens(p);
+ erts_proc_unlock(p, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_MSGQ);
}
}
- erts_thr_progress_unblock();
- erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_thr_progress_unblock();
+ erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
BIF_RET(am_true);
} else if (BIF_ARG_1 == am_scheduler_wall_time) {
diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c
index b373d3a577..7e0be2a2a7 100644
--- a/erts/emulator/beam/big.c
+++ b/erts/emulator/beam/big.c
@@ -668,27 +668,25 @@ static dsize_t I_mul(ErtsDigit* x, dsize_t xl, ErtsDigit* y, dsize_t yl, ErtsDig
static dsize_t I_sqr(ErtsDigit* x, dsize_t xl, ErtsDigit* r)
{
- ErtsDigit d_next = *x;
ErtsDigit d;
ErtsDigit* r0 = r;
ErtsDigit* s = r;
if ((r + xl) == x) /* "Inline" operation */
*x = 0;
- x++;
while(xl--) {
- ErtsDigit* y = x;
+ ErtsDigit* y;
ErtsDigit y_0 = 0, y_1 = 0, y_2 = 0, y_3 = 0;
ErtsDigit b0, b1;
ErtsDigit z0, z1, z2;
ErtsDigit t;
dsize_t y_l = xl;
-
+
+ d = *x;
+ x++;
+ y = x;
s = r;
- d = d_next;
- d_next = *x;
- x++;
DMUL(d, d, b1, b0);
DSUMc(*s, b0, y_3, t);
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index d5dfb096b1..3a50b294d1 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -2438,27 +2438,9 @@ erts_copy_one_frag(Eterm** hpp, ErlOffHeap* off_heap,
cpy_words:
ASSERT(sz >= cpy_sz);
sz -= cpy_sz;
- while (cpy_sz >= 8) {
- cpy_sz -= 8;
- *hp++ = *fhp++;
- *hp++ = *fhp++;
- *hp++ = *fhp++;
- *hp++ = *fhp++;
- *hp++ = *fhp++;
- *hp++ = *fhp++;
- *hp++ = *fhp++;
- *hp++ = *fhp++;
- }
- switch (cpy_sz) {
- case 7: *hp++ = *fhp++;
- case 6: *hp++ = *fhp++;
- case 5: *hp++ = *fhp++;
- case 4: *hp++ = *fhp++;
- case 3: *hp++ = *fhp++;
- case 2: *hp++ = *fhp++;
- case 1: *hp++ = *fhp++;
- default: break;
- }
+ sys_memcpy(hp, fhp, cpy_sz * sizeof(Eterm));
+ hp += cpy_sz;
+ fhp += cpy_sz;
if (oh) {
/* Add to offheap list */
oh->next = off_heap->first;
@@ -2477,7 +2459,7 @@ erts_copy_one_frag(Eterm** hpp, ErlOffHeap* off_heap,
*hpp = hp;
for (i = 0; i < nrefs; i++) {
- if (is_not_immed(refs[i]) && !erts_is_literal(refs[i],boxed_val(refs[i])))
+ if (is_not_immed(refs[i]) && !erts_is_literal(refs[i],ptr_val(refs[i])))
refs[i] = offset_ptr(refs[i], offs);
}
bp->off_heap.first = NULL;
diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c
index f343e984f7..18418a76e1 100644
--- a/erts/emulator/beam/erl_proc_sig_queue.c
+++ b/erts/emulator/beam/erl_proc_sig_queue.c
@@ -3812,7 +3812,6 @@ clear_seq_trace_token(ErtsMessage *sig)
void
erts_proc_sig_clear_seq_trace_tokens(Process *c_p)
{
- ASSERT(erts_thr_progress_is_blocking());
erts_proc_sig_fetch(c_p);
ERTS_FOREACH_SIG_PRIVQS(c_p, sig, clear_seq_trace_token(sig));
}
diff --git a/erts/emulator/beam/erl_proc_sig_queue.h b/erts/emulator/beam/erl_proc_sig_queue.h
index 3fc2d06b2d..6b065a7add 100644
--- a/erts/emulator/beam/erl_proc_sig_queue.h
+++ b/erts/emulator/beam/erl_proc_sig_queue.h
@@ -989,8 +989,7 @@ erts_proc_sig_fetch(Process *proc)
Sint res = 0;
ErtsSignal *sig;
- ERTS_LC_ASSERT(erts_thr_progress_is_blocking()
- || ERTS_PROC_IS_EXITING(proc)
+ ERTS_LC_ASSERT(ERTS_PROC_IS_EXITING(proc)
|| ((erts_proc_lc_my_proc_locks(proc)
& (ERTS_PROC_LOCK_MAIN
| ERTS_PROC_LOCK_MSGQ))
diff --git a/erts/emulator/test/big_SUITE.erl b/erts/emulator/test/big_SUITE.erl
index 29508ffc7c..3b9b9e5989 100644
--- a/erts/emulator/test/big_SUITE.erl
+++ b/erts/emulator/test/big_SUITE.erl
@@ -168,7 +168,11 @@ eval({op,_,Op,A0,B0}, LFH) ->
Res = eval_op(Op, A, B),
erlang:garbage_collect(),
Res;
-eval({integer,_,I}, _) -> I;
+eval({integer,_,I}, _) ->
+ %% "Parasitic" ("symbiotic"?) test of squaring all numbers
+ %% found in the test data.
+ test_squaring(I),
+ I;
eval({call,_,{atom,_,Local},Args0}, LFH) ->
Args = eval_list(Args0, LFH),
LFH(Local, Args).
@@ -192,6 +196,18 @@ eval_op('bxor', A, B) -> A bxor B;
eval_op('bsl', A, B) -> A bsl B;
eval_op('bsr', A, B) -> A bsr B.
+test_squaring(I) ->
+ %% Multiplying an integer by itself is specially optimized, so we
+ %% should take special care to test squaring. The optimization
+ %% will kick in when the two operands have the same address.
+ Sqr = I * I,
+
+ %% This expression will be multiplied in the usual way, because
+ %% the the two operands for '*' are stored at different addresses.
+ Sqr = I * ((I + id(1)) - id(1)),
+
+ ok.
+
%% Built in test functions
fac(0) -> 1;