~ubuntu-branches/ubuntu/quantal/libgc/quantal

« back to all changes in this revision

Viewing changes to dbg_mlc.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger
  • Date: 2011-03-02 13:43:18 UTC
  • mfrom: (1.2.5 upstream) (3.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20110302134318-82ful0us5ce82qe8
Tags: 1:7.1-7
* Add ppc64 symbol file (Closes: #615469)
* Add sh4 symbol file (Closes: #614744)
* Add armhf symbol file
* Add powerpcspe symbol file
* Handle sparc64 the same as sparc
* Clear non-arch symbol file to support building on not yet captured
  architectures
* add -pthread to fix build with --no-add-needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved.
4
4
 * Copyright (c) 1997 by Silicon Graphics.  All rights reserved.
5
5
 * Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P.
 
6
 * Copyright (C) 2007 Free Software Foundation, Inc
6
7
 *
7
8
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8
9
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
20
21
 
21
22
void GC_default_print_heap_obj_proc();
22
23
GC_API void GC_register_finalizer_no_order
23
 
        GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
24
 
                  GC_finalization_proc *ofn, GC_PTR *ocd));
 
24
        (void * obj, GC_finalization_proc fn, void * cd,
 
25
         GC_finalization_proc *ofn, void * *ocd);
25
26
 
26
27
 
27
28
#ifndef SHORT_DBG_HDRS
34
35
/* on free lists may not have debug information set.  Thus it's */
35
36
/* not always safe to return TRUE, even if the client does      */
36
37
/* its part.                                                    */
37
 
GC_bool GC_has_other_debug_info(p)
38
 
ptr_t p;
 
38
GC_bool GC_has_other_debug_info(ptr_t p)
39
39
{
40
40
    register oh * ohdr = (oh *)p;
41
41
    register ptr_t body = (ptr_t)(ohdr + 1);
61
61
 
62
62
# include <stdlib.h>
63
63
 
64
 
# if defined(LINUX) || defined(SUNOS4) || defined(SUNOS5) \
 
64
# if defined(__GLIBC__) || defined(SOLARIS) \
65
65
     || defined(HPUX) || defined(IRIX5) || defined(OSF1)
66
66
#   define RANDOM() random()
67
67
# else
146
146
        /* e.g. RAND_MAX = 1.5* GC_heapsize.  But for typical cases,    */
147
147
        /* it's not too bad.                                            */
148
148
    for (i = 0; i < GC_n_heap_sects; ++ i) {
149
 
        int size = GC_heap_sects[i].hs_bytes;
 
149
        size_t size = GC_heap_sects[i].hs_bytes;
150
150
        if (heap_offset < size) {
151
151
            return GC_heap_sects[i].hs_start + heap_offset;
152
152
        } else {
182
182
    void *base;
183
183
 
184
184
    GC_print_heap_obj(GC_base(current));
185
 
    GC_err_printf0("\n");
 
185
    GC_err_printf("\n");
186
186
    for (i = 0; ; ++i) {
187
187
      source = GC_get_back_ptr_info(current, &base, &offset);
188
188
      if (GC_UNREFERENCED == source) {
189
 
        GC_err_printf0("Reference could not be found\n");
 
189
        GC_err_printf("Reference could not be found\n");
190
190
        goto out;
191
191
      }
192
192
      if (GC_NO_SPACE == source) {
193
 
        GC_err_printf0("No debug info in object: Can't find reference\n");
 
193
        GC_err_printf("No debug info in object: Can't find reference\n");
194
194
        goto out;
195
195
      }
196
 
      GC_err_printf1("Reachable via %d levels of pointers from ",
 
196
      GC_err_printf("Reachable via %d levels of pointers from ",
197
197
                 (unsigned long)i);
198
198
      switch(source) {
199
199
        case GC_REFD_FROM_ROOT:
200
 
          GC_err_printf1("root at 0x%lx\n\n", (unsigned long)base);
 
200
          GC_err_printf("root at %p\n\n", base);
201
201
          goto out;
202
202
        case GC_REFD_FROM_REG:
203
 
          GC_err_printf0("root in register\n\n");
 
203
          GC_err_printf("root in register\n\n");
204
204
          goto out;
205
205
        case GC_FINALIZER_REFD:
206
 
          GC_err_printf0("list of finalizable objects\n\n");
 
206
          GC_err_printf("list of finalizable objects\n\n");
207
207
          goto out;
208
208
        case GC_REFD_FROM_HEAP:
209
 
          GC_err_printf1("offset %ld in object:\n", (unsigned long)offset);
 
209
          GC_err_printf("offset %ld in object:\n", (unsigned long)offset);
210
210
          /* Take GC_base(base) to get real base, i.e. header. */
211
211
          GC_print_heap_obj(GC_base(base));
212
 
          GC_err_printf0("\n");
 
212
          GC_err_printf("\n");
213
213
          break;
214
214
      }
215
215
      current = base;
223
223
  {
224
224
    void * current;
225
225
    current = GC_generate_random_valid_address();
226
 
    GC_printf1("\n****Chose address 0x%lx in object\n", (unsigned long)current);
 
226
    GC_printf("\n****Chose address %p in object\n", current);
227
227
    GC_print_backtrace(current);
228
228
  }
229
229
    
239
239
        (((word)(p + sizeof(oh) + sz - 1) ^ (word)p) >= HBLKSIZE)
240
240
/* Store debugging info into p.  Return displaced pointer. */
241
241
/* Assumes we don't hold allocation lock.                  */
242
 
ptr_t GC_store_debug_info(p, sz, string, integer)
243
 
register ptr_t p;       /* base pointer */
244
 
word sz;        /* bytes */
245
 
GC_CONST char * string;
246
 
word integer;
 
242
ptr_t GC_store_debug_info(ptr_t p, word sz, const char *string, word integer)
247
243
{
248
244
    register word * result = (word *)((oh *)p + 1);
249
245
    DCL_LOCK_STATE;
275
271
#ifdef DBG_HDRS_ALL
276
272
/* Store debugging info into p.  Return displaced pointer.         */
277
273
/* This version assumes we do hold the allocation lock.            */
278
 
ptr_t GC_store_debug_info_inner(p, sz, string, integer)
279
 
register ptr_t p;       /* base pointer */
280
 
word sz;        /* bytes */
281
 
char * string;
282
 
word integer;
 
274
ptr_t GC_store_debug_info_inner(ptr_t p, word sz, char *string, word integer)
283
275
{
284
276
    register word * result = (word *)((oh *)p + 1);
285
277
    
310
302
/* Check the object with debugging info at ohdr         */
311
303
/* return NIL if it's OK.  Else return clobbered        */
312
304
/* address.                                             */
313
 
ptr_t GC_check_annotated_obj(ohdr)
314
 
register oh * ohdr;
 
305
ptr_t GC_check_annotated_obj(oh *ohdr)
315
306
{
316
307
    register ptr_t body = (ptr_t)(ohdr + 1);
317
308
    register word gc_sz = GC_size((ptr_t)ohdr);
334
325
 
335
326
static GC_describe_type_fn GC_describe_type_fns[MAXOBJKINDS] = {0};
336
327
 
337
 
void GC_register_describe_type_fn(kind, fn)
338
 
int kind;
339
 
GC_describe_type_fn fn;
 
328
void GC_register_describe_type_fn(int kind, GC_describe_type_fn fn)
340
329
{
341
330
  GC_describe_type_fns[kind] = fn;
342
331
}
343
332
 
344
333
/* Print a type description for the object whose client-visible address */
345
334
/* is p.                                                                */
346
 
void GC_print_type(p)
347
 
ptr_t p;
 
335
void GC_print_type(ptr_t p)
348
336
{
349
337
    hdr * hhdr = GC_find_header(p);
350
338
    char buffer[GC_TYPE_DESCR_LEN + 1];
377
365
            GC_err_puts("STUBBORN");
378
366
            break;
379
367
          default:
380
 
            GC_err_printf2("kind %ld, descr 0x%lx", kind, hhdr -> hb_descr);
 
368
            GC_err_printf("kind %d, descr 0x%lx", kind,
 
369
                          (unsigned long)(hhdr -> hb_descr));
381
370
        }
382
371
    }
383
372
}
384
373
 
385
374
    
386
375
 
387
 
void GC_print_obj(p)
388
 
ptr_t p;
 
376
void GC_print_obj(ptr_t p)
389
377
{
390
378
    register oh * ohdr = (oh *)GC_base(p);
391
379
    
392
 
    GC_ASSERT(!I_HOLD_LOCK());
393
 
    GC_err_printf1("0x%lx (", ((unsigned long)ohdr + sizeof(oh)));
 
380
    GC_ASSERT(I_DONT_HOLD_LOCK());
 
381
    GC_err_printf("%p (", ((ptr_t)ohdr + sizeof(oh)));
394
382
    GC_err_puts(ohdr -> oh_string);
395
383
#   ifdef SHORT_DBG_HDRS
396
 
      GC_err_printf1(":%ld, ", (unsigned long)(ohdr -> oh_int));
 
384
      GC_err_printf(":%ld, ", (unsigned long)(ohdr -> oh_int));
397
385
#   else
398
 
      GC_err_printf2(":%ld, sz=%ld, ", (unsigned long)(ohdr -> oh_int),
 
386
      GC_err_printf(":%ld, sz=%ld, ", (unsigned long)(ohdr -> oh_int),
399
387
                                        (unsigned long)(ohdr -> oh_sz));
400
388
#   endif
401
389
    GC_print_type((ptr_t)(ohdr + 1));
403
391
    PRINT_CALL_CHAIN(ohdr);
404
392
}
405
393
 
406
 
# if defined(__STDC__) || defined(__cplusplus)
407
 
    void GC_debug_print_heap_obj_proc(ptr_t p)
408
 
# else
409
 
    void GC_debug_print_heap_obj_proc(p)
410
 
    ptr_t p;
411
 
# endif
 
394
void GC_debug_print_heap_obj_proc(ptr_t p)
412
395
{
413
 
    GC_ASSERT(!I_HOLD_LOCK());
 
396
    GC_ASSERT(I_DONT_HOLD_LOCK());
414
397
    if (GC_HAS_DEBUG_INFO(p)) {
415
398
        GC_print_obj(p);
416
399
    } else {
419
402
}
420
403
 
421
404
#ifndef SHORT_DBG_HDRS
422
 
void GC_print_smashed_obj(p, clobbered_addr)
423
 
ptr_t p, clobbered_addr;
 
405
/* Use GC_err_printf and friends to print a description of the object   */
 
406
/* whose client-visible address is p, and which was smashed at          */
 
407
/* clobbered_addr.                                                      */
 
408
void GC_print_smashed_obj(ptr_t p, ptr_t clobbered_addr)
424
409
{
425
410
    register oh * ohdr = (oh *)GC_base(p);
426
411
    
427
 
    GC_ASSERT(!I_HOLD_LOCK());
428
 
    GC_err_printf2("0x%lx in object at 0x%lx(", (unsigned long)clobbered_addr,
429
 
                                                (unsigned long)p);
 
412
    GC_ASSERT(I_DONT_HOLD_LOCK());
 
413
    GC_err_printf("%p in or near object at %p(", clobbered_addr, p);
430
414
    if (clobbered_addr <= (ptr_t)(&(ohdr -> oh_sz))
431
415
        || ohdr -> oh_string == 0) {
432
 
        GC_err_printf1("<smashed>, appr. sz = %ld)\n",
 
416
        GC_err_printf("<smashed>, appr. sz = %ld)\n",
433
417
                       (GC_size((ptr_t)ohdr) - DEBUG_BYTES));
434
418
    } else {
435
419
        if (ohdr -> oh_string[0] == '\0') {
437
421
        } else {
438
422
            GC_err_puts(ohdr -> oh_string);
439
423
        }
440
 
        GC_err_printf2(":%ld, sz=%ld)\n", (unsigned long)(ohdr -> oh_int),
 
424
        GC_err_printf(":%ld, sz=%ld)\n", (unsigned long)(ohdr -> oh_int),
441
425
                                          (unsigned long)(ohdr -> oh_sz));
442
426
        PRINT_CALL_CHAIN(ohdr);
443
427
    }
444
428
}
445
429
#endif
446
430
 
447
 
void GC_check_heap_proc GC_PROTO((void));
448
 
 
449
 
void GC_print_all_smashed_proc GC_PROTO((void));
450
 
 
451
 
void GC_do_nothing() {}
452
 
 
453
 
void GC_start_debugging()
 
431
void GC_check_heap_proc (void);
 
432
 
 
433
void GC_print_all_smashed_proc (void);
 
434
 
 
435
void GC_do_nothing(void) {}
 
436
 
 
437
void GC_start_debugging(void)
454
438
{
455
439
#   ifndef SHORT_DBG_HDRS
456
440
      GC_check_heap = GC_check_heap_proc;
466
450
 
467
451
size_t GC_debug_header_size = sizeof(oh);
468
452
 
469
 
# if defined(__STDC__) || defined(__cplusplus)
470
 
    void GC_debug_register_displacement(GC_word offset)
471
 
# else
472
 
    void GC_debug_register_displacement(offset) 
473
 
    GC_word offset;
474
 
# endif
 
453
void GC_debug_register_displacement(size_t offset)
475
454
{
476
455
    GC_register_displacement(offset);
477
456
    GC_register_displacement((word)sizeof(oh) + offset);
478
457
}
479
458
 
480
 
# ifdef __STDC__
481
 
    GC_PTR GC_debug_malloc(size_t lb, GC_EXTRA_PARAMS)
482
 
# else
483
 
    GC_PTR GC_debug_malloc(lb, s, i)
484
 
    size_t lb;
485
 
    char * s;
486
 
    int i;
487
 
#   ifdef GC_ADD_CALLER
488
 
        --> GC_ADD_CALLER not implemented for K&R C
489
 
#   endif
490
 
# endif
491
 
{
492
 
    GC_PTR result = GC_malloc(lb + DEBUG_BYTES);
493
 
    
494
 
    if (result == 0) {
495
 
        GC_err_printf1("GC_debug_malloc(%ld) returning NIL (",
496
 
                       (unsigned long) lb);
497
 
        GC_err_puts(s);
498
 
        GC_err_printf1(":%ld)\n", (unsigned long)i);
499
 
        return(0);
500
 
    }
501
 
    if (!GC_debugging_started) {
502
 
        GC_start_debugging();
503
 
    }
504
 
    ADD_CALL_CHAIN(result, ra);
505
 
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
506
 
}
507
 
 
508
 
# ifdef __STDC__
509
 
    GC_PTR GC_debug_malloc_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
510
 
# else
511
 
    GC_PTR GC_debug_malloc_ignore_off_page(lb, s, i)
512
 
    size_t lb;
513
 
    char * s;
514
 
    int i;
515
 
#   ifdef GC_ADD_CALLER
516
 
        --> GC_ADD_CALLER not implemented for K&R C
517
 
#   endif
518
 
# endif
519
 
{
520
 
    GC_PTR result = GC_malloc_ignore_off_page(lb + DEBUG_BYTES);
521
 
    
522
 
    if (result == 0) {
523
 
        GC_err_printf1("GC_debug_malloc_ignore_off_page(%ld) returning NIL (",
524
 
                       (unsigned long) lb);
525
 
        GC_err_puts(s);
526
 
        GC_err_printf1(":%ld)\n", (unsigned long)i);
527
 
        return(0);
528
 
    }
529
 
    if (!GC_debugging_started) {
530
 
        GC_start_debugging();
531
 
    }
532
 
    ADD_CALL_CHAIN(result, ra);
533
 
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
534
 
}
535
 
 
536
 
# ifdef __STDC__
537
 
    GC_PTR GC_debug_malloc_atomic_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
538
 
# else
539
 
    GC_PTR GC_debug_malloc_atomic_ignore_off_page(lb, s, i)
540
 
    size_t lb;
541
 
    char * s;
542
 
    int i;
543
 
#   ifdef GC_ADD_CALLER
544
 
        --> GC_ADD_CALLER not implemented for K&R C
545
 
#   endif
546
 
# endif
547
 
{
548
 
    GC_PTR result = GC_malloc_atomic_ignore_off_page(lb + DEBUG_BYTES);
549
 
    
550
 
    if (result == 0) {
551
 
        GC_err_printf1("GC_debug_malloc_atomic_ignore_off_page(%ld)"
 
459
void * GC_debug_malloc(size_t lb, GC_EXTRA_PARAMS)
 
460
{
 
461
    void * result = GC_malloc(lb + DEBUG_BYTES);
 
462
    
 
463
    if (result == 0) {
 
464
        GC_err_printf("GC_debug_malloc(%lu) returning NIL (",
 
465
                      (unsigned long) lb);
 
466
        GC_err_puts(s);
 
467
        GC_err_printf(":%ld)\n", (unsigned long)i);
 
468
        return(0);
 
469
    }
 
470
    if (!GC_debugging_started) {
 
471
        GC_start_debugging();
 
472
    }
 
473
    ADD_CALL_CHAIN(result, ra);
 
474
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
 
475
}
 
476
 
 
477
void * GC_debug_malloc_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
 
478
{
 
479
    void * result = GC_malloc_ignore_off_page(lb + DEBUG_BYTES);
 
480
    
 
481
    if (result == 0) {
 
482
        GC_err_printf("GC_debug_malloc_ignore_off_page(%lu) returning NIL (",
 
483
                       (unsigned long) lb);
 
484
        GC_err_puts(s);
 
485
        GC_err_printf(":%lu)\n", (unsigned long)i);
 
486
        return(0);
 
487
    }
 
488
    if (!GC_debugging_started) {
 
489
        GC_start_debugging();
 
490
    }
 
491
    ADD_CALL_CHAIN(result, ra);
 
492
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
 
493
}
 
494
 
 
495
void * GC_debug_malloc_atomic_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
 
496
{
 
497
    void * result = GC_malloc_atomic_ignore_off_page(lb + DEBUG_BYTES);
 
498
    
 
499
    if (result == 0) {
 
500
        GC_err_printf("GC_debug_malloc_atomic_ignore_off_page(%lu)"
552
501
                       " returning NIL (", (unsigned long) lb);
553
502
        GC_err_puts(s);
554
 
        GC_err_printf1(":%ld)\n", (unsigned long)i);
 
503
        GC_err_printf(":%lu)\n", (unsigned long)i);
555
504
        return(0);
556
505
    }
557
506
    if (!GC_debugging_started) {
570
519
 * We assume debugging was started in collector initialization,
571
520
 * and we already hold the GC lock.
572
521
 */
573
 
  GC_PTR GC_debug_generic_malloc_inner(size_t lb, int k)
 
522
  void * GC_debug_generic_malloc_inner(size_t lb, int k)
574
523
  {
575
 
    GC_PTR result = GC_generic_malloc_inner(lb + DEBUG_BYTES, k);
 
524
    void * result = GC_generic_malloc_inner(lb + DEBUG_BYTES, k);
576
525
    
577
526
    if (result == 0) {
578
 
        GC_err_printf1("GC internal allocation (%ld bytes) returning NIL\n",
 
527
        GC_err_printf("GC internal allocation (%lu bytes) returning NIL\n",
579
528
                       (unsigned long) lb);
580
529
        return(0);
581
530
    }
583
532
    return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
584
533
  }
585
534
 
586
 
  GC_PTR GC_debug_generic_malloc_inner_ignore_off_page(size_t lb, int k)
 
535
  void * GC_debug_generic_malloc_inner_ignore_off_page(size_t lb, int k)
587
536
  {
588
 
    GC_PTR result = GC_generic_malloc_inner_ignore_off_page(
 
537
    void * result = GC_generic_malloc_inner_ignore_off_page(
589
538
                                                lb + DEBUG_BYTES, k);
590
539
    
591
540
    if (result == 0) {
592
 
        GC_err_printf1("GC internal allocation (%ld bytes) returning NIL\n",
 
541
        GC_err_printf("GC internal allocation (%lu bytes) returning NIL\n",
593
542
                       (unsigned long) lb);
594
543
        return(0);
595
544
    }
599
548
# endif
600
549
 
601
550
#ifdef STUBBORN_ALLOC
602
 
# ifdef __STDC__
603
 
    GC_PTR GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
604
 
# else
605
 
    GC_PTR GC_debug_malloc_stubborn(lb, s, i)
606
 
    size_t lb;
607
 
    char * s;
608
 
    int i;
609
 
# endif
 
551
void * GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
610
552
{
611
 
    GC_PTR result = GC_malloc_stubborn(lb + DEBUG_BYTES);
 
553
    void * result = GC_malloc_stubborn(lb + DEBUG_BYTES);
612
554
    
613
555
    if (result == 0) {
614
 
        GC_err_printf1("GC_debug_malloc(%ld) returning NIL (",
615
 
                       (unsigned long) lb);
 
556
        GC_err_printf("GC_debug_malloc(%lu) returning NIL (",
 
557
                      (unsigned long) lb);
616
558
        GC_err_puts(s);
617
 
        GC_err_printf1(":%ld)\n", (unsigned long)i);
 
559
        GC_err_printf(":%lu)\n", (unsigned long)i);
618
560
        return(0);
619
561
    }
620
562
    if (!GC_debugging_started) {
624
566
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
625
567
}
626
568
 
627
 
void GC_debug_change_stubborn(p)
628
 
GC_PTR p;
 
569
void GC_debug_change_stubborn(void *p)
629
570
{
630
 
    register GC_PTR q = GC_base(p);
631
 
    register hdr * hhdr;
 
571
    void * q = GC_base(p);
 
572
    hdr * hhdr;
632
573
    
633
574
    if (q == 0) {
634
 
        GC_err_printf1("Bad argument: 0x%lx to GC_debug_change_stubborn\n",
635
 
                       (unsigned long) p);
 
575
        GC_err_printf("Bad argument: %p to GC_debug_change_stubborn\n", p);
636
576
        ABORT("GC_debug_change_stubborn: bad arg");
637
577
    }
638
578
    hhdr = HDR(q);
639
579
    if (hhdr -> hb_obj_kind != STUBBORN) {
640
 
        GC_err_printf1("GC_debug_change_stubborn arg not stubborn: 0x%lx\n",
641
 
                       (unsigned long) p);
 
580
        GC_err_printf("GC_debug_change_stubborn arg not stubborn: %p\n", p);
642
581
        ABORT("GC_debug_change_stubborn: arg not stubborn");
643
582
    }
644
583
    GC_change_stubborn(q);
645
584
}
646
585
 
647
 
void GC_debug_end_stubborn_change(p)
648
 
GC_PTR p;
 
586
void GC_debug_end_stubborn_change(void *p)
649
587
{
650
 
    register GC_PTR q = GC_base(p);
 
588
    register void * q = GC_base(p);
651
589
    register hdr * hhdr;
652
590
    
653
591
    if (q == 0) {
654
 
        GC_err_printf1("Bad argument: 0x%lx to GC_debug_end_stubborn_change\n",
655
 
                       (unsigned long) p);
 
592
        GC_err_printf("Bad argument: %p to GC_debug_end_stubborn_change\n", p);
656
593
        ABORT("GC_debug_end_stubborn_change: bad arg");
657
594
    }
658
595
    hhdr = HDR(q);
659
596
    if (hhdr -> hb_obj_kind != STUBBORN) {
660
 
        GC_err_printf1("debug_end_stubborn_change arg not stubborn: 0x%lx\n",
661
 
                       (unsigned long) p);
 
597
        GC_err_printf("debug_end_stubborn_change arg not stubborn: %p\n", p);
662
598
        ABORT("GC_debug_end_stubborn_change: arg not stubborn");
663
599
    }
664
600
    GC_end_stubborn_change(q);
666
602
 
667
603
#else /* !STUBBORN_ALLOC */
668
604
 
669
 
# ifdef __STDC__
670
 
    GC_PTR GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
671
 
# else
672
 
    GC_PTR GC_debug_malloc_stubborn(lb, s, i)
673
 
    size_t lb;
674
 
    char * s;
675
 
    int i;
676
 
# endif
 
605
void * GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
677
606
{
678
607
    return GC_debug_malloc(lb, OPT_RA s, i);
679
608
}
680
609
 
681
 
void GC_debug_change_stubborn(p)
682
 
GC_PTR p;
 
610
void GC_debug_change_stubborn(void *p)
683
611
{
684
612
}
685
613
 
686
 
void GC_debug_end_stubborn_change(p)
687
 
GC_PTR p;
 
614
void GC_debug_end_stubborn_change(void *p)
688
615
{
689
616
}
690
617
 
691
618
#endif /* !STUBBORN_ALLOC */
692
619
 
693
 
# ifdef __STDC__
694
 
    GC_PTR GC_debug_malloc_atomic(size_t lb, GC_EXTRA_PARAMS)
695
 
# else
696
 
    GC_PTR GC_debug_malloc_atomic(lb, s, i)
697
 
    size_t lb;
698
 
    char * s;
699
 
    int i;
700
 
# endif
 
620
void * GC_debug_malloc_atomic(size_t lb, GC_EXTRA_PARAMS)
701
621
{
702
 
    GC_PTR result = GC_malloc_atomic(lb + DEBUG_BYTES);
 
622
    void * result = GC_malloc_atomic(lb + DEBUG_BYTES);
703
623
    
704
624
    if (result == 0) {
705
 
        GC_err_printf1("GC_debug_malloc_atomic(%ld) returning NIL (",
 
625
        GC_err_printf("GC_debug_malloc_atomic(%lu) returning NIL (",
706
626
                      (unsigned long) lb);
707
627
        GC_err_puts(s);
708
 
        GC_err_printf1(":%ld)\n", (unsigned long)i);
 
628
        GC_err_printf(":%lu)\n", (unsigned long)i);
709
629
        return(0);
710
630
    }
711
631
    if (!GC_debugging_started) {
715
635
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
716
636
}
717
637
 
718
 
# ifdef __STDC__
719
 
    char *GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
720
 
#else
721
 
    char *GC_debug_strdup(str, s, i)
722
 
    char *str;
723
 
    char *s;
724
 
    int i;
725
 
#endif
 
638
char *GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
726
639
{
727
640
    char *copy;
728
641
    if (str == NULL) return NULL;
735
648
    return copy;
736
649
}
737
650
 
738
 
# ifdef __STDC__
739
 
    GC_PTR GC_debug_malloc_uncollectable(size_t lb, GC_EXTRA_PARAMS)
740
 
# else
741
 
    GC_PTR GC_debug_malloc_uncollectable(lb, s, i)
742
 
    size_t lb;
743
 
    char * s;
744
 
    int i;
745
 
# endif
 
651
void * GC_debug_malloc_uncollectable(size_t lb, GC_EXTRA_PARAMS)
746
652
{
747
 
    GC_PTR result = GC_malloc_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
 
653
    void * result = GC_malloc_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
748
654
    
749
655
    if (result == 0) {
750
 
        GC_err_printf1("GC_debug_malloc_uncollectable(%ld) returning NIL (",
 
656
        GC_err_printf("GC_debug_malloc_uncollectable(%lu) returning NIL (",
751
657
                      (unsigned long) lb);
752
658
        GC_err_puts(s);
753
 
        GC_err_printf1(":%ld)\n", (unsigned long)i);
 
659
        GC_err_printf(":%lu)\n", (unsigned long)i);
754
660
        return(0);
755
661
    }
756
662
    if (!GC_debugging_started) {
761
667
}
762
668
 
763
669
#ifdef ATOMIC_UNCOLLECTABLE
764
 
# ifdef __STDC__
765
 
    GC_PTR GC_debug_malloc_atomic_uncollectable(size_t lb, GC_EXTRA_PARAMS)
766
 
# else
767
 
    GC_PTR GC_debug_malloc_atomic_uncollectable(lb, s, i)
768
 
    size_t lb;
769
 
    char * s;
770
 
    int i;
771
 
# endif
 
670
void * GC_debug_malloc_atomic_uncollectable(size_t lb, GC_EXTRA_PARAMS)
772
671
{
773
 
    GC_PTR result =
 
672
    void * result =
774
673
        GC_malloc_atomic_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
775
674
    
776
675
    if (result == 0) {
777
 
        GC_err_printf1(
778
 
                "GC_debug_malloc_atomic_uncollectable(%ld) returning NIL (",
 
676
        GC_err_printf(
 
677
                "GC_debug_malloc_atomic_uncollectable(%lu) returning NIL (",
779
678
                (unsigned long) lb);
780
679
        GC_err_puts(s);
781
 
        GC_err_printf1(":%ld)\n", (unsigned long)i);
 
680
        GC_err_printf(":%lu)\n", (unsigned long)i);
782
681
        return(0);
783
682
    }
784
683
    if (!GC_debugging_started) {
789
688
}
790
689
#endif /* ATOMIC_UNCOLLECTABLE */
791
690
 
792
 
# ifdef __STDC__
793
 
    void GC_debug_free(GC_PTR p)
794
 
# else
795
 
    void GC_debug_free(p)
796
 
    GC_PTR p;
797
 
# endif
 
691
void GC_debug_free(void * p)
798
692
{
799
 
    register GC_PTR base;
800
 
    register ptr_t clobbered;
 
693
    ptr_t base;
 
694
    ptr_t clobbered;
801
695
    
802
696
    if (0 == p) return;
803
697
    base = GC_base(p);
804
698
    if (base == 0) {
805
 
        GC_err_printf1("Attempt to free invalid pointer %lx\n",
806
 
                       (unsigned long)p);
 
699
        GC_err_printf("Attempt to free invalid pointer %p\n", p);
807
700
        ABORT("free(invalid pointer)");
808
701
    }
809
702
    if ((ptr_t)p - (ptr_t)base != sizeof(oh)) {
810
 
        GC_err_printf1(
811
 
                  "GC_debug_free called on pointer %lx wo debugging info\n",
812
 
                  (unsigned long)p);
 
703
        GC_err_printf(
 
704
                  "GC_debug_free called on pointer %p wo debugging info\n", p);
813
705
    } else {
814
706
#     ifndef SHORT_DBG_HDRS
815
707
        clobbered = GC_check_annotated_obj((oh *)base);
816
708
        if (clobbered != 0) {
817
709
          if (((oh *)base) -> oh_sz == GC_size(base)) {
818
 
            GC_err_printf0(
 
710
            GC_err_printf(
819
711
                  "GC_debug_free: found previously deallocated (?) object at ");
820
712
          } else {
821
 
            GC_err_printf0("GC_debug_free: found smashed location at ");
 
713
            GC_err_printf("GC_debug_free: found smashed location at ");
822
714
          }
823
715
          GC_print_smashed_obj(p, clobbered);
824
716
        }
829
721
    if (GC_find_leak) {
830
722
        GC_free(base);
831
723
    } else {
832
 
        register hdr * hhdr = HDR(p);
 
724
        hdr * hhdr = HDR(p);
833
725
        GC_bool uncollectable = FALSE;
834
726
 
835
727
        if (hhdr ->  hb_obj_kind == UNCOLLECTABLE) {
844
736
            GC_free(base);
845
737
        } else {
846
738
            size_t i;
847
 
            size_t obj_sz = hhdr -> hb_sz - BYTES_TO_WORDS(sizeof(oh));
 
739
            size_t obj_sz = BYTES_TO_WORDS(hhdr -> hb_sz - sizeof(oh));
848
740
 
849
741
            for (i = 0; i < obj_sz; ++i) ((word *)p)[i] = 0xdeadbeef;
850
 
            GC_ASSERT((word *)p + i == (word *)base + hhdr -> hb_sz);
 
742
            GC_ASSERT((word *)p + i == (word *)(base + hhdr -> hb_sz));
851
743
        }
852
744
    } /* !GC_find_leak */
853
745
}
854
746
 
855
747
#ifdef THREADS
856
748
 
857
 
extern void GC_free_inner(GC_PTR p);
 
749
extern void GC_free_inner(void * p);
858
750
 
859
751
/* Used internally; we assume it's called correctly.    */
860
 
void GC_debug_free_inner(GC_PTR p)
 
752
void GC_debug_free_inner(void * p)
861
753
{
862
754
    GC_free_inner(GC_base(p));
863
755
}
864
756
#endif
865
757
 
866
 
# ifdef __STDC__
867
 
    GC_PTR GC_debug_realloc(GC_PTR p, size_t lb, GC_EXTRA_PARAMS)
868
 
# else
869
 
    GC_PTR GC_debug_realloc(p, lb, s, i)
870
 
    GC_PTR p;
871
 
    size_t lb;
872
 
    char *s;
873
 
    int i;
874
 
# endif
 
758
void * GC_debug_realloc(void * p, size_t lb, GC_EXTRA_PARAMS)
875
759
{
876
 
    register GC_PTR base = GC_base(p);
877
 
    register ptr_t clobbered;
878
 
    register GC_PTR result;
879
 
    register size_t copy_sz = lb;
880
 
    register size_t old_sz;
881
 
    register hdr * hhdr;
 
760
    void * base = GC_base(p);
 
761
    ptr_t clobbered;
 
762
    void * result;
 
763
    size_t copy_sz = lb;
 
764
    size_t old_sz;
 
765
    hdr * hhdr;
882
766
    
883
767
    if (p == 0) return(GC_debug_malloc(lb, OPT_RA s, i));
884
768
    if (base == 0) {
885
 
        GC_err_printf1(
886
 
              "Attempt to reallocate invalid pointer %lx\n", (unsigned long)p);
 
769
        GC_err_printf("Attempt to reallocate invalid pointer %p\n", p);
887
770
        ABORT("realloc(invalid pointer)");
888
771
    }
889
772
    if ((ptr_t)p - (ptr_t)base != sizeof(oh)) {
890
 
        GC_err_printf1(
891
 
                "GC_debug_realloc called on pointer %lx wo debugging info\n",
892
 
                (unsigned long)p);
 
773
        GC_err_printf(
 
774
                "GC_debug_realloc called on pointer %p wo debugging info\n", p);
893
775
        return(GC_realloc(p, lb));
894
776
    }
895
777
    hhdr = HDR(base);
914
796
        break;
915
797
#    endif
916
798
      default:
917
 
        GC_err_printf0("GC_debug_realloc: encountered bad kind\n");
 
799
        GC_err_printf("GC_debug_realloc: encountered bad kind\n");
918
800
        ABORT("bad kind");
919
801
    }
920
802
#   ifdef SHORT_DBG_HDRS
922
804
#   else
923
805
      clobbered = GC_check_annotated_obj((oh *)base);
924
806
      if (clobbered != 0) {
925
 
        GC_err_printf0("GC_debug_realloc: found smashed location at ");
 
807
        GC_err_printf("GC_debug_realloc: found smashed location at ");
926
808
        GC_print_smashed_obj(p, clobbered);
927
809
      }
928
810
      old_sz = ((oh *)base) -> oh_sz;
944
826
ptr_t GC_smashed[MAX_SMASHED];
945
827
unsigned GC_n_smashed = 0;
946
828
 
947
 
# if defined(__STDC__) || defined(__cplusplus)
948
 
    void GC_add_smashed(ptr_t smashed)
949
 
# else
950
 
    void GC_add_smashed(smashed)
951
 
    ptr_t smashed;
952
 
#endif
 
829
void GC_add_smashed(ptr_t smashed)
953
830
{
954
831
    GC_ASSERT(GC_is_marked(GC_base(smashed)));
955
832
    GC_smashed[GC_n_smashed] = smashed;
960
837
}
961
838
 
962
839
/* Print all objects on the list.  Clear the list.      */
963
 
void GC_print_all_smashed_proc ()
 
840
void GC_print_all_smashed_proc(void)
964
841
{
965
842
    unsigned i;
966
843
 
967
 
    GC_ASSERT(!I_HOLD_LOCK());
 
844
    GC_ASSERT(I_DONT_HOLD_LOCK());
968
845
    if (GC_n_smashed == 0) return;
969
 
    GC_err_printf0("GC_check_heap_block: found smashed heap objects:\n");
 
846
    GC_err_printf("GC_check_heap_block: found smashed heap objects:\n");
970
847
    for (i = 0; i < GC_n_smashed; ++i) {
971
 
        GC_print_smashed_obj(GC_base(GC_smashed[i]), GC_smashed[i]);
 
848
        GC_print_smashed_obj((ptr_t)GC_base(GC_smashed[i]) + sizeof(oh),
 
849
                             GC_smashed[i]);
972
850
        GC_smashed[i] = 0;
973
851
    }
974
852
    GC_n_smashed = 0;
975
853
}
976
854
 
977
 
/* Check all marked objects in the given block for validity */
 
855
/* Check all marked objects in the given block for validity     */
 
856
/* Avoid GC_apply_to_each_object for performance reasons.       */
978
857
/*ARGSUSED*/
979
 
# if defined(__STDC__) || defined(__cplusplus)
980
 
    void GC_check_heap_block(register struct hblk *hbp, word dummy)
981
 
# else
982
 
    void GC_check_heap_block(hbp, dummy)
983
 
    register struct hblk *hbp;  /* ptr to current heap block            */
984
 
    word dummy;
985
 
# endif
 
858
void GC_check_heap_block(struct hblk *hbp, word dummy)
986
859
{
987
 
    register struct hblkhdr * hhdr = HDR(hbp);
988
 
    register word sz = hhdr -> hb_sz;
989
 
    register int word_no;
990
 
    register word *p, *plim;
 
860
    struct hblkhdr * hhdr = HDR(hbp);
 
861
    size_t sz = hhdr -> hb_sz;
 
862
    size_t bit_no;
 
863
    char *p, *plim;
991
864
    
992
 
    p = (word *)(hbp->hb_body);
993
 
    word_no = 0;
994
 
    if (sz > MAXOBJSZ) {
 
865
    p = hbp->hb_body;
 
866
    bit_no = 0;
 
867
    if (sz > MAXOBJBYTES) {
995
868
        plim = p;
996
869
    } else {
997
 
        plim = (word *)((((word)hbp) + HBLKSIZE) - WORDS_TO_BYTES(sz));
 
870
        plim = hbp->hb_body + HBLKSIZE - sz;
998
871
    }
999
872
    /* go through all words in block */
1000
873
        while( p <= plim ) {
1001
 
            if( mark_bit_from_hdr(hhdr, word_no)
 
874
            if( mark_bit_from_hdr(hhdr, bit_no)
1002
875
                && GC_HAS_DEBUG_INFO((ptr_t)p)) {
1003
876
                ptr_t clobbered = GC_check_annotated_obj((oh *)p);
1004
877
                
1005
878
                if (clobbered != 0) GC_add_smashed(clobbered);
1006
879
            }
1007
 
            word_no += sz;
 
880
            bit_no += MARK_BIT_OFFSET(sz);
1008
881
            p += sz;
1009
882
        }
1010
883
}
1012
885
 
1013
886
/* This assumes that all accessible objects are marked, and that        */
1014
887
/* I hold the allocation lock.  Normally called by collector.           */
1015
 
void GC_check_heap_proc()
 
888
void GC_check_heap_proc(void)
1016
889
{
1017
890
#   ifndef SMALL_CONFIG
1018
 
#     ifdef ALIGN_DOUBLE
1019
 
        GC_STATIC_ASSERT((sizeof(oh) & (2 * sizeof(word) - 1)) == 0);
1020
 
#     else
1021
 
        GC_STATIC_ASSERT((sizeof(oh) & (sizeof(word) - 1)) == 0);
1022
 
#     endif
 
891
      /* Ignore gcc no effect warning on the following.         */
 
892
      GC_STATIC_ASSERT((sizeof(oh) & (GRANULE_BYTES - 1)) == 0);
 
893
      /* FIXME: Should we check for twice that alignment?       */
1023
894
#   endif
1024
895
    GC_apply_to_all_blocks(GC_check_heap_block, (word)0);
1025
896
}
1028
899
 
1029
900
struct closure {
1030
901
    GC_finalization_proc cl_fn;
1031
 
    GC_PTR cl_data;
 
902
    void * cl_data;
1032
903
};
1033
904
 
1034
 
# ifdef __STDC__
1035
 
    void * GC_make_closure(GC_finalization_proc fn, void * data)
1036
 
# else
1037
 
    GC_PTR GC_make_closure(fn, data)
1038
 
    GC_finalization_proc fn;
1039
 
    GC_PTR data;
1040
 
# endif
 
905
void * GC_make_closure(GC_finalization_proc fn, void * data)
1041
906
{
1042
907
    struct closure * result =
1043
908
#   ifdef DBG_HDRS_ALL
1049
914
    
1050
915
    result -> cl_fn = fn;
1051
916
    result -> cl_data = data;
1052
 
    return((GC_PTR)result);
 
917
    return((void *)result);
1053
918
}
1054
919
 
1055
 
# ifdef __STDC__
1056
 
    void GC_debug_invoke_finalizer(void * obj, void * data)
1057
 
# else
1058
 
    void GC_debug_invoke_finalizer(obj, data)
1059
 
    char * obj;
1060
 
    char * data;
1061
 
# endif
 
920
void GC_debug_invoke_finalizer(void * obj, void * data)
1062
921
{
1063
922
    register struct closure * cl = (struct closure *) data;
1064
923
    
1065
 
    (*(cl -> cl_fn))((GC_PTR)((char *)obj + sizeof(oh)), cl -> cl_data);
 
924
    (*(cl -> cl_fn))((void *)((char *)obj + sizeof(oh)), cl -> cl_data);
1066
925
1067
926
 
1068
927
/* Set ofn and ocd to reflect the values we got back.   */
1069
 
static void store_old (obj, my_old_fn, my_old_cd, ofn, ocd)
1070
 
GC_PTR obj;
1071
 
GC_finalization_proc my_old_fn;
1072
 
struct closure * my_old_cd;
1073
 
GC_finalization_proc *ofn;
1074
 
GC_PTR *ocd;
 
928
static void store_old (void *obj, GC_finalization_proc my_old_fn,
 
929
                       struct closure *my_old_cd, GC_finalization_proc *ofn,
 
930
                       void **ocd)
1075
931
{
1076
932
    if (0 != my_old_fn) {
1077
933
      if (my_old_fn != GC_debug_invoke_finalizer) {
1078
 
        GC_err_printf1("Debuggable object at 0x%lx had non-debug finalizer.\n",
1079
 
                       obj);
 
934
        GC_err_printf("Debuggable object at %p had non-debug finalizer.\n",
 
935
                      obj);
1080
936
        /* This should probably be fatal. */
1081
937
      } else {
1082
938
        if (ofn) *ofn = my_old_cd -> cl_fn;
1088
944
    }
1089
945
}
1090
946
 
1091
 
# ifdef __STDC__
1092
 
    void GC_debug_register_finalizer(GC_PTR obj, GC_finalization_proc fn,
1093
 
                                     GC_PTR cd, GC_finalization_proc *ofn,
1094
 
                                     GC_PTR *ocd)
1095
 
# else
1096
 
    void GC_debug_register_finalizer(obj, fn, cd, ofn, ocd)
1097
 
    GC_PTR obj;
1098
 
    GC_finalization_proc fn;
1099
 
    GC_PTR cd;
1100
 
    GC_finalization_proc *ofn;
1101
 
    GC_PTR *ocd;
1102
 
# endif
 
947
void GC_debug_register_finalizer(void * obj, GC_finalization_proc fn,
 
948
                                 void * cd, GC_finalization_proc *ofn,
 
949
                                 void * *ocd)
1103
950
{
1104
951
    GC_finalization_proc my_old_fn;
1105
 
    GC_PTR my_old_cd;
 
952
    void * my_old_cd;
1106
953
    ptr_t base = GC_base(obj);
1107
954
    if (0 == base) return;
1108
955
    if ((ptr_t)obj - base != sizeof(oh)) {
1109
 
        GC_err_printf1(
1110
 
            "GC_debug_register_finalizer called with non-base-pointer 0x%lx\n",
 
956
        GC_err_printf(
 
957
            "GC_debug_register_finalizer called with non-base-pointer %p\n",
1111
958
            obj);
1112
959
    }
1113
960
    if (0 == fn) {
1119
966
    store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
1120
967
}
1121
968
 
1122
 
# ifdef __STDC__
1123
 
    void GC_debug_register_finalizer_no_order
1124
 
                                    (GC_PTR obj, GC_finalization_proc fn,
1125
 
                                     GC_PTR cd, GC_finalization_proc *ofn,
1126
 
                                     GC_PTR *ocd)
1127
 
# else
1128
 
    void GC_debug_register_finalizer_no_order
1129
 
                                    (obj, fn, cd, ofn, ocd)
1130
 
    GC_PTR obj;
1131
 
    GC_finalization_proc fn;
1132
 
    GC_PTR cd;
1133
 
    GC_finalization_proc *ofn;
1134
 
    GC_PTR *ocd;
1135
 
# endif
 
969
void GC_debug_register_finalizer_no_order
 
970
                                    (void * obj, GC_finalization_proc fn,
 
971
                                     void * cd, GC_finalization_proc *ofn,
 
972
                                     void * *ocd)
1136
973
{
1137
974
    GC_finalization_proc my_old_fn;
1138
 
    GC_PTR my_old_cd;
 
975
    void * my_old_cd;
1139
976
    ptr_t base = GC_base(obj);
1140
977
    if (0 == base) return;
1141
978
    if ((ptr_t)obj - base != sizeof(oh)) {
1142
 
        GC_err_printf1(
1143
 
          "GC_debug_register_finalizer_no_order called with non-base-pointer 0x%lx\n",
 
979
        GC_err_printf(
 
980
          "GC_debug_register_finalizer_no_order called with "
 
981
          "non-base-pointer %p\n",
1144
982
          obj);
1145
983
    }
1146
984
    if (0 == fn) {
1151
989
                                     &my_old_cd);
1152
990
    }
1153
991
    store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
1154
 
 }
 
992
}
1155
993
 
1156
 
# ifdef __STDC__
1157
 
    void GC_debug_register_finalizer_ignore_self
1158
 
                                    (GC_PTR obj, GC_finalization_proc fn,
1159
 
                                     GC_PTR cd, GC_finalization_proc *ofn,
1160
 
                                     GC_PTR *ocd)
1161
 
# else
1162
 
    void GC_debug_register_finalizer_ignore_self
1163
 
                                    (obj, fn, cd, ofn, ocd)
1164
 
    GC_PTR obj;
1165
 
    GC_finalization_proc fn;
1166
 
    GC_PTR cd;
1167
 
    GC_finalization_proc *ofn;
1168
 
    GC_PTR *ocd;
1169
 
# endif
 
994
void GC_debug_register_finalizer_unreachable
 
995
                                    (void * obj, GC_finalization_proc fn,
 
996
                                     void * cd, GC_finalization_proc *ofn,
 
997
                                     void * *ocd)
1170
998
{
1171
999
    GC_finalization_proc my_old_fn;
1172
 
    GC_PTR my_old_cd;
 
1000
    void * my_old_cd;
1173
1001
    ptr_t base = GC_base(obj);
1174
1002
    if (0 == base) return;
1175
1003
    if ((ptr_t)obj - base != sizeof(oh)) {
1176
 
        GC_err_printf1(
1177
 
            "GC_debug_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n",
 
1004
        GC_err_printf(
 
1005
            "GC_debug_register_finalizer_unreachable called with "
 
1006
            "non-base-pointer %p\n",
1178
1007
            obj);
1179
1008
    }
1180
1009
    if (0 == fn) {
 
1010
      GC_register_finalizer_unreachable(base, 0, 0, &my_old_fn, &my_old_cd);
 
1011
    } else {
 
1012
      GC_register_finalizer_unreachable(base, GC_debug_invoke_finalizer,
 
1013
                                        GC_make_closure(fn,cd), &my_old_fn,
 
1014
                                        &my_old_cd);
 
1015
    }
 
1016
    store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
 
1017
}
 
1018
 
 
1019
void GC_debug_register_finalizer_ignore_self
 
1020
                                    (void * obj, GC_finalization_proc fn,
 
1021
                                     void * cd, GC_finalization_proc *ofn,
 
1022
                                     void * *ocd)
 
1023
{
 
1024
    GC_finalization_proc my_old_fn;
 
1025
    void * my_old_cd;
 
1026
    ptr_t base = GC_base(obj);
 
1027
    if (0 == base) return;
 
1028
    if ((ptr_t)obj - base != sizeof(oh)) {
 
1029
        GC_err_printf(
 
1030
            "GC_debug_register_finalizer_ignore_self called with "
 
1031
            "non-base-pointer %p\n", obj);
 
1032
    }
 
1033
    if (0 == fn) {
1181
1034
      GC_register_finalizer_ignore_self(base, 0, 0, &my_old_fn, &my_old_cd);
1182
1035
    } else {
1183
1036
      GC_register_finalizer_ignore_self(base, GC_debug_invoke_finalizer,
1193
1046
# define RA
1194
1047
#endif
1195
1048
 
1196
 
GC_PTR GC_debug_malloc_replacement(lb)
1197
 
size_t lb;
 
1049
void * GC_debug_malloc_replacement(size_t lb)
1198
1050
{
1199
1051
    return GC_debug_malloc(lb, RA "unknown", 0);
1200
1052
}
1201
1053
 
1202
 
GC_PTR GC_debug_realloc_replacement(p, lb)
1203
 
GC_PTR p;
1204
 
size_t lb;
 
1054
void * GC_debug_realloc_replacement(void *p, size_t lb)
1205
1055
{
1206
1056
    return GC_debug_realloc(p, lb, RA "unknown", 0);
1207
1057
}