bug#58883:

Po Lu via CC-Mode-help <[email protected]> Fri, 18 Nov 2022 15:35:30 +0800
Newsgroups gmane.emacs.cc-mode.general
Message-ID <[email protected]>
Po Lu <[email protected]> writes:

> Big problem: trying to edit in a string literal in a big file results is
> very slow.  Quitting reveals the following call stack:
>
> Debugger entered--entering a function:
> * re-search-forward("[[:alpha:]_]" 25554 bound)
>   c-unfind-tokens-in-region(1 25554)
>   c-before-change(1 25554)
>   c-after-change(25546 25547 0)
>   self-insert-command(1 100)
>   funcall-interactively(self-insert-command 1 100)
>   command-execute(self-insert-command)
>
> here is some text to reproduce the problem.  Insert the following text
> in a c-mode buffer:
>
> void
> verify_image_data (struct test_display *display, Window window,
> 		   const char *filename)
> {
>   XImage *image;
>   XWindowAttributes attrs;
>   unsigned char *data;
>   struct image_data_header header;
>   unsigned short data_bpp, i;
>   int byte_order;
>   struct image_difference_statistics statistics;
>
>   statistics.min_diff = 0;
>   statistics.max_diff = 0;
>
>   if (write_image_data_instead)
>     write_image_data (display, window, filename);
>
>   data = load_image_data (filename, &header);
>
>   if (!data)
>     report_test_failure ("failed to load input file: %s", filename);
>
>   XGetWindowAttributes (display->x_display, window, &attrs);
>   image = XGetImage (display->x_display, window, 0, 0, attrs.width,
> 		     attrs.height, ~0, ZPixmap);
>
>   test_log ("verifying image data from: %s", filename);
>
>   if (!image)
>     report_test_failure ("failed to load from drawable 0x%lx", window);
>
>   /* Check if the image data is compatible.  */
>   data_bpp = bytes_per_pixel_for_format (header.format);
>   byte_order = byte_order_for_format (header.format);
>
>   if (byte_order != image->byte_order)
>     report_test_failure ("image data has wrong byte order");
>
>   if (data_bpp * 8 != image->bits_per_pixel)
>     report_test_failure ("image data has %d bits per pixel, but reference"
> 			 " data has %hd * 8", image->bits_per_pixel, data_bpp);
>
>   if (image->width != header.width
>       || image->height != header.height)
>     report_test_failure ("image data is %d by %d, but reference data is"
> 			 " %hd by %hd", image->width, image->height,
> 			 header.width, header.height);
>
>   /* Now compare the actual image data.  Make sure this is done with
>      the same visual as the reference data was saved in!  */
>
>   for (i = 0; i < header.height; ++i)
>     compare_single_row (data, i, &header, image, &statistics);
>
>   /* Note that statistics is not always used by
>      compare_single_row.  */
>
>   test_log ("comparison finished.  channel differences were: %d, %d",
> 	    statistics.min_diff, statistics.max_diff);
>
>   if (statistics.min_diff < -3 || statistics.max_diff > 4)
>     {
>       /* Write the reject to a file.  */
>       test_log ("writing reject to reject.dump");
>       write_image_data_1 (image, "reject.dump");
>
>       report_test_failure ("differences exceeded thresholds (-3, 4)");
>     }
>
>   /* Destroy the images.  */
>   free (data);
>   XDestroyImage (image);
>
>   test_log ("verified image data");
> }
> void
> verify_image_data (struct test_display *display, Window window,
> 		   const char *filename)
> {
>   XImage *image;
>   XWindowAttributes attrs;
>   unsigned char *data;
>   struct image_data_header header;
>   unsigned short data_bpp, i;
>   int byte_order;
>   struct image_difference_statistics statistics;
>
>   statistics.min_diff = 0;
>   statistics.max_diff = 0;
>
>   if (write_image_data_instead)
>     write_image_data (display, window, filename);
>
>   data = load_image_data (filename, &header);
>
>   if (!data)
>     report_test_failure ("failed to load input file: %s", filename);
>
>   XGetWindowAttributes (display->x_display, window, &attrs);
>   image = XGetImage (display->x_display, window, 0, 0, attrs.width,
> 		     attrs.height, ~0, ZPixmap);
>
>   test_log ("verifying image data from: %s", filename);
>
>   if (!image)
>     report_test_failure ("failed to load from drawable 0x%lx", window);
>
>   /* Check if the image data is compatible.  */
>   data_bpp = bytes_per_pixel_for_format (header.format);
>   byte_order = byte_order_for_format (header.format);
>
>   if (byte_order != image->byte_order)
>     report_test_failure ("image data has wrong byte order");
>
>   if (data_bpp * 8 != image->bits_per_pixel)
>     report_test_failure ("image data has %d bits per pixel, but reference"
> 			 " data has %hd * 8", image->bits_per_pixel, data_bpp);
>
>   if (image->width != header.width
>       || image->height != header.height)
>     report_test_failure ("image data is %d by %d, but reference data is"
> 			 " %hd by %hd", image->width, image->height,
> 			 header.width, header.height);
>
>   /* Now compare the actual image data.  Make sure this is done with
>      the same visual as the reference data was saved in!  */
>
>   for (i = 0; i < header.height; ++i)
>     compare_single_row (data, i, &header, image, &statistics);
>
>   /* Note that statistics is not always used by
>      compare_single_row.  */
>
>   test_log ("comparison finished.  channel differences were: %d, %d",
> 	    statistics.min_diff, statistics.max_diff);
>
>   if (statistics.min_diff < -3 || statistics.max_diff > 4)
>     {
>       /* Write the reject to a file.  */
>       test_log ("writing reject to reject.dump");
>       write_image_data_1 (image, "reject.dump");
>
>       report_test_failure ("differences exceeded thresholds (-3, 4)");
>     }
>
>   /* Destroy the images.  */
>   free (data);
>   XDestroyImage (image);
>
>   test_log ("verified image data");
> }
>
> /* Verify the image data against a file.  */
>
> void
> verify_image_data (struct test_display *display, Window window,
> 		   const char *filename)
> {
>   XImage *image;
>   XWindowAttributes attrs;
>   unsigned char *data;
>   struct image_data_header header;
>   unsigned short data_bpp, i;
>   int byte_order;
>   struct image_difference_statistics statistics;
>
>   statistics.min_diff = 0;
>   statistics.max_diff = 0;
>
>   if (write_image_data_instead)
>     write_image_data (display, window, filename);
>
>   data = load_image_data (filename, &header);
>
>   if (!data)
>     report_test_failure ("failed to load input file: %s", filename);
>
>   XGetWindowAttributes (display->x_display, window, &attrs);
>   image = XGetImage (display->x_display, window, 0, 0, attrs.width,
> 		     attrs.height, ~0, ZPixmap);
>
>   test_log ("verifying image data from: %s", filename);
>
>   if (!image)
>     report_test_failure ("failed to load from drawable 0x%lx", window);
>
>   /* Check if the image data is compatible.  */
>   data_bpp = bytes_per_pixel_for_format (header.format);
>   byte_order = byte_order_for_format (header.format);
>
>   if (byte_order != image->byte_order)
>     report_test_failure ("image data has wrong byte order");
>
>   if (data_bpp * 8 != image->bits_per_pixel)
>     report_test_failure ("image data has %d bits per pixel, but reference"
> 			 " data has %hd * 8", image->bits_per_pixel, data_bpp);
>
>   if (image->width != header.width
>       || image->height != header.height)
>     report_test_failure ("image data is %d by %d, but reference data is"
> 			 " %hd by %hd", image->width, image->height,
> 			 header.width, header.height);
>
>   /* Now compare the actual image data.  Make sure this is done with
>      the same visual as the reference data was saved in!  */
>
>   for (i = 0; i < header.height; ++i)
>     compare_single_row (data, i, &header, image, &statistics);
>
>   /* Note that statistics is not always used by
>      compare_single_row.  */
>
>   test_log ("comparison finished.  channel differences were: %d, %d",
> 	    statistics.min_diff, statistics.max_diff);
>
>   if (statistics.min_diff < -3 || statistics.max_diff > 4)
>     {
>       /* Write the reject to a file.  */
>       test_log ("writing reject to reject.dump");
>       write_image_data_1 (image, "reject.dump");
>
>       report_test_failure ("differences exceeded thresholds (-3, 4)");
>     }
>
>   /* Destroy the images.  */
>   free (data);
>   XDestroyImage (image);
>
>   test_log ("verified image data");
> }
>
> void
> test_set_scale (struct test_display *display, int scale)
> {
>   test_scale_lock_set_scale (display->scale_lock, scale);
> }
>
> void
> test_init (void)
> {
>   write_image_data_instead
>     = getenv ("TEST_WRITE_REFERENCE") != NULL;
> }
>
> 
>
> static void
> handle_seat_controller_device_id (void *data,
> 				  struct test_seat_controller *controller,
> 				  uint32_t device_id)
> {
>   struct test_display *display;
>
>   display = data;
>   display->seat->device_id = device_id;
> }
>
> static const struct test_seat_controller_listener seat_controller_listener =
>   {
>     handle_seat_controller_device_id,
>   };
>
> 
>
> void
> test_init_seat (struct test_display *display)
> {
>   if (display->seat)
>     report_test_internal_error ("tried to initialize seat twice");
>
>   display->seat = malloc (sizeof *display->seat);
>
>   if (!display->seat)
>     report_test_failure ("failed to allocate seat");
>
>   display->seat->controller
>     = test_manager_get_test_seat (display->test_manager);
>
>   if (!display->seat->controller)
>     report_test_failure ("failed to obtain seat controller");
>
>   display->seat->device_controller
>     = test_seat_controller_get_device_controller (display->seat->controller);
>
>   if (!display->seat->device_controller)
>     report_test_failure ("failed to obtain device controller");
>
>   /* Fetch the device ID of the seat.  */
>   display->seat->device_id = 0;
>   test_seat_controller_add_listener (display->seat->controller,
> 				     &seat_controller_listener,
> 				     display);
>   wl_display_roundtrip (display->display);
>
>   if (!display->seat->device_id)
>     report_test_failure ("failed to obtain device ID");
>
>   /* The protocol translator currently supports version 8 of wl_seat,
>      so bind to that.  */
>
>   display->seat->seat
>     = test_seat_controller_bind_seat (display->seat->controller,
> 				      8);
>
>   if (!display->seat->seat)
>     report_test_failure ("failed to bind to test seat");
>
>   display->seat->pointer
>     = wl_seat_get_pointer (display->seat->seat);
>
>   if (!display->seat->pointer)
>     report_test_failure ("failed to bind to test pointer");
>
>   display->seat->keyboard
>     = wl_seat_get_keyboard (display->seat->seat);
>
>   if (!display->seat->keyboard)
>     report_test_failure ("failed to bind to test keyboard");
> }
>
> void __attribute__ ((noreturn))
> test_complete (void)
> {
>   test_log ("test ran successfully");
>   exit_with_code (0);
> }
>
> uint32_t
> test_get_serial (struct test_display *display)
> {
>   test_manager_get_serial (display->test_manager);
>   wl_display_roundtrip (display->display);
>
>   return display->serial;
> }
>
> void
> verify_window_size (struct test_display *display,
> 		    Window window, int width, int height)
> {
>   XWindowAttributes attrs;
>
>   XGetWindowAttributes (display->x_display, window, &attrs);
>
>   if (width != attrs.width || height != attrs.height)
>     report_test_failure ("window is incorrect size.  expected: %d %d"
> 			 ", actual: %d %d", width, height,
> 			 attrs.width, attrs.height);
> }
>
> 
>
> static void
> handle_wl_buffer_release (void *data, struct wl_buffer *buffer)
> {
>   struct test_buffer *test_buffer;
>
>   test_buffer = data;
>   test_buffer->busy = false;
> }
>
> static const struct wl_buffer_listener test_buffer_listener =
>   {
>     handle_wl_buffer_release,
>   };
>
> 
>
> struct test_buffer *
> get_test_buffer (struct test_display *display, struct wl_buffer *buffer)
> {
>   struct test_buffer *test_buffer;
>
>   test_buffer = malloc (sizeof *test_buffer);
>
>   if (!test_buffer)
>     return NULL;
>
>   test_buffer->buffer = buffer;
>   test_buffer->busy = false;
>
>   wl_buffer_add_listener (buffer, &test_buffer_listener, test_buffer);
> }
>
> void
> test_buffer_committed (struct test_buffer *test_buffer)
> {
>   test_buffer->busy = true;
> }
>
> void
> verify_buffer_released (struct test_buffer *buffer)
> {
>   if (!test_buffer->busy)
>     report_test_failure ("buffer %p");
> }
>
> and type " is busy, but should have been released" after "%p".  Editing
> will slow down to a crawl.
>
> Thanks.

Also, it seems that `CHECK_LISP_OBJECT_TYPE' is fontified as a type in
lisp.h, tho I've no idea whether or not that is related to this patch.