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

« back to all changes in this revision

Viewing changes to typd_mlc.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger
  • Date: 2011-02-19 12:19:56 UTC
  • mfrom: (1.3.2 upstream) (0.1.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20110219121956-67rb69xlt5nud3v2
Tags: 1:7.1-5
Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
65
65
    struct LeafDescriptor {     /* Describes simple array       */
66
66
        word ld_tag;
67
67
#       define LEAF_TAG 1
68
 
        word ld_size;           /* bytes per element    */
 
68
        size_t ld_size;         /* bytes per element    */
69
69
                                /* multiple of ALIGNMENT        */
70
 
        word ld_nelements;      /* Number of elements.  */
 
70
        size_t ld_nelements;    /* Number of elements.  */
71
71
        GC_descr ld_descriptor; /* A simple length, bitmap,     */
72
72
                                /* or procedure descriptor.     */
73
73
    } ld;
74
74
    struct ComplexArrayDescriptor {
75
75
        word ad_tag;
76
76
#       define ARRAY_TAG 2
77
 
        word ad_nelements;
 
77
        size_t ad_nelements;
78
78
        union ComplexDescriptor * ad_element_descr;
79
79
    } ad;
80
80
    struct SequenceDescriptor {
89
89
ext_descr * GC_ext_descriptors; /* Points to array of extended  */
90
90
                                /* descriptors.                 */
91
91
 
92
 
word GC_ed_size = 0;    /* Current size of above arrays.        */
 
92
size_t GC_ed_size = 0;  /* Current size of above arrays.        */
93
93
# define ED_INITIAL_SIZE 100;
94
94
 
95
 
word GC_avail_descr = 0;        /* Next available slot.         */
 
95
size_t GC_avail_descr = 0;      /* Next available slot.         */
96
96
 
97
97
int GC_typed_mark_proc_index;   /* Indices of my mark           */
98
98
int GC_array_mark_proc_index;   /* procedures.                  */
99
99
 
 
100
static void GC_push_typed_structures_proc (void)
 
101
{
 
102
  GC_push_all((ptr_t)&GC_ext_descriptors, (ptr_t)&GC_ext_descriptors + sizeof(word));
 
103
}
 
104
 
100
105
/* Add a multiword bitmap to GC_ext_descriptors arrays.  Return */
101
106
/* starting index.                                              */
102
107
/* Returns -1 on failure.                                       */
103
108
/* Caller does not hold allocation lock.                        */
104
 
signed_word GC_add_ext_descriptor(bm, nbits)
105
 
GC_bitmap bm;
106
 
word nbits;
 
109
signed_word GC_add_ext_descriptor(GC_bitmap bm, word nbits)
107
110
{
108
 
    register size_t nwords = divWORDSZ(nbits + WORDSZ-1);
109
 
    register signed_word result;
110
 
    register word i;
111
 
    register word last_part;
112
 
    register int extra_bits;
 
111
    size_t nwords = divWORDSZ(nbits + WORDSZ-1);
 
112
    signed_word result;
 
113
    size_t i;
 
114
    word last_part;
 
115
    size_t extra_bits;
113
116
    DCL_LOCK_STATE;
114
117
 
115
 
    DISABLE_SIGNALS();
116
118
    LOCK();
117
119
    while (GC_avail_descr + nwords >= GC_ed_size) {
118
120
        ext_descr * new;
119
121
        size_t new_size;
120
122
        word ed_size = GC_ed_size;
121
123
        
122
 
        UNLOCK();
123
 
        ENABLE_SIGNALS();
124
124
        if (ed_size == 0) {
 
125
            GC_push_typed_structures = GC_push_typed_structures_proc;
 
126
            UNLOCK();
125
127
            new_size = ED_INITIAL_SIZE;
126
128
        } else {
 
129
            UNLOCK();
127
130
            new_size = 2 * ed_size;
128
131
            if (new_size > MAX_ENV) return(-1);
129
132
        } 
130
133
        new = (ext_descr *) GC_malloc_atomic(new_size * sizeof(ext_descr));
131
134
        if (new == 0) return(-1);
132
 
        DISABLE_SIGNALS();
133
135
        LOCK();
134
136
        if (ed_size == GC_ed_size) {
135
137
            if (GC_avail_descr != 0) {
154
156
    GC_ext_descriptors[result + i].ed_continued = FALSE;
155
157
    GC_avail_descr += nwords;
156
158
    UNLOCK();
157
 
    ENABLE_SIGNALS();
158
159
    return(result);
159
160
}
160
161
 
166
167
/* The result is known to be short enough to fit into a bitmap          */
167
168
/* descriptor.                                                          */
168
169
/* Descriptor is a GC_DS_LENGTH or GC_DS_BITMAP descriptor.             */
169
 
GC_descr GC_double_descr(descriptor, nwords)
170
 
register GC_descr descriptor;
171
 
register word nwords;
 
170
GC_descr GC_double_descr(GC_descr descriptor, word nwords)
172
171
{
173
172
    if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) {
174
173
        descriptor = GC_bm_table[BYTES_TO_WORDS((word)descriptor)];
198
197
# define LEAF 1
199
198
# define SIMPLE 0
200
199
# define NO_MEM (-1)
201
 
int GC_make_array_descriptor(nelements, size, descriptor,
202
 
                             simple_d, complex_d, leaf)
203
 
word size;
204
 
word nelements;
205
 
GC_descr descriptor;
206
 
GC_descr *simple_d;
207
 
complex_descriptor **complex_d;
208
 
struct LeafDescriptor * leaf;
 
200
int GC_make_array_descriptor(size_t nelements, size_t size, GC_descr descriptor,
 
201
                             GC_descr *simple_d,
 
202
                             complex_descriptor **complex_d,
 
203
                             struct LeafDescriptor * leaf)
209
204
{
210
205
#   define OPT_THRESHOLD 50
211
206
        /* For larger arrays, we try to combine descriptors of adjacent */
212
207
        /* descriptors to speed up marking, and to reduce the amount    */
213
208
        /* of space needed on the mark stack.                           */
214
209
    if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) {
215
 
      if ((word)descriptor == size) {
 
210
      if (descriptor == (GC_descr)size) {
216
211
        *simple_d = nelements * descriptor;
217
212
        return(SIMPLE);
218
213
      } else if ((word)descriptor == 0) {
298
293
    }
299
294
}
300
295
 
301
 
complex_descriptor * GC_make_sequence_descriptor(first, second)
302
 
complex_descriptor * first;
303
 
complex_descriptor * second;
 
296
complex_descriptor * GC_make_sequence_descriptor(complex_descriptor *first,
 
297
                                                 complex_descriptor *second)
304
298
{
305
299
    struct SequenceDescriptor * result =
306
300
        (struct SequenceDescriptor *)
317
311
}
318
312
 
319
313
#ifdef UNDEFINED
320
 
complex_descriptor * GC_make_complex_array_descriptor(nelements, descr)
321
 
word nelements;
322
 
complex_descriptor * descr;
 
314
complex_descriptor * GC_make_complex_array_descriptor(word nelements,
 
315
                                                      complex_descriptor *descr)
323
316
{
324
317
    struct ComplexArrayDescriptor * result =
325
318
        (struct ComplexArrayDescriptor *)
338
331
 
339
332
ptr_t * GC_arobjfreelist;
340
333
 
341
 
mse * GC_typed_mark_proc GC_PROTO((register word * addr,
342
 
                                   register mse * mark_stack_ptr,
343
 
                                   mse * mark_stack_limit,
344
 
                                   word env));
 
334
mse * GC_typed_mark_proc(word * addr, mse * mark_stack_ptr,
 
335
                         mse * mark_stack_limit, word env);
345
336
 
346
 
mse * GC_array_mark_proc GC_PROTO((register word * addr,
347
 
                                   register mse * mark_stack_ptr,
348
 
                                   mse * mark_stack_limit,
349
 
                                   word env));
 
337
mse * GC_array_mark_proc(word * addr, mse * mark_stack_ptr,
 
338
                         mse * mark_stack_limit, word env);
350
339
 
351
340
/* Caller does not hold allocation lock. */
352
 
void GC_init_explicit_typing()
 
341
void GC_init_explicit_typing(void)
353
342
{
354
343
    register int i;
355
344
    DCL_LOCK_STATE;
356
345
 
357
346
    
358
 
#   ifdef PRINTSTATS
359
 
        if (sizeof(struct LeafDescriptor) % sizeof(word) != 0)
360
 
            ABORT("Bad leaf descriptor size");
361
 
#   endif
362
 
    DISABLE_SIGNALS();
 
347
    /* Ignore gcc "no effect" warning.  */
 
348
    GC_STATIC_ASSERT(sizeof(struct LeafDescriptor) % sizeof(word) == 0);
363
349
    LOCK();
364
350
    if (GC_explicit_typing_initialized) {
365
351
      UNLOCK();
366
 
      ENABLE_SIGNALS();
367
352
      return;
368
353
    }
369
354
    GC_explicit_typing_initialized = TRUE;
388
373
          GC_bm_table[i] = d;
389
374
      }
390
375
    UNLOCK();
391
 
    ENABLE_SIGNALS();
392
376
}
393
377
 
394
 
# if defined(__STDC__) || defined(__cplusplus)
395
 
    mse * GC_typed_mark_proc(register word * addr,
396
 
                             register mse * mark_stack_ptr,
397
 
                             mse * mark_stack_limit,
398
 
                             word env)
399
 
# else
400
 
    mse * GC_typed_mark_proc(addr, mark_stack_ptr, mark_stack_limit, env)
401
 
    register word * addr;
402
 
    register mse * mark_stack_ptr;
403
 
    mse * mark_stack_limit;
404
 
    word env;
405
 
# endif
 
378
mse * GC_typed_mark_proc(word * addr, mse * mark_stack_ptr,
 
379
                         mse * mark_stack_limit, word env)
406
380
{
407
 
    register word bm = GC_ext_descriptors[env].ed_bitmap;
408
 
    register word * current_p = addr;
409
 
    register word current;
410
 
    register ptr_t greatest_ha = GC_greatest_plausible_heap_addr;
411
 
    register ptr_t least_ha = GC_least_plausible_heap_addr;
412
 
    
 
381
    word bm = GC_ext_descriptors[env].ed_bitmap;
 
382
    word * current_p = addr;
 
383
    word current;
 
384
    ptr_t greatest_ha = GC_greatest_plausible_heap_addr;
 
385
    ptr_t least_ha = GC_least_plausible_heap_addr;
 
386
    DECLARE_HDR_CACHE;
 
387
 
 
388
    INIT_HDR_CACHE;
413
389
    for (; bm != 0; bm >>= 1, current_p++) {
414
390
        if (bm & 1) {
415
391
            current = *current_p;
429
405
        if (mark_stack_ptr >= mark_stack_limit) {
430
406
            mark_stack_ptr = GC_signal_mark_stack_overflow(mark_stack_ptr);
431
407
        }
432
 
        mark_stack_ptr -> mse_start = addr + WORDSZ;
 
408
        mark_stack_ptr -> mse_start = (ptr_t)(addr + WORDSZ);
433
409
        mark_stack_ptr -> mse_descr =
434
410
                GC_MAKE_PROC(GC_typed_mark_proc_index, env+1);
435
411
    }
439
415
/* Return the size of the object described by d.  It would be faster to */
440
416
/* store this directly, or to compute it as part of                     */
441
417
/* GC_push_complex_descriptor, but hopefully it doesn't matter.         */
442
 
word GC_descr_obj_size(d)
443
 
register complex_descriptor *d;
 
418
word GC_descr_obj_size(complex_descriptor *d)
444
419
{
445
420
    switch(d -> TAG) {
446
421
      case LEAF_TAG:
459
434
 
460
435
/* Push descriptors for the object at addr with complex descriptor d    */
461
436
/* onto the mark stack.  Return 0 if the mark stack overflowed.         */
462
 
mse * GC_push_complex_descriptor(addr, d, msp, msl)
463
 
word * addr;
464
 
register complex_descriptor *d;
465
 
register mse * msp;
466
 
mse * msl;
 
437
mse * GC_push_complex_descriptor(word *addr, complex_descriptor *d,
 
438
                                 mse *msp, mse *msl)
467
439
{
468
440
    register ptr_t current = (ptr_t) addr;
469
441
    register word nelements;
480
452
          sz = d -> ld.ld_size;
481
453
          for (i = 0; i < nelements; i++) {
482
454
              msp++;
483
 
              msp -> mse_start = (word *)current;
 
455
              msp -> mse_start = current;
484
456
              msp -> mse_descr = descr;
485
457
              current += sz;
486
458
          }
518
490
}
519
491
 
520
492
/*ARGSUSED*/
521
 
# if defined(__STDC__) || defined(__cplusplus)
522
 
    mse * GC_array_mark_proc(register word * addr,
523
 
                             register mse * mark_stack_ptr,
524
 
                             mse * mark_stack_limit,
525
 
                             word env)
526
 
# else
527
 
    mse * GC_array_mark_proc(addr, mark_stack_ptr, mark_stack_limit, env)
528
 
    register word * addr;
529
 
    register mse * mark_stack_ptr;
530
 
    mse * mark_stack_limit;
531
 
    word env;
532
 
# endif
 
493
mse * GC_array_mark_proc(word * addr, mse * mark_stack_ptr,
 
494
                         mse * mark_stack_limit, word env)
533
495
{
534
 
    register hdr * hhdr = HDR(addr);
535
 
    register word sz = hhdr -> hb_sz;
536
 
    register complex_descriptor * descr = (complex_descriptor *)(addr[sz-1]);
 
496
    hdr * hhdr = HDR(addr);
 
497
    size_t sz = hhdr -> hb_sz;
 
498
    size_t nwords = BYTES_TO_WORDS(sz);
 
499
    complex_descriptor * descr = (complex_descriptor *)(addr[nwords-1]);
537
500
    mse * orig_mark_stack_ptr = mark_stack_ptr;
538
501
    mse * new_mark_stack_ptr;
539
502
    
554
517
        /* the original array entry.                                    */
555
518
        GC_mark_stack_too_small = TRUE;
556
519
        new_mark_stack_ptr = orig_mark_stack_ptr + 1;
557
 
        new_mark_stack_ptr -> mse_start = addr;
558
 
        new_mark_stack_ptr -> mse_descr = WORDS_TO_BYTES(sz) | GC_DS_LENGTH;
 
520
        new_mark_stack_ptr -> mse_start = (ptr_t)addr;
 
521
        new_mark_stack_ptr -> mse_descr = sz | GC_DS_LENGTH;
559
522
    } else {
560
523
        /* Push descriptor itself */
561
524
        new_mark_stack_ptr++;
562
 
        new_mark_stack_ptr -> mse_start = addr + sz - 1;
 
525
        new_mark_stack_ptr -> mse_start = (ptr_t)(addr + nwords - 1);
563
526
        new_mark_stack_ptr -> mse_descr = sizeof(word) | GC_DS_LENGTH;
564
527
    }
565
 
    return(new_mark_stack_ptr);
 
528
    return new_mark_stack_ptr;
566
529
}
567
530
 
568
 
#if defined(__STDC__) || defined(__cplusplus)
569
 
  GC_descr GC_make_descriptor(GC_bitmap bm, size_t len)
570
 
#else
571
 
  GC_descr GC_make_descriptor(bm, len)
572
 
  GC_bitmap bm;
573
 
  size_t len;
574
 
#endif
 
531
GC_descr GC_make_descriptor(GC_bitmap bm, size_t len)
575
532
{
576
 
    register signed_word last_set_bit = len - 1;
577
 
    register word result;
578
 
    register int i;
 
533
    signed_word last_set_bit = len - 1;
 
534
    GC_descr result;
 
535
    signed_word i;
579
536
#   define HIGH_BIT (((word)1) << (WORDSZ - 1))
580
537
    
581
538
    if (!GC_explicit_typing_initialized) GC_init_explicit_typing();
592
549
      }
593
550
      if (all_bits_set) {
594
551
        /* An initial section contains all pointers.  Use length descriptor. */
595
 
        return(WORDS_TO_BYTES(last_set_bit+1) | GC_DS_LENGTH);
 
552
        return (WORDS_TO_BYTES(last_set_bit+1) | GC_DS_LENGTH);
596
553
      }
597
554
    }
598
555
#   endif
614
571
                                /* Out of memory: use conservative      */
615
572
                                /* approximation.                       */
616
573
        result = GC_MAKE_PROC(GC_typed_mark_proc_index, (word)index);
617
 
        return(result);
 
574
        return result;
618
575
    }
619
576
}
620
577
 
621
578
ptr_t GC_clear_stack();
622
579
 
623
580
#define GENERAL_MALLOC(lb,k) \
624
 
    (GC_PTR)GC_clear_stack(GC_generic_malloc((word)lb, k))
 
581
    (void *)GC_clear_stack(GC_generic_malloc((word)lb, k))
625
582
    
626
583
#define GENERAL_MALLOC_IOP(lb,k) \
627
 
    (GC_PTR)GC_clear_stack(GC_generic_malloc_ignore_off_page(lb, k))
 
584
    (void *)GC_clear_stack(GC_generic_malloc_ignore_off_page(lb, k))
628
585
 
629
 
#if defined(__STDC__) || defined(__cplusplus)
630
 
  void * GC_malloc_explicitly_typed(size_t lb, GC_descr d)
631
 
#else
632
 
  char * GC_malloc_explicitly_typed(lb, d)
633
 
  size_t lb;
634
 
  GC_descr d;
635
 
#endif
 
586
void * GC_malloc_explicitly_typed(size_t lb, GC_descr d)
636
587
{
637
 
register ptr_t op;
638
 
register ptr_t * opp;
639
 
register word lw;
640
 
DCL_LOCK_STATE;
 
588
    ptr_t op;
 
589
    ptr_t * opp;
 
590
    size_t lg;
 
591
    DCL_LOCK_STATE;
641
592
 
642
593
    lb += TYPD_EXTRA_BYTES;
643
 
    if( SMALL_OBJ(lb) ) {
644
 
#       ifdef MERGE_SIZES
645
 
          lw = GC_size_map[lb];
646
 
#       else
647
 
          lw = ALIGNED_WORDS(lb);
648
 
#       endif
649
 
        opp = &(GC_eobjfreelist[lw]);
650
 
        FASTLOCK();
651
 
        if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
652
 
            FASTUNLOCK();
 
594
    if(SMALL_OBJ(lb)) {
 
595
        lg = GC_size_map[lb];
 
596
        opp = &(GC_eobjfreelist[lg]);
 
597
        LOCK();
 
598
        if( (op = *opp) == 0 ) {
 
599
            UNLOCK();
653
600
            op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
654
601
            if (0 == op) return 0;
655
 
#           ifdef MERGE_SIZES
656
 
                lw = GC_size_map[lb];   /* May have been uninitialized. */
657
 
#           endif
 
602
            lg = GC_size_map[lb];       /* May have been uninitialized. */
658
603
        } else {
659
604
            *opp = obj_link(op);
660
605
            obj_link(op) = 0;
661
 
            GC_words_allocd += lw;
662
 
            FASTUNLOCK();
 
606
            GC_bytes_allocd += GRANULES_TO_BYTES(lg);
 
607
            UNLOCK();
663
608
        }
664
609
   } else {
665
610
       op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
666
611
       if (op != NULL)
667
 
            lw = BYTES_TO_WORDS(GC_size(op));
 
612
            lg = BYTES_TO_GRANULES(GC_size(op));
668
613
   }
669
614
   if (op != NULL)
670
 
       ((word *)op)[lw - 1] = d;
671
 
   return((GC_PTR) op);
 
615
       ((word *)op)[GRANULES_TO_WORDS(lg) - 1] = d;
 
616
   return((void *) op);
672
617
}
673
618
 
674
 
#if defined(__STDC__) || defined(__cplusplus)
675
 
  void * GC_malloc_explicitly_typed_ignore_off_page(size_t lb, GC_descr d)
676
 
#else
677
 
  char * GC_malloc_explicitly_typed_ignore_off_page(lb, d)
678
 
  size_t lb;
679
 
  GC_descr d;
680
 
#endif
 
619
void * GC_malloc_explicitly_typed_ignore_off_page(size_t lb, GC_descr d)
681
620
{
682
 
register ptr_t op;
683
 
register ptr_t * opp;
684
 
register word lw;
 
621
ptr_t op;
 
622
ptr_t * opp;
 
623
size_t lg;
685
624
DCL_LOCK_STATE;
686
625
 
687
626
    lb += TYPD_EXTRA_BYTES;
688
627
    if( SMALL_OBJ(lb) ) {
689
 
#       ifdef MERGE_SIZES
690
 
          lw = GC_size_map[lb];
691
 
#       else
692
 
          lw = ALIGNED_WORDS(lb);
693
 
#       endif
694
 
        opp = &(GC_eobjfreelist[lw]);
695
 
        FASTLOCK();
696
 
        if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
697
 
            FASTUNLOCK();
 
628
        lg = GC_size_map[lb];
 
629
        opp = &(GC_eobjfreelist[lg]);
 
630
        LOCK();
 
631
        if( (op = *opp) == 0 ) {
 
632
            UNLOCK();
698
633
            op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind);
699
 
#           ifdef MERGE_SIZES
700
 
                lw = GC_size_map[lb];   /* May have been uninitialized. */
701
 
#           endif
 
634
            lg = GC_size_map[lb];       /* May have been uninitialized. */
702
635
        } else {
703
636
            *opp = obj_link(op);
704
637
            obj_link(op) = 0;
705
 
            GC_words_allocd += lw;
706
 
            FASTUNLOCK();
 
638
            GC_bytes_allocd += GRANULES_TO_BYTES(lg);
 
639
            UNLOCK();
707
640
        }
708
641
   } else {
709
642
       op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind);
710
643
       if (op != NULL)
711
 
       lw = BYTES_TO_WORDS(GC_size(op));
 
644
         lg = BYTES_TO_WORDS(GC_size(op));
712
645
   }
713
646
   if (op != NULL)
714
 
       ((word *)op)[lw - 1] = d;
715
 
   return((GC_PTR) op);
 
647
       ((word *)op)[GRANULES_TO_WORDS(lg) - 1] = d;
 
648
   return((void *) op);
716
649
}
717
650
 
718
 
#if defined(__STDC__) || defined(__cplusplus)
719
 
  void * GC_calloc_explicitly_typed(size_t n,
720
 
                                    size_t lb,
721
 
                                    GC_descr d)
722
 
#else
723
 
  char * GC_calloc_explicitly_typed(n, lb, d)
724
 
  size_t n;
725
 
  size_t lb;
726
 
  GC_descr d;
727
 
#endif
 
651
void * GC_calloc_explicitly_typed(size_t n, size_t lb, GC_descr d)
728
652
{
729
 
register ptr_t op;
730
 
register ptr_t * opp;
731
 
register word lw;
 
653
ptr_t op;
 
654
ptr_t * opp;
 
655
size_t lg;
732
656
GC_descr simple_descr;
733
657
complex_descriptor *complex_descr;
734
658
register int descr_type;
750
674
            break;
751
675
    }
752
676
    if( SMALL_OBJ(lb) ) {
753
 
#       ifdef MERGE_SIZES
754
 
          lw = GC_size_map[lb];
755
 
#       else
756
 
          lw = ALIGNED_WORDS(lb);
757
 
#       endif
758
 
        opp = &(GC_arobjfreelist[lw]);
759
 
        FASTLOCK();
760
 
        if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
761
 
            FASTUNLOCK();
 
677
        lg = GC_size_map[lb];
 
678
        opp = &(GC_arobjfreelist[lg]);
 
679
        LOCK();
 
680
        if( (op = *opp) == 0 ) {
 
681
            UNLOCK();
762
682
            op = (ptr_t)GENERAL_MALLOC((word)lb, GC_array_kind);
763
683
            if (0 == op) return(0);
764
 
#           ifdef MERGE_SIZES
765
 
                lw = GC_size_map[lb];   /* May have been uninitialized. */            
766
 
#           endif
 
684
            lg = GC_size_map[lb];       /* May have been uninitialized. */            
767
685
        } else {
768
686
            *opp = obj_link(op);
769
687
            obj_link(op) = 0;
770
 
            GC_words_allocd += lw;
771
 
            FASTUNLOCK();
 
688
            GC_bytes_allocd += GRANULES_TO_BYTES(lg);
 
689
            UNLOCK();
772
690
        }
773
691
   } else {
774
692
       op = (ptr_t)GENERAL_MALLOC((word)lb, GC_array_kind);
775
693
       if (0 == op) return(0);
776
 
       lw = BYTES_TO_WORDS(GC_size(op));
 
694
       lg = BYTES_TO_GRANULES(GC_size(op));
777
695
   }
778
696
   if (descr_type == LEAF) {
779
697
       /* Set up the descriptor inside the object itself. */
780
 
       VOLATILE struct LeafDescriptor * lp =
 
698
       volatile struct LeafDescriptor * lp =
781
699
           (struct LeafDescriptor *)
782
700
               ((word *)op
783
 
                + lw - (BYTES_TO_WORDS(sizeof(struct LeafDescriptor)) + 1));
 
701
                + GRANULES_TO_WORDS(lg)
 
702
                - (BYTES_TO_WORDS(sizeof(struct LeafDescriptor)) + 1));
784
703
                
785
704
       lp -> ld_tag = LEAF_TAG;
786
705
       lp -> ld_size = leaf.ld_size;
787
706
       lp -> ld_nelements = leaf.ld_nelements;
788
707
       lp -> ld_descriptor = leaf.ld_descriptor;
789
 
       ((VOLATILE word *)op)[lw - 1] = (word)lp;
 
708
       ((volatile word *)op)[GRANULES_TO_WORDS(lg) - 1] = (word)lp;
790
709
   } else {
791
710
       extern unsigned GC_finalization_failures;
792
711
       unsigned ff = GC_finalization_failures;
 
712
       size_t lw = GRANULES_TO_WORDS(lg);
793
713
       
794
714
       ((word *)op)[lw - 1] = (word)complex_descr;
795
715
       /* Make sure the descriptor is cleared once there is any danger  */
796
716
       /* it may have been collected.                                   */
797
717
       (void)
798
 
         GC_general_register_disappearing_link((GC_PTR *)
 
718
         GC_general_register_disappearing_link((void * *)
799
719
                                                  ((word *)op+lw-1),
800
 
                                                  (GC_PTR) op);
 
720
                                                  (void *) op);
801
721
       if (ff != GC_finalization_failures) {
802
722
           /* Couldn't register it due to lack of memory.  Punt.        */
803
723
           /* This will probably fail too, but gives the recovery code  */
805
725
           return(GC_malloc(n*lb));
806
726
       }                                  
807
727
   }
808
 
   return((GC_PTR) op);
 
728
   return((void *) op);
809
729
}