~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to erts/emulator/beam/erl_mtrace.c

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#  include "config.h"
35
35
#endif
36
36
 
37
 
#define ERTS_MTRACE_INTERNAL__
38
37
#include "sys.h"
39
38
#include "global.h"
40
39
#include "erl_sock.h"
 
40
#include "erl_threads.h"
 
41
#include "erl_memory_trace_protocol.h"
 
42
#include "erl_mtrace.h"
 
43
 
 
44
#if defined(MAXHOSTNAMELEN) && MAXHOSTNAMELEN > 255
 
45
#  undef MAXHOSTNAMELEN
 
46
#endif
 
47
 
 
48
#ifndef MAXHOSTNAMELEN
 
49
#  define MAXHOSTNAMELEN 255
 
50
#endif
41
51
 
42
52
#define TRACE_PRINTOUTS 0
43
53
#ifdef TRACE_PRINTOUTS
44
54
#define MSB2BITS(X) ((((unsigned)(X))+1)*8)
45
55
#endif
46
56
 
47
 
#ifdef USE_THREADS
48
 
#define ERL_THREADS_EMU_INTERNAL__
49
 
#include "erl_threads.h"
50
 
#define LOCK    erts_mutex_lock(mutex)
51
 
#define UNLOCK  erts_mutex_unlock(mutex)
52
 
static erts_mutex_t mutex;
53
 
#else
54
 
#define LOCK
55
 
#define UNLOCK
56
 
#endif
 
57
static erts_mtx_t mtrace_op_mutex;
 
58
static erts_mtx_t mtrace_buf_mutex;
57
59
 
58
60
#define TRACE_BUF_SZ                            (16*1024)
59
61
 
182
184
#ifdef DEBUG
183
185
void
184
186
check_alloc_entry(byte *sp, byte *ep,
 
187
                  byte tag,
 
188
                  Uint16 ct_no, int ct_no_n,
185
189
                  Uint16 type, int type_n,
186
190
                  Uint res, int res_n,
187
191
                  Uint size, int size_n,
188
192
                  Uint32 ti,int ti_n);
189
193
void
190
 
