diff options
| author | Mattias EngdegÄrd | 2023-09-19 21:48:19 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2023-09-20 11:30:31 +0200 |
| commit | 054fc8a5e030d19d3c041391369d727d10287c50 (patch) | |
| tree | 442971f531962df3d14e5fad69fdb18b10c21438 | |
| parent | fb8dfba0f14c5db43fa161103b28764ff198db8f (diff) | |
| download | emacs-054fc8a5e030d19d3c041391369d727d10287c50.tar.gz emacs-054fc8a5e030d19d3c041391369d727d10287c50.zip | |
* src/alloc.c: (cleanup_vector) Dispatch on pseudovector type
Enable the compiler to generate a jump table instead of a chain of
conditional branches.
| -rw-r--r-- | src/alloc.c | 189 |
1 files changed, 115 insertions, 74 deletions
diff --git a/src/alloc.c b/src/alloc.c index addbb54e01f..67b39c5e57d 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3328,93 +3328,134 @@ static void | |||
| 3328 | cleanup_vector (struct Lisp_Vector *vector) | 3328 | cleanup_vector (struct Lisp_Vector *vector) |
| 3329 | { | 3329 | { |
| 3330 | detect_suspicious_free (vector); | 3330 | detect_suspicious_free (vector); |
| 3331 | 3331 | if ((vector->header.size & PSEUDOVECTOR_FLAG) == 0) | |
| 3332 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BIGNUM)) | 3332 | return; /* nothing more to do for plain vectors */ |
| 3333 | mpz_clear (PSEUDOVEC_STRUCT (vector, Lisp_Bignum)->value); | 3333 | switch (PSEUDOVECTOR_TYPE (vector)) |
| 3334 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_OVERLAY)) | ||
| 3335 | { | ||
| 3336 | struct Lisp_Overlay *ol = PSEUDOVEC_STRUCT (vector, Lisp_Overlay); | ||
| 3337 | xfree (ol->interval); | ||
| 3338 | } | ||
| 3339 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FINALIZER)) | ||
| 3340 | unchain_finalizer (PSEUDOVEC_STRUCT (vector, Lisp_Finalizer)); | ||
| 3341 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT)) | ||
| 3342 | { | 3334 | { |
| 3343 | if ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX) | 3335 | case PVEC_BIGNUM: |
| 3344 | { | 3336 | mpz_clear (PSEUDOVEC_STRUCT (vector, Lisp_Bignum)->value); |
| 3345 | struct font *font = PSEUDOVEC_STRUCT (vector, font); | 3337 | break; |
| 3346 | struct font_driver const *drv = font->driver; | 3338 | case PVEC_OVERLAY: |
| 3339 | { | ||
| 3340 | struct Lisp_Overlay *ol = PSEUDOVEC_STRUCT (vector, Lisp_Overlay); | ||
| 3341 | xfree (ol->interval); | ||
| 3342 | } | ||
| 3343 | break; | ||
| 3344 | case PVEC_FINALIZER: | ||
| 3345 | unchain_finalizer (PSEUDOVEC_STRUCT (vector, Lisp_Finalizer)); | ||
| 3346 | break; | ||
| 3347 | case PVEC_FONT: | ||
| 3348 | { | ||
| 3349 | if ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX) | ||
| 3350 | { | ||
| 3351 | struct font *font = PSEUDOVEC_STRUCT (vector, font); | ||
| 3352 | struct font_driver const *drv = font->driver; | ||
| 3347 | 3353 | ||
| 3348 | /* The font driver might sometimes be NULL, e.g. if Emacs was | 3354 | /* The font driver might sometimes be NULL, e.g. if Emacs was |
| 3349 | interrupted before it had time to set it up. */ | 3355 | interrupted before it had time to set it up. */ |
| 3350 | if (drv) | 3356 | if (drv) |
| 3351 | { | 3357 | { |
| 3352 | /* Attempt to catch subtle bugs like Bug#16140. */ | 3358 | /* Attempt to catch subtle bugs like Bug#16140. */ |
| 3353 | eassert (valid_font_driver (drv)); | 3359 | eassert (valid_font_driver (drv)); |
| 3354 | drv->close_font (font); | 3360 | drv->close_font (font); |
| 3355 | } | 3361 | } |
| 3356 | } | 3362 | } |
| 3357 | 3363 | ||
| 3358 | #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY | 3364 | #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY |
| 3359 | /* The Android font driver needs the ability to associate extra | 3365 | /* The Android font driver needs the ability to associate extra |
| 3360 | information with font entities. */ | 3366 | information with font entities. */ |
| 3361 | if (((vector->header.size & PSEUDOVECTOR_SIZE_MASK) | 3367 | if (((vector->header.size & PSEUDOVECTOR_SIZE_MASK) |
| 3362 | == FONT_ENTITY_MAX) | 3368 | == FONT_ENTITY_MAX) |
| 3363 | && PSEUDOVEC_STRUCT (vector, font_entity)->is_android) | 3369 | && PSEUDOVEC_STRUCT (vector, font_entity)->is_android) |
| 3364 | android_finalize_font_entity (PSEUDOVEC_STRUCT (vector, font_entity)); | 3370 | android_finalize_font_entity (PSEUDOVEC_STRUCT (vector, font_entity)); |
| 3365 | #endif | 3371 | #endif |
| 3366 | } | 3372 | } |
| 3367 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_THREAD)) | 3373 | break; |
| 3368 | finalize_one_thread (PSEUDOVEC_STRUCT (vector, thread_state)); | 3374 | case PVEC_THREAD: |
| 3369 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_MUTEX)) | 3375 | finalize_one_thread (PSEUDOVEC_STRUCT (vector, thread_state)); |
| 3370 | finalize_one_mutex (PSEUDOVEC_STRUCT (vector, Lisp_Mutex)); | 3376 | break; |
| 3371 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_CONDVAR)) | 3377 | case PVEC_MUTEX: |
| 3372 | finalize_one_condvar (PSEUDOVEC_STRUCT (vector, Lisp_CondVar)); | 3378 | finalize_one_mutex (PSEUDOVEC_STRUCT (vector, Lisp_Mutex)); |
| 3373 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_MARKER)) | 3379 | break; |
| 3374 | { | 3380 | case PVEC_CONDVAR: |
| 3381 | finalize_one_condvar (PSEUDOVEC_STRUCT (vector, Lisp_CondVar)); | ||
| 3382 | break; | ||
| 3383 | case PVEC_MARKER: | ||
| 3375 | /* sweep_buffer should already have unchained this from its buffer. */ | 3384 | /* sweep_buffer should already have unchained this from its buffer. */ |
| 3376 | eassert (! PSEUDOVEC_STRUCT (vector, Lisp_Marker)->buffer); | 3385 | eassert (! PSEUDOVEC_STRUCT (vector, Lisp_Marker)->buffer); |
| 3377 | } | 3386 | break; |
| 3378 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_USER_PTR)) | 3387 | case PVEC_USER_PTR: |
| 3379 | { | 3388 | { |
| 3380 | struct Lisp_User_Ptr *uptr = PSEUDOVEC_STRUCT (vector, Lisp_User_Ptr); | 3389 | struct Lisp_User_Ptr *uptr = PSEUDOVEC_STRUCT (vector, Lisp_User_Ptr); |
| 3381 | if (uptr->finalizer) | 3390 | if (uptr->finalizer) |
| 3382 | uptr->finalizer (uptr->p); | 3391 | uptr->finalizer (uptr->p); |
| 3383 | } | 3392 | } |
| 3393 | break; | ||
| 3394 | case PVEC_TS_PARSER: | ||
| 3395 | #ifdef HAVE_TREE_SITTER | ||
| 3396 | treesit_delete_parser (PSEUDOVEC_STRUCT (vector, Lisp_TS_Parser)); | ||
| 3397 | #endif | ||
| 3398 | break; | ||
| 3399 | case PVEC_TS_COMPILED_QUERY: | ||
| 3384 | #ifdef HAVE_TREE_SITTER | 3400 | #ifdef HAVE_TREE_SITTER |
| 3385 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_TS_PARSER)) | 3401 | treesit_delete_query (PSEUDOVEC_STRUCT (vector, Lisp_TS_Query)); |
| 3386 | treesit_delete_parser (PSEUDOVEC_STRUCT (vector, Lisp_TS_Parser)); | ||
| 3387 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_TS_COMPILED_QUERY)) | ||
| 3388 | treesit_delete_query (PSEUDOVEC_STRUCT (vector, Lisp_TS_Query)); | ||
| 3389 | #endif | 3402 | #endif |
| 3403 | break; | ||
| 3404 | case PVEC_MODULE_FUNCTION: | ||
| 3390 | #ifdef HAVE_MODULES | 3405 | #ifdef HAVE_MODULES |
| 3391 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_MODULE_FUNCTION)) | 3406 | { |
| 3392 | { | 3407 | ATTRIBUTE_MAY_ALIAS struct Lisp_Module_Function *function |
| 3393 | ATTRIBUTE_MAY_ALIAS struct Lisp_Module_Function *function | 3408 | = (struct Lisp_Module_Function *) vector; |
| 3394 | = (struct Lisp_Module_Function *) vector; | 3409 | module_finalize_function (function); |
| 3395 | module_finalize_function (function); | 3410 | } |
| 3396 | } | ||
| 3397 | #endif | 3411 | #endif |
| 3412 | break; | ||
| 3413 | case PVEC_NATIVE_COMP_UNIT: | ||
| 3398 | #ifdef HAVE_NATIVE_COMP | 3414 | #ifdef HAVE_NATIVE_COMP |
| 3399 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_NATIVE_COMP_UNIT)) | 3415 | { |
| 3400 | { | 3416 | struct Lisp_Native_Comp_Unit *cu = |
| 3401 | struct Lisp_Native_Comp_Unit *cu = | 3417 | PSEUDOVEC_STRUCT (vector, Lisp_Native_Comp_Unit); |
| 3402 | PSEUDOVEC_STRUCT (vector, Lisp_Native_Comp_Unit); | 3418 | unload_comp_unit (cu); |
| 3403 | unload_comp_unit (cu); | 3419 | } |
| 3404 | } | 3420 | #endif |
| 3405 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_SUBR)) | 3421 | break; |
| 3406 | { | 3422 | case PVEC_SUBR: |
| 3407 | struct Lisp_Subr *subr = | 3423 | #ifdef HAVE_NATIVE_COMP |
| 3408 | PSEUDOVEC_STRUCT (vector, Lisp_Subr); | 3424 | { |
| 3409 | if (!NILP (subr->native_comp_u)) | 3425 | struct Lisp_Subr *subr = PSEUDOVEC_STRUCT (vector, Lisp_Subr); |
| 3410 | { | 3426 | if (!NILP (subr->native_comp_u)) |
| 3411 | /* FIXME Alternative and non invasive solution to this | 3427 | { |
| 3412 | cast? */ | 3428 | /* FIXME Alternative and non invasive solution to this cast? */ |
| 3413 | xfree ((char *)subr->symbol_name); | 3429 | xfree ((char *)subr->symbol_name); |
| 3414 | xfree (subr->native_c_name); | 3430 | xfree (subr->native_c_name); |
| 3415 | } | 3431 | } |
| 3416 | } | 3432 | } |
| 3417 | #endif | 3433 | #endif |
| 3434 | break; | ||
| 3435 | /* Keep the switch exhaustive. */ | ||
| 3436 | case PVEC_NORMAL_VECTOR: | ||
| 3437 | case PVEC_FREE: | ||
| 3438 | case PVEC_SYMBOL_WITH_POS: | ||
| 3439 | case PVEC_MISC_PTR: | ||
| 3440 | case PVEC_PROCESS: | ||
| 3441 | case PVEC_FRAME: | ||
| 3442 | case PVEC_WINDOW: | ||
| 3443 | case PVEC_BOOL_VECTOR: | ||
| 3444 | case PVEC_BUFFER: | ||
| 3445 | case PVEC_HASH_TABLE: | ||
| 3446 | case PVEC_TERMINAL: | ||
| 3447 | case PVEC_WINDOW_CONFIGURATION: | ||
| 3448 | case PVEC_OTHER: | ||
| 3449 | case PVEC_XWIDGET: | ||
| 3450 | case PVEC_XWIDGET_VIEW: | ||
| 3451 | case PVEC_TS_NODE: | ||
| 3452 | case PVEC_SQLITE: | ||
| 3453 | case PVEC_COMPILED: | ||
| 3454 | case PVEC_CHAR_TABLE: | ||
| 3455 | case PVEC_SUB_CHAR_TABLE: | ||
| 3456 | case PVEC_RECORD: | ||
| 3457 | break; | ||
| 3458 | } | ||
| 3418 | } | 3459 | } |
| 3419 | 3460 | ||
| 3420 | /* Reclaim space used by unmarked vectors. */ | 3461 | /* Reclaim space used by unmarked vectors. */ |