Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 1676:a72f7bf813c9
[xemacs-hg @ 2003-09-11 09:11:07 by crestani]
2003-09-11 Marcus Crestani <crestani@informatik.uni-tuebingen.de>
* alloc.c: Clean up #ifdef USE_KKCC, move stack code to better
position. Add lrecord_memory_descriptions table.
(KKCC_GC_STACK_FULL): Replace functions with macros.
(KKCC_GC_STACK_EMPTY):
(kkcc_gc_stack_push):
(kkcc_gc_stack_pop):
(kkcc_gc_stack_push_lisp_object):
(mark_object): Add #ifdef to remove unused code.
(garbage_collect_1): Remove some #ifdefs.
* dumper.c (pdump): Dump lrecord_memory_descriptions table.
* lrecord.h: Add lrecord_memory_descriptions.
author | crestani |
---|---|
date | Thu, 11 Sep 2003 09:11:08 +0000 |
parents | 763f577d57b0 |
children | a8d8f419b459 |
comparison
equal
deleted
inserted
replaced
1675:114679353c2f | 1676:a72f7bf813c9 |
---|---|
2775 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. | 2775 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. |
2776 Additional ones may be defined by a module (none yet). We leave some | 2776 Additional ones may be defined by a module (none yet). We leave some |
2777 room in `lrecord_implementations_table' for such new lisp object types. */ | 2777 room in `lrecord_implementations_table' for such new lisp object types. */ |
2778 const struct lrecord_implementation *lrecord_implementations_table[(int)lrecord_type_last_built_in_type + MODULE_DEFINABLE_TYPE_COUNT]; | 2778 const struct lrecord_implementation *lrecord_implementations_table[(int)lrecord_type_last_built_in_type + MODULE_DEFINABLE_TYPE_COUNT]; |
2779 int lrecord_type_count = lrecord_type_last_built_in_type; | 2779 int lrecord_type_count = lrecord_type_last_built_in_type; |
2780 #ifndef USE_KKCC | |
2780 /* Object marker functions are in the lrecord_implementation structure. | 2781 /* Object marker functions are in the lrecord_implementation structure. |
2781 But copying them to a parallel array is much more cache-friendly. | 2782 But copying them to a parallel array is much more cache-friendly. |
2782 This hack speeds up (garbage-collect) by about 5%. */ | 2783 This hack speeds up (garbage-collect) by about 5%. */ |
2783 Lisp_Object (*lrecord_markers[countof (lrecord_implementations_table)]) (Lisp_Object); | 2784 Lisp_Object (*lrecord_markers[countof (lrecord_implementations_table)]) (Lisp_Object); |
2785 #endif /* not USE_KKCC */ | |
2784 | 2786 |
2785 struct gcpro *gcprolist; | 2787 struct gcpro *gcprolist; |
2786 | 2788 |
2787 /* We want the staticpro list relocated, but not the pointers found | 2789 /* We want the staticpro list relocated, but not the pointers found |
2788 therein, because they refer to locations in the global data segment, not | 2790 therein, because they refer to locations in the global data segment, not |
2948 sizeof (Lisp_Object), | 2950 sizeof (Lisp_Object), |
2949 lisp_object_description_1 | 2951 lisp_object_description_1 |
2950 }; | 2952 }; |
2951 | 2953 |
2952 #if defined (USE_KKCC) || defined (PDUMP) | 2954 #if defined (USE_KKCC) || defined (PDUMP) |
2953 | |
2954 /* the initial stack size in kkcc_gc_stack_entries */ | |
2955 #define KKCC_INIT_GC_STACK_SIZE 16384 | |
2956 | |
2957 typedef struct | |
2958 { | |
2959 void *data; | |
2960 const struct memory_description *desc; | |
2961 } kkcc_gc_stack_entry; | |
2962 | |
2963 static kkcc_gc_stack_entry *kkcc_gc_stack_ptr; | |
2964 static kkcc_gc_stack_entry *kkcc_gc_stack_top; | |
2965 static kkcc_gc_stack_entry *kkcc_gc_stack_last_entry; | |
2966 static int kkcc_gc_stack_size; | |
2967 | |
2968 static void | |
2969 kkcc_gc_stack_init (void) | |
2970 { | |
2971 kkcc_gc_stack_size = KKCC_INIT_GC_STACK_SIZE; | |
2972 kkcc_gc_stack_ptr = (kkcc_gc_stack_entry *) | |
2973 malloc (kkcc_gc_stack_size * sizeof (kkcc_gc_stack_entry)); | |
2974 if (!kkcc_gc_stack_ptr) | |
2975 { | |
2976 stderr_out ("stack init failed for size %d\n", kkcc_gc_stack_size); | |
2977 exit(23); | |
2978 } | |
2979 kkcc_gc_stack_top = kkcc_gc_stack_ptr - 1; | |
2980 kkcc_gc_stack_last_entry = kkcc_gc_stack_ptr + kkcc_gc_stack_size - 1; | |
2981 } | |
2982 | |
2983 static void | |
2984 kkcc_gc_stack_free (void) | |
2985 { | |
2986 free (kkcc_gc_stack_ptr); | |
2987 kkcc_gc_stack_ptr = 0; | |
2988 kkcc_gc_stack_top = 0; | |
2989 kkcc_gc_stack_size = 0; | |
2990 } | |
2991 | |
2992 static void | |
2993 kkcc_gc_stack_realloc (void) | |
2994 { | |
2995 int current_offset = (int)(kkcc_gc_stack_top - kkcc_gc_stack_ptr); | |
2996 kkcc_gc_stack_size *= 2; | |
2997 kkcc_gc_stack_ptr = (kkcc_gc_stack_entry *) | |
2998 realloc (kkcc_gc_stack_ptr, | |
2999 kkcc_gc_stack_size * sizeof (kkcc_gc_stack_entry)); | |
3000 if (!kkcc_gc_stack_ptr) | |
3001 { | |
3002 stderr_out ("stack realloc failed for size %d\n", kkcc_gc_stack_size); | |
3003 exit(23); | |
3004 } | |
3005 kkcc_gc_stack_top = kkcc_gc_stack_ptr + current_offset; | |
3006 kkcc_gc_stack_last_entry = kkcc_gc_stack_ptr + kkcc_gc_stack_size - 1; | |
3007 } | |
3008 | |
3009 static int | |
3010 kkcc_gc_stack_full (void) | |
3011 { | |
3012 if (kkcc_gc_stack_top >= kkcc_gc_stack_last_entry) | |
3013 return 1; | |
3014 return 0; | |
3015 } | |
3016 | |
3017 static int | |
3018 kkcc_gc_stack_empty (void) | |
3019 { | |
3020 if (kkcc_gc_stack_top < kkcc_gc_stack_ptr) | |
3021 return 1; | |
3022 return 0; | |
3023 } | |
3024 | |
3025 static void | |
3026 kkcc_gc_stack_push (void *data, const struct memory_description *desc) | |
3027 { | |
3028 if (kkcc_gc_stack_full ()) | |
3029 kkcc_gc_stack_realloc(); | |
3030 kkcc_gc_stack_top++; | |
3031 kkcc_gc_stack_top->data = data; | |
3032 kkcc_gc_stack_top->desc = desc; | |
3033 } | |
3034 | |
3035 static kkcc_gc_stack_entry * | |
3036 kkcc_gc_stack_pop (void) //void *data, const struct memory_description *desc) | |
3037 { | |
3038 if (kkcc_gc_stack_empty ()) | |
3039 return 0; | |
3040 kkcc_gc_stack_top--; | |
3041 return kkcc_gc_stack_top + 1; | |
3042 } | |
3043 | |
3044 void | |
3045 kkcc_gc_stack_push_lisp_object (Lisp_Object obj) | |
3046 { | |
3047 if (XTYPE (obj) == Lisp_Type_Record) | |
3048 { | |
3049 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
3050 const struct memory_description *desc; | |
3051 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
3052 desc = LHEADER_IMPLEMENTATION (lheader)->description; | |
3053 if (! MARKED_RECORD_HEADER_P (lheader)) | |
3054 { | |
3055 MARK_RECORD_HEADER (lheader); | |
3056 kkcc_gc_stack_push((void*) lheader, desc); | |
3057 } | |
3058 } | |
3059 } | |
3060 | 2955 |
3061 /* This function extracts the value of a count variable described somewhere | 2956 /* This function extracts the value of a count variable described somewhere |
3062 else in the description. It is converted corresponding to the type */ | 2957 else in the description. It is converted corresponding to the type */ |
3063 EMACS_INT | 2958 EMACS_INT |
3064 lispdesc_indirect_count_1 (EMACS_INT code, | 2959 lispdesc_indirect_count_1 (EMACS_INT code, |
3298 #ifdef USE_KKCC | 3193 #ifdef USE_KKCC |
3299 /* The following functions implement the new mark algorithm. | 3194 /* The following functions implement the new mark algorithm. |
3300 They mark objects according to their descriptions. They | 3195 They mark objects according to their descriptions. They |
3301 are modeled on the corresponding pdumper procedures. */ | 3196 are modeled on the corresponding pdumper procedures. */ |
3302 | 3197 |
3198 /* Object memory descriptions are in the lrecord_implementation structure. | |
3199 But copying them to a parallel array is much more cache-friendly. */ | |
3200 const struct memory_description *lrecord_memory_descriptions[countof (lrecord_implementations_table)]; | |
3201 | |
3202 /* the initial stack size in kkcc_gc_stack_entries */ | |
3203 #define KKCC_INIT_GC_STACK_SIZE 16384 | |
3204 | |
3205 typedef struct | |
3206 { | |
3207 void *data; | |
3208 const struct memory_description *desc; | |
3209 } kkcc_gc_stack_entry; | |
3210 | |
3211 static kkcc_gc_stack_entry *kkcc_gc_stack_ptr; | |
3212 static kkcc_gc_stack_entry *kkcc_gc_stack_top; | |
3213 static kkcc_gc_stack_entry *kkcc_gc_stack_last_entry; | |
3214 static int kkcc_gc_stack_size; | |
3215 | |
3216 static void | |
3217 kkcc_gc_stack_init (void) | |
3218 { | |
3219 kkcc_gc_stack_size = KKCC_INIT_GC_STACK_SIZE; | |
3220 kkcc_gc_stack_ptr = (kkcc_gc_stack_entry *) | |
3221 malloc (kkcc_gc_stack_size * sizeof (kkcc_gc_stack_entry)); | |
3222 if (!kkcc_gc_stack_ptr) | |
3223 { | |
3224 stderr_out ("stack init failed for size %d\n", kkcc_gc_stack_size); | |
3225 exit(23); | |
3226 } | |
3227 kkcc_gc_stack_top = kkcc_gc_stack_ptr - 1; | |
3228 kkcc_gc_stack_last_entry = kkcc_gc_stack_ptr + kkcc_gc_stack_size - 1; | |
3229 } | |
3230 | |
3231 static void | |
3232 kkcc_gc_stack_free (void) | |
3233 { | |
3234 free (kkcc_gc_stack_ptr); | |
3235 kkcc_gc_stack_ptr = 0; | |
3236 kkcc_gc_stack_top = 0; | |
3237 kkcc_gc_stack_size = 0; | |
3238 } | |
3239 | |
3240 static void | |
3241 kkcc_gc_stack_realloc (void) | |
3242 { | |
3243 int current_offset = (int)(kkcc_gc_stack_top - kkcc_gc_stack_ptr); | |
3244 kkcc_gc_stack_size *= 2; | |
3245 kkcc_gc_stack_ptr = (kkcc_gc_stack_entry *) | |
3246 realloc (kkcc_gc_stack_ptr, | |
3247 kkcc_gc_stack_size * sizeof (kkcc_gc_stack_entry)); | |
3248 if (!kkcc_gc_stack_ptr) | |
3249 { | |
3250 stderr_out ("stack realloc failed for size %d\n", kkcc_gc_stack_size); | |
3251 exit(23); | |
3252 } | |
3253 kkcc_gc_stack_top = kkcc_gc_stack_ptr + current_offset; | |
3254 kkcc_gc_stack_last_entry = kkcc_gc_stack_ptr + kkcc_gc_stack_size - 1; | |
3255 } | |
3256 | |
3257 #define KKCC_GC_STACK_FULL (kkcc_gc_stack_top >= kkcc_gc_stack_last_entry) | |
3258 #define KKCC_GC_STACK_EMPTY (kkcc_gc_stack_top < kkcc_gc_stack_ptr) | |
3259 | |
3260 static void | |
3261 kkcc_gc_stack_push (void *data, const struct memory_description *desc) | |
3262 { | |
3263 if (KKCC_GC_STACK_FULL) | |
3264 kkcc_gc_stack_realloc(); | |
3265 kkcc_gc_stack_top++; | |
3266 kkcc_gc_stack_top->data = data; | |
3267 kkcc_gc_stack_top->desc = desc; | |
3268 } | |
3269 | |
3270 static kkcc_gc_stack_entry * | |
3271 kkcc_gc_stack_pop (void) | |
3272 { | |
3273 if (KKCC_GC_STACK_EMPTY) | |
3274 return 0; | |
3275 kkcc_gc_stack_top--; | |
3276 return kkcc_gc_stack_top + 1; | |
3277 } | |
3278 | |
3279 void | |
3280 kkcc_gc_stack_push_lisp_object (Lisp_Object obj) | |
3281 { | |
3282 if (XTYPE (obj) == Lisp_Type_Record) | |
3283 { | |
3284 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
3285 const struct memory_description *desc; | |
3286 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
3287 desc = RECORD_DESCRIPTION (lheader); | |
3288 if (! MARKED_RECORD_HEADER_P (lheader)) | |
3289 { | |
3290 MARK_RECORD_HEADER (lheader); | |
3291 kkcc_gc_stack_push((void*) lheader, desc); | |
3292 } | |
3293 } | |
3294 } | |
3295 | |
3303 #ifdef ERROR_CHECK_GC | 3296 #ifdef ERROR_CHECK_GC |
3304 #define KKCC_DO_CHECK_FREE(obj, allow_free) \ | 3297 #define KKCC_DO_CHECK_FREE(obj, allow_free) \ |
3305 do \ | 3298 do \ |
3306 { \ | 3299 { \ |
3307 if (!allow_free && XTYPE (obj) == Lisp_Type_Record) \ | 3300 if (!allow_free && XTYPE (obj) == Lisp_Type_Record) \ |
3317 #ifdef ERROR_CHECK_GC | 3310 #ifdef ERROR_CHECK_GC |
3318 static void | 3311 static void |
3319 mark_object_maybe_checking_free (Lisp_Object obj, int allow_free) | 3312 mark_object_maybe_checking_free (Lisp_Object obj, int allow_free) |
3320 { | 3313 { |
3321 KKCC_DO_CHECK_FREE (obj, allow_free); | 3314 KKCC_DO_CHECK_FREE (obj, allow_free); |
3322 #ifdef USE_KKCC | |
3323 kkcc_gc_stack_push_lisp_object (obj); | 3315 kkcc_gc_stack_push_lisp_object (obj); |
3324 #else /* NOT USE_KKCC */ | |
3325 mark_object (obj); | |
3326 #endif /* NOT USE_KKCC */ | |
3327 } | 3316 } |
3328 #else | 3317 #else |
3329 #define mark_object_maybe_checking_free(obj, allow_free) \ | 3318 #define mark_object_maybe_checking_free(obj, allow_free) \ |
3330 kkcc_gc_stack_push_lisp_object (obj) | 3319 kkcc_gc_stack_push_lisp_object (obj) |
3331 #endif /* ERROR_CHECK_GC */ | 3320 #endif /* ERROR_CHECK_GC */ |
3472 #ifdef USE_KKCC | 3461 #ifdef USE_KKCC |
3473 /* this code should never be reached when configured for KKCC */ | 3462 /* this code should never be reached when configured for KKCC */ |
3474 stderr_out ("KKCC: Invalid mark_object call.\n"); | 3463 stderr_out ("KKCC: Invalid mark_object call.\n"); |
3475 stderr_out ("Replace mark_object with kkcc_gc_stack_push_lisp_object.\n"); | 3464 stderr_out ("Replace mark_object with kkcc_gc_stack_push_lisp_object.\n"); |
3476 abort (); | 3465 abort (); |
3477 #endif /* USE_KKCC */ | 3466 #else /* not USE_KKCC */ |
3478 | 3467 |
3479 tail_recurse: | 3468 tail_recurse: |
3480 | 3469 |
3481 /* Checks we used to perform */ | 3470 /* Checks we used to perform */ |
3482 /* if (EQ (obj, Qnull_pointer)) return; */ | 3471 /* if (EQ (obj, Qnull_pointer)) return; */ |
3503 obj = RECORD_MARKER (lheader) (obj); | 3492 obj = RECORD_MARKER (lheader) (obj); |
3504 if (!NILP (obj)) goto tail_recurse; | 3493 if (!NILP (obj)) goto tail_recurse; |
3505 } | 3494 } |
3506 } | 3495 } |
3507 } | 3496 } |
3497 #endif /* not KKCC */ | |
3508 } | 3498 } |
3509 | 3499 |
3510 | 3500 |
3511 static int gc_count_num_short_string_in_use; | 3501 static int gc_count_num_short_string_in_use; |
3512 static Bytecount gc_count_string_total_size; | 3502 static Bytecount gc_count_string_total_size; |
4588 /* Mark all the special slots that serve as the roots of accessibility. */ | 4578 /* Mark all the special slots that serve as the roots of accessibility. */ |
4589 | 4579 |
4590 #ifdef USE_KKCC | 4580 #ifdef USE_KKCC |
4591 /* initialize kkcc stack */ | 4581 /* initialize kkcc stack */ |
4592 kkcc_gc_stack_init(); | 4582 kkcc_gc_stack_init(); |
4583 #define mark_object kkcc_gc_stack_push_lisp_object | |
4593 #endif /* USE_KKCC */ | 4584 #endif /* USE_KKCC */ |
4594 | 4585 |
4595 { /* staticpro() */ | 4586 { /* staticpro() */ |
4596 Lisp_Object **p = Dynarr_begin (staticpros); | 4587 Lisp_Object **p = Dynarr_begin (staticpros); |
4597 Elemcount count; | 4588 Elemcount count; |
4598 for (count = Dynarr_length (staticpros); count; count--) | 4589 for (count = Dynarr_length (staticpros); count; count--) |
4599 #ifdef USE_KKCC | |
4600 kkcc_gc_stack_push_lisp_object (**p++); | |
4601 #else /* NOT USE_KKCC */ | |
4602 mark_object (**p++); | 4590 mark_object (**p++); |
4603 #endif /* NOT USE_KKCC */ | |
4604 } | 4591 } |
4605 | 4592 |
4606 { /* staticpro_nodump() */ | 4593 { /* staticpro_nodump() */ |
4607 Lisp_Object **p = Dynarr_begin (staticpros_nodump); | 4594 Lisp_Object **p = Dynarr_begin (staticpros_nodump); |
4608 Elemcount count; | 4595 Elemcount count; |
4609 for (count = Dynarr_length (staticpros_nodump); count; count--) | 4596 for (count = Dynarr_length (staticpros_nodump); count; count--) |
4610 #ifdef USE_KKCC | |
4611 kkcc_gc_stack_push_lisp_object (**p++); | |
4612 #else /* NOT USE_KKCC */ | |
4613 mark_object (**p++); | 4597 mark_object (**p++); |
4614 #endif /* NOT USE_KKCC */ | |
4615 } | 4598 } |
4616 | 4599 |
4617 { /* GCPRO() */ | 4600 { /* GCPRO() */ |
4618 struct gcpro *tail; | 4601 struct gcpro *tail; |
4619 int i; | 4602 int i; |
4620 for (tail = gcprolist; tail; tail = tail->next) | 4603 for (tail = gcprolist; tail; tail = tail->next) |
4621 for (i = 0; i < tail->nvars; i++) | 4604 for (i = 0; i < tail->nvars; i++) |
4622 #ifdef USE_KKCC | |
4623 kkcc_gc_stack_push_lisp_object (tail->var[i]); | |
4624 #else /* NOT USE_KKCC */ | |
4625 mark_object (tail->var[i]); | 4605 mark_object (tail->var[i]); |
4626 #endif /* NOT USE_KKCC */ | |
4627 } | 4606 } |
4628 | 4607 |
4629 { /* specbind() */ | 4608 { /* specbind() */ |
4630 struct specbinding *bind; | 4609 struct specbinding *bind; |
4631 for (bind = specpdl; bind != specpdl_ptr; bind++) | 4610 for (bind = specpdl; bind != specpdl_ptr; bind++) |
4632 { | 4611 { |
4633 #ifdef USE_KKCC | |
4634 kkcc_gc_stack_push_lisp_object (bind->symbol); | |
4635 kkcc_gc_stack_push_lisp_object (bind->old_value); | |
4636 #else /* NOT USE_KKCC */ | |
4637 mark_object (bind->symbol); | 4612 mark_object (bind->symbol); |
4638 mark_object (bind->old_value); | 4613 mark_object (bind->old_value); |
4639 #endif /* NOT USE_KKCC */ | |
4640 } | 4614 } |
4641 } | 4615 } |
4642 | 4616 |
4643 { | 4617 { |
4644 struct catchtag *catch; | 4618 struct catchtag *catch; |
4645 for (catch = catchlist; catch; catch = catch->next) | 4619 for (catch = catchlist; catch; catch = catch->next) |
4646 { | 4620 { |
4647 #ifdef USE_KKCC | |
4648 kkcc_gc_stack_push_lisp_object (catch->tag); | |
4649 kkcc_gc_stack_push_lisp_object (catch->val); | |
4650 kkcc_gc_stack_push_lisp_object (catch->actual_tag); | |
4651 #else /* NOT USE_KKCC */ | |
4652 mark_object (catch->tag); | 4621 mark_object (catch->tag); |
4653 mark_object (catch->val); | 4622 mark_object (catch->val); |
4654 mark_object (catch->actual_tag); | 4623 mark_object (catch->actual_tag); |
4655 #endif /* NOT USE_KKCC */ | |
4656 } | 4624 } |
4657 } | 4625 } |
4658 | 4626 |
4659 { | 4627 { |
4660 struct backtrace *backlist; | 4628 struct backtrace *backlist; |
4661 for (backlist = backtrace_list; backlist; backlist = backlist->next) | 4629 for (backlist = backtrace_list; backlist; backlist = backlist->next) |
4662 { | 4630 { |
4663 int nargs = backlist->nargs; | 4631 int nargs = backlist->nargs; |
4664 int i; | 4632 int i; |
4665 | 4633 |
4666 #ifdef USE_KKCC | |
4667 kkcc_gc_stack_push_lisp_object (*backlist->function); | |
4668 if (nargs < 0 /* nargs == UNEVALLED || nargs == MANY */ | |
4669 /* might be fake (internal profiling entry) */ | |
4670 && backlist->args) | |
4671 kkcc_gc_stack_push_lisp_object (backlist->args[0]); | |
4672 else | |
4673 for (i = 0; i < nargs; i++) | |
4674 kkcc_gc_stack_push_lisp_object (backlist->args[i]); | |
4675 #else /* NOT USE_KKCC */ | |
4676 mark_object (*backlist->function); | 4634 mark_object (*backlist->function); |
4677 if (nargs < 0 /* nargs == UNEVALLED || nargs == MANY */ | 4635 if (nargs < 0 /* nargs == UNEVALLED || nargs == MANY */ |
4678 /* might be fake (internal profiling entry) */ | 4636 /* might be fake (internal profiling entry) */ |
4679 && backlist->args) | 4637 && backlist->args) |
4680 mark_object (backlist->args[0]); | 4638 mark_object (backlist->args[0]); |
4681 else | 4639 else |
4682 for (i = 0; i < nargs; i++) | 4640 for (i = 0; i < nargs; i++) |
4683 mark_object (backlist->args[i]); | 4641 mark_object (backlist->args[i]); |
4684 #endif /* NOT USE_KKCC */ | |
4685 } | 4642 } |
4686 } | 4643 } |
4687 | 4644 |
4688 mark_profiling_info (); | 4645 mark_profiling_info (); |
4689 | 4646 |
4715 ; | 4672 ; |
4716 | 4673 |
4717 #ifdef USE_KKCC | 4674 #ifdef USE_KKCC |
4718 kkcc_marking (); | 4675 kkcc_marking (); |
4719 kkcc_gc_stack_free (); | 4676 kkcc_gc_stack_free (); |
4677 #undef mark_object | |
4720 #endif /* USE_KKCC */ | 4678 #endif /* USE_KKCC */ |
4721 | 4679 |
4722 /* And prune (this needs to be called after everything else has been | 4680 /* And prune (this needs to be called after everything else has been |
4723 marked and before we do any sweeping). */ | 4681 marked and before we do any sweeping). */ |
4724 /* #### this is somewhat ad-hoc and should probably be an object | 4682 /* #### this is somewhat ad-hoc and should probably be an object |