check_realloc_entry(byte *sp, byte *ep, int no_previous_block, int moved,
 
194
check_realloc_entry(byte *sp, byte *ep,
 
195
                    byte tag,
 
196
                    Uint16 ct_no, int ct_no_n,
191
197
                    Uint16 type, int type_n,
192
198
                    Uint res, int res_n,
193
199
                    Uint ptr, int ptr_n,
195
201
                    Uint32 ti,int ti_n);
196
202
void
197
203
check_free_entry(byte *sp, byte *ep,
 
204
                 byte tag,
 
205
                 Uint16 ct_no, int ct_no_n,
 
206
                 Uint16 t_no, int t_no_n,
198
207
                 Uint ptr, int ptr_n,
199
208
                 Uint32 ti,int ti_n);
200
209
void
212
221
static byte *endp;
213
222
static SysTimeval last_tv;
214
223
 
 
224
#if ERTS_MTRACE_SEGMENT_ID >= ERTS_ALC_A_MIN || ERTS_MTRACE_SEGMENT_ID < 0
 
225
#error ERTS_MTRACE_SEGMENT_ID >= ERTS_ALC_A_MIN || ERTS_MTRACE_SEGMENT_ID < 0
 
226
#endif
 
227
 
215
228
char* erl_errno_id(int error);
216
229
 
217
230
#define INVALID_TIME_INC (0xffffffff)
247
260
    else {
248
261
        /* Increment too large to fit in a 32-bit integer;
249
262
           put a time inc entry in trace ... */
250
 
        if (MAKE_TBUF_SZ(UI16_SZ + 2*UI32_SZ)) {
 
263
        if (MAKE_TBUF_SZ(UI8_SZ + UI16_SZ + 2*UI32_SZ)) {
251
264
            byte *hdrp;
252
265
            Uint16 hdr;
253
266
            int secs_n, usecs_n;
254
267
 
 
268
            *(tracep++) = ERTS_MT_TIME_INC_BDY_TAG;
 
269
 
255
270
            hdrp = tracep;
256
271
            tracep += 2;
257
272
 
263
278
            hdr <<= UI32_MSB_EHF_SZ;
264
279
            hdr |= secs_n;
265
280
 
266
 
            hdr <<= TAG_EHF_SZ;
267
 
            hdr |= ERTS_MT_TIME_INC_TAG;
268
 
 
269
281
            WRITE_UI16(hdrp, hdr);
270
282
#ifdef DEBUG
271
 
            check_time_inc_entry(hdrp, tracep,
 
283
            check_time_inc_entry(hdrp-1, tracep,
272
284
                                 (Uint32) secs, secs_n,
273
285
                                 (Uint32) usecs, usecs_n);
274
286
#endif
287
299
static void
288
300
disable_trace(int error, char *reason, int eno)
289
301
{
290
 
#define ENO_BUF_SZ 100
291
 
    char buf[ENO_BUF_SZ];
 
302
    char *mt_dis = "Memory trace disabled";
292
303
    char *eno_str;
293
304
 
294
 
    if (eno) {
 
305
    erts_mtrace_enabled = 0;
 
306
    erts_sock_close(socket_desc);
 
307
    socket_desc = ERTS_SOCK_INVALID_SOCKET;
 
308
 
 
309
    if (eno == 0)
 
310
        erts_fprintf(stderr, "%s: %s\n", mt_dis, reason);
 
311
    else {
295
312
        eno_str = erl_errno_id(eno);
296
 
 
297
313
        if (strcmp(eno_str, "unknown") == 0)
298
 
            sprintf(buf, ": %d", eno);
299
 
        else {
300
 
            int i;
301
 
            buf[0] = ':'; buf[1] = ' ';
302
 
            for (i = 2; i < ENO_BUF_SZ && eno_str[i-2]; i++)
303
 
                buf[i] = eno_str[i-2];
304
 
        }
305
 
        eno_str = buf;
306
 
    }
307
 
    else
308
 
        eno_str = "";
309
 
 
310
 
    erts_mtrace_enabled = 0;
311
 
    erts_sock_close(socket_desc);
312
 
    socket_desc = ERTS_SOCK_INVALID_SOCKET;
313
 
    cerr_pos = 0;
314
 
    erl_printf(erts_initialized ? CBUF : CERR,
315
 
               "Memory trace disabled: %s%s\n", reason, eno_str);
316
 
    if (erts_initialized) {
317
 
        if (error)
318
 
            send_error_to_logger(NIL);
 
314
            erts_fprintf(stderr, "%s: %s: %d\n", mt_dis, reason, eno);
319
315
        else
320
 
            send_error_to_logger(NIL);
 
316
            erts_fprintf(stderr, "%s: %s: %s\n", mt_dis, reason, eno_str);
321
317
    }
322
 
 
323
 
#undef ENO_BUF_SZ
324
318
}
325
319
 
326
320
static int
362
356
 
363
357
 
364
358
static int
365
 
write_trace_header(void)
 
359
write_trace_header(char *nodename, char *pid, char *hostname)
366
360
{
367
 
    Uint32 flags;
368
 
    Uint32 hdr_sz;
369
 
    byte *hdr_szp;
 
361
#ifdef DEBUG
 
362
    byte *startp;
 
363
#endif
 
364
    Uint16 entry_sz;
 
365
    Uint32 flags, n_len, h_len, p_len, hdr_prolog_len;
370
366
    int i, no, str_len;
371
367
    const char *str;
372
 
 
373
 
    if (!MAKE_TBUF_SZ(5*UI32_SZ + 2*UI16_SZ))
 
368
    struct {
 
369
        Uint32 gsec;
 
370
        Uint32 sec;
 
371
        Uint32 usec;
 
372
    } start_time;
 
373
 
 
374
    sys_gettimeofday(&last_tv);
 
375
 
 
376
    start_time.gsec = (Uint32) (last_tv.tv_sec / 1000000000);
 
377
    start_time.sec  = (Uint32) (last_tv.tv_sec % 1000000000);
 
378
    start_time.usec = (Uint32) last_tv.tv_usec;
 
379
 
 
380
    if (!MAKE_TBUF_SZ(3*UI32_SZ))
374
381
        return 0;
375
382
 
376
383
    flags = 0;
377
384
#ifdef ARCH_64
378
385
    flags |= ERTS_MT_64_BIT_FLAG;
379
386
#endif
 
387
    flags |= ERTS_MT_CRR_INFO;
 
388
#ifdef ERTS_CAN_TRACK_MALLOC
 
389
    flags |= ERTS_MT_SEG_CRR_INFO;
 
390
#endif
380
391
 
 
392
    /*
 
393
     * The following 3 ui32 words *always* have to come
 
394
     * first in the trace.
 
395
     */
381
396
    PUT_UI32(tracep, ERTS_MT_START_WORD);
382
397
    PUT_UI32(tracep, ERTS_MT_MAJOR_VSN);
383
398
    PUT_UI32(tracep, ERTS_MT_MINOR_VSN);
 
399
 
 
400
    n_len = strlen(nodename);
 
401
    h_len = strlen(hostname);
 
402
    p_len = strlen(pid);
 
403
    hdr_prolog_len = (2*UI32_SZ
 
404
                      + 3*UI16_SZ
 
405
                      + 3*UI32_SZ
 
406
                      + 3*UI8_SZ
 
407
                      + n_len
 
408
                      + h_len
 
409
                      + p_len);
 
410
 
 
411
    if (!MAKE_TBUF_SZ(hdr_prolog_len))
 
412
        return 0;
 
413
 
 
414
    /*
 
415
     * New stuff can be added at the end the of header prolog
 
416
     * (EOHP). The reader should skip stuff at the end, that it
 
417
     * doesn't understand.
 
418
     */
 
419
 
 
420
#ifdef DEBUG
 
421
    startp = tracep;
 
422
#endif
 
423
 
 
424
    PUT_UI32(tracep, hdr_prolog_len);
384
425
    PUT_UI32(tracep, flags);
385
 
    hdr_szp = tracep;
386
 
    tracep += UI32_SZ;
387
 
 
 
426
    PUT_UI16(tracep, ERTS_MTRACE_SEGMENT_ID);
388
427
    PUT_UI16(tracep, ERTS_ALC_A_MAX);
389
428
    PUT_UI16(tracep, ERTS_ALC_N_MAX);
390
429
 
391
 
    hdr_sz = 5*UI32_SZ + 2*UI16_SZ;
 
430
    PUT_UI32(tracep, start_time.gsec);
 
431
    PUT_UI32(tracep, start_time.sec);
 
432
    PUT_UI32(tracep, start_time.usec);
 
433
 
 
434
    PUT_UI8(tracep, (byte) n_len);
 
435
    memcpy((void *) tracep, (void *) nodename, n_len);
 
436
    tracep += n_len;
 
437
 
 
438
    PUT_UI8(tracep, (byte) h_len);
 
439
    memcpy((void *) tracep, (void *) hostname, h_len);
 
440
    tracep += h_len;
 
441
 
 
442
    PUT_UI8(tracep, (byte) p_len);
 
443
    memcpy((void *) tracep, (void *) pid, p_len);
 
444
    tracep += p_len;
 
445
 
 
446
    ASSERT(startp + hdr_prolog_len == tracep);
 
447
 
 
448
    /*
 
449
     * EOHP
 
450
     */
 
451
 
 
452
    /*
 
453
     * All tags from here on should be followed by an Uint16 size
 
454
     * field containing the total size of the entry.
 
455
     *
 
456
     * New stuff can eigther be added at the end of an entry, or
 
457
     * as a new tagged entry. The reader should skip stuff at the
 
458
     * end, that it doesn't understand.
 
459
     */
392
460
 
393
461
    for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
 
462
        Uint16 aflags = 0;
 
463
 
 
464
#ifndef ERTS_CAN_TRACK_MALLOC
 
465
        if (i != ERTS_ALC_A_SYSTEM)
 
466
#endif
 
467
            aflags |= ERTS_MT_ALLCTR_USD_CRR_INFO;
 
468
 
394
469
        str = ERTS_ALC_A2AD(i);
395
470
        ASSERT(str);
396
471
        str_len = strlen(str);
398
473
            disable_trace(1, "Excessively large allocator string", 0);
399
474
            return 0;
400
475
        }
401
 
            
402
 
        if (!MAKE_TBUF_SZ(UI8_SZ + 2*UI16_SZ + str_len))
 
476
 
 
477
        entry_sz = UI8_SZ + 3*UI16_SZ + UI8_SZ;
 
478
        entry_sz += (erts_allctrs_info[i].alloc_util ? 2 : 1)*UI16_SZ;
 
479
        entry_sz += UI8_SZ + str_len;
 
480
 
 
481
        if (!MAKE_TBUF_SZ(entry_sz))
403
482
            return 0;
404
 
        hdr_sz += UI8_SZ + 2*UI16_SZ + str_len;
405
483
 
406
 
        PUT_UI16(tracep, ERTS_MT_ALLOCATOR_TAG);
 
484
#ifdef DEBUG
 
485
        startp = tracep;
 
486
#endif
 
487
        PUT_UI8(tracep, ERTS_MT_ALLOCATOR_HDR_TAG);
 
488
        PUT_UI16(tracep, entry_sz);
 
489
        PUT_UI16(tracep, aflags);
407
490
        PUT_UI16(tracep, (Uint16) i);
408
491
        PUT_UI8( tracep, (byte) str_len);
409
492
        memcpy((void *) tracep, (void *) str, str_len);
410
493
        tracep += str_len;
 
494
        if (erts_allctrs_info[i].alloc_util) {
 
495
            PUT_UI8(tracep, 2);
 
496
            PUT_UI16(tracep, ERTS_MTRACE_SEGMENT_ID);
 
497
            PUT_UI16(tracep, ERTS_ALC_A_SYSTEM);
 
498
        }
 
499
        else {
 
500
            PUT_UI8(tracep, 1);
 
501
            switch (i) {
 
502
            case ERTS_ALC_A_SYSTEM:
 
503
                PUT_UI16(tracep, ERTS_MTRACE_SEGMENT_ID);
 
504
                break;
 
505
            case ERTS_ALC_A_FIXED_SIZE:
 
506
                if (erts_allctrs_info[ERTS_FIX_CORE_ALLOCATOR].enabled)
 
507
                    PUT_UI16(tracep, ERTS_FIX_CORE_ALLOCATOR);
 
508
                else
 
509
                    PUT_UI16(tracep, ERTS_ALC_A_SYSTEM);
 
510
                break;
 
511
            default:
 
512
                PUT_UI16(tracep, ERTS_MTRACE_SEGMENT_ID);
 
513
                break;
 
514
            }
 
515
        }
 
516
        ASSERT(startp + entry_sz == tracep);
411
517
    }
412
518
 
413
519
    for (i = ERTS_ALC_N_MIN; i <= ERTS_ALC_N_MAX; i++) {
 
520
        Uint16 nflags = 0;
414
521
        str = ERTS_ALC_N2TD(i);
415
522
        ASSERT(str);
416
523
 
425
532
            no = ERTS_ALC_A_SYSTEM;
426
533
        ASSERT(ERTS_ALC_A_MIN <= no && no <= ERTS_ALC_A_MAX);
427
534
 
428
 
        if (!MAKE_TBUF_SZ(UI8_SZ + 3*UI16_SZ + str_len))
 
535
        entry_sz = UI8_SZ + 3*UI16_SZ + UI8_SZ + str_len + UI16_SZ;
 
536
 
 
537
        if (!MAKE_TBUF_SZ(entry_sz))
429
538
            return 0;
430
539
 
431
 
        hdr_sz += UI8_SZ + 3*UI16_SZ + str_len;
432
 
 
433
 
        PUT_UI16(tracep, ERTS_MT_BLOCK_TYPE_TAG);
 
540
#ifdef DEBUG
 
541
        startp = tracep;
 
542
#endif
 
543
        PUT_UI8(tracep, ERTS_MT_BLOCK_TYPE_HDR_TAG);
 
544
        PUT_UI16(tracep, entry_sz);
 
545
        PUT_UI16(tracep, nflags);
434
546
        PUT_UI16(tracep, (Uint16) i);
435
 
        PUT_UI8( tracep, (byte) str_len);
 
547
        PUT_UI8(tracep, (byte) str_len);
436
548
        memcpy((void *) tracep, (void *) str, str_len);
437
549
        tracep += str_len;
438
550
        PUT_UI16(tracep, no);
 
551
        ASSERT(startp + entry_sz == tracep);
439
552
    }
440
553
 
441
 
    WRITE_UI32(hdr_szp,   hdr_sz);
 
554
    entry_sz = UI8_SZ + UI16_SZ;
 
555
    if (!MAKE_TBUF_SZ(entry_sz))
 
556
        return 0;
 
557
    PUT_UI8(tracep, ERTS_MT_END_OF_HDR_TAG);
 
558
    PUT_UI16(tracep, entry_sz);
442
559
 
443
560
    return 1;
444
561
}
449
566
 
450
567
static ErtsAllocatorFunctions_t real_allctrs[ERTS_ALC_A_MAX+1];
451
568
 
452
 
void erts_mtrace_init(char *receiver)
453
 
{
 
569
void erts_mtrace_pre_init(void)
 
570
{
 
571
}
 
572
 
 
573
void erts_mtrace_init(char *receiver, char *nodename)
 
574
{
 
575
    char hostname[MAXHOSTNAMELEN];
 
576
    char pid[21]; /* enough for a 64 bit number */
 
577
 
454
578
    socket_desc = ERTS_SOCK_INVALID_SOCKET;
455
579
    erts_mtrace_enabled = receiver != NULL;
456
580
 
457
581
    if (erts_mtrace_enabled) {
458
 
        int i;
459
582
        unsigned a, b, c, d, p;
460
583
        byte ip_addr[4];
461
584
        Uint16 port;
462
 
        
463
 
        /* Install trace functions */
464
 
        ASSERT(sizeof(erts_allctrs) == sizeof(real_allctrs));
465
 
 
466
 
        sys_memcpy((void *) real_allctrs,
467
 
                   (void *) erts_allctrs,
468
 
                   sizeof(erts_allctrs));
469
 
 
470
 
        for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
471
 
            erts_allctrs[i].alloc       = mtrace_alloc;
472
 
            erts_allctrs[i].realloc     = mtrace_realloc;
473
 
            erts_allctrs[i].free        = mtrace_free;
474
 
            erts_allctrs[i].extra       = (void *) &real_allctrs[i];
475
 
        }
476
 
 
477
 
 
478
 
#ifdef USE_THREADS
479
 
        mutex = erts_mutex_sys(ERTS_MUTEX_SYS_MTRACE);
480
 
        if(!mutex || erts_mutex_set_default_atfork(mutex))
481
 
            erl_exit(1, "Failed to initialize mtrace mutex\n");
482
 
#endif
 
585
 
 
586
        erts_mtx_init(&mtrace_buf_mutex, "mtrace_buf");
 
587
        erts_mtx_set_forksafe(&mtrace_buf_mutex);
 
588
        erts_mtx_init(&mtrace_op_mutex, "mtrace_op");
 
589
        erts_mtx_set_forksafe(&mtrace_op_mutex);
483
590
 
484
591
        socket_desc = erts_sock_open();
485
592
        if (socket_desc == ERTS_SOCK_INVALID_SOCKET) {
506
613
                          erts_sock_errno());
507
614
            return;
508
615
        }
509
 
        sys_gettimeofday(&last_tv);
510
616
        tracep = trace_buffer;
511
617
        endp = trace_buffer + TRACE_BUF_SZ;
512
 
        write_trace_header();
 
618
        if (erts_sock_gethostname(hostname, MAXHOSTNAMELEN) != 0)
 
619
            hostname[0] = '\0';
 
620
        hostname[MAXHOSTNAMELEN-1] = '\0';
 
621
        sys_get_pid(pid);
 
622
        write_trace_header(nodename ? nodename : "", pid, hostname);
 
623
        erts_mtrace_update_heap_size();
 
624
    }
 
625
}
 
626
 
 
627
void
 
628
erts_mtrace_install_wrapper_functions(void)
 
629
{
 
630
    if (erts_mtrace_enabled) {
 
631
        int i;
 
632
        /* Install trace functions */
 
633
        ASSERT(sizeof(erts_allctrs) == sizeof(real_allctrs));
 
634
 
 
635
        sys_memcpy((void *) real_allctrs,
 
636
                   (void *) erts_allctrs,
 
637
                   sizeof(erts_allctrs));
 
638
 
 
639
        for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
 
640
            erts_allctrs[i].alloc       = mtrace_alloc;
 
641
            erts_allctrs[i].realloc     = mtrace_realloc;
 
642
            erts_allctrs[i].free        = mtrace_free;
 
643
            erts_allctrs[i].extra       = (void *) &real_allctrs[i];
 
644
        }
513
645
    }
514
646
}
515
647
 
516
648
void
517
649
erts_mtrace_stop(void)
518
650
{
519
 
    LOCK;
 
651
    erts_mtx_lock(&mtrace_op_mutex);
 
652
    erts_mtx_lock(&mtrace_buf_mutex);
520
653
    if (erts_mtrace_enabled) {
521
654
        Uint32 ti = get_time_inc();
522
655
    
523
 
        if (ti != INVALID_TIME_INC && MAKE_TBUF_SZ(UI16_SZ + UI32_SZ)) {
 
656
        if (ti != INVALID_TIME_INC
 
657
            && MAKE_TBUF_SZ(UI8_SZ + UI16_SZ + UI32_SZ)) {
524
658
            byte *hdrp;
525
659
            Uint16 hdr;
526
660
            int ti_n;
527
661
 
 
662
            *(tracep++) = ERTS_MT_STOP_BDY_TAG;
 
663
 
528
664
            hdrp = tracep;
529
665
            tracep += 2;
530
666
 
532
668
 
533
669
            hdr = ti_n;
534
670
 
535
 
            hdr <<= TAG_EHF_SZ;
536
 
            hdr |= ERTS_MT_STOP_TAG;
537
 
 
538
671
            WRITE_UI16(hdrp, hdr);
539
672
 
540
673
            if(send_trace_buffer()) {
544
677
            }
545
678
        }
546
679
    }
547
 
    UNLOCK;
 
680
    erts_mtx_unlock(&mtrace_buf_mutex);
 
681
    erts_mtx_unlock(&mtrace_op_mutex);
548
682
}
549
683
 
550
684
void
551
685
erts_mtrace_exit(Uint32 exit_value)
552
686
{
553
 
    LOCK;
 
687
    erts_mtx_lock(&mtrace_op_mutex);
 
688
    erts_mtx_lock(&mtrace_buf_mutex);
554
689
    if (erts_mtrace_enabled) {
555
690
        Uint32 ti = get_time_inc();
556
691
    
557
 
        if (ti != INVALID_TIME_INC && MAKE_TBUF_SZ(UI16_SZ + 2*UI32_SZ)) {
 
692
        if (ti != INVALID_TIME_INC
 
693
            && MAKE_TBUF_SZ(UI8_SZ + UI16_SZ + 2*UI32_SZ)) {
558
694
            byte *hdrp;
559
695
            Uint16 hdr;
560
696
            int ti_n, exit_value_n;
561
697
 
 
698
            *(tracep++) = ERTS_MT_EXIT_BDY_TAG;
 
699
 
562
700
            hdrp = tracep;
563
701
            tracep += 2;
564
702
 
570
708
            hdr <<= UI32_MSB_EHF_SZ;
571
709
            hdr |= exit_value_n;
572
710
 
573
 
            hdr <<= TAG_EHF_SZ;
574
 
            hdr |= ERTS_MT_EXIT_TAG;
575
 
 
576
711
            WRITE_UI16(hdrp, hdr);
577
712
 
578
713
            if(send_trace_buffer()) {
582
717
            }
583
718
        }
584
719
    }
585
 
    UNLOCK;
 
720
    erts_mtx_unlock(&mtrace_buf_mutex);
 
721
    erts_mtx_unlock(&mtrace_op_mutex);
586
722
}
587
723
 
588
 
static void *
589
 
mtrace_alloc(ErtsAlcType_t n, void *extra, Uint size)
 
724
static ERTS_INLINE void
 
725
write_alloc_entry(byte tag,
 
726
                  void *res,
 
727
                  ErtsAlcType_t x,
 
728
                  ErtsAlcType_t y,
 
729
                  Uint size)
590
730
{
591
 
    ErtsAllocatorFunctions_t *real_af = (ErtsAllocatorFunctions_t *) extra;
592
 
    void *res;
593
 
    Uint32 ti;
594
 
 
595
 
    LOCK;
596
 
 
597
 
    res = (*real_af->alloc)(n, real_af->extra, size);
598
 
 
 
731
    erts_mtx_lock(&mtrace_buf_mutex);
599
732
    if (erts_mtrace_enabled) {
600
 
        Uint16 t_no = (Uint16) n;
601
 
        ti = get_time_inc();
 
733
        Uint32 ti = get_time_inc();
602
734
 
603
735
        if (ti != INVALID_TIME_INC
604
 
            && MAKE_TBUF_SZ(UI8_SZ + UI16_SZ + 2*UI_SZ + UI32_SZ)) {
 
736
            && MAKE_TBUF_SZ(UI8_SZ + 2*UI16_SZ + 2*UI_SZ + UI32_SZ)) {
 
737
            Uint16 hdr, t_no = (Uint16) x, ct_no = (Uint16) y;
605
738
            byte *hdrp;
606
 
            Uint16 hdr;
607
 
            int t_no_n, res_n, size_n, ti_n;
 
739
            int t_no_n, ct_no_n = 0, res_n, size_n, ti_n;
 
740
 
 
741
            *(tracep++) = tag;
608
742
 
609
743
            hdrp = tracep;
610
744
            tracep += 2;
611
745
 
 
746
            if (tag == ERTS_MT_CRR_ALLOC_BDY_TAG) {
 
747
                PUT_VSZ_UI16(tracep, ct_no_n, ct_no);
 
748
            }
612
749
            PUT_VSZ_UI16(tracep, t_no_n, t_no);
613
750
            PUT_VSZ_UI(  tracep, res_n, res);
614
751
            PUT_VSZ_UI(  tracep, size_n, size);
625
762
            hdr <<= UI16_MSB_EHF_SZ;
626
763
            hdr |= t_no_n;
627
764
 
628
 
            hdr <<= TAG_EHF_SZ;
629
 
            hdr |= ERTS_MT_ALLOC_TAG;
 
765
            if (tag == ERTS_MT_CRR_ALLOC_BDY_TAG) {
 
766
                hdr <<= UI16_MSB_EHF_SZ;
 
767
                hdr |= ct_no_n;
 
768
            }
630
769
 
631
770
            WRITE_UI16(hdrp, hdr);
632
771
 
633
772
#if TRACE_PRINTOUTS
634
 
            fprintf(stderr,
635
 
                    "{alloc, {%u, %u, %u}, {%u, %u, %u, %u}}\n",
636
 
 
637
 
                    (unsigned) t_no, (unsigned) res, (unsigned) size,
638
 
 
639
 
                    MSB2BITS(t_no_n), MSB2BITS(res_n),
640
 
                    MSB2BITS(size_n), MSB2BITS(ti_n));
641
 
            fflush(stderr);
 
773
            print_trace_entry(tag,
 
774
                              ct_no, ct_no_n,
 
775
                              t_no, t_no_n,
 
776
                              (Uint) res, res_n,
 
777
                              0, 0,
 
778
                              size, size_n,
 
779
                              ti, ti_n);
642
780
#endif
643
781
 
644
782
#ifdef DEBUG
645
 
            check_alloc_entry(hdrp, tracep,
 
783
            check_alloc_entry(hdrp-1, tracep,
 
784
                              tag,
 
785
                              ct_no, ct_no_n,
646
786
                              t_no, t_no_n,
647
787
                              (Uint) res, res_n,
648
788
                              size, size_n,
652
792
        }
653
793
 
654
794
    }
655
 
 
656
 
    UNLOCK;
657
 
 
658
 
    return res;
 
795
    erts_mtx_unlock(&mtrace_buf_mutex);
 
796
 
659
797
}
660
798
 
661
 
static void *
662
 
mtrace_realloc(ErtsAlcType_t n, void *extra, void *ptr, Uint size)
 
799
static ERTS_INLINE void
 
800
write_realloc_entry(byte tag,
 
801
                    void *res,
 
802
                    ErtsAlcType_t x,
 
803
                    ErtsAlcType_t y,
 
804
                    void *ptr,
 
805
                    Uint size)
663
806
{
664
 
    ErtsAllocatorFunctions_t *real_af = (ErtsAllocatorFunctions_t *) extra;
665
 
    void *res;
666
 
    Uint32 ti;
667
 
 
668
 
    LOCK;
669
 
 
670
 
    res = (*real_af->realloc)(n, real_af->extra, ptr, size);
671
 
 
 
807
    erts_mtx_lock(&mtrace_buf_mutex);
672
808
    if (erts_mtrace_enabled) {
673
 
        Uint16 t_no;
674
 
        int no_previous_block;
675
 
        int moved;
676
 
        ti = get_time_inc();
677
 
 
678
 
        no_previous_block = (ptr == NULL);
679
 
        moved = (!no_previous_block && res != ptr);
 
809
        Uint32 ti = get_time_inc();
680
810
 
681
811
        if (ti != INVALID_TIME_INC
682
 
            && MAKE_TBUF_SZ(2*UI16_SZ + (moved ? 3 : 2)*UI_SZ + UI32_SZ)) {
 
812
            && MAKE_TBUF_SZ(UI8_SZ + 2*UI16_SZ + 3*UI_SZ + UI32_SZ)) {
 
813
            Uint16 hdr, t_no = (Uint16) x, ct_no = (Uint16) y;
683
814
            byte *hdrp;
684
 
            Uint16 hdr;
685
 
            int t_no_n, res_n, ptr_n, size_n, ti_n;
 
815
            int t_no_n, ct_no_n = 0, res_n, ptr_n, size_n, ti_n;
 
816
 
 
817
            *(tracep++) = tag;
686
818
 
687
819
            hdrp = tracep;
688
820
            tracep += 2;
689
821
 
690
 
            if (no_previous_block) {
691
 
                t_no = (Uint16) n;
692
 
                PUT_VSZ_UI16(tracep, t_no_n, t_no);
693
 
            }
694
 
            else {
695
 
                t_no = 0;
696
 
                t_no_n = 0;
697
 
            }
 
822
            if (tag == ERTS_MT_CRR_REALLOC_BDY_TAG) {
 
823
                PUT_VSZ_UI16(tracep, ct_no_n, ct_no);
 
824
            }
 
825
            PUT_VSZ_UI16(tracep, t_no_n, t_no);
698
826
            PUT_VSZ_UI(  tracep, res_n, res);
699
 
            if (moved)
700
 
                PUT_VSZ_UI(  tracep, ptr_n, ptr);
701
 
            else
702
 
                ptr_n = 0;
 
827
            PUT_VSZ_UI(  tracep, ptr_n, ptr);
703
828
            PUT_VSZ_UI(  tracep, size_n, size);
704
829
            PUT_VSZ_UI32(tracep, ti_n, ti);
705
830
 
708
833
            hdr <<= UI_MSB_EHF_SZ;
709
834
            hdr |= size_n;
710
835
 
711
 
            if (moved) {
712
 
                hdr <<= UI_MSB_EHF_SZ;
713
 
                hdr |= ptr_n;
714
 
            }
 
836
            hdr <<= UI_MSB_EHF_SZ;
 
837
            hdr |= ptr_n;
715
838
 
716
839
            hdr <<= UI_MSB_EHF_SZ;
717
840
            hdr |= res_n;
718
841
 
719
 
            if (no_previous_block) {
 
842
            hdr <<= UI16_MSB_EHF_SZ;
 
843
            hdr |= t_no_n;
 
844
 
 
845
            if (tag == ERTS_MT_CRR_REALLOC_BDY_TAG) {
720
846
                hdr <<= UI16_MSB_EHF_SZ;
721
 
                hdr |= t_no_n;
 
847
                hdr |= ct_no_n;
722
848
            }
723
849
 
724
 
            hdr <<= TAG_EHF_SZ;
725
 
            if (no_previous_block)
726
 
                hdr |= ERTS_MT_REALLOC_NPB_TAG;
727
 
            else if (moved)
728
 
                hdr |= ERTS_MT_REALLOC_MV_TAG;
729
 
            else
730
 
                hdr |= ERTS_MT_REALLOC_NMV_TAG;
731
 
 
732
850
            WRITE_UI16(hdrp, hdr);
733
851
 
734
852
#if TRACE_PRINTOUTS
735
 
            if (moved)
736
 
                fprintf(stderr,
737
 
                        "{realloc_mv, {%u, %u, %u, %u}, {%u, %u, %u, %u, %u}}\n",
738
 
 
739
 
                        (unsigned) t_no, (unsigned) res,
740
 
                        (unsigned) ptr, (unsigned) size,
741
 
 
742
 
                        MSB2BITS(t_no_n), MSB2BITS(res_n),
743
 
                        MSB2BITS(ptr_n), MSB2BITS(size_n),
744
 
                        MSB2BITS(ti_n));
745
 
            else
746
 
                fprintf(stderr,
747
 
                        "{realloc_nmv, {%u, %u, %u}, {%u, %u, %u, %u}}\n",
748
 
 
749
 
                        (unsigned) t_no, (unsigned) ptr, (unsigned) size,
750
 
 
751
 
                        MSB2BITS(t_no_n), MSB2BITS(ptr_n),
752
 
                        MSB2BITS(size_n), MSB2BITS(ti_n));
753
 
                
754
 
            fflush(stderr);
 
853
            print_trace_entry(tag,
 
854
                              ct_no, ct_no_n,
 
855
                              t_no, t_no_n,
 
856
                              (Uint) res, res_n,
 
857
                              (Uint) ptr, ptr_n,
 
858
                              size, size_n,
 
859
                              ti, ti_n);
755
860
#endif
756
861
 
757
862
#ifdef DEBUG
758
 
            check_realloc_entry(hdrp, tracep, no_previous_block, moved,
 
863
            check_realloc_entry(hdrp-1, tracep,
 
864
                                tag,
 
865
                                ct_no, ct_no_n,
759
866
                                t_no, t_no_n,
760
867
                                (Uint) res, res_n,
761
868
                                (Uint) ptr, ptr_n,
765
872
 
766
873
        }
767
874
    }
768
 
 
769
 
    UNLOCK;
770
 
 
771
 
    return res;
772
 
 
 
875
    erts_mtx_unlock(&mtrace_buf_mutex);
773
876
}
774
877
 
775
 
static void
776
 
mtrace_free(ErtsAlcType_t n, void *extra, void *ptr)
 
878
static ERTS_INLINE void
 
879
write_free_entry(byte tag,
 
880
                 ErtsAlcType_t x,
 
881
                 ErtsAlcType_t y,
 
882
                 void *ptr)
777
883
{
778
 
    ErtsAllocatorFunctions_t *real_af = (ErtsAllocatorFunctions_t *) extra;
779
 
    Uint32 ti;
780
 
 
781
 
    LOCK;
782
 
 
783
 
    (*real_af->free)(n, real_af->extra, ptr);
784
 
 
 
884
    erts_mtx_lock(&mtrace_buf_mutex);
785
885
    if (erts_mtrace_enabled) {
786
 
        ti = get_time_inc();
 
886
        Uint32 ti = get_time_inc();
787
887
 
788
888
        if (ti != INVALID_TIME_INC
789
 
            && MAKE_TBUF_SZ(2*UI16_SZ + UI_SZ + UI32_SZ)) {
 
889
            && MAKE_TBUF_SZ(UI8_SZ + 2*UI16_SZ + UI_SZ + UI32_SZ)) {
 
890
            Uint16 hdr, t_no = (Uint16) x, ct_no = (Uint16) y;
790
891
            byte *hdrp;
791
 
            Uint16 hdr;
792
 
            int ptr_n, ti_n;
 
892
            int t_no_n, ct_no_n = 0, ptr_n, ti_n;
 
893
 
 
894
            *(tracep++) = tag;
793
895
 
794
896
            hdrp = tracep;
795
897
            tracep += 2;
796
898
 
 
899
            if (tag == ERTS_MT_CRR_FREE_BDY_TAG) {
 
900
                PUT_VSZ_UI16(tracep, ct_no_n, ct_no);
 
901
            }
 
902
            PUT_VSZ_UI16(tracep, t_no_n, t_no);
797
903
            PUT_VSZ_UI(  tracep, ptr_n,  ptr);
798
904
            PUT_VSZ_UI32(tracep, ti_n,   ti);
799
905
 
802
908
            hdr <<= UI_MSB_EHF_SZ;
803
909
            hdr |= ptr_n;
804
910
 
805
 
            hdr <<= TAG_EHF_SZ;
806
 
            hdr |= ERTS_MT_FREE_TAG;
 
911
            hdr <<= UI16_MSB_EHF_SZ;
 
912
            hdr |= t_no_n;
 
913
 
 
914
            if (tag == ERTS_MT_CRR_FREE_BDY_TAG) {
 
915
                hdr <<= UI16_MSB_EHF_SZ;
 
916
                hdr |= ct_no_n;
 
917
            }
807
918
 
808
919
            WRITE_UI16(hdrp, hdr);
809
920
 
810
 
 
811
921
#if TRACE_PRINTOUTS
812
 
            fprintf(stderr,
813
 
                    "{free, {%u}, {%u, %u}}\n",
814
 
                    (unsigned) ptr, MSB2BITS(ptr_n), MSB2BITS(ti_n));
815
 
                
816
 
            fflush(stderr);
 
922
            print_trace_entry(tag,
 
923
                              ct_no, ct_no_n,
 
924
                              t_no, t_no_n,
 
925
                              (Uint) 0, 0,
 
926
                              (Uint) ptr, ptr_n,
 
927
                              0, 0,
 
928
                              ti, ti_n);
817
929
#endif
818
930
 
819
931
#ifdef DEBUG
820
 
            check_free_entry(hdrp, tracep,
 
932
            check_free_entry(hdrp-1, tracep,
 
933
                             tag,
 
934
                             ct_no, ct_no_n,
 
935
                             t_no, t_no_n,
821
936
                             (Uint) ptr, ptr_n,
822
937
                             ti, ti_n);
823
938
#endif
824
939
        }
825
940
 
826
941
    }
827
 
 
828
 
    UNLOCK;
829
 
}
 
942
    erts_mtx_unlock(&mtrace_buf_mutex);
 
943
}
 
944
 
 
945
static void *
 
946
mtrace_alloc(ErtsAlcType_t n, void *extra, Uint size)
 
947
{
 
948
    ErtsAllocatorFunctions_t *real_af = (ErtsAllocatorFunctions_t *) extra;
 
949
    void *res;
 
950
 
 
951
    erts_mtx_lock(&mtrace_op_mutex);
 
952
 
 
953
    res = (*real_af->alloc)(n, real_af->extra, size);
 
954
    write_alloc_entry(ERTS_MT_ALLOC_BDY_TAG, res, n, 0, size);
 
955
 
 
956
    erts_mtx_unlock(&mtrace_op_mutex);
 
957
 
 
958
    return res;
 
959
}
 
960
 
 
961
static void *
 
962
mtrace_realloc(ErtsAlcType_t n, void *extra, void *ptr, Uint size)
 
963
{
 
964
    ErtsAllocatorFunctions_t *real_af = (ErtsAllocatorFunctions_t *) extra;
 
965
    void *res;
 
966
 
 
967
    erts_mtx_lock(&mtrace_op_mutex);
 
968
 
 
969
    res = (*real_af->realloc)(n, real_af->extra, ptr, size);
 
970
    write_realloc_entry(ERTS_MT_REALLOC_BDY_TAG, res, n, 0, ptr, size);
 
971
 
 
972
    erts_mtx_unlock(&mtrace_op_mutex);
 
973
 
 
974
    return res;
 
975
 
 
976
}
 
977
 
 
978
static void
 
979
mtrace_free(ErtsAlcType_t n, void *extra, void *ptr)
 
980
{
 
981
    ErtsAllocatorFunctions_t *real_af = (ErtsAllocatorFunctions_t *) extra;
 
982
 
 
983
    erts_mtx_lock(&mtrace_op_mutex);
 
984
 
 
985
    (*real_af->free)(n, real_af->extra, ptr);
 
986
    write_free_entry(ERTS_MT_FREE_BDY_TAG, n, 0, ptr);
 
987
 
 
988
    erts_mtx_unlock(&mtrace_op_mutex);
 
989
}
 
990
 
 
991
 
 
992
void
 
993
erts_mtrace_crr_alloc(void *res, ErtsAlcType_t n, ErtsAlcType_t m, Uint size)
 
994
{
 
995
    write_alloc_entry(ERTS_MT_CRR_ALLOC_BDY_TAG, res, n, m, size);
 
996
}
 
997
 
 
998
void
 
999
erts_mtrace_crr_realloc(void *res, ErtsAlcType_t n, ErtsAlcType_t m, void *ptr,
 
1000
                        Uint size)
 
1001
{
 
1002
    write_realloc_entry(ERTS_MT_CRR_REALLOC_BDY_TAG, res, n, m, ptr, size);
 
1003
}
 
1004
 
 
1005
void
 
1006
erts_mtrace_crr_free(ErtsAlcType_t n, ErtsAlcType_t m, void *ptr)
 
1007
{
 
1008
    write_free_entry(ERTS_MT_CRR_FREE_BDY_TAG, n, m, ptr);
 
1009
}
 
1010
 
 
1011
 
 
1012
#if TRACE_PRINTOUTS
 
1013
static void
 
1014
print_trace_entry(byte tag,
 
1015
                  Uint16 t_no, int t_no_n,
 
1016
                  Uint16 ct_no, int ct_no_n,
 
1017
                  Uint res, int res_n,
 
1018
                  Uint ptr, int ptr_n,
 
1019
                  Uint size, int size_n,
 
1020
                  Uint32 ti,int ti_n)
 
1021
{
 
1022
    switch (tag) {
 
1023
    case ERTS_MT_ALLOC_BDY_TAG:
 
1024
        fprintf(stderr,
 
1025
                "{alloc, {%lu, %lu, %lu}, {%u, %u, %u, %u}}\n\r",
 
1026
 
 
1027
                (unsigned long) t_no, (unsigned long) res,
 
1028
                (unsigned long) size,
 
1029
            
 
1030
                MSB2BITS(t_no_n), MSB2BITS(res_n),
 
1031
                MSB2BITS(size_n), MSB2BITS(ti_n));
 
1032
        break;
 
1033
    case ERTS_MT_REALLOC_BDY_TAG:
 
1034
        fprintf(stderr,
 
1035
                "{realloc, {%lu, %lu, %lu, %lu}, {%u, %u, %u, %u, %u}}\n\r",
 
1036
 
 
1037
                (unsigned long) t_no, (unsigned long) res,
 
1038
                (unsigned long) ptr, (unsigned long) size,
 
1039
            
 
1040
                MSB2BITS(t_no_n), MSB2BITS(res_n),
 
1041
                MSB2BITS(ptr_n), MSB2BITS(size_n), MSB2BITS(ti_n));
 
1042
        break;
 
1043
    case ERTS_MT_FREE_BDY_TAG:
 
1044
        fprintf(stderr,
 
1045
                "{free, {%lu, %lu}, {%u, %u, %u, %u, %u}}\n\r",
 
1046
 
 
1047
                (unsigned long) t_no, (unsigned long) ptr,
 
1048
            
 
1049
                MSB2BITS(t_no_n), MSB2BITS(ptr_n), MSB2BITS(ti_n));
 
1050
        break;
 
1051
    case ERTS_MT_CRR_ALLOC_BDY_TAG:
 
1052
        fprintf(stderr,
 
1053
                "{crr_alloc, {%lu, %lu, %lu, %lu}, {%u, %u, %u, %u, %u}}\n\r",
 
1054
 
 
1055
                (unsigned long) ct_no, (unsigned long) t_no,
 
1056
                (unsigned long) res, (unsigned long) size,
 
1057
            
 
1058
                MSB2BITS(ct_no_n), MSB2BITS(t_no_n),
 
1059
                MSB2BITS(res_n), MSB2BITS(size_n),
 
1060
                MSB2BITS(ti_n));
 
1061
        break;
 
1062
    case ERTS_MT_CRR_REALLOC_BDY_TAG:
 
1063
        fprintf(stderr,
 
1064
                "{crr_realloc, {%lu, %lu, %lu, %lu, %lu}, "
 
1065
                "{%u, %u, %u, %u, %u, %u}}\n\r",
 
1066
 
 
1067
                (unsigned long) ct_no, (unsigned long) t_no,
 
1068
                (unsigned long) res, (unsigned long) ptr,
 
1069
                (unsigned long) size,
 
1070
            
 
1071
                MSB2BITS(ct_no_n), MSB2BITS(t_no_n),
 
1072
                MSB2BITS(res_n), MSB2BITS(ptr_n),
 
1073
                MSB2BITS(size_n), MSB2BITS(ti_n));
 
1074
        break;
 
1075
    case ERTS_MT_CRR_FREE_BDY_TAG:
 
1076
        fprintf(stderr,
 
1077
                "{crr_free, {%lu, %lu, %lu}, {%u, %u, %u, %u}}\n\r",
 
1078
 
 
1079
                (unsigned long) ct_no, (unsigned long) t_no,
 
1080
                (unsigned long) ptr,
 
1081
            
 
1082
                MSB2BITS(ct_no_n), MSB2BITS(t_no_n),
 
1083
                MSB2BITS(ptr_n), MSB2BITS(ti_n));
 
1084
        break;
 
1085
    default:
 
1086
        fprintf(stderr, "{'\?\?\?'}\n\r");
 
1087
        break;
 
1088
    }
 
1089
}
 
1090
 
 
1091
#endif /* #if TRACE_PRINTOUTS */
830
1092
 
831
1093
#ifdef DEBUG
832
1094
 
869
1131
 
870
1132
void
871
1133
check_alloc_entry(byte *sp, byte *ep,
 
1134
                  byte tag,
 
1135
                  Uint16 ct_no, int ct_no_n,
872
1136
                  Uint16 t_no, int t_no_n,
873
1137
                  Uint res, int res_n,
874
1138
                  Uint size, int size_n,
877
1141
    byte *p = sp;
878
1142
    Uint16 hdr;
879
1143
 
880
 
    ASSERT((ERTS_MT_ALLOC_TAG & ~TAG_EHF_MSK) == 0);
 
1144
    ASSERT(*p == tag);
 
1145
    p++;
881
1146
 
882
1147
    hdr = GET_UI16(p);
883
 
    ASSERT((hdr & TAG_EHF_MSK) == ERTS_MT_ALLOC_TAG);
884
 
    hdr >>= TAG_EHF_SZ;
885
1148
 
 
1149
    if (tag == ERTS_MT_CRR_ALLOC_BDY_TAG)
 
1150
        check_ui(&hdr, &p, ct_no, ct_no_n, UI16_MSB_EHF_MSK, UI16_MSB_EHF_SZ);
886
1151
    check_ui(&hdr, &p, t_no, t_no_n, UI16_MSB_EHF_MSK, UI16_MSB_EHF_SZ);
887
1152
    check_ui(&hdr, &p, res,  res_n,  UI_MSB_EHF_MSK,   UI_MSB_EHF_SZ);
888
1153
    check_ui(&hdr, &p, size, size_n, UI_MSB_EHF_MSK,   UI_MSB_EHF_SZ);
893
1158
}
894
1159
 
895
1160
void
896
 
check_realloc_entry(byte *sp, byte *ep, int no_previous_block, int moved,
 
1161
check_realloc_entry(byte *sp, byte *ep,
 
1162
                    byte tag,
 
1163
                    Uint16 ct_no, int ct_no_n,
897
1164
                    Uint16 t_no, int t_no_n,
898
1165
                    Uint res, int res_n,
899
1166
                    Uint ptr, int ptr_n,
903
1170
    byte *p = sp;
904
1171
    Uint16 hdr;
905
1172
 
906
 
    ASSERT((ERTS_MT_REALLOC_MV_TAG & ~TAG_EHF_MSK) == 0);
907
 
    ASSERT((ERTS_MT_REALLOC_NMV_TAG & ~TAG_EHF_MSK) == 0);
 
1173
    ASSERT(*p == tag);
 
1174
    p++;
908
1175
 
909
1176
    hdr = GET_UI16(p);
910
 
    if (no_previous_block) {
911
 
        ASSERT((hdr & TAG_EHF_MSK) == ERTS_MT_REALLOC_NPB_TAG);
912
 
    }
913
 
    if (moved) {
914
 
        ASSERT((hdr & TAG_EHF_MSK) == ERTS_MT_REALLOC_MV_TAG);
915
 
    }
916
 
    else {
917
 
        ASSERT((hdr & TAG_EHF_MSK) == ERTS_MT_REALLOC_NMV_TAG);
918
 
    }
919
 
    hdr >>= TAG_EHF_SZ;
920
1177
 
921
 
    if (no_previous_block)
922
 
        check_ui(&hdr, &p, t_no, t_no_n, UI16_MSB_EHF_MSK, UI16_MSB_EHF_SZ);
 
1178
    if (tag == ERTS_MT_CRR_REALLOC_BDY_TAG)
 
1179
        check_ui(&hdr, &p, ct_no, ct_no_n, UI16_MSB_EHF_MSK, UI16_MSB_EHF_SZ);
 
1180
    check_ui(&hdr, &p, t_no, t_no_n, UI16_MSB_EHF_MSK, UI16_MSB_EHF_SZ);
923
1181
    check_ui(&hdr, &p, res,  res_n,  UI_MSB_EHF_MSK,   UI_MSB_EHF_SZ);
924
 
    if (moved)
925
 
        check_ui(&hdr, &p, ptr,  ptr_n,  UI_MSB_EHF_MSK,   UI_MSB_EHF_SZ);
 
1182
    check_ui(&hdr, &p, ptr,  ptr_n,  UI_MSB_EHF_MSK,   UI_MSB_EHF_SZ);
926
1183
    check_ui(&hdr, &p, size, size_n, UI_MSB_EHF_MSK,   UI_MSB_EHF_SZ);
927
1184
    check_ui(&hdr, &p, ti,   ti_n,   UI32_MSB_EHF_MSK, UI32_MSB_EHF_SZ);
928
1185
 
932
1189
 
933
1190
void
934
1191
check_free_entry(byte *sp, byte *ep,
 
1192
                 byte tag,
 
1193
                 Uint16 ct_no, int ct_no_n,
 
1194
                 Uint16 t_no, int t_no_n,
935
1195
                 Uint ptr, int ptr_n,
936
1196
                 Uint32 ti,int ti_n)
937
1197
{
938
1198
    byte *p = sp;
939
1199
    Uint16 hdr;
940
1200
 
941
 
    ASSERT((ERTS_MT_FREE_TAG & ~TAG_EHF_MSK) == 0);
 
1201
    ASSERT(*p == tag);
 
1202
    p++;
942
1203
 
943
1204
    hdr = GET_UI16(p);
944
 
    ASSERT((hdr & TAG_EHF_MSK) == ERTS_MT_FREE_TAG);
945
 
    hdr >>= TAG_EHF_SZ;
946
1205
 
 
1206
    if (tag == ERTS_MT_CRR_FREE_BDY_TAG)
 
1207
        check_ui(&hdr, &p, ct_no, ct_no_n, UI16_MSB_EHF_MSK, UI16_MSB_EHF_SZ);
 
1208
    check_ui(&hdr, &p, t_no, t_no_n, UI16_MSB_EHF_MSK, UI16_MSB_EHF_SZ);
947
1209
    check_ui(&hdr, &p, ptr,  ptr_n,  UI_MSB_EHF_MSK,   UI_MSB_EHF_SZ);
948
1210
    check_ui(&hdr, &p, ti,   ti_n,   UI32_MSB_EHF_MSK, UI32_MSB_EHF_SZ);
949
1211
 
960
1222
    byte *p = sp;
961
1223
    Uint16 hdr;
962
1224
 
963
 
    ASSERT((ERTS_MT_TIME_INC_TAG & ~TAG_EHF_MSK) == 0);
 
1225
    ASSERT(*p == ERTS_MT_TIME_INC_BDY_TAG);
 
1226
    p++;
964
1227
 
965
1228
    hdr = GET_UI16(p);
966
 
    ASSERT((hdr & TAG_EHF_MSK) == ERTS_MT_TIME_INC_TAG);
967
 
    hdr >>= TAG_EHF_SZ;
968
1229
 
969
1230
    check_ui(&hdr, &p, secs,  secs_n,  UI32_MSB_EHF_MSK, UI32_MSB_EHF_SZ);
970
1231
    check_ui(&hdr, &p, usecs, usecs_n, UI32_MSB_EHF_MSK, UI32_MSB_EHF_SZ);