From 0d23e179a67e3cd48fd528952255b59c250db8b6 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Wed, 12 Feb 2025 15:39:50 -0500 Subject: [PATCH] BMessage: Allocate more temporary data on the stack if possible. Some methods already did, but used a very large size of 16KB. Reduce that to 4KB, do it in more places, and use BStackOrHeapArray where possible. Change-Id: Ia2d64582e76da6c1850e502107c07cb10bcd8226 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8969 Reviewed-by: waddlesplash --- src/kits/app/Message.cpp | 60 ++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/src/kits/app/Message.cpp b/src/kits/app/Message.cpp index 62fec0e167..beda658c68 100644 --- a/src/kits/app/Message.cpp +++ b/src/kits/app/Message.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -114,6 +115,7 @@ handle_reply(port_id replyPort, int32* _code, bigtime_t timeout, BMessage* reply) { DEBUG_FUNCTION_ENTER2; + ssize_t size; do { size = port_buffer_size_etc(replyPort, B_RELATIVE_TIMEOUT, timeout); @@ -122,22 +124,19 @@ handle_reply(port_id replyPort, int32* _code, bigtime_t timeout, if (size < 0) return size; - status_t result; - char* buffer = (char*)malloc(size); - if (buffer == NULL) + BStackOrHeapArray buffer(size); + if (!buffer.IsValid()) return B_NO_MEMORY; + status_t result; do { result = read_port(replyPort, _code, buffer, size); } while (result == B_INTERRUPTED); - if (result < 0 || *_code != kPortMessageCode) { - free(buffer); + if (result < 0 || *_code != kPortMessageCode) return result < 0 ? result : B_ERROR; - } result = reply->Unflatten(buffer); - free(buffer); return result; } @@ -2133,7 +2132,9 @@ BMessage::_SendMessage(port_id port, team_id portOwner, int32 token, bigtime_t timeout, bool replyRequired, BMessenger& replyTo) const { DEBUG_FUNCTION_ENTER; + ssize_t size = 0; + char stackBuffer[4096]; char* buffer = NULL; message_header* header = NULL; status_t result = B_OK; @@ -2199,13 +2200,17 @@ BMessage::_SendMessage(port_id port, team_id portOwner, int32 token, #endif } else { size = FlattenedSize(); - buffer = (char*)malloc(size); - if (buffer == NULL) - return B_NO_MEMORY; + if (size > (ssize_t)sizeof(stackBuffer)) { + buffer = (char*)malloc(size); + if (buffer == NULL) + return B_NO_MEMORY; + } else + buffer = stackBuffer; result = Flatten(buffer, size); if (result != B_OK) { - free(buffer); + if (buffer != stackBuffer) + free(buffer); return result; } @@ -2269,7 +2274,8 @@ BMessage::_SendMessage(port_id port, team_id portOwner, int32 token, direct->Release(); } - free(buffer); + if (buffer != stackBuffer) + free(buffer); return result; } @@ -2751,25 +2757,16 @@ BMessage::AddMessage(const char* name, const BMessage* message) // copying an extra buffer. Functions can be added that return a direct // pointer into the message. - char stackBuffer[16384]; ssize_t size = message->FlattenedSize(); - - char* buffer; - if (size > (ssize_t)sizeof(stackBuffer)) { - buffer = (char*)malloc(size); - if (buffer == NULL) - return B_NO_MEMORY; - } else - buffer = stackBuffer; + BStackOrHeapArray buffer(size); + if (!buffer.IsValid()) + return B_NO_MEMORY; status_t error = message->Flatten(buffer, size); if (error >= B_OK) error = AddData(name, B_MESSAGE_TYPE, buffer, size, false); - if (buffer != stackBuffer) - free(buffer); - return error; } @@ -2787,25 +2784,16 @@ BMessage::AddFlat(const char* name, const BFlattenable* object, int32 count) if (object == NULL) return B_BAD_VALUE; - char stackBuffer[16384]; ssize_t size = object->FlattenedSize(); - - char* buffer; - if (size > (ssize_t)sizeof(stackBuffer)) { - buffer = (char*)malloc(size); - if (buffer == NULL) - return B_NO_MEMORY; - } else - buffer = stackBuffer; + BStackOrHeapArray buffer(size); + if (!buffer.IsValid()) + return B_NO_MEMORY; status_t error = object->Flatten(buffer, size); if (error >= B_OK) error = AddData(name, object->TypeCode(), buffer, size, false); - if (buffer != stackBuffer) - free(buffer); - return error; }