[api] Remove out-of-line write_raw_ wrappers to save flash

The wrappers called write_raw_inline_ which expanded the full fast
path code, defeating the purpose. Cold callers now call write_raw_slow_
directly with sent=-1, which is the same behavior without duplicating
the fast path at each cold call site.
This commit is contained in:
J. Nick Koston
2026-03-29 11:25:33 -10:00
parent 3af6001cdf
commit f1e780be0c
4 changed files with 6 additions and 17 deletions
@@ -112,14 +112,6 @@ APIError APIFrameHelper::drain_overflow_and_handle_errors_() {
return APIError::OK;
}
// Out-of-line wrappers — same logic as write_raw_inline_ but not force-inlined.
// Used by cold callers (handshake, error handling) to avoid code bloat.
APIError APIFrameHelper::write_raw_(const void *data, uint16_t len) { return this->write_raw_inline_(data, len); }
APIError APIFrameHelper::write_raw_(const struct iovec *iov, int iovcnt, uint16_t total_write_len) {
return this->write_raw_inline_(iov, iovcnt, total_write_len);
}
// Single-buffer slow path: wraps data in iovec and delegates to the iovec slow path.
APIError APIFrameHelper::write_raw_slow_(const void *data, uint16_t len, ssize_t sent) {
struct iovec iov = {const_cast<void *>(data), len};
+2 -5
View File
@@ -190,10 +190,6 @@ class APIFrameHelper {
// Returns OK for transient errors (WOULD_BLOCK), SOCKET_WRITE_FAILED for hard errors.
APIError drain_overflow_and_handle_errors_();
// Out-of-line write methods — used by cold paths (handshake, error handling)
APIError write_raw_(const void *data, uint16_t len);
APIError write_raw_(const struct iovec *iov, int iovcnt, uint16_t total_write_len);
// Inlined write methods — used by hot paths (write_protobuf_packet, write_protobuf_messages)
// These inline the fast path (overflow empty + full write) and tail-call the out-of-line
// slow path only on failure/partial write.
@@ -217,7 +213,8 @@ class APIFrameHelper {
return this->write_raw_slow_(iov, iovcnt, total_write_len, sent);
}
// Slow path: handle partial writes, errors, overflow buffering (private — only called by write_raw_inline_)
// Write methods — used by cold paths (handshake, error handling)
// These go through the slow path directly, avoiding inlining the fast path at the call site.
APIError write_raw_slow_(const void *data, uint16_t len, ssize_t sent);
APIError write_raw_slow_(const struct iovec *iov, int iovcnt, uint16_t total_write_len, ssize_t sent);
@@ -540,7 +540,7 @@ APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, uint16_t len) {
header[2] = (uint8_t) len;
if (len == 0) {
return this->write_raw_(header, 3);
return this->write_raw_slow_(header, 3, -1);
}
struct iovec iov[2];
iov[0].iov_base = header;
@@ -548,7 +548,7 @@ APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, uint16_t len) {
iov[1].iov_base = const_cast<uint8_t *>(data);
iov[1].iov_len = len;
return this->write_raw_(iov, 2, 3 + len);
return this->write_raw_slow_(iov, 2, 3 + len, -1);
}
/** Initiate the data structures for the handshake.
@@ -219,11 +219,11 @@ APIError APIPlaintextFrameHelper::read_packet(ReadPacketBuffer *buffer) {
"Bad indicator byte";
char msg[INDICATOR_MSG_SIZE];
memcpy_P(msg, MSG_PROGMEM, INDICATOR_MSG_SIZE);
this->write_raw_(msg, INDICATOR_MSG_SIZE);
this->write_raw_slow_(msg, INDICATOR_MSG_SIZE, -1);
#else
static const char MSG[] = "\x00"
"Bad indicator byte";
this->write_raw_(MSG, INDICATOR_MSG_SIZE);
this->write_raw_slow_(MSG, INDICATOR_MSG_SIZE, -1);
#endif
}
return aerr;