comparison src/alloc.c @ 1598:ac1be85b4a5f

[xemacs-hg @ 2003-07-31 13:32:24 by crestani] 2003-07-29 Marcus Crestani <crestani@informatik.uni-tuebingen.de> Markus Kaltenbach <makalten@informatik.uni-tuebingen.de> * README.kkcc: Aligned to the changes. * alloc.c: Implemented the kkcc_gc_stack. (kkcc_gc_stack_init): (kkcc_gc_stack_free): (kkcc_gc_stack_realloc): (kkcc_gc_stack_full): (kkcc_gc_stack_empty): (kkcc_gc_stack_push): (kkcc_gc_stack_pop): (kkcc_gc_stack_push_lisp_object): (mark_object_maybe_checking_free): Push objects on kkcc stack instead of marking. (mark_struct_contents): Push objects on kkcc stack instead of marking. (kkcc_marking): KKCC mark algorithm using the kkcc_gc_stack. (mark_object): Removed KKCC ifdefs. (garbage_collect_1): Push objects on kkcc stack instead of marking. * data.c: Added XD_FLAG_NO_KKCC to ephemeron_description and to weak_list_description. * data.c (finish_marking_weak_lists): Push objects on kkcc stack instead of marking. (continue_marking_ephemerons): Push objects on kkcc stack instead of marking. (finish_marking_ephemerons): Push objects on kkcc stack instead of marking. * elhash.c (finish_marking_weak_hash_tables): Push objects on kkcc stack instead of marking. * eval.c: Added XD_FLAG_NO_KKCC to subr_description. * lisp.h: Added prototype for kkcc_gc_stack_push_lisp_object. * profile.c (mark_profiling_info_maphash): Push keys on kkcc stack instead of marking.
author crestani
date Thu, 31 Jul 2003 13:32:26 +0000
parents 03009473262a
children 750821e2c014
comparison
equal deleted inserted replaced
1597:4b6ee17c5f37 1598:ac1be85b4a5f
2948 sizeof (Lisp_Object), 2948 sizeof (Lisp_Object),
2949 lisp_object_description_1 2949 lisp_object_description_1
2950 }; 2950 };
2951 2951
2952 #if defined (USE_KKCC) || defined (PDUMP) 2952 #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 int kkcc_gc_stack_size;
2966 static int kkcc_gc_stack_count;
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 =
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_count = 0;
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 kkcc_gc_stack_size *= 2;
2996 kkcc_gc_stack_ptr =
2997 realloc (kkcc_gc_stack_ptr,
2998 kkcc_gc_stack_size * sizeof (kkcc_gc_stack_entry));
2999 if (!kkcc_gc_stack_ptr)
3000 {
3001 stderr_out ("stack realloc failed for size %d\n", kkcc_gc_stack_size);
3002 exit(23);
3003 }
3004 kkcc_gc_stack_top = kkcc_gc_stack_ptr + kkcc_gc_stack_count - 1;
3005 }
3006
3007 static int
3008 kkcc_gc_stack_full (void)
3009 {
3010 if (kkcc_gc_stack_count > (kkcc_gc_stack_size - 1))
3011 return 1;
3012 return 0;
3013 }
3014
3015 static int
3016 kkcc_gc_stack_empty (void)
3017 {
3018 if (kkcc_gc_stack_count == 0)
3019 return 1;
3020 return 0;
3021 }
3022
3023 static void
3024 kkcc_gc_stack_push (void *data, const struct memory_description *desc)
3025 {
3026 if (kkcc_gc_stack_full ())
3027 kkcc_gc_stack_realloc();
3028
3029 kkcc_gc_stack_top++;
3030 kkcc_gc_stack_count++;
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
3041 kkcc_gc_stack_top--;
3042 kkcc_gc_stack_count--;
3043
3044 return kkcc_gc_stack_top + 1;
3045 }
3046
3047 void
3048 kkcc_gc_stack_push_lisp_object (Lisp_Object obj)
3049 {
3050 if (XTYPE (obj) == Lisp_Type_Record)
3051 {
3052 struct lrecord_header *lheader = XRECORD_LHEADER (obj);
3053 const struct memory_description *desc;
3054 GC_CHECK_LHEADER_INVARIANTS (lheader);
3055 desc = LHEADER_IMPLEMENTATION (lheader)->description;
3056 if (! MARKED_RECORD_HEADER_P (lheader))
3057 {
3058 MARK_RECORD_HEADER (lheader);
3059 kkcc_gc_stack_push((void*) lheader, desc);
3060 }
3061 }
3062 }
2953 3063
2954 /* This function extracts the value of a count variable described somewhere 3064 /* This function extracts the value of a count variable described somewhere
2955 else in the description. It is converted corresponding to the type */ 3065 else in the description. It is converted corresponding to the type */
2956 EMACS_INT 3066 EMACS_INT
2957 lispdesc_indirect_count_1 (EMACS_INT code, 3067 lispdesc_indirect_count_1 (EMACS_INT code,
3191 #ifdef USE_KKCC 3301 #ifdef USE_KKCC
3192 /* The following functions implement the new mark algorithm. 3302 /* The following functions implement the new mark algorithm.
3193 They mark objects according to their descriptions. They 3303 They mark objects according to their descriptions. They
3194 are modeled on the corresponding pdumper procedures. */ 3304 are modeled on the corresponding pdumper procedures. */
3195 3305
3196 static void mark_struct_contents (const void *data,
3197 const struct sized_memory_description *sdesc,
3198 int count);
3199
3200 #ifdef ERROR_CHECK_GC 3306 #ifdef ERROR_CHECK_GC
3201 #define KKCC_DO_CHECK_FREE(obj, allow_free) \ 3307 #define KKCC_DO_CHECK_FREE(obj, allow_free) \
3202 do \ 3308 do \
3203 { \ 3309 { \
3204 if (!allow_free && XTYPE (obj) == Lisp_Type_Record) \ 3310 if (!allow_free && XTYPE (obj) == Lisp_Type_Record) \
3210 #else 3316 #else
3211 #define KKCC_DO_CHECK_FREE(obj, allow_free) 3317 #define KKCC_DO_CHECK_FREE(obj, allow_free)
3212 #endif 3318 #endif
3213 3319
3214 #ifdef ERROR_CHECK_GC 3320 #ifdef ERROR_CHECK_GC
3215 void 3321 static void
3216 mark_object_maybe_checking_free (Lisp_Object obj, int allow_free) 3322 mark_object_maybe_checking_free (Lisp_Object obj, int allow_free)
3217 { 3323 {
3218 KKCC_DO_CHECK_FREE (obj, allow_free); 3324 KKCC_DO_CHECK_FREE (obj, allow_free);
3325 #ifdef USE_KKCC
3326 kkcc_gc_stack_push_lisp_object (obj);
3327 #else /* NOT USE_KKCC */
3219 mark_object (obj); 3328 mark_object (obj);
3329 #endif /* NOT USE_KKCC */
3220 } 3330 }
3221 #else 3331 #else
3222 #define mark_object_maybe_checking_free(obj, allow_free) mark_object (obj) 3332 #define mark_object_maybe_checking_free(obj, allow_free) mark_object (obj)
3223 #endif /* ERROR_CHECK_GC */ 3333 #endif /* ERROR_CHECK_GC */
3224 3334
3225 /* This function is called to mark the elements of an object. It processes
3226 the description of the object and calls mark object with every described
3227 object. */
3228 static void
3229 mark_with_description (const void *data,
3230 const struct memory_description *desc)
3231 {
3232 int pos;
3233 static const Lisp_Object *last_occurred_object = (Lisp_Object *) 0;
3234 static int mark_last_occurred_object = 0;
3235 #ifdef ERROR_CHECK_GC
3236 static int last_occurred_flags;
3237 #endif
3238
3239 tail_recurse:
3240
3241 for (pos = 0; desc[pos].type != XD_END; pos++)
3242 {
3243 const struct memory_description *desc1 = &desc[pos];
3244 const void *rdata =
3245 (const char *) data + lispdesc_indirect_count (desc1->offset,
3246 desc, data);
3247 union_switcheroo:
3248
3249 /* If the flag says don't mark, then don't mark. */
3250 if ((desc1->flags) & XD_FLAG_NO_KKCC)
3251 continue;
3252
3253 switch (desc1->type)
3254 {
3255 case XD_BYTECOUNT:
3256 case XD_ELEMCOUNT:
3257 case XD_HASHCODE:
3258 case XD_INT:
3259 case XD_LONG:
3260 case XD_INT_RESET:
3261 case XD_LO_LINK:
3262 case XD_OPAQUE_PTR:
3263 case XD_OPAQUE_DATA_PTR:
3264 case XD_C_STRING:
3265 case XD_DOC_STRING:
3266 break;
3267 case XD_LISP_OBJECT:
3268 {
3269 const Lisp_Object *stored_obj = (const Lisp_Object *) rdata;
3270
3271 /* Because of the way that tagged objects work (pointers and
3272 Lisp_Objects have the same representation), XD_LISP_OBJECT
3273 can be used for untagged pointers. They might be NULL,
3274 though. */
3275 if (EQ (*stored_obj, Qnull_pointer))
3276 break;
3277
3278 if (desc[pos+1].type == XD_END)
3279 {
3280 mark_last_occurred_object = 1;
3281 last_occurred_object = stored_obj;
3282 #ifdef ERROR_CHECK_GC
3283 last_occurred_flags = desc1->flags;
3284 #endif
3285 break;
3286 }
3287 else
3288 mark_object_maybe_checking_free
3289 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT);
3290
3291 break;
3292 }
3293 case XD_LISP_OBJECT_ARRAY:
3294 {
3295 int i;
3296 EMACS_INT count =
3297 lispdesc_indirect_count (desc1->data1, desc, data);
3298
3299 for (i = 0; i < count; i++)
3300 {
3301 const Lisp_Object *stored_obj =
3302 (const Lisp_Object *) rdata + i;
3303
3304 if (EQ (*stored_obj, Qnull_pointer))
3305 break;
3306
3307 mark_object_maybe_checking_free
3308 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT);
3309 }
3310 break;
3311 }
3312 case XD_STRUCT_PTR:
3313 {
3314 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc,
3315 data);
3316 const struct sized_memory_description *sdesc =
3317 lispdesc_indirect_description (data, desc1->data2);
3318 const char *dobj = * (const char **) rdata;
3319 if (dobj)
3320 mark_struct_contents (dobj, sdesc, count);
3321 break;
3322 }
3323 case XD_STRUCT_ARRAY:
3324 {
3325 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc,
3326 data);
3327 const struct sized_memory_description *sdesc =
3328 lispdesc_indirect_description (data, desc1->data2);
3329
3330 mark_struct_contents (rdata, sdesc, count);
3331 break;
3332 }
3333 case XD_UNION:
3334 case XD_UNION_DYNAMIC_SIZE:
3335 desc1 = lispdesc_process_xd_union (desc1, desc, data);
3336 if (desc1)
3337 goto union_switcheroo;
3338 break;
3339
3340 default:
3341 stderr_out ("Unsupported description type : %d\n", desc1->type);
3342 abort ();
3343 }
3344 }
3345
3346 if (mark_last_occurred_object)
3347 {
3348 Lisp_Object obj = *last_occurred_object;
3349
3350 old_tail_recurse:
3351 /* NOTE: The second parameter isn't even evaluated
3352 non-ERROR_CHECK_GC, so it's OK for the variable not to exist.
3353 */
3354 KKCC_DO_CHECK_FREE
3355 (obj, (last_occurred_flags & XD_FLAG_FREE_LISP_OBJECT) != 0);
3356
3357 if (XTYPE (obj) == Lisp_Type_Record)
3358 {
3359 struct lrecord_header *lheader = XRECORD_LHEADER (obj);
3360
3361 GC_CHECK_LHEADER_INVARIANTS (lheader);
3362
3363 /* All c_readonly objects have their mark bit set,
3364 so that we only need to check the mark bit here. */
3365 if (! MARKED_RECORD_HEADER_P (lheader))
3366 {
3367 MARK_RECORD_HEADER (lheader);
3368
3369 {
3370 desc = LHEADER_IMPLEMENTATION (lheader)->description;
3371 if (desc) /* && !CONSP(obj))*/ /* KKCC cons special case */
3372 {
3373 data = lheader;
3374 mark_last_occurred_object = 0;
3375 goto tail_recurse;
3376 }
3377 else
3378 {
3379 if (RECORD_MARKER (lheader))
3380 {
3381 obj = RECORD_MARKER (lheader) (obj);
3382 if (!NILP (obj)) goto old_tail_recurse;
3383 }
3384 }
3385 }
3386 }
3387 }
3388
3389 mark_last_occurred_object = 0;
3390 }
3391 }
3392 3335
3393 /* This function loops all elements of a struct pointer and calls 3336 /* This function loops all elements of a struct pointer and calls
3394 mark_with_description with each element. */ 3337 mark_with_description with each element. */
3395 static void 3338 static void
3396 mark_struct_contents (const void *data, 3339 mark_struct_contents (const void *data,
3401 Bytecount elsize; 3344 Bytecount elsize;
3402 elsize = lispdesc_structure_size (data, sdesc); 3345 elsize = lispdesc_structure_size (data, sdesc);
3403 3346
3404 for (i = 0; i < count; i++) 3347 for (i = 0; i < count; i++)
3405 { 3348 {
3406 mark_with_description (((char *) data) + elsize * i, 3349 kkcc_gc_stack_push (((char *) data) + elsize * i, sdesc->description);
3407 sdesc->description);
3408 } 3350 }
3409 } 3351 }
3410 3352
3353
3354 /* This function implements the KKCC mark algorithm.
3355 Instead of calling mark_object, all the alive Lisp_Objects are pushed
3356 on the kkcc_gc_stack. This function processes all elements on the stack
3357 according to their descriptions. */
3358 static void
3359 kkcc_marking (void)
3360 {
3361 kkcc_gc_stack_entry *stack_entry = 0;
3362 void *data = 0;
3363 const struct memory_description *desc = 0;
3364 int pos;
3365
3366 while ((stack_entry = kkcc_gc_stack_pop ()) != 0)
3367 {
3368 data = stack_entry->data;
3369 desc = stack_entry->desc;
3370
3371 for (pos = 0; desc[pos].type != XD_END; pos++)
3372 {
3373 const struct memory_description *desc1 = &desc[pos];
3374 const void *rdata =
3375 (const char *) data + lispdesc_indirect_count (desc1->offset,
3376 desc, data);
3377 union_switcheroo:
3378
3379 /* If the flag says don't mark, then don't mark. */
3380 if ((desc1->flags) & XD_FLAG_NO_KKCC)
3381 continue;
3382
3383 switch (desc1->type)
3384 {
3385 case XD_BYTECOUNT:
3386 case XD_ELEMCOUNT:
3387 case XD_HASHCODE:
3388 case XD_INT:
3389 case XD_LONG:
3390 case XD_INT_RESET:
3391 case XD_LO_LINK:
3392 case XD_OPAQUE_PTR:
3393 case XD_OPAQUE_DATA_PTR:
3394 case XD_C_STRING:
3395 case XD_DOC_STRING:
3396 break;
3397 case XD_LISP_OBJECT:
3398 {
3399 const Lisp_Object *stored_obj = (const Lisp_Object *) rdata;
3400
3401 /* Because of the way that tagged objects work (pointers and
3402 Lisp_Objects have the same representation), XD_LISP_OBJECT
3403 can be used for untagged pointers. They might be NULL,
3404 though. */
3405 if (EQ (*stored_obj, Qnull_pointer))
3406 break;
3407 mark_object_maybe_checking_free
3408 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT);
3409
3410 break;
3411 }
3412 case XD_LISP_OBJECT_ARRAY:
3413 {
3414 int i;
3415 EMACS_INT count =
3416 lispdesc_indirect_count (desc1->data1, desc, data);
3417
3418 for (i = 0; i < count; i++)
3419 {
3420 const Lisp_Object *stored_obj =
3421 (const Lisp_Object *) rdata + i;
3422
3423 if (EQ (*stored_obj, Qnull_pointer))
3424 break;
3425
3426 mark_object_maybe_checking_free
3427 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT);
3428 }
3429 break;
3430 }
3431 case XD_STRUCT_PTR:
3432 {
3433 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc,
3434 data);
3435 const struct sized_memory_description *sdesc =
3436 lispdesc_indirect_description (data, desc1->data2);
3437 const char *dobj = * (const char **) rdata;
3438 if (dobj)
3439 mark_struct_contents (dobj, sdesc, count);
3440 break;
3441 }
3442 case XD_STRUCT_ARRAY:
3443 {
3444 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc,
3445 data);
3446 const struct sized_memory_description *sdesc =
3447 lispdesc_indirect_description (data, desc1->data2);
3448
3449 mark_struct_contents (rdata, sdesc, count);
3450 break;
3451 }
3452 case XD_UNION:
3453 case XD_UNION_DYNAMIC_SIZE:
3454 desc1 = lispdesc_process_xd_union (desc1, desc, data);
3455 if (desc1)
3456 goto union_switcheroo;
3457 break;
3458
3459 default:
3460 stderr_out ("Unsupported description type : %d\n", desc1->type);
3461 abort ();
3462 }
3463 }
3464 }
3465 }
3411 #endif /* USE_KKCC */ 3466 #endif /* USE_KKCC */
3412 3467
3413 /* Mark reference to a Lisp_Object. If the object referred to has not been 3468 /* Mark reference to a Lisp_Object. If the object referred to has not been
3414 seen yet, recursively mark all the references contained in it. */ 3469 seen yet, recursively mark all the references contained in it. */
3415 3470
3416 void 3471 void
3417 mark_object (Lisp_Object obj) 3472 mark_object (Lisp_Object obj)
3418 { 3473 {
3474 #ifdef USE_KKCC
3475 /* this code should never be reached when configured for KKCC */
3476 stderr_out ("KKCC: Invalid mark_object call.\n");
3477 stderr_out ("Replace mark_object with kkcc_gc_stack_push_lisp_object.\n");
3478 abort ();
3479 #endif /* USE_KKCC */
3480
3419 tail_recurse: 3481 tail_recurse:
3420 3482
3421 /* Checks we used to perform */ 3483 /* Checks we used to perform */
3422 /* if (EQ (obj, Qnull_pointer)) return; */ 3484 /* if (EQ (obj, Qnull_pointer)) return; */
3423 /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return; */ 3485 /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return; */
3427 { 3489 {
3428 struct lrecord_header *lheader = XRECORD_LHEADER (obj); 3490 struct lrecord_header *lheader = XRECORD_LHEADER (obj);
3429 3491
3430 GC_CHECK_LHEADER_INVARIANTS (lheader); 3492 GC_CHECK_LHEADER_INVARIANTS (lheader);
3431 3493
3432 #ifndef USE_KKCC
3433 /* We handle this separately, above, so we can mark free objects */ 3494 /* We handle this separately, above, so we can mark free objects */
3434 GC_CHECK_NOT_FREE (lheader); 3495 GC_CHECK_NOT_FREE (lheader);
3435 #endif /* not USE_KKCC */
3436 3496
3437 /* All c_readonly objects have their mark bit set, 3497 /* All c_readonly objects have their mark bit set,
3438 so that we only need to check the mark bit here. */ 3498 so that we only need to check the mark bit here. */
3439 if (! MARKED_RECORD_HEADER_P (lheader)) 3499 if (! MARKED_RECORD_HEADER_P (lheader))
3440 { 3500 {
3441 MARK_RECORD_HEADER (lheader); 3501 MARK_RECORD_HEADER (lheader);
3442 3502
3443 { 3503 if (RECORD_MARKER (lheader))
3444 #ifdef USE_KKCC 3504 {
3445 const struct memory_description *desc; 3505 obj = RECORD_MARKER (lheader) (obj);
3446 desc = LHEADER_IMPLEMENTATION (lheader)->description; 3506 if (!NILP (obj)) goto tail_recurse;
3447 if (desc) /* && !CONSP(obj))*/ /* KKCC cons special case */ 3507 }
3448 mark_with_description (lheader, desc);
3449 else
3450 #endif /* USE_KKCC */
3451 {
3452 if (RECORD_MARKER (lheader))
3453 {
3454 obj = RECORD_MARKER (lheader) (obj);
3455 if (!NILP (obj)) goto tail_recurse;
3456 }
3457 }
3458 }
3459 } 3508 }
3460 } 3509 }
3461 } 3510 }
3462 3511
3463
3464 /* Find all structures not marked, and free them. */
3465 3512
3466 static int gc_count_num_short_string_in_use; 3513 static int gc_count_num_short_string_in_use;
3467 static Bytecount gc_count_string_total_size; 3514 static Bytecount gc_count_string_total_size;
3468 static Bytecount gc_count_short_string_total_size; 3515 static Bytecount gc_count_short_string_total_size;
3469 3516
4540 cleanup_specifiers (); 4587 cleanup_specifiers ();
4541 cleanup_buffer_undo_lists (); 4588 cleanup_buffer_undo_lists ();
4542 4589
4543 /* Mark all the special slots that serve as the roots of accessibility. */ 4590 /* Mark all the special slots that serve as the roots of accessibility. */
4544 4591
4592 #ifdef USE_KKCC
4593 /* initialize kkcc stack */
4594 kkcc_gc_stack_init();
4595 #endif /* USE_KKCC */
4596
4545 { /* staticpro() */ 4597 { /* staticpro() */
4546 Lisp_Object **p = Dynarr_begin (staticpros); 4598 Lisp_Object **p = Dynarr_begin (staticpros);
4547 Elemcount count; 4599 Elemcount count;
4548 for (count = Dynarr_length (staticpros); count; count--) 4600 for (count = Dynarr_length (staticpros); count; count--)
4601 #ifdef USE_KKCC
4602 kkcc_gc_stack_push_lisp_object (**p++);
4603 #else /* NOT USE_KKCC */
4549 mark_object (**p++); 4604 mark_object (**p++);
4605 #endif /* NOT USE_KKCC */
4550 } 4606 }
4551 4607
4552 { /* staticpro_nodump() */ 4608 { /* staticpro_nodump() */
4553 Lisp_Object **p = Dynarr_begin (staticpros_nodump); 4609 Lisp_Object **p = Dynarr_begin (staticpros_nodump);
4554 Elemcount count; 4610 Elemcount count;
4555 for (count = Dynarr_length (staticpros_nodump); count; count--) 4611 for (count = Dynarr_length (staticpros_nodump); count; count--)
4612 #ifdef USE_KKCC
4613 kkcc_gc_stack_push_lisp_object (**p++);
4614 #else /* NOT USE_KKCC */
4556 mark_object (**p++); 4615 mark_object (**p++);
4616 #endif /* NOT USE_KKCC */
4557 } 4617 }
4558 4618
4559 { /* GCPRO() */ 4619 { /* GCPRO() */
4560 struct gcpro *tail; 4620 struct gcpro *tail;
4561 int i; 4621 int i;
4562 for (tail = gcprolist; tail; tail = tail->next) 4622 for (tail = gcprolist; tail; tail = tail->next)
4563 for (i = 0; i < tail->nvars; i++) 4623 for (i = 0; i < tail->nvars; i++)
4624 #ifdef USE_KKCC
4625 kkcc_gc_stack_push_lisp_object (tail->var[i]);
4626 #else /* NOT USE_KKCC */
4564 mark_object (tail->var[i]); 4627 mark_object (tail->var[i]);
4628 #endif /* NOT USE_KKCC */
4565 } 4629 }
4566 4630
4567 { /* specbind() */ 4631 { /* specbind() */
4568 struct specbinding *bind; 4632 struct specbinding *bind;
4569 for (bind = specpdl; bind != specpdl_ptr; bind++) 4633 for (bind = specpdl; bind != specpdl_ptr; bind++)
4570 { 4634 {
4635 #ifdef USE_KKCC
4636 kkcc_gc_stack_push_lisp_object (bind->symbol);
4637 kkcc_gc_stack_push_lisp_object (bind->old_value);
4638 #else /* NOT USE_KKCC */
4571 mark_object (bind->symbol); 4639 mark_object (bind->symbol);
4572 mark_object (bind->old_value); 4640 mark_object (bind->old_value);
4641 #endif /* NOT USE_KKCC */
4573 } 4642 }
4574 } 4643 }
4575 4644
4576 { 4645 {
4577 struct catchtag *catch; 4646 struct catchtag *catch;
4578 for (catch = catchlist; catch; catch = catch->next) 4647 for (catch = catchlist; catch; catch = catch->next)
4579 { 4648 {
4649 #ifdef USE_KKCC
4650 kkcc_gc_stack_push_lisp_object (catch->tag);
4651 kkcc_gc_stack_push_lisp_object (catch->val);
4652 kkcc_gc_stack_push_lisp_object (catch->actual_tag);
4653 #else /* NOT USE_KKCC */
4580 mark_object (catch->tag); 4654 mark_object (catch->tag);
4581 mark_object (catch->val); 4655 mark_object (catch->val);
4582 mark_object (catch->actual_tag); 4656 mark_object (catch->actual_tag);
4657 #endif /* NOT USE_KKCC */
4583 } 4658 }
4584 } 4659 }
4585 4660
4586 { 4661 {
4587 struct backtrace *backlist; 4662 struct backtrace *backlist;
4588 for (backlist = backtrace_list; backlist; backlist = backlist->next) 4663 for (backlist = backtrace_list; backlist; backlist = backlist->next)
4589 { 4664 {
4590 int nargs = backlist->nargs; 4665 int nargs = backlist->nargs;
4591 int i; 4666 int i;
4592 4667
4668 #ifdef USE_KKCC
4669 kkcc_gc_stack_push_lisp_object (*backlist->function);
4670 if (nargs < 0 /* nargs == UNEVALLED || nargs == MANY */
4671 /* might be fake (internal profiling entry) */
4672 && backlist->args)
4673 kkcc_gc_stack_push_lisp_object (backlist->args[0]);
4674 else
4675 for (i = 0; i < nargs; i++)
4676 kkcc_gc_stack_push_lisp_object (backlist->args[i]);
4677 #else /* NOT USE_KKCC */
4593 mark_object (*backlist->function); 4678 mark_object (*backlist->function);
4594 if (nargs < 0 /* nargs == UNEVALLED || nargs == MANY */ 4679 if (nargs < 0 /* nargs == UNEVALLED || nargs == MANY */
4595 /* might be fake (internal profiling entry) */ 4680 /* might be fake (internal profiling entry) */
4596 && backlist->args) 4681 && backlist->args)
4597 mark_object (backlist->args[0]); 4682 mark_object (backlist->args[0]);
4598 else 4683 else
4599 for (i = 0; i < nargs; i++) 4684 for (i = 0; i < nargs; i++)
4600 mark_object (backlist->args[i]); 4685 mark_object (backlist->args[i]);
4686 #endif /* NOT USE_KKCC */
4601 } 4687 }
4602 } 4688 }
4603 4689
4604 mark_profiling_info (); 4690 mark_profiling_info ();
4605 4691
4607 are only marked when something else is marked (e.g. weak hash tables). 4693 are only marked when something else is marked (e.g. weak hash tables).
4608 There may be complex dependencies between such objects -- e.g. 4694 There may be complex dependencies between such objects -- e.g.
4609 a weak hash table might be unmarked, but after processing a later 4695 a weak hash table might be unmarked, but after processing a later
4610 weak hash table, the former one might get marked. So we have to 4696 weak hash table, the former one might get marked. So we have to
4611 iterate until nothing more gets marked. */ 4697 iterate until nothing more gets marked. */
4612 4698 #ifdef USE_KKCC
4699 kkcc_marking ();
4700 #endif /* USE_KKCC */
4613 init_marking_ephemerons (); 4701 init_marking_ephemerons ();
4614 while (finish_marking_weak_hash_tables () > 0 || 4702 while (finish_marking_weak_hash_tables () > 0 ||
4615 finish_marking_weak_lists () > 0 || 4703 finish_marking_weak_lists () > 0 ||
4616 continue_marking_ephemerons () > 0) 4704 continue_marking_ephemerons () > 0)
4617 ; 4705 ;
4706
4707 #ifdef USE_KKCC
4708 kkcc_marking ();
4709 kkcc_gc_stack_free ();
4710 #endif /* USE_KKCC */
4618 4711
4619 /* At this point, we know which objects need to be finalized: we 4712 /* At this point, we know which objects need to be finalized: we
4620 still need to resurrect them */ 4713 still need to resurrect them */
4621 4714
4622 while (finish_marking_ephemerons () > 0 || 4715 while (finish_marking_ephemerons () > 0 ||