-- Leo's gemini proxy

-- Connecting to git.thebackupbox.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

repo: rxvt-unicode-sixel
action: commit
revision:
path_from:
revision_from: c6f5624ccc98163f7af4a8e07fd12dbbd5250ece:
path_to:
revision_to:

git.thebackupbox.net

rxvt-unicode-sixel

git://git.thebackupbox.net/rxvt-unicode-sixel

commit c6f5624ccc98163f7af4a8e07fd12dbbd5250ece
Author: Marc Lehmann <schmorp@schmorp.de>
Date:   Mon May 28 14:25:16 2012 +0000

    use one big chunk for all line_t's and rend/text data, get rid fo salloc

diff --git a/Changes b/Changes

index 1e98b6218ed421326a7b4c445f6b4839294fc84d..

index ..b69df1c070f97b1959ad2be249888bd84f85b4e4 100644

--- a/Changes
+++ b/Changes
@@ -39,6 +39,9 @@ TODO: DEC PM 4h/4l should toggle jumpscroll on or off (PrivMode_smoothScroll)
         - update to CVS version of libev, for a whopping 11kb size decrease.
         - do not ship yet another copy of ecb.h, use the one in libev or
           libptytty instead.
+        - allocate all screen memory in one go and let the virtual memory
+          subsystem sort it out. this simplifies code, improves access
+          locality, saves a bit of ram and makes thigs a bit faster, too.

 9.15 Sat Jan 21 13:36:56 CET 2012
 	- remove "using namespace std" because clang erroneously
diff --git a/MANIFEST b/MANIFEST

index 09cfee713fd21e6d100881ef9f922c18fb070bb9..

index ..4eab17e7a4591bb79417c2b44a4e5dce2bfda18c 100644

--- a/MANIFEST
+++ b/MANIFEST
@@ -73,8 +73,6 @@ src/rxvtc.C
 src/rxvtd.C
 src/rxvtdaemon.C
 src/rxvtdaemon.h
-src/salloc.C
-src/salloc.h
 src/screen.C
 src/scrollbar-next.C
 src/scrollbar-rxvt.C
diff --git a/src/rxvt.h b/src/rxvt.h

index 803f6c61218a86e5ac0428ea91d0d6bb3e60a038..

index ..ef0957e620ea79d80929f2ee1172e3ee0cf4a058 100644

--- a/src/rxvt.h
+++ b/src/rxvt.h
@@ -753,6 +753,16 @@ struct line_t
    tlen_t_ l; // length of each text line
    uint32_t f; // flags

