mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 14:18:26 +02:00
Use a single alloc for all segments of historybuf when resizing
This commit is contained in:
@@ -16,28 +16,32 @@ extern PyTypeObject Line_Type;
|
|||||||
#define SEGMENT_SIZE 2048
|
#define SEGMENT_SIZE 2048
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_segment(HistoryBuf *self) {
|
add_segment(HistoryBuf *self, index_type num) {
|
||||||
self->num_segments += 1;
|
self->segments = realloc(self->segments, sizeof(HistoryBufSegment) * (self->num_segments + num));
|
||||||
self->segments = realloc(self->segments, sizeof(HistoryBufSegment) * self->num_segments);
|
|
||||||
if (self->segments == NULL) fatal("Out of memory allocating new history buffer segment");
|
if (self->segments == NULL) fatal("Out of memory allocating new history buffer segment");
|
||||||
HistoryBufSegment *s = self->segments + self->num_segments - 1;
|
|
||||||
const size_t cpu_cells_size = self->xnum * SEGMENT_SIZE * sizeof(CPUCell);
|
const size_t cpu_cells_size = self->xnum * SEGMENT_SIZE * sizeof(CPUCell);
|
||||||
const size_t gpu_cells_size = self->xnum * SEGMENT_SIZE * sizeof(GPUCell);
|
const size_t gpu_cells_size = self->xnum * SEGMENT_SIZE * sizeof(GPUCell);
|
||||||
s->cpu_cells = calloc(1, cpu_cells_size + gpu_cells_size + SEGMENT_SIZE * sizeof(LineAttrs));
|
const size_t segment_size = cpu_cells_size + gpu_cells_size + SEGMENT_SIZE * sizeof(LineAttrs);
|
||||||
if (!s->cpu_cells) fatal("Out of memory allocating new history buffer segment");
|
char *mem = calloc(num, segment_size);
|
||||||
|
if (!mem) fatal("Out of memory allocating new history buffer segment");
|
||||||
|
self->segments[self->num_segments].mem = mem;
|
||||||
|
for (HistoryBufSegment *s = self->segments + self->num_segments; s < self->segments + self->num_segments + num; s++, mem += segment_size) {
|
||||||
|
s->cpu_cells = (CPUCell*)mem;
|
||||||
s->gpu_cells = (GPUCell*)(((uint8_t*)s->cpu_cells) + cpu_cells_size);
|
s->gpu_cells = (GPUCell*)(((uint8_t*)s->cpu_cells) + cpu_cells_size);
|
||||||
s->line_attrs = (LineAttrs*)(((uint8_t*)s->gpu_cells) + gpu_cells_size);
|
s->line_attrs = (LineAttrs*)(((uint8_t*)s->gpu_cells) + gpu_cells_size);
|
||||||
|
}
|
||||||
|
self->num_segments += num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_segment(HistoryBufSegment *s) {
|
free_segment(HistoryBufSegment *s) {
|
||||||
free(s->cpu_cells); memset(s, 0, sizeof(HistoryBufSegment));
|
free(s->mem); zero_at_ptr(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static index_type
|
static index_type
|
||||||
segment_for(HistoryBuf *self, index_type y) {
|
segment_for(HistoryBuf *self, index_type y) {
|
||||||
index_type seg_num = y / SEGMENT_SIZE;
|
index_type seg_num = y / SEGMENT_SIZE;
|
||||||
while (UNLIKELY(seg_num >= self->num_segments && SEGMENT_SIZE * self->num_segments < self->ynum)) add_segment(self);
|
while (UNLIKELY(seg_num >= self->num_segments && SEGMENT_SIZE * self->num_segments < self->ynum)) add_segment(self, 1);
|
||||||
if (UNLIKELY(seg_num >= self->num_segments)) fatal("Out of bounds access to history buffer line number: %u", y);
|
if (UNLIKELY(seg_num >= self->num_segments)) fatal("Out of bounds access to history buffer line number: %u", y);
|
||||||
return seg_num;
|
return seg_num;
|
||||||
}
|
}
|
||||||
@@ -125,7 +129,7 @@ create_historybuf(PyTypeObject *type, unsigned int xnum, unsigned int ynum, unsi
|
|||||||
self->xnum = xnum;
|
self->xnum = xnum;
|
||||||
self->ynum = ynum;
|
self->ynum = ynum;
|
||||||
self->num_segments = 0;
|
self->num_segments = 0;
|
||||||
add_segment(self);
|
add_segment(self, 1);
|
||||||
self->text_cache = tc_incref(tc);
|
self->text_cache = tc_incref(tc);
|
||||||
self->line = alloc_line(self->text_cache);
|
self->line = alloc_line(self->text_cache);
|
||||||
self->line->xnum = xnum;
|
self->line->xnum = xnum;
|
||||||
@@ -217,8 +221,10 @@ historybuf_clear(HistoryBuf *self) {
|
|||||||
pagerhist_clear(self);
|
pagerhist_clear(self);
|
||||||
self->count = 0;
|
self->count = 0;
|
||||||
self->start_of_data = 0;
|
self->start_of_data = 0;
|
||||||
for (size_t i = 1; i < self->num_segments; i++) free_segment(self->segments + i);
|
for (size_t i = 0; i < self->num_segments; i++) free_segment(self->segments + i);
|
||||||
self->num_segments = 1;
|
free(self->segments); self->segments = NULL;
|
||||||
|
self->num_segments = 0;
|
||||||
|
add_segment(self, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -626,7 +632,7 @@ historybuf_alloc_for_rewrap(unsigned int columns, HistoryBuf *self) {
|
|||||||
if (!self) return NULL;
|
if (!self) return NULL;
|
||||||
HistoryBuf *ans = alloc_historybuf(self->ynum, columns, 0, self->text_cache);
|
HistoryBuf *ans = alloc_historybuf(self->ynum, columns, 0, self->text_cache);
|
||||||
if (ans) {
|
if (ans) {
|
||||||
while(ans->num_segments < self->num_segments) add_segment(ans);
|
if (ans->num_segments < self->num_segments) add_segment(ans, self->num_segments - ans->num_segments);
|
||||||
ans->count = 0; ans->start_of_data = 0;
|
ans->count = 0; ans->start_of_data = 0;
|
||||||
}
|
}
|
||||||
return ans;
|
return ans;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ typedef struct {
|
|||||||
GPUCell *gpu_cells;
|
GPUCell *gpu_cells;
|
||||||
CPUCell *cpu_cells;
|
CPUCell *cpu_cells;
|
||||||
LineAttrs *line_attrs;
|
LineAttrs *line_attrs;
|
||||||
|
void *mem;
|
||||||
} HistoryBufSegment;
|
} HistoryBufSegment;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user