version 1.6, 2002/07/24 08:00:08 |
version 1.7, 2003/06/24 05:11:32 |
|
|
# include <stdlib.h> |
# include <stdlib.h> |
|
|
# if defined(LINUX) || defined(SUNOS4) || defined(SUNOS5) \ |
# if defined(LINUX) || defined(SUNOS4) || defined(SUNOS5) \ |
|| defined(HPUX) || defined(IRIX) || defined(OSF1) |
|| defined(HPUX) || defined(IRIX5) || defined(OSF1) |
# define RANDOM() random() |
# define RANDOM() random() |
# else |
# else |
# define RANDOM() (long)rand() |
# define RANDOM() (long)rand() |
|
|
|
|
#endif /* KEEP_BACK_PTRS */ |
#endif /* KEEP_BACK_PTRS */ |
|
|
|
# define CROSSES_HBLK(p, sz) \ |
|
(((word)(p + sizeof(oh) + sz - 1) ^ (word)p) >= HBLKSIZE) |
/* Store debugging info into p. Return displaced pointer. */ |
/* Store debugging info into p. Return displaced pointer. */ |
/* Assumes we don't hold allocation lock. */ |
/* Assumes we don't hold allocation lock. */ |
ptr_t GC_store_debug_info(p, sz, string, integer) |
ptr_t GC_store_debug_info(p, sz, string, integer) |
|
|
/* But that's expensive. And this way things should only appear */ |
/* But that's expensive. And this way things should only appear */ |
/* inconsistent while we're in the handler. */ |
/* inconsistent while we're in the handler. */ |
LOCK(); |
LOCK(); |
|
GC_ASSERT(GC_size(p) >= sizeof(oh) + sz); |
|
GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz))); |
# ifdef KEEP_BACK_PTRS |
# ifdef KEEP_BACK_PTRS |
((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED); |
((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED); |
# endif |
# endif |
|
|
/* There is some argument that we should disable signals here. */ |
/* There is some argument that we should disable signals here. */ |
/* But that's expensive. And this way things should only appear */ |
/* But that's expensive. And this way things should only appear */ |
/* inconsistent while we're in the handler. */ |
/* inconsistent while we're in the handler. */ |
|
GC_ASSERT(GC_size(p) >= sizeof(oh) + sz); |
|
GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz))); |
# ifdef KEEP_BACK_PTRS |
# ifdef KEEP_BACK_PTRS |
((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED); |
((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED); |
# endif |
# endif |
Line 436 void GC_start_debugging() |
|
Line 442 void GC_start_debugging() |
|
return (GC_store_debug_info(result, (word)lb, s, (word)i)); |
return (GC_store_debug_info(result, (word)lb, s, (word)i)); |
} |
} |
|
|
|
# ifdef __STDC__ |
|
GC_PTR GC_debug_malloc_ignore_off_page(size_t lb, GC_EXTRA_PARAMS) |
|
# else |
|
GC_PTR GC_debug_malloc_ignore_off_page(lb, s, i) |
|
size_t lb; |
|
char * s; |
|
int i; |
|
# ifdef GC_ADD_CALLER |
|
--> GC_ADD_CALLER not implemented for K&R C |
|
# endif |
|
# endif |
|
{ |
|
GC_PTR result = GC_malloc_ignore_off_page(lb + DEBUG_BYTES); |
|
|
|
if (result == 0) { |
|
GC_err_printf1("GC_debug_malloc_ignore_off_page(%ld) returning NIL (", |
|
(unsigned long) lb); |
|
GC_err_puts(s); |
|
GC_err_printf1(":%ld)\n", (unsigned long)i); |
|
return(0); |
|
} |
|
if (!GC_debugging_started) { |
|
GC_start_debugging(); |
|
} |
|
ADD_CALL_CHAIN(result, ra); |
|
return (GC_store_debug_info(result, (word)lb, s, (word)i)); |
|
} |
|
|
|
# ifdef __STDC__ |
|
GC_PTR GC_debug_malloc_atomic_ignore_off_page(size_t lb, GC_EXTRA_PARAMS) |
|
# else |
|
GC_PTR GC_debug_malloc_atomic_ignore_off_page(lb, s, i) |
|
size_t lb; |
|
char * s; |
|
int i; |
|
# ifdef GC_ADD_CALLER |
|
--> GC_ADD_CALLER not implemented for K&R C |
|
# endif |
|
# endif |
|
{ |
|
GC_PTR result = GC_malloc_atomic_ignore_off_page(lb + DEBUG_BYTES); |
|
|
|
if (result == 0) { |
|
GC_err_printf1("GC_debug_malloc_atomic_ignore_off_page(%ld)" |
|
" returning NIL (", (unsigned long) lb); |
|
GC_err_puts(s); |
|
GC_err_printf1(":%ld)\n", (unsigned long)i); |
|
return(0); |
|
} |
|
if (!GC_debugging_started) { |
|
GC_start_debugging(); |
|
} |
|
ADD_CALL_CHAIN(result, ra); |
|
return (GC_store_debug_info(result, (word)lb, s, (word)i)); |
|
} |
|
|
# ifdef DBG_HDRS_ALL |
# ifdef DBG_HDRS_ALL |
/* |
/* |
* An allocation function for internal use. |
* An allocation function for internal use. |
Line 454 void GC_start_debugging() |
|
Line 516 void GC_start_debugging() |
|
(unsigned long) lb); |
(unsigned long) lb); |
return(0); |
return(0); |
} |
} |
ADD_CALL_CHAIN(result, ra); |
ADD_CALL_CHAIN(result, GC_RETURN_ADDR); |
return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0)); |
return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0)); |
} |
} |
|
|
Line 468 void GC_start_debugging() |
|
Line 530 void GC_start_debugging() |
|
(unsigned long) lb); |
(unsigned long) lb); |
return(0); |
return(0); |
} |
} |
ADD_CALL_CHAIN(result, ra); |
ADD_CALL_CHAIN(result, GC_RETURN_ADDR); |
return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0)); |
return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0)); |
} |
} |
# endif |
# endif |
Line 798 unsigned GC_n_smashed = 0; |
|
Line 860 unsigned GC_n_smashed = 0; |
|
ptr_t smashed; |
ptr_t smashed; |
#endif |
#endif |
{ |
{ |
|
GC_ASSERT(GC_is_marked(GC_base(smashed))); |
GC_smashed[GC_n_smashed] = smashed; |
GC_smashed[GC_n_smashed] = smashed; |
if (GC_n_smashed < MAX_SMASHED - 1) ++GC_n_smashed; |
if (GC_n_smashed < MAX_SMASHED - 1) ++GC_n_smashed; |
|
/* In case of overflow, we keep the first MAX_SMASHED-1 */ |
|
/* entries plus the last one. */ |
|
GC_have_errors = TRUE; |
} |
} |
|
|
/* Print all objects on the list. Clear the list. */ |
/* Print all objects on the list. Clear the list. */ |
void GC_print_all_smashed_proc () |
void GC_print_all_smashed_proc () |
{ |
{ |
int i; |
unsigned i; |
|
|
GC_ASSERT(!I_HOLD_LOCK()); |
GC_ASSERT(!I_HOLD_LOCK()); |
if (GC_n_smashed == 0) return; |
if (GC_n_smashed == 0) return; |
Line 858 void GC_print_all_smashed_proc () |
|
Line 924 void GC_print_all_smashed_proc () |
|
void GC_check_heap_proc() |
void GC_check_heap_proc() |
{ |
{ |
# ifndef SMALL_CONFIG |
# ifndef SMALL_CONFIG |
if (sizeof(oh) & (2 * sizeof(word) - 1) != 0) { |
# ifdef ALIGN_DOUBLE |
ABORT("Alignment problem: object header has inappropriate size\n"); |
GC_STATIC_ASSERT((sizeof(oh) & (2 * sizeof(word) - 1)) == 0); |
} |
# else |
|
GC_STATIC_ASSERT((sizeof(oh) & (sizeof(word) - 1)) == 0); |
|
# endif |
# endif |
# endif |
GC_apply_to_all_blocks(GC_check_heap_block, (word)0); |
GC_apply_to_all_blocks(GC_check_heap_block, (word)0); |
} |
} |
Line 881 struct closure { |
|
Line 949 struct closure { |
|
# endif |
# endif |
{ |
{ |
struct closure * result = |
struct closure * result = |
# ifdef DBG_HDRS_ALL |
# ifdef DBG_HDRS_ALL |
(struct closure *) GC_debug_malloc(sizeof (struct closure), |
(struct closure *) GC_debug_malloc(sizeof (struct closure), |
GC_EXTRAS); |
GC_EXTRAS); |
# else |
# else |
(struct closure *) GC_malloc(sizeof (struct closure)); |
(struct closure *) GC_malloc(sizeof (struct closure)); |
# endif |
# endif |
|
|
result -> cl_fn = fn; |
result -> cl_fn = fn; |
result -> cl_data = data; |
result -> cl_data = data; |
|
|
ptr_t base = GC_base(obj); |
ptr_t base = GC_base(obj); |
if (0 == base || (ptr_t)obj - base != sizeof(oh)) { |
if (0 == base || (ptr_t)obj - base != sizeof(oh)) { |
GC_err_printf1( |
GC_err_printf1( |
"GC_register_finalizer called with non-base-pointer 0x%lx\n", |
"GC_debug_register_finalizer called with non-base-pointer 0x%lx\n", |
obj); |
obj); |
} |
} |
if (0 == fn) { |
if (0 == fn) { |
|
|
ptr_t base = GC_base(obj); |
ptr_t base = GC_base(obj); |
if (0 == base || (ptr_t)obj - base != sizeof(oh)) { |
if (0 == base || (ptr_t)obj - base != sizeof(oh)) { |
GC_err_printf1( |
GC_err_printf1( |
"GC_register_finalizer_no_order called with non-base-pointer 0x%lx\n", |
"GC_debug_register_finalizer_no_order called with non-base-pointer 0x%lx\n", |
obj); |
obj); |
} |
} |
if (0 == fn) { |
if (0 == fn) { |
|
|
ptr_t base = GC_base(obj); |
ptr_t base = GC_base(obj); |
if (0 == base || (ptr_t)obj - base != sizeof(oh)) { |
if (0 == base || (ptr_t)obj - base != sizeof(oh)) { |
GC_err_printf1( |
GC_err_printf1( |
"GC_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n", |
"GC_debug_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n", |
obj); |
obj); |
} |
} |
if (0 == fn) { |
if (0 == fn) { |