repo: rxvt-unicode-sixel action: commit revision: path_from: revision_from: c6f5624ccc98163f7af4a8e07fd12dbbd5250ece: path_to: revision_to:
commit c6f5624ccc98163f7af4a8e07fd12dbbd5250ece Author: Marc LehmannDate: 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
--- 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
--- 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
--- 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 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
- *
- * 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
-
-// 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
--- 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-----