perf: misc inlines and branch hints
Inlined trivial functions, added cold branch hints to error paths, added likely branch hints to common pathspull/9645/head
parent
58c26957b4
commit
3e8d94bb1c
|
|
@ -312,6 +312,7 @@ pub fn next(self: *Parser, c: u8) [3]?Action {
|
|||
|
||||
pub inline fn collect(self: *Parser, c: u8) void {
|
||||
if (self.intermediates_idx >= MAX_INTERMEDIATE) {
|
||||
@branchHint(.cold);
|
||||
log.warn("invalid intermediates count", .{});
|
||||
return;
|
||||
}
|
||||
|
|
@ -386,6 +387,7 @@ inline fn doAction(self: *Parser, action: TransitionAction, c: u8) ?Action {
|
|||
|
||||
// We only allow colon or mixed separators for the 'm' command.
|
||||
if (c != 'm' and self.params_sep.count() > 0) {
|
||||
@branchHint(.cold);
|
||||
log.warn(
|
||||
"CSI colon or mixed separators only allowed for 'm' command, got: {f}",
|
||||
.{result},
|
||||
|
|
|
|||
|
|
@ -293,7 +293,10 @@ pub fn print(self: *Terminal, c: u21) !void {
|
|||
// log.debug("print={x} y={} x={}", .{ c, self.screens.active.cursor.y, self.screens.active.cursor.x });
|
||||
|
||||
// If we're not on the main display, do nothing for now
|
||||
if (self.status_display != .main) return;
|
||||
if (self.status_display != .main) {
|
||||
@branchHint(.cold);
|
||||
return;
|
||||
}
|
||||
|
||||
// After doing any printing, wrapping, scrolling, etc. we want to ensure
|
||||
// that our screen remains in a consistent state.
|
||||
|
|
@ -313,6 +316,7 @@ pub fn print(self: *Terminal, c: u21) !void {
|
|||
self.modes.get(.grapheme_cluster) and
|
||||
self.screens.active.cursor.x > 0)
|
||||
grapheme: {
|
||||
@branchHint(.unlikely);
|
||||
// We need the previous cell to determine if we're at a grapheme
|
||||
// break or not. If we are NOT, then we are still combining the
|
||||
// same grapheme. Otherwise, we can stay in this cell.
|
||||
|
|
@ -478,6 +482,7 @@ pub fn print(self: *Terminal, c: u21) !void {
|
|||
|
||||
// Attach zero-width characters to our cell as grapheme data.
|
||||
if (width == 0) {
|
||||
@branchHint(.unlikely);
|
||||
// If we have grapheme clustering enabled, we don't blindly attach
|
||||
// any zero width character to our cells and we instead just ignore
|
||||
// it.
|
||||
|
|
@ -535,6 +540,7 @@ pub fn print(self: *Terminal, c: u21) !void {
|
|||
switch (width) {
|
||||
// Single cell is very easy: just write in the cell
|
||||
1 => {
|
||||
@branchHint(.likely);
|
||||
self.screens.active.cursorMarkDirty();
|
||||
@call(.always_inline, printCell, .{ self, c, .narrow });
|
||||
},
|
||||
|
|
@ -602,10 +608,14 @@ fn printCell(
|
|||
self.screens.active.charset.single_shift = null;
|
||||
break :blk key_once;
|
||||
} else self.screens.active.charset.gl;
|
||||
|
||||
const set = self.screens.active.charset.charsets.get(key);
|
||||
|
||||
// UTF-8 or ASCII is used as-is
|
||||
if (set == .utf8 or set == .ascii) break :c unmapped_c;
|
||||
if (set == .utf8 or set == .ascii) {
|
||||
@branchHint(.likely);
|
||||
break :c unmapped_c;
|
||||
}
|
||||
|
||||
// If we're outside of ASCII range this is an invalid value in
|
||||
// this table so we just return space.
|
||||
|
|
@ -718,6 +728,7 @@ fn printCell(
|
|||
// row so that the renderer can lookup rows with these much faster.
|
||||
if (comptime build_options.kitty_graphics) {
|
||||
if (c == kitty.graphics.unicode.placeholder) {
|
||||
@branchHint(.unlikely);
|
||||
self.screens.active.cursor.page_row.kitty_virtual_placeholder = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -727,6 +738,7 @@ fn printCell(
|
|||
// overwriting the same hyperlink.
|
||||
if (self.screens.active.cursor.hyperlink_id > 0) {
|
||||
self.screens.active.cursorSetHyperlink() catch |err| {
|
||||
@branchHint(.unlikely);
|
||||
log.warn("error reallocating for more hyperlink space, ignoring hyperlink err={}", .{err});
|
||||
assert(!cell.hyperlink);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -356,8 +356,12 @@ pub const RGB = packed struct(u24) {
|
|||
///
|
||||
/// The value should be between 0.0 and 1.0, inclusive.
|
||||
fn fromIntensity(value: []const u8) !u8 {
|
||||
const i = std.fmt.parseFloat(f64, value) catch return error.InvalidFormat;
|
||||
const i = std.fmt.parseFloat(f64, value) catch {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
};
|
||||
if (i < 0.0 or i > 1.0) {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
}
|
||||
|
||||
|
|
@ -370,10 +374,15 @@ pub const RGB = packed struct(u24) {
|
|||
/// value scaled in 4, 8, 12, or 16 bits, respectively.
|
||||
fn fromHex(value: []const u8) !u8 {
|
||||
if (value.len == 0 or value.len > 4) {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
}
|
||||
|
||||
const color = std.fmt.parseUnsigned(u16, value, 16) catch return error.InvalidFormat;
|
||||
const color = std.fmt.parseUnsigned(u16, value, 16) catch {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
};
|
||||
|
||||
const divisor: usize = switch (value.len) {
|
||||
1 => std.math.maxInt(u4),
|
||||
2 => std.math.maxInt(u8),
|
||||
|
|
@ -407,6 +416,7 @@ pub const RGB = packed struct(u24) {
|
|||
/// per color channel.
|
||||
pub fn parse(value: []const u8) !RGB {
|
||||
if (value.len == 0) {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
}
|
||||
|
||||
|
|
@ -433,7 +443,10 @@ pub const RGB = packed struct(u24) {
|
|||
.b = try RGB.fromHex(value[9..13]),
|
||||
},
|
||||
|
||||
else => return error.InvalidFormat,
|
||||
else => {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -443,6 +456,7 @@ pub const RGB = packed struct(u24) {
|
|||
if (x11_color.map.get(std.mem.trim(u8, value, " "))) |rgb| return rgb;
|
||||
|
||||
if (value.len < "rgb:a/a/a".len or !std.mem.eql(u8, value[0..3], "rgb")) {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
}
|
||||
|
||||
|
|
@ -454,6 +468,7 @@ pub const RGB = packed struct(u24) {
|
|||
} else false;
|
||||
|
||||
if (value[i] != ':') {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
}
|
||||
|
||||
|
|
@ -462,8 +477,10 @@ pub const RGB = packed struct(u24) {
|
|||
const r = r: {
|
||||
const slice = if (std.mem.indexOfScalarPos(u8, value, i, '/')) |end|
|
||||
value[i..end]
|
||||
else
|
||||
else {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
};
|
||||
|
||||
i += slice.len + 1;
|
||||
|
||||
|
|
@ -476,8 +493,10 @@ pub const RGB = packed struct(u24) {
|
|||
const g = g: {
|
||||
const slice = if (std.mem.indexOfScalarPos(u8, value, i, '/')) |end|
|
||||
value[i..end]
|
||||
else
|
||||
else {
|
||||
@branchHint(.cold);
|
||||
return error.InvalidFormat;
|
||||
};
|
||||
|
||||
i += slice.len + 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -524,6 +524,7 @@ pub const Parser = struct {
|
|||
// We always keep space for 1 byte at the end to null-terminate
|
||||
// values.
|
||||
if (self.buf_idx >= self.buf.len - 1) {
|
||||
@branchHint(.cold);
|
||||
if (self.state != .invalid) {
|
||||
log.warn(
|
||||
"OSC sequence too long (> {d}), ignoring. state={}",
|
||||
|
|
@ -1048,6 +1049,7 @@ pub const Parser = struct {
|
|||
';' => {
|
||||
const ext = self.buf[self.buf_start .. self.buf_idx - 1];
|
||||
if (!std.mem.eql(u8, ext, "notify")) {
|
||||
@branchHint(.cold);
|
||||
log.warn("unknown rxvt extension: {s}", .{ext});
|
||||
self.state = .invalid;
|
||||
return;
|
||||
|
|
@ -1601,11 +1603,13 @@ pub const Parser = struct {
|
|||
|
||||
fn endKittyColorProtocolOption(self: *Parser, kind: enum { key_only, key_and_value }, final: bool) void {
|
||||
if (self.temp_state.key.len == 0) {
|
||||
@branchHint(.cold);
|
||||
log.warn("zero length key in kitty color protocol", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
const key = kitty_color.Kind.parse(self.temp_state.key) orelse {
|
||||
@branchHint(.cold);
|
||||
log.warn("unknown key in kitty color protocol: {s}", .{self.temp_state.key});
|
||||
return;
|
||||
};
|
||||
|
|
@ -1620,6 +1624,7 @@ pub const Parser = struct {
|
|||
.kitty_color_protocol => |*v| {
|
||||
// Cap our allocation amount for our list.
|
||||
if (v.list.items.len >= @as(usize, kitty_color.Kind.max) * 2) {
|
||||
@branchHint(.cold);
|
||||
self.state = .invalid;
|
||||
log.warn("exceeded limit for number of keys in kitty color protocol, ignoring", .{});
|
||||
return;
|
||||
|
|
@ -1631,11 +1636,13 @@ pub const Parser = struct {
|
|||
|
||||
if (kind == .key_only or value.len == 0) {
|
||||
v.list.append(alloc, .{ .reset = key }) catch |err| {
|
||||
@branchHint(.cold);
|
||||
log.warn("unable to append kitty color protocol option: {}", .{err});
|
||||
return;
|
||||
};
|
||||
} else if (mem.eql(u8, "?", value)) {
|
||||
v.list.append(alloc, .{ .query = key }) catch |err| {
|
||||
@branchHint(.cold);
|
||||
log.warn("unable to append kitty color protocol option: {}", .{err});
|
||||
return;
|
||||
};
|
||||
|
|
@ -1651,6 +1658,7 @@ pub const Parser = struct {
|
|||
},
|
||||
},
|
||||
}) catch |err| {
|
||||
@branchHint(.cold);
|
||||
log.warn("unable to append kitty color protocol option: {}", .{err});
|
||||
return;
|
||||
};
|
||||
|
|
@ -1681,6 +1689,7 @@ pub const Parser = struct {
|
|||
const alloc = self.alloc.?;
|
||||
const list = self.buf_dynamic.?;
|
||||
list.append(alloc, 0) catch {
|
||||
@branchHint(.cold);
|
||||
log.warn("allocation failed on allocable string termination", .{});
|
||||
self.temp_state.str.* = "";
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1896,7 +1896,7 @@ pub const Cell = packed struct(u64) {
|
|||
return cell;
|
||||
}
|
||||
|
||||
pub fn isZero(self: Cell) bool {
|
||||
pub inline fn isZero(self: Cell) bool {
|
||||
return @as(u64, @bitCast(self)) == 0;
|
||||
}
|
||||
|
||||
|
|
@ -1906,7 +1906,7 @@ pub const Cell = packed struct(u64) {
|
|||
/// - Cell text is blank
|
||||
/// - Cell is styled but only with a background color and no text
|
||||
/// - Cell has a unicode placeholder for Kitty graphics protocol
|
||||
pub fn hasText(self: Cell) bool {
|
||||
pub inline fn hasText(self: Cell) bool {
|
||||
return switch (self.content_tag) {
|
||||
.codepoint,
|
||||
.codepoint_grapheme,
|
||||
|
|
@ -1918,7 +1918,7 @@ pub const Cell = packed struct(u64) {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn codepoint(self: Cell) u21 {
|
||||
pub inline fn codepoint(self: Cell) u21 {
|
||||
return switch (self.content_tag) {
|
||||
.codepoint,
|
||||
.codepoint_grapheme,
|
||||
|
|
@ -1931,14 +1931,14 @@ pub const Cell = packed struct(u64) {
|
|||
}
|
||||
|
||||
/// The width in grid cells that this cell takes up.
|
||||
pub fn gridWidth(self: Cell) u2 {
|
||||
pub inline fn gridWidth(self: Cell) u2 {
|
||||
return switch (self.wide) {
|
||||
.narrow, .spacer_head, .spacer_tail => 1,
|
||||
.wide => 2,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn hasStyling(self: Cell) bool {
|
||||
pub inline fn hasStyling(self: Cell) bool {
|
||||
return self.style_id != stylepkg.default_id;
|
||||
}
|
||||
|
||||
|
|
@ -1957,12 +1957,12 @@ pub const Cell = packed struct(u64) {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn hasGrapheme(self: Cell) bool {
|
||||
pub inline fn hasGrapheme(self: Cell) bool {
|
||||
return self.content_tag == .codepoint_grapheme;
|
||||
}
|
||||
|
||||
/// Returns true if the set of cells has text in it.
|
||||
pub fn hasTextAny(cells: []const Cell) bool {
|
||||
pub inline fn hasTextAny(cells: []const Cell) bool {
|
||||
for (cells) |cell| {
|
||||
if (cell.hasText()) return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ pub fn RefCountedSet(
|
|||
// we may end up with a PSL of `len` which would exceed the bounds.
|
||||
// In such a case, we claim to be out of memory.
|
||||
if (self.psl_stats[self.psl_stats.len - 1] > 0) {
|
||||
@branchHint(.cold);
|
||||
return AddError.OutOfMemory;
|
||||
}
|
||||
|
||||
|
|
@ -308,6 +309,7 @@ pub fn RefCountedSet(
|
|||
if (items[id].meta.ref == 0) {
|
||||
// See comment in `addContext` for details.
|
||||
if (self.psl_stats[self.psl_stats.len - 1] > 0) {
|
||||
@branchHint(.cold);
|
||||
return AddError.OutOfMemory;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue