From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Alex Gramiak Newsgroups: gmane.emacs.devel Subject: Re: NS port: How to debug excessive garbage collection? Date: Sun, 14 Apr 2019 17:31:16 -0600 Message-ID: <87pnpotb97.fsf@gmail.com> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="68732"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) Cc: eliz@gnu.org, dancol@dancol.org, emacs-devel@gnu.org To: Keith David Bershatsky Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Apr 15 01:31:41 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hFob0-000Hcp-9k for ged-emacs-devel@m.gmane.org; Mon, 15 Apr 2019 01:31:34 +0200 Original-Received: from localhost ([127.0.0.1]:42033 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hFoaz-00034U-AB for ged-emacs-devel@m.gmane.org; Sun, 14 Apr 2019 19:31:33 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:43675) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hFoap-000322-Ne for emacs-devel@gnu.org; Sun, 14 Apr 2019 19:31:25 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hFoao-0007pR-AV for emacs-devel@gnu.org; Sun, 14 Apr 2019 19:31:23 -0400 Original-Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]:38404) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hFoan-0007oe-Sj; Sun, 14 Apr 2019 19:31:22 -0400 Original-Received: by mail-pl1-x634.google.com with SMTP id f36so7646116plb.5; Sun, 14 Apr 2019 16:31:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=kjQK/ov7XDCpJ0ZKddjMDl0boA3PvTbvwwk3CRxVtVk=; b=r+9Am41nfk37dYn4PIggdZlXy63ypX6qDcez2Vdmg7T5JpS5QN6y2DJh6008SnPPGR mhNzApt7476wM90+zPWhdBHTapmP6iBRbS5+gFngj3GCG+RhK5zoALE61gjJJk2ioBiU WEklGJXgYTIvch7VxRWixSQMTHaFiRzntWGoSU3rh9rY84kt+cUG3MRtBalC6TDDk3NM AdVT/P+9rH8285o9awWNwWKOiPi3AG4R3K8JuFNxdgKLA8THZgd2N63wgeiCnglgXfj8 i15GkCnBGlqsdKGTcN8CX9/uO2q/azpUCcdc8PgsNmjJYVReT1hBrbaEYWWEg4spi+w6 N7eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=kjQK/ov7XDCpJ0ZKddjMDl0boA3PvTbvwwk3CRxVtVk=; b=cli1HSX1Wa8kzzrI4koqXcZ+je7v8Yo7R0GFm0aBPT/39w/N45FXPDQ985e0ekQEX6 pW/qMP5o/qpVQdGUeONd4qDk0pZKMjX9wCaaGpXzniRcMQVli0JLTnlodFbNwCQQ1wuh neAcIGcK/ymhHL3YJhnbL0PfDW04ixBVQsYAdl8U4+iYF/HJUm6eyoddKpbC+zYcOzD/ qOZac9ooThatVX0B4mt4A4Ih5RqB5VCrqqQ0BiYwVA8aQxs57wNqUJsu3eZMLPZoj96B qZUM4RnCgtKO25DM0KcT3sAJDdFP7lfzu4sf29zD872xUo53PQ1sQ4KSYkRHiUfG0wRB PWOw== X-Gm-Message-State: APjAAAVDUUqhftF1AEZoWCs4ZX8SWQDsnCht+A6EOphCPZPykXkKekOZ 7zODyRzB4RHmj4Ueahl7Lre5Hrwn X-Google-Smtp-Source: APXvYqwZ5x+lPHDRmDO/5z5G+Zw9Ba8m71LDxls3NV5dwWzHThQkieCSOxsrC43nZ+CXC6Lvtte4xg== X-Received: by 2002:a17:902:2a6a:: with SMTP id i97mr16835863plb.273.1555284678572; Sun, 14 Apr 2019 16:31:18 -0700 (PDT) Original-Received: from lylat ([2604:3d09:e37f:1500:1a72:4878:e793:7302]) by smtp.gmail.com with ESMTPSA id d68sm72196011pfg.16.2019.04.14.16.31.17 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 14 Apr 2019 16:31:17 -0700 (PDT) In-Reply-To: (Keith David Bershatsky's message of "Sun, 14 Apr 2019 12:46:28 -0700") X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::634 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:235465 Archived-At: --=-=-= Content-Type: text/plain Keith David Bershatsky writes: > The attched patch (debug_mwe_001.diff) is a minimal working example that demonstrates the issue on all three platforms (X11, W32, NS) using the GUI version of Emacs built from the master branch as of 04/08/2019 (a038df77de7b1aa2d73a6478493b8838b59e4982). > > The snippet that I am pasting and evaluating in the minibuffer is as follows: > > (progn > (find-library "simple") > (fundamental-mode) > (blink-cursor-mode -1) > (global-eldoc-mode -1) > (setq timer-list nil > timer-idle-list nil > crosshairs t)) > > Here are Youtube links to screen recordings of the minimal working example on all three platforms: > > NS (screen recording): https://youtu.be/4IzXfP2j2GY > > X11 (screen recording): https://youtu.be/zrRH72qdmx0 > > W32 (screen recording): https://youtu.be/cfIG4fbkesY > > MINIMAL WORKING EXAMPLE: > > 1. Imaginary / Pretend: We imagine that all fake cursors are erased at the outset of update_window while w->current_matrix is still valid; i.e., before scrolling_window does its thing. > > 2. The master cache of fake cursors (w->ch_cache) is set to Qnil. > > 3. Imaginary / Pretend: We imagine .... As to the rows in the w->desired_matrix that must be updated with update_text_area, we draw fake cursors immediately after draw_glyphs finishes updating the row. As we are laying fake cursors, we use a temporary cache (w->mc_temp_cache) to store the relevant data so that we can redraw any fake cursors that get erased because they are left/right_overwritten as determined by draw_glyphs. Once the row has been updated with fake cursors, we set the termporary cache (w->mc_temp_cache) to Qnil and we set the master cache with the new data -- appending new data if the cache is non-nil. > > 4. As to all remaining rows that are not updated with update_text_area (which uses w->desired_matrix), we use the w->current_matrix and draw/cache the fake cursors using the same approach as mentioned in the preceding step; i.e., a temporary cache (w->mc_temp_cache) so that we can fix any fake cursors that got left/right_overwritten and then that cache is set to Qnil and the master cache (w->mc_cache) is updated. > > In the above minimal working example, the window Lisp_Object caches are rather simple: > > '((make_fixnum (1)) > (make_fixnum (2)) > (make_fixnum (3)) > ... > (make_fixnum (99))) If I'm looking at this right, the float issue is now resolved, but there's still a cons cell issue. A way to fix this in the MWE is to reuse the cons cells rather than making new cells each time. I've included a diff below (that just includes the parts I touched on your diff) that should solve, or at least mitigate, your problem. Hopefully it's useful. Looking at your actual implementation though, I don't see a reason for your cache to be a Lisp_Object at all; am I missing something? It seems that you could just use a C array of length 14. Not making any cons cells at all is the best approach if you can do so. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=mc.diff Content-Description: mc diff --git a/src/dispnew.c b/src/dispnew.c index ccb08ec1b9..068296212f 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3497,6 +3497,40 @@ update_window (struct window *w, bool force_p) set_cursor: + +/* *************************************************************************** */ +/* MULTIPLE-CURSORS */ + + for (struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, 0); + desired_row < end + && (force_p || !input_pending) + && BUFFERP (w->contents) + && (!NILP (BVAR (XBUFFER (w->contents), crosshairs))); + ++desired_row) + { + if (desired_row->enabled_p) + continue; + wset_mc_temp_cache (w, Qnil); + int vpos = MATRIX_ROW_VPOS (desired_row, desired_matrix); + struct glyph_matrix *current_matrix = w->current_matrix; + struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos); + if (current_row->enabled_p) + { + Lisp_Object head = w->mc_temp_cache; + // Replace each element with the Lisp integer position + for (int i = 0; CONSP (head); ++i, head = XCDR (head)) + XSETCAR (head, make_fixnum (i)); + } + } + + Lisp_Object head = w->ch_cache; + // Replace each element with the Lisp integer position + for (int i = 0; CONSP (head); ++i, head = XCDR (head)) + XSETCAR (head, make_fixnum (i)); + +/* *************************************************************************** */ + + /* Update the header line after scrolling because a new header line would otherwise overwrite lines at the top of the window that can be scrolled. */ diff --git a/src/window.c b/src/window.c index ef2ed63850..6ee1f65d9f 100644 --- a/src/window.c +++ b/src/window.c @@ -4252,6 +4252,9 @@ make_window (void) w->scroll_bar_width = -1; w->scroll_bar_height = -1; w->column_number_displayed = -1; + /* Your MC caches -- note there's only 2 lists ever created for them */ + w->ch_cache = Fmake_list (make_fixnum (100), Qnil); + w->mc_temp_cache = Fmake_list (make_fixnum (100), Qnil); /* Reset window_list. */ Vwindow_list = Qnil; /* Return window. */ --=-=-=--