Skip to content

Commit

Permalink
Merge pull request #2 from zmkfirmware/optimize/reduce-stack-usage
Browse files Browse the repository at this point in the history
Various stack size reduction tweaks
  • Loading branch information
petejohanson authored Sep 26, 2024
2 parents 65cbefb + 6276a4f commit bf32817
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
16 changes: 16 additions & 0 deletions pb.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
/* Disable support for error messages in order to save some code space. */
/* #define PB_NO_ERRMSG 1 */

/* Disable checks to ensure sub-message encoded size is consistent when re-run. */
/* #define PB_NO_ENCODE_SIZE_CHECK 1 */

/* Disable support for custom streams (support only memory buffers). */
/* #define PB_BUFFER_ONLY 1 */

Expand Down Expand Up @@ -126,6 +129,19 @@ extern "C" {
# define pb_packed
#endif

// Define for explicitly not inlining a given function
#if defined(__GNUC__) || defined(__clang__)
/* For GCC and clang */
# define pb_noinline __attribute__((noinline))
#elif defined(__ICCARM__) || defined(__CC_ARM)
/* For IAR ARM and Keil MDK-ARM compilers */
# define pb_noinline
#elif defined(_MSC_VER) && (_MSC_VER >= 1500)
# define pb_noinline __declspec(noinline)
#else
# define pb_noinline
#endif

/* Detect endianness */
#ifndef PB_LITTLE_ENDIAN_8BIT
#if ((defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \
Expand Down
22 changes: 12 additions & 10 deletions pb_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *fie
static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field);
static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field);
static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field);
static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field);
static pb_noinline bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field);
static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension);
static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high);
static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field);
Expand Down Expand Up @@ -483,7 +483,7 @@ static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb

/* Walk through all the registered extensions and give them a chance
* to encode themselves. */
static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field)
static pb_noinline bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field)
{
const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData;

Expand Down Expand Up @@ -724,8 +724,6 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *
{
/* First calculate the message size using a non-writing substream. */
pb_ostream_t substream = PB_OSTREAM_SIZING;
size_t size;
bool status;

if (!pb_encode(&substream, fields, src_struct))
{
Expand All @@ -735,17 +733,20 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *
return false;
}

size = substream.bytes_written;

if (!pb_encode_varint(stream, (pb_uint64_t)size))
if (!pb_encode_varint(stream, (pb_uint64_t)substream.bytes_written))
return false;

if (stream->callback == NULL)
return pb_write(stream, NULL, size); /* Just sizing */
return pb_write(stream, NULL, substream.bytes_written); /* Just sizing */

if (stream->bytes_written + size > stream->max_size)
if (stream->bytes_written + substream.bytes_written > stream->max_size)
PB_RETURN_ERROR(stream, "stream full");

#if PB_NO_ENCODE_SIZE_CHECK
return pb_encode(stream, fields, src_struct);
#else
bool status;
size_t size = substream.bytes_written;
/* Use a substream to verify that a callback doesn't write more than
* what it did the first time. */
substream.callback = stream->callback;
Expand All @@ -766,8 +767,9 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *

if (substream.bytes_written != size)
PB_RETURN_ERROR(stream, "submsg size changed");

return status;
#endif
}

/* Field encoders */
Expand Down

0 comments on commit bf32817

Please sign in to comment.