version 1.2, 2000/12/01 09:26:13 |
version 1.3, 2001/04/20 07:39:20 |
|
|
/* |
/* |
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. |
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. |
|
* opyright (c) 1999-2000 by Hewlett-Packard Company. All rights reserved. |
* |
* |
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
|
|
* modified is included with the above copyright notice. |
* modified is included with the above copyright notice. |
* |
* |
*/ |
*/ |
/* Boehm, July 31, 1995 5:02 pm PDT */ |
|
|
|
|
|
/* |
/* |
|
|
* since they are not accessible through the current interface. |
* since they are not accessible through the current interface. |
*/ |
*/ |
|
|
#include "gc_priv.h" |
#include "private/gc_pmark.h" |
#include "gc_mark.h" |
|
#include "gc_typed.h" |
#include "gc_typed.h" |
|
|
# ifdef ADD_BYTE_AT_END |
# define TYPD_EXTRA_BYTES (sizeof(word) - EXTRA_BYTES) |
# define EXTRA_BYTES (sizeof(word) - 1) |
|
# else |
|
# define EXTRA_BYTES (sizeof(word)) |
|
# endif |
|
|
|
GC_bool GC_explicit_typing_initialized = FALSE; |
GC_bool GC_explicit_typing_initialized = FALSE; |
|
|
Line 170 GC_descr GC_bm_table[WORDSZ/2]; |
|
Line 165 GC_descr GC_bm_table[WORDSZ/2]; |
|
/* each of which is described by descriptor. */ |
/* each of which is described by descriptor. */ |
/* The result is known to be short enough to fit into a bitmap */ |
/* The result is known to be short enough to fit into a bitmap */ |
/* descriptor. */ |
/* descriptor. */ |
/* Descriptor is a DS_LENGTH or DS_BITMAP descriptor. */ |
/* Descriptor is a GC_DS_LENGTH or GC_DS_BITMAP descriptor. */ |
GC_descr GC_double_descr(descriptor, nwords) |
GC_descr GC_double_descr(descriptor, nwords) |
register GC_descr descriptor; |
register GC_descr descriptor; |
register word nwords; |
register word nwords; |
{ |
{ |
if (descriptor & DS_TAGS == DS_LENGTH) { |
if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) { |
descriptor = GC_bm_table[BYTES_TO_WORDS((word)descriptor)]; |
descriptor = GC_bm_table[BYTES_TO_WORDS((word)descriptor)]; |
}; |
}; |
descriptor |= (descriptor & ~DS_TAGS) >> nwords; |
descriptor |= (descriptor & ~GC_DS_TAGS) >> nwords; |
return(descriptor); |
return(descriptor); |
} |
} |
|
|
Line 196 complex_descriptor * GC_make_sequence_descriptor(); |
|
Line 191 complex_descriptor * GC_make_sequence_descriptor(); |
|
/* is returned in *simple_d. */ |
/* is returned in *simple_d. */ |
/* If the result is NO_MEM, then */ |
/* If the result is NO_MEM, then */ |
/* we failed to allocate the descriptor. */ |
/* we failed to allocate the descriptor. */ |
/* The implementation knows that DS_LENGTH is 0. */ |
/* The implementation knows that GC_DS_LENGTH is 0. */ |
/* *leaf, *complex_d, and *simple_d may be used as temporaries */ |
/* *leaf, *complex_d, and *simple_d may be used as temporaries */ |
/* during the construction. */ |
/* during the construction. */ |
# define COMPLEX 2 |
# define COMPLEX 2 |
Line 216 struct LeafDescriptor * leaf; |
|
Line 211 struct LeafDescriptor * leaf; |
|
/* For larger arrays, we try to combine descriptors of adjacent */ |
/* For larger arrays, we try to combine descriptors of adjacent */ |
/* descriptors to speed up marking, and to reduce the amount */ |
/* descriptors to speed up marking, and to reduce the amount */ |
/* of space needed on the mark stack. */ |
/* of space needed on the mark stack. */ |
if ((descriptor & DS_TAGS) == DS_LENGTH) { |
if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) { |
if ((word)descriptor == size) { |
if ((word)descriptor == size) { |
*simple_d = nelements * descriptor; |
*simple_d = nelements * descriptor; |
return(SIMPLE); |
return(SIMPLE); |
Line 236 struct LeafDescriptor * leaf; |
|
Line 231 struct LeafDescriptor * leaf; |
|
} |
} |
} |
} |
} else if (size <= BITMAP_BITS/2 |
} else if (size <= BITMAP_BITS/2 |
&& (descriptor & DS_TAGS) != DS_PROC |
&& (descriptor & GC_DS_TAGS) != GC_DS_PROC |
&& (size & (sizeof(word)-1)) == 0) { |
&& (size & (sizeof(word)-1)) == 0) { |
int result = |
int result = |
GC_make_array_descriptor(nelements/2, 2*size, |
GC_make_array_descriptor(nelements/2, 2*size, |
Line 343 ptr_t * GC_eobjfreelist; |
|
Line 338 ptr_t * GC_eobjfreelist; |
|
|
|
ptr_t * GC_arobjfreelist; |
ptr_t * GC_arobjfreelist; |
|
|
mse * GC_typed_mark_proc(); |
mse * GC_typed_mark_proc GC_PROTO((register word * addr, |
|
register mse * mark_stack_ptr, |
|
mse * mark_stack_limit, |
|
word env)); |
|
|
mse * GC_array_mark_proc(); |
mse * GC_array_mark_proc GC_PROTO((register word * addr, |
|
register mse * mark_stack_ptr, |
|
mse * mark_stack_limit, |
|
word env)); |
|
|
GC_descr GC_generic_array_descr; |
GC_descr GC_generic_array_descr; |
|
|
Line 370 void GC_init_explicit_typing() |
|
Line 371 void GC_init_explicit_typing() |
|
GC_explicit_typing_initialized = TRUE; |
GC_explicit_typing_initialized = TRUE; |
/* Set up object kind with simple indirect descriptor. */ |
/* Set up object kind with simple indirect descriptor. */ |
GC_eobjfreelist = (ptr_t *) |
GC_eobjfreelist = (ptr_t *) |
GC_generic_malloc_inner((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); |
GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); |
if (GC_eobjfreelist == 0) ABORT("Couldn't allocate GC_eobjfreelist"); |
if (GC_eobjfreelist == 0) ABORT("Couldn't allocate GC_eobjfreelist"); |
BZERO(GC_eobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); |
BZERO(GC_eobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); |
GC_explicit_kind = GC_n_kinds++; |
GC_explicit_kind = GC_n_kinds++; |
GC_obj_kinds[GC_explicit_kind].ok_freelist = GC_eobjfreelist; |
GC_obj_kinds[GC_explicit_kind].ok_freelist = GC_eobjfreelist; |
GC_obj_kinds[GC_explicit_kind].ok_reclaim_list = 0; |
GC_obj_kinds[GC_explicit_kind].ok_reclaim_list = 0; |
GC_obj_kinds[GC_explicit_kind].ok_descriptor = |
GC_obj_kinds[GC_explicit_kind].ok_descriptor = |
(((word)WORDS_TO_BYTES(-1)) | DS_PER_OBJECT); |
(((word)WORDS_TO_BYTES(-1)) | GC_DS_PER_OBJECT); |
GC_obj_kinds[GC_explicit_kind].ok_relocate_descr = TRUE; |
GC_obj_kinds[GC_explicit_kind].ok_relocate_descr = TRUE; |
GC_obj_kinds[GC_explicit_kind].ok_init = TRUE; |
GC_obj_kinds[GC_explicit_kind].ok_init = TRUE; |
/* Descriptors are in the last word of the object. */ |
/* Descriptors are in the last word of the object. */ |
Line 387 void GC_init_explicit_typing() |
|
Line 388 void GC_init_explicit_typing() |
|
/* Moving this up breaks DEC AXP compiler. */ |
/* Moving this up breaks DEC AXP compiler. */ |
/* Set up object kind with array descriptor. */ |
/* Set up object kind with array descriptor. */ |
GC_arobjfreelist = (ptr_t *) |
GC_arobjfreelist = (ptr_t *) |
GC_generic_malloc_inner((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); |
GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE); |
if (GC_arobjfreelist == 0) ABORT("Couldn't allocate GC_arobjfreelist"); |
if (GC_arobjfreelist == 0) ABORT("Couldn't allocate GC_arobjfreelist"); |
BZERO(GC_arobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); |
BZERO(GC_arobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t)); |
if (GC_n_mark_procs >= MAX_MARK_PROCS) |
if (GC_n_mark_procs >= MAX_MARK_PROCS) |
Line 399 void GC_init_explicit_typing() |
|
Line 400 void GC_init_explicit_typing() |
|
GC_obj_kinds[GC_array_kind].ok_freelist = GC_arobjfreelist; |
GC_obj_kinds[GC_array_kind].ok_freelist = GC_arobjfreelist; |
GC_obj_kinds[GC_array_kind].ok_reclaim_list = 0; |
GC_obj_kinds[GC_array_kind].ok_reclaim_list = 0; |
GC_obj_kinds[GC_array_kind].ok_descriptor = |
GC_obj_kinds[GC_array_kind].ok_descriptor = |
MAKE_PROC(GC_array_mark_proc_index, 0);; |
GC_MAKE_PROC(GC_array_mark_proc_index, 0);; |
GC_obj_kinds[GC_array_kind].ok_relocate_descr = FALSE; |
GC_obj_kinds[GC_array_kind].ok_relocate_descr = FALSE; |
GC_obj_kinds[GC_array_kind].ok_init = TRUE; |
GC_obj_kinds[GC_array_kind].ok_init = TRUE; |
/* Descriptors are in the last word of the object. */ |
/* Descriptors are in the last word of the object. */ |
GC_mark_procs[GC_array_mark_proc_index] = GC_array_mark_proc; |
GC_mark_procs[GC_array_mark_proc_index] = GC_array_mark_proc; |
for (i = 0; i < WORDSZ/2; i++) { |
for (i = 0; i < WORDSZ/2; i++) { |
GC_descr d = (((word)(-1)) >> (WORDSZ - i)) << (WORDSZ - i); |
GC_descr d = (((word)(-1)) >> (WORDSZ - i)) << (WORDSZ - i); |
d |= DS_BITMAP; |
d |= GC_DS_BITMAP; |
GC_bm_table[i] = d; |
GC_bm_table[i] = d; |
} |
} |
GC_generic_array_descr = MAKE_PROC(GC_array_mark_proc_index, 0); |
GC_generic_array_descr = GC_MAKE_PROC(GC_array_mark_proc_index, 0); |
UNLOCK(); |
UNLOCK(); |
ENABLE_SIGNALS(); |
ENABLE_SIGNALS(); |
} |
} |
|
|
mse * GC_typed_mark_proc(addr, mark_stack_ptr, mark_stack_limit, env) |
# if defined(__STDC__) || defined(__cplusplus) |
register word * addr; |
mse * GC_typed_mark_proc(register word * addr, |
register mse * mark_stack_ptr; |
register mse * mark_stack_ptr, |
mse * mark_stack_limit; |
mse * mark_stack_limit, |
word env; |
word env) |
|
# else |
|
mse * GC_typed_mark_proc(addr, mark_stack_ptr, mark_stack_limit, env) |
|
register word * addr; |
|
register mse * mark_stack_ptr; |
|
mse * mark_stack_limit; |
|
word env; |
|
# endif |
{ |
{ |
register word bm = GC_ext_descriptors[env].ed_bitmap; |
register word bm = GC_ext_descriptors[env].ed_bitmap; |
register word * current_p = addr; |
register word * current_p = addr; |
|
|
} |
} |
mark_stack_ptr -> mse_start = addr + WORDSZ; |
mark_stack_ptr -> mse_start = addr + WORDSZ; |
mark_stack_ptr -> mse_descr = |
mark_stack_ptr -> mse_descr = |
MAKE_PROC(GC_typed_mark_proc_index, env+1); |
GC_MAKE_PROC(GC_typed_mark_proc_index, env+1); |
} |
} |
return(mark_stack_ptr); |
return(mark_stack_ptr); |
} |
} |
|
|
} |
} |
|
|
/*ARGSUSED*/ |
/*ARGSUSED*/ |
mse * GC_array_mark_proc(addr, mark_stack_ptr, mark_stack_limit, env) |
# if defined(__STDC__) || defined(__cplusplus) |
register word * addr; |
mse * GC_array_mark_proc(register word * addr, |
register mse * mark_stack_ptr; |
register mse * mark_stack_ptr, |
mse * mark_stack_limit; |
mse * mark_stack_limit, |
word env; |
word env) |
|
# else |
|
mse * GC_array_mark_proc(addr, mark_stack_ptr, mark_stack_limit, env) |
|
register word * addr; |
|
register mse * mark_stack_ptr; |
|
mse * mark_stack_limit; |
|
word env; |
|
# endif |
{ |
{ |
register hdr * hhdr = HDR(addr); |
register hdr * hhdr = HDR(addr); |
register word sz = hhdr -> hb_sz; |
register word sz = hhdr -> hb_sz; |
|
|
GC_mark_stack_too_small = TRUE; |
GC_mark_stack_too_small = TRUE; |
new_mark_stack_ptr = orig_mark_stack_ptr + 1; |
new_mark_stack_ptr = orig_mark_stack_ptr + 1; |
new_mark_stack_ptr -> mse_start = addr; |
new_mark_stack_ptr -> mse_start = addr; |
new_mark_stack_ptr -> mse_descr = WORDS_TO_BYTES(sz) | DS_LENGTH; |
new_mark_stack_ptr -> mse_descr = WORDS_TO_BYTES(sz) | GC_DS_LENGTH; |
} else { |
} else { |
/* Push descriptor itself */ |
/* Push descriptor itself */ |
new_mark_stack_ptr++; |
new_mark_stack_ptr++; |
new_mark_stack_ptr -> mse_start = addr + sz - 1; |
new_mark_stack_ptr -> mse_start = addr + sz - 1; |
new_mark_stack_ptr -> mse_descr = sizeof(word) | DS_LENGTH; |
new_mark_stack_ptr -> mse_descr = sizeof(word) | GC_DS_LENGTH; |
} |
} |
return(new_mark_stack_ptr); |
return(new_mark_stack_ptr); |
} |
} |
|
|
} |
} |
if (all_bits_set) { |
if (all_bits_set) { |
/* An initial section contains all pointers. Use length descriptor. */ |
/* An initial section contains all pointers. Use length descriptor. */ |
return(WORDS_TO_BYTES(last_set_bit+1) | DS_LENGTH); |
return(WORDS_TO_BYTES(last_set_bit+1) | GC_DS_LENGTH); |
} |
} |
} |
} |
# endif |
# endif |
|
|
result >>= 1; |
result >>= 1; |
if (GC_get_bit(bm, i)) result |= HIGH_BIT; |
if (GC_get_bit(bm, i)) result |= HIGH_BIT; |
} |
} |
result |= DS_BITMAP; |
result |= GC_DS_BITMAP; |
return(result); |
return(result); |
} else { |
} else { |
signed_word index; |
signed_word index; |
|
|
index = GC_add_ext_descriptor(bm, (word)last_set_bit+1); |
index = GC_add_ext_descriptor(bm, (word)last_set_bit+1); |
if (index == -1) return(WORDS_TO_BYTES(last_set_bit+1) | DS_LENGTH); |
if (index == -1) return(WORDS_TO_BYTES(last_set_bit+1) | GC_DS_LENGTH); |
/* Out of memory: use conservative */ |
/* Out of memory: use conservative */ |
/* approximation. */ |
/* approximation. */ |
result = MAKE_PROC(GC_typed_mark_proc_index, (word)index); |
result = GC_MAKE_PROC(GC_typed_mark_proc_index, (word)index); |
return(result); |
return(result); |
} |
} |
} |
} |
Line 647 register ptr_t * opp; |
|
Line 662 register ptr_t * opp; |
|
register word lw; |
register word lw; |
DCL_LOCK_STATE; |
DCL_LOCK_STATE; |
|
|
lb += EXTRA_BYTES; |
lb += TYPD_EXTRA_BYTES; |
if( SMALL_OBJ(lb) ) { |
if( SMALL_OBJ(lb) ) { |
# ifdef MERGE_SIZES |
# ifdef MERGE_SIZES |
lw = GC_size_map[lb]; |
lw = GC_size_map[lb]; |
Line 692 register ptr_t * opp; |
|
Line 707 register ptr_t * opp; |
|
register word lw; |
register word lw; |
DCL_LOCK_STATE; |
DCL_LOCK_STATE; |
|
|
lb += EXTRA_BYTES; |
lb += TYPD_EXTRA_BYTES; |
if( SMALL_OBJ(lb) ) { |
if( SMALL_OBJ(lb) ) { |
# ifdef MERGE_SIZES |
# ifdef MERGE_SIZES |
lw = GC_size_map[lb]; |
lw = GC_size_map[lb]; |
|
|
case SIMPLE: return(GC_malloc_explicitly_typed(n*lb, simple_descr)); |
case SIMPLE: return(GC_malloc_explicitly_typed(n*lb, simple_descr)); |
case LEAF: |
case LEAF: |
lb *= n; |
lb *= n; |
lb += sizeof(struct LeafDescriptor) + EXTRA_BYTES; |
lb += sizeof(struct LeafDescriptor) + TYPD_EXTRA_BYTES; |
break; |
break; |
case COMPLEX: |
case COMPLEX: |
lb *= n; |
lb *= n; |
lb += EXTRA_BYTES; |
lb += TYPD_EXTRA_BYTES; |
break; |
break; |
} |
} |
if( SMALL_OBJ(lb) ) { |
if( SMALL_OBJ(lb) ) { |