From 11c7990ec8932b750f20f4d42f2414ba73b68368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 15 May 2021 15:15:32 +0200 Subject: [PATCH 1/2] =?UTF-8?q?grid:=20reflow:=20don=E2=80=99t=20initializ?= =?UTF-8?q?e=20newly=20allocated=20rows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We’re going to write to it immediately anyway. In most cases, *all* newly allocated, and zero-initialized, cells are overwritten. So let’s skip the zero-initialization of the new cells. There are two cases where we need to explicitly clear cells now: * When inserting a hard line break - erase the remaining cells * When done, the *last* row may not have been completely written - erase the remaining cells --- grid.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/grid.c b/grid.c index eb923756..996cf8d4 100644 --- a/grid.c +++ b/grid.c @@ -341,11 +341,10 @@ _line_wrap(struct grid *old_grid, struct row **new_grid, struct row *row, if (new_row == NULL) { /* Scrollback not yet full, allocate a completely new row */ - new_row = grid_row_alloc(col_count, true); + new_row = grid_row_alloc(col_count, false); new_grid[*row_idx] = new_row; } else { /* Scrollback is full, need to re-use a row */ - memset(new_row->cells, 0, col_count * sizeof(new_row->cells[0])); grid_row_reset_extra(new_row); new_row->linebreak = false; @@ -451,7 +450,7 @@ grid_resize_and_reflow( struct row *new_row = new_grid[new_row_idx]; xassert(new_row == NULL); - new_row = grid_row_alloc(new_cols, true); + new_row = grid_row_alloc(new_cols, false); new_grid[new_row_idx] = new_row; /* Start at the beginning of the old grid's scrollback. That is, @@ -649,6 +648,9 @@ grid_resize_and_reflow( } if (old_row->linebreak) { + /* Erase the remaining cells */ + memset(&new_row->cells[new_col_idx], 0, + (new_cols - new_col_idx) * sizeof(new_row->cells[0])); new_row->linebreak = true; line_wrap(); } @@ -657,6 +659,10 @@ grid_resize_and_reflow( #undef line_wrap } + /* Erase the remaining cells */ + memset(&new_row->cells[new_col_idx], 0, + (new_cols - new_col_idx) * sizeof(new_row->cells[0])); + xassert(old_rows == 0 || *next_tp == &terminator); #if defined(_DEBUG) From 1aa4a31c6f8aaf6a504d080396d8aff1c2a39d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 May 2021 10:11:41 +0200 Subject: [PATCH 2/2] =?UTF-8?q?grid:=20reflow:=20free=20old=20rows=20as=20?= =?UTF-8?q?soon=20as=20we=E2=80=99re=20done=20with=20them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reduces the memory cost of reflowing text, as we no longer needs to hold both the old and the new grid, in their entirety, in memory at the same time. --- grid.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/grid.c b/grid.c index 996cf8d4..0e116793 100644 --- a/grid.c +++ b/grid.c @@ -655,6 +655,9 @@ grid_resize_and_reflow( line_wrap(); } + grid_row_free(old_grid[old_row_idx]); + grid->rows[old_row_idx] = NULL; + #undef print_spacer #undef line_wrap } @@ -678,6 +681,10 @@ grid_resize_and_reflow( tll_foreach(row->extra->uri_ranges, it) xassert(it->item.end >= 0); } + + /* Verify all old rows have been free:d */ + for (int i = 0; i < old_rows; i++) + xassert(grid->rows[i] == NULL); #endif /* Set offset such that the last reflowed row is at the bottom */ @@ -711,9 +718,7 @@ grid_resize_and_reflow( xassert(new_grid[idx] != NULL); } - /* Free old grid */ - for (int r = 0; r < grid->num_rows; r++) - grid_row_free(old_grid[r]); + /* Free old grid (rows already free:d) */ free(grid->rows); grid->rows = new_grid;