+   bool valid ()
+   {
+     return l >= 0;
+   }
+
+   void alloc ()
+   {
+     l = 0;
+   }
+
    bool is_longer ()
    {
      return f & LINE_LONGER;
@@ -1032,6 +1042,7 @@ struct rxvt_vars : TermWin_t
   XSizeHints      szHint;
   rxvt_color     *pix_colors;
   Cursor          TermWin_cursor;       /* cursor for vt window */
+
   line_t         *row_buf;      // all lines, scrollback + terminal, circular
   line_t         *drawn_buf;    // text on screen
   line_t         *swap_buf;     // lines for swap buffer
@@ -1248,8 +1259,10 @@ struct rxvt_term : zero_initialized, rxvt_vars, rxvt_screen

   ptytty         *pty;

-  rxvt_salloc    *talloc;             // text line allocator
-  rxvt_salloc    *ralloc;             // rend line allocator
+  // chunk contains all line_t's as well as rend_t and text_t buffers
+  // for drawn_buf, swap_buf and row_buf, in this order
+  void           *chunk;
+  size_t          chunk_size;

   static vector<rxvt_term *> termlist; // a vector of all running rxvt_term's

@@ -1433,34 +1446,6 @@ struct rxvt_term : zero_initialized, rxvt_vars, rxvt_screen

   // screen.C

-  void lalloc (line_t &l) const
-  {
-    l.t = (text_t *)talloc->alloc ();
-    l.r = (rend_t *)ralloc->alloc ();
-  }
-
-#if 0
-  void lfree (line_t &l)
-  {
-    talloc->free (l.t);
-    ralloc->free (l.r);
-  }
-#endif
-
-  void lresize (line_t &l) const
-  {
-    if (!l.t)
-      return;
-
-    l.t = (text_t *)talloc->alloc (l.t, prev_ncol * sizeof (text_t));
-    l.r = (rend_t *)ralloc->alloc (l.r, prev_ncol * sizeof (rend_t));
-
-    l.l = min (l.l, ncol);
-
-    if (ncol > prev_ncol)
-      scr_blank_line (l, prev_ncol, ncol - prev_ncol, DEFAULT_RSTYLE);
-  }
-
   int fgcolor_of (rend_t r) const NOTHROW
   {
     int base = GET_BASEFG (r);
@@ -1499,6 +1484,7 @@ struct rxvt_term : zero_initialized, rxvt_vars, rxvt_screen
   // modifies first argument(!)
   void tt_paste (char *data, unsigned int len) NOTHROW;
   void paste (char *data, unsigned int len) NOTHROW;
+  void scr_alloc () NOTHROW;
   void scr_blank_line (line_t &l, unsigned int col, unsigned int width, rend_t efs) const NOTHROW;
   void scr_blank_screen_mem (line_t &l, rend_t efs) const NOTHROW;
   void scr_kill_char (line_t &l, int col) const NOTHROW;
diff --git a/src/salloc.C b/src/salloc.C
deleted file mode 100644
index c4b7ec0bc742048c022b4ea74049c4f6ca19b516..0000000000000000000000000000000000000000
--- a/src/salloc.C
+++ /dev/null
@@ -1,99 +0,0 @@
-/*----------------------------------------------------------------------*
- * File:	salloc.C
- *----------------------------------------------------------------------*
- *
- * All portions of code are copyright by their respective author/s.
- * Copyright (c) 2003-2006 Marc Lehmann <schmorp@schmorp.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *----------------------------------------------------------------------*/
-
-#include "salloc.h"
-
-#define SALLOC_BLOCK 65536 // size of basic block to allocate
-
-rxvt_salloc::rxvt_salloc (unsigned int size)
-{
-  this->size = size < sizeof (chain) ? sizeof (chain) : size;
-  firstline = 0;
-  firstblock = 0;
-  firstfree = SALLOC_BLOCK;
-}
-
-rxvt_salloc::~rxvt_salloc ()
-{
-  while (firstblock)
-    {
-      chain *next = firstblock->next;
-      ::free (firstblock);
-      firstblock = next;
-    }
-}
-
-void *
-rxvt_salloc::alloc ()
-{
-  void *r;
-
-  if (firstline)
-    {
-      r = (void *)firstline;
-      firstline = firstline->next;
-    }
-  else
-    {
-      if (firstfree + size > SALLOC_BLOCK)
-        {
-          chain *next = (chain *)rxvt_malloc ((SALLOC_BLOCK - sizeof (chain)) / size * size + sizeof (chain));
-          next->next = firstblock;
-          firstblock = next;
-          firstfree = sizeof (chain);
-        }
-
-      r = (void *) ((char *)firstblock + firstfree);
-
-      firstfree += size;
-    }
-
-  return r;
-}
-
-void *
-rxvt_salloc::alloc (void *data, unsigned int datalen)
-{
-  void *s = alloc ();
-
-  if (datalen < size)
-    {
-      memcpy (s, data, datalen);
-      memset ((unsigned char *)s + datalen, 0, size - datalen); // not strictly required for screen.C
-    }
-  else
-    memcpy (s, data, size);
-
-  return s;
-}
-
-void
-rxvt_salloc::free (void *data)
-{
-  if (!data)
-    return;
-
-  chain *line = (chain *)data;
-  line->next = firstline;
-  firstline = line;
-}
-
diff --git a/src/salloc.h b/src/salloc.h
deleted file mode 100644
index 1407ef6f92f16ad1055f2fd1bd13b655947cf666..0000000000000000000000000000000000000000
--- a/src/salloc.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef RXVT_SALLOC_H_
-#define RXVT_SALLOC_H_
-
-#include <stdlib.h>
-
-// small blocks allocator
-
-struct rxvt_salloc
-{
-  struct chain {
-    struct chain *next;
-  };
-
-  chain *firstblock;
-  chain *firstline;
-  unsigned int firstfree;
-  unsigned int size;
-
-  rxvt_salloc (unsigned int size);
-  ~rxvt_salloc ();
-
-  void *alloc ();
-  void *alloc (void *data, unsigned int datalen);
-  void free (void *data);
-};
-
-#endif
diff --git a/src/screen.C b/src/screen.C

index 276c3db4db9488ea4a760961044a023558f2e7d4..

index ..d9b7f6c8bd9d897ee9e894c602b5894c629fc3a6 100644

--- a/src/screen.C
+++ b/src/screen.C
@@ -100,9 +100,9 @@ fill_text (text_t *start, text_t value, int len)
 void
 rxvt_term::scr_blank_line (line_t &l, unsigned int col, unsigned int width, rend_t efs) const NOTHROW
 {
-  if (!l.t)
+  if (!l.valid ())
     {
-      lalloc (l);
+      l.alloc ();
       col = 0;
       width = ncol;
     }
@@ -158,6 +158,40 @@ rxvt_term::scr_kill_char (line_t &l, int col) const NOTHROW
  *                          SCREEN INITIALISATION                            *
  * ------------------------------------------------------------------------- */

+void
+rxvt_term::scr_alloc ()
+{
+  int tsize = sizeof (text_t) * ncol;
+  int rsize = sizeof (rend_t) * ncol;
+
+  // we assume that rend_t size is a sufficient alignment
+  // factor for tetx_t and line_t values, and we only
+  // need to adjust tsize.
+  tsize = (tsize + sizeof (rend_t) - 1);
+  tsize -= tsize % sizeof (rend_t);
+
+  int all_rows = total_rows + nrow + nrow;
+
+  chunk_size = (sizeof (line_t) + rsize + tsize) * all_rows;
+  chunk = rxvt_malloc (chunk_size);
+
+  char *base = (char *)chunk + sizeof (line_t) * all_rows;
+
+  for (int row = 0; row < all_rows; ++row)
+    {
+      line_t &l = ((line_t *)chunk) [row];
+
+      l.t = (text_t *)base; base += tsize;
+      l.r = (rend_t *)base; base += rsize;
+      l.l = -1;
+      l.f = 0;
+    }
+
+  drawn_buf = (line_t *)chunk;
+  swap_buf  = drawn_buf + nrow;
+  row_buf   = swap_buf  + nrow;
+}
+
 void
 rxvt_term::scr_reset ()
 {
@@ -194,7 +228,16 @@ rxvt_term::scr_reset ()
   screen.tscroll = 0;
   screen.bscroll = nrow - 1;

-  if (!row_buf)
+  void *prev_chunk = chunk;
+  line_t *prev_drawn_buf = drawn_buf;
+  line_t *prev_swap_buf  = swap_buf;
+  line_t *prev_row_buf   = row_buf;
+
+  int common_col = min (prev_ncol, ncol);
+
+  scr_alloc ();
+
+  if (!prev_row_buf)
     {
       /*
        * first time called so just malloc everything: don't rely on realloc
@@ -202,20 +245,6 @@ rxvt_term::scr_reset ()
       top_row    = 0;
       term_start = 0;

-      talloc = new rxvt_salloc (ncol * sizeof (text_t));
-      ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
-
-      row_buf   = (line_t *)rxvt_calloc (total_rows       , sizeof (line_t));
-      drawn_buf = (line_t *)rxvt_calloc (nrow             , sizeof (line_t));
-      swap_buf  = (line_t *)rxvt_calloc (nrow             , sizeof (line_t));
-
-      for (int row = nrow; row--; )
-        {
-          scr_blank_screen_mem (ROW (row), DEFAULT_RSTYLE);
-          scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE);
-          scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE);
-        }
-
       memset (charsets, 'B', sizeof (charsets));
       rstyle = DEFAULT_RSTYLE;
       screen.flags = Screen_DefaultFlags;
@@ -247,38 +276,17 @@ rxvt_term::scr_reset ()
        * add or delete rows as appropriate
        */

-      rxvt_salloc *old_ta = talloc; talloc = new rxvt_salloc (ncol * sizeof (text_t));
-      rxvt_salloc *old_ra = ralloc; ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
-
-#if 0
-      if (nrow < prev_nrow)
-        {
-          for (int row = nrow; row < prev_nrow; row++)
-            {
-              lfree (swap_buf [row]);
-              lfree (drawn_buf[row]);
-            }
-        }
-#endif
-
-      drawn_buf = (line_t *)rxvt_realloc (drawn_buf, nrow * sizeof (line_t));
-      swap_buf  = (line_t *)rxvt_realloc (swap_buf , nrow * sizeof (line_t));
-
       for (int row = min (nrow, prev_nrow); row--; )
         {
-          lresize (drawn_buf[row]);
-          lresize (swap_buf [row]);
-        }
+          scr_blank_screen_mem (drawn_buf [row], DEFAULT_RSTYLE);
+          scr_blank_screen_mem (swap_buf  [row], DEFAULT_RSTYLE);

-      for (int row = prev_nrow; row < nrow; row++)
-        {
-          swap_buf [row].clear (); scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE);
-          drawn_buf[row].clear (); scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE);
+          memcpy (drawn_buf [row].t, prev_drawn_buf [row].t, sizeof (text_t) * common_col);
+          memcpy (drawn_buf [row].r, prev_drawn_buf [row].r, sizeof (rend_t) * common_col);
+          memcpy (swap_buf  [row].t, prev_swap_buf  [row].t, sizeof (text_t) * common_col);
+          memcpy (swap_buf  [row].r, prev_swap_buf  [row].r, sizeof (rend_t) * common_col);
         }

-      line_t *old_buf = row_buf;
-      row_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
-
       int p    = MOD (term_start + prev_nrow, prev_total_rows);  // previous row
       int pend = MOD (term_start + top_row  , prev_total_rows);
       int q    = total_rows; // rewrapped row
@@ -295,11 +303,11 @@ rxvt_term::scr_reset ()
           do
             {
               p = MOD (p - 1, prev_total_rows);
-              assert (old_buf [MOD (p, prev_total_rows)].t);
+              assert (prev_row_buf [MOD (p, prev_total_rows)].t);
               int plines = 1;
-              int llen = old_buf [MOD (p, prev_total_rows)].l;
+              int llen = prev_row_buf [MOD (p, prev_total_rows)].l;

-              while (p != pend && old_buf [MOD (p - 1, prev_total_rows)].is_longer ())
+              while (p != pend && prev_row_buf [MOD (p - 1, prev_total_rows)].is_longer ())
                 {
                   p = MOD (p - 1, prev_total_rows);

@@ -322,7 +330,7 @@ rxvt_term::scr_reset ()
               for (int qrow = q; qlines--; qrow++)
                 {
                   qline = row_buf + qrow;
-                  lalloc (*qline);
+                  qline->alloc (); // redundant with next line
                   qline->l = ncol;
                   qline->is_longer (1);

@@ -347,7 +355,7 @@ rxvt_term::scr_reset ()
                       if (prow == ocur.row)
                         screen.cur.row = q - (total_rows - nrow);

-                      line_t &pline = old_buf [prow];
+                      line_t &pline = prev_row_buf [prow];

                       int len = min (min (prev_ncol - pcol, ncol - qcol), llen - lofs);

@@ -378,29 +386,34 @@ rxvt_term::scr_reset ()

           for (int row = min (nrow, prev_nrow); row--; )
             {
-              line_t &pline = old_buf [MOD (term_start + row, prev_total_rows)];
-              line_t &qline = row_buf [row];
+              line_t &src = prev_row_buf [MOD (term_start + row, prev_total_rows)];
+              line_t &dst = row_buf [row];

-              qline = pline;
-              lresize (qline);
+              scr_blank_screen_mem (dst, DEFAULT_RSTYLE);
+
+              memcpy (dst.t, src.t, sizeof (text_t) * common_col);
+              memcpy (dst.r, src.r, sizeof (rend_t) * common_col);
             }

           for (int row = prev_nrow; row < nrow; row++)
-            {
-              row_buf [row].clear (); scr_blank_screen_mem (row_buf [row], DEFAULT_RSTYLE);
-            }
+            scr_blank_screen_mem (row_buf [row], DEFAULT_RSTYLE);

           term_start = 0;
         }

-      free (old_buf);
-      delete old_ta;
-      delete old_ra;
-
       clamp_it (screen.cur.row, 0, nrow - 1);
       clamp_it (screen.cur.col, 0, ncol - 1);
     }

+  for (int row = nrow; row--; )
+    {
+      if (!ROW       (row).valid ()) scr_blank_screen_mem (ROW       (row), DEFAULT_RSTYLE);
+      if (!swap_buf  [row].valid ()) scr_blank_screen_mem (swap_buf  [row], DEFAULT_RSTYLE);
+      if (!drawn_buf [row].valid ()) scr_blank_screen_mem (drawn_buf [row], DEFAULT_RSTYLE);
+    }
+
+  free (prev_chunk);
+
   free (tabs);
   tabs = (char *)rxvt_malloc (ncol);

@@ -424,19 +437,8 @@ rxvt_term::scr_reset ()
 void
 rxvt_term::scr_release () NOTHROW
 {
-  if (row_buf)
-    {
-      delete talloc; talloc = 0;
-      delete ralloc; ralloc = 0;
-
-      free (row_buf);
-      free (swap_buf);
-      free (drawn_buf);
-      row_buf = 0; // signal that we freed all the arrays above
-
-      free (tabs);
-      tabs = 0;
-    }
+  free (chunk);
+  free (tabs);
 }

 /* ------------------------------------------------------------------------- */
@@ -447,6 +449,9 @@ void
 rxvt_term::scr_poweron ()
 {
   scr_release ();
+
+  row_buf = 0;
+  tabs = 0;
   prev_nrow = prev_ncol = 0;
   rvideo_mode = false;
   scr_soft_reset ();
@@ -2505,7 +2510,7 @@ rxvt_term::scr_refresh () NOTHROW
 void
 rxvt_term::scr_remap_chars (line_t &l) NOTHROW
 {
-  if (!l.t)
+  if (!l.valid ())
     return;

   l.touch (); // maybe a bit of an overkill, but it's not performance-relevant

-----END OF PAGE-----

-- Response ended

-- Page fetched on Sun Jun 2 10:20:15 2024