65
65
struct LeafDescriptor { /* Describes simple array */
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. */
74
74
struct ComplexArrayDescriptor {
76
76
# define ARRAY_TAG 2
78
78
union ComplexDescriptor * ad_element_descr;
80
80
struct SequenceDescriptor {
89
89
ext_descr * GC_ext_descriptors; /* Points to array of extended */
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;
95
word GC_avail_descr = 0; /* Next available slot. */
95
size_t GC_avail_descr = 0; /* Next available slot. */
97
97
int GC_typed_mark_proc_index; /* Indices of my mark */
98
98
int GC_array_mark_proc_index; /* procedures. */
100
static void GC_push_typed_structures_proc (void)
102
GC_push_all((ptr_t)&GC_ext_descriptors, (ptr_t)&GC_ext_descriptors + sizeof(word));
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)
109
signed_word GC_add_ext_descriptor(GC_bitmap bm, word nbits)
108
register size_t nwords = divWORDSZ(nbits + WORDSZ-1);
109
register signed_word result;
111
register word last_part;
112
register int extra_bits;
111
size_t nwords = divWORDSZ(nbits + WORDSZ-1);
117
119
while (GC_avail_descr + nwords >= GC_ed_size) {
120
122
word ed_size = GC_ed_size;
124
124
if (ed_size == 0) {
125
GC_push_typed_structures = GC_push_typed_structures_proc;
125
127
new_size = ED_INITIAL_SIZE;
127
130
new_size = 2 * ed_size;
128
131
if (new_size > MAX_ENV) return(-1);
130
133
new = (ext_descr *) GC_malloc_atomic(new_size * sizeof(ext_descr));
131
134
if (new == 0) return(-1);
134
136
if (ed_size == GC_ed_size) {
135
137
if (GC_avail_descr != 0) {
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)
173
172
if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) {
174
173
descriptor = GC_bm_table[BYTES_TO_WORDS((word)descriptor)];
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)
207
complex_descriptor **complex_d;
208
struct LeafDescriptor * leaf;
200
int GC_make_array_descriptor(size_t nelements, size_t size, GC_descr descriptor,
202
complex_descriptor **complex_d,
203
struct LeafDescriptor * leaf)
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;
218
213
} else if ((word)descriptor == 0) {
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)
305
299
struct SequenceDescriptor * result =
306
300
(struct SequenceDescriptor *)
339
332
ptr_t * GC_arobjfreelist;
341
mse * GC_typed_mark_proc GC_PROTO((register word * addr,
342
register mse * mark_stack_ptr,
343
mse * mark_stack_limit,
334
mse * GC_typed_mark_proc(word * addr, mse * mark_stack_ptr,
335
mse * mark_stack_limit, word env);
346
mse * GC_array_mark_proc GC_PROTO((register word * addr,
347
register mse * mark_stack_ptr,
348
mse * mark_stack_limit,
337
mse * GC_array_mark_proc(word * addr, mse * mark_stack_ptr,
338
mse * mark_stack_limit, word env);
351
340
/* Caller does not hold allocation lock. */
352
void GC_init_explicit_typing()
341
void GC_init_explicit_typing(void)
359
if (sizeof(struct LeafDescriptor) % sizeof(word) != 0)
360
ABORT("Bad leaf descriptor size");
347
/* Ignore gcc "no effect" warning. */
348
GC_STATIC_ASSERT(sizeof(struct LeafDescriptor) % sizeof(word) == 0);
364
350
if (GC_explicit_typing_initialized) {
369
354
GC_explicit_typing_initialized = TRUE;
388
373
GC_bm_table[i] = d;
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,
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;
378
mse * GC_typed_mark_proc(word * addr, mse * mark_stack_ptr,
379
mse * mark_stack_limit, word env)
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;
381
word bm = GC_ext_descriptors[env].ed_bitmap;
382
word * current_p = addr;
384
ptr_t greatest_ha = GC_greatest_plausible_heap_addr;
385
ptr_t least_ha = GC_least_plausible_heap_addr;
413
389
for (; bm != 0; bm >>= 1, current_p++) {
415
391
current = *current_p;
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)
464
register complex_descriptor *d;
437
mse * GC_push_complex_descriptor(word *addr, complex_descriptor *d,
468
440
register ptr_t current = (ptr_t) addr;
469
441
register word nelements;
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,
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;
493
mse * GC_array_mark_proc(word * addr, mse * mark_stack_ptr,
494
mse * mark_stack_limit, word env)
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;
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;
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;
565
return(new_mark_stack_ptr);
528
return new_mark_stack_ptr;
568
#if defined(__STDC__) || defined(__cplusplus)
569
GC_descr GC_make_descriptor(GC_bitmap bm, size_t len)
571
GC_descr GC_make_descriptor(bm, len)
531
GC_descr GC_make_descriptor(GC_bitmap bm, size_t len)
576
register signed_word last_set_bit = len - 1;
577
register word result;
533
signed_word last_set_bit = len - 1;
579
536
# define HIGH_BIT (((word)1) << (WORDSZ - 1))
581
538
if (!GC_explicit_typing_initialized) GC_init_explicit_typing();
614
571
/* Out of memory: use conservative */
615
572
/* approximation. */
616
573
result = GC_MAKE_PROC(GC_typed_mark_proc_index, (word)index);
621
578
ptr_t GC_clear_stack();
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))
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))
629
#if defined(__STDC__) || defined(__cplusplus)
630
void * GC_malloc_explicitly_typed(size_t lb, GC_descr d)
632
char * GC_malloc_explicitly_typed(lb, d)
586
void * GC_malloc_explicitly_typed(size_t lb, GC_descr d)
638
register ptr_t * opp;
642
593
lb += TYPD_EXTRA_BYTES;
643
if( SMALL_OBJ(lb) ) {
645
lw = GC_size_map[lb];
647
lw = ALIGNED_WORDS(lb);
649
opp = &(GC_eobjfreelist[lw]);
651
if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
595
lg = GC_size_map[lb];
596
opp = &(GC_eobjfreelist[lg]);
598
if( (op = *opp) == 0 ) {
653
600
op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
654
601
if (0 == op) return 0;
656
lw = GC_size_map[lb]; /* May have been uninitialized. */
602
lg = GC_size_map[lb]; /* May have been uninitialized. */
659
604
*opp = obj_link(op);
660
605
obj_link(op) = 0;
661
GC_words_allocd += lw;
606
GC_bytes_allocd += GRANULES_TO_BYTES(lg);
665
610
op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
667
lw = BYTES_TO_WORDS(GC_size(op));
612
lg = BYTES_TO_GRANULES(GC_size(op));
670
((word *)op)[lw - 1] = d;
615
((word *)op)[GRANULES_TO_WORDS(lg) - 1] = d;
674
#if defined(__STDC__) || defined(__cplusplus)
675
void * GC_malloc_explicitly_typed_ignore_off_page(size_t lb, GC_descr d)
677
char * GC_malloc_explicitly_typed_ignore_off_page(lb, d)
619
void * GC_malloc_explicitly_typed_ignore_off_page(size_t lb, GC_descr d)
683
register ptr_t * opp;
687
626
lb += TYPD_EXTRA_BYTES;
688
627
if( SMALL_OBJ(lb) ) {
690
lw = GC_size_map[lb];
692
lw = ALIGNED_WORDS(lb);
694
opp = &(GC_eobjfreelist[lw]);
696
if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
628
lg = GC_size_map[lb];
629
opp = &(GC_eobjfreelist[lg]);
631
if( (op = *opp) == 0 ) {
698
633
op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind);
700
lw = GC_size_map[lb]; /* May have been uninitialized. */
634
lg = GC_size_map[lb]; /* May have been uninitialized. */
703
636
*opp = obj_link(op);
704
637
obj_link(op) = 0;
705
GC_words_allocd += lw;
638
GC_bytes_allocd += GRANULES_TO_BYTES(lg);
709
642
op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind);
711
lw = BYTES_TO_WORDS(GC_size(op));
644
lg = BYTES_TO_WORDS(GC_size(op));
714
((word *)op)[lw - 1] = d;
647
((word *)op)[GRANULES_TO_WORDS(lg) - 1] = d;
718
#if defined(__STDC__) || defined(__cplusplus)
719
void * GC_calloc_explicitly_typed(size_t n,
723
char * GC_calloc_explicitly_typed(n, lb, d)
651
void * GC_calloc_explicitly_typed(size_t n, size_t lb, GC_descr d)
730
register ptr_t * opp;
732
656
GC_descr simple_descr;
733
657
complex_descriptor *complex_descr;
734
658
register int descr_type;
752
676
if( SMALL_OBJ(lb) ) {
754
lw = GC_size_map[lb];
756
lw = ALIGNED_WORDS(lb);
758
opp = &(GC_arobjfreelist[lw]);
760
if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
677
lg = GC_size_map[lb];
678
opp = &(GC_arobjfreelist[lg]);
680
if( (op = *opp) == 0 ) {
762
682
op = (ptr_t)GENERAL_MALLOC((word)lb, GC_array_kind);
763
683
if (0 == op) return(0);
765
lw = GC_size_map[lb]; /* May have been uninitialized. */
684
lg = GC_size_map[lb]; /* May have been uninitialized. */
768
686
*opp = obj_link(op);
769
687
obj_link(op) = 0;
770
GC_words_allocd += lw;
688
GC_bytes_allocd += GRANULES_TO_BYTES(lg);
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));
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 *)
783
+ lw - (BYTES_TO_WORDS(sizeof(struct LeafDescriptor)) + 1));
701
+ GRANULES_TO_WORDS(lg)
702
- (BYTES_TO_WORDS(sizeof(struct LeafDescriptor)) + 1));
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;
791
710
extern unsigned GC_finalization_failures;
792
711
unsigned ff = GC_finalization_failures;
712
size_t lw = GRANULES_TO_WORDS(lg);
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. */
798
GC_general_register_disappearing_link((GC_PTR *)
718
GC_general_register_disappearing_link((void * *)
799
719
((word *)op+lw-1),
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 */