Skip to content

Commit

Permalink
Mark rarely-used functions as "cold" in gcc.
Browse files Browse the repository at this point in the history
The compiler will optimise these functions for size, rather than speed.
It buys us a tiny reduction in executable size.  Moreover, it may reduce
instruction cache pressure in some cases.
  • Loading branch information
jtv committed Jan 7, 2022
1 parent 09d8ed9 commit fdb26ab
Show file tree
Hide file tree
Showing 19 changed files with 105 additions and 80 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- Build docs in `doc/html/`, no longer in `doc/html/Reference/`.
- Disable some `std::filesystem` features on Windows.
- Shut up stupid Visual Studio warnings.
- On gcc, mark rarely-used functions as "cold," to be optimised for size.
7.6.0
- Removed bad string conversion to `std::basic_string_view<std::byte>`. (#463)
- Add C++20 concepts: `binary`, `char_string`, `char_strings`.
Expand Down
2 changes: 1 addition & 1 deletion include/pqxx/connection.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ public:
/** Takes a binary string as escaped by PostgreSQL, and returns a restored
* copy of the original binary data.
*/
[[nodiscard, deprecated("Use unesc_bin() intead.")]] std::string
[[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string
unesc_raw(char const text[]) const;

// TODO: Make "into buffer" variant to eliminate a string allocation.
Expand Down
8 changes: 8 additions & 0 deletions include/pqxx/internal/compiler-public.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@
#endif


#if defined(__GNUC__)
/// Tell the compiler to optimise a function for size, not speed.
# define PQXX_COLD __attribute__((cold))
#else
# define PQXX_COLD /* cold */
#endif


// Workarounds for Windows
#ifdef _WIN32

Expand Down
2 changes: 1 addition & 1 deletion src/array.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
#include "pqxx/array"
#include "pqxx/except"

#include "pqxx/internal/compiler-internal-pre.hxx"
#include "pqxx/internal/array-composite.hxx"
#include "pqxx/internal/compiler-internal-post.hxx"
#include "pqxx/internal/compiler-internal-pre.hxx"

#include "pqxx/internal/concat.hxx"
#include "pqxx/strconv"
Expand Down
9 changes: 5 additions & 4 deletions src/binarystring.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace
{
/// Copy data to a heap-allocated buffer.
std::shared_ptr<unsigned char>
copy_to_buffer(void const *data, std::size_t len)
PQXX_COLD copy_to_buffer(void const *data, std::size_t len)
{
void *const output{malloc(len + 1)};
if (output == nullptr)
Expand All @@ -41,7 +41,7 @@ copy_to_buffer(void const *data, std::size_t len)
} // namespace


pqxx::binarystring::binarystring(field const &F)
PQXX_COLD pqxx::binarystring::binarystring(field const &F)
{
unsigned char const *data{
reinterpret_cast<unsigned char const *>(F.c_str())};
Expand Down Expand Up @@ -72,7 +72,8 @@ bool pqxx::binarystring::operator==(binarystring const &rhs) const noexcept
pqxx::binarystring &
pqxx::binarystring::operator=(binarystring const &rhs) = default;

pqxx::binarystring::const_reference pqxx::binarystring::at(size_type n) const
PQXX_COLD pqxx::binarystring::const_reference
pqxx::binarystring::at(size_type n) const
{
if (n >= m_size)
{
Expand All @@ -86,7 +87,7 @@ pqxx::binarystring::const_reference pqxx::binarystring::at(size_type n) const
}


void pqxx::binarystring::swap(binarystring &rhs)
PQXX_COLD void pqxx::binarystring::swap(binarystring &rhs)
{
m_buf.swap(rhs.m_buf);

Expand Down
2 changes: 1 addition & 1 deletion src/blob.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
#include "pqxx/blob"
#include "pqxx/except"

#include "pqxx/internal/compiler-internal-post.hxx"
#include "pqxx/internal/compiler-internal-pre.hxx"
#include "pqxx/internal/concat.hxx"
#include "pqxx/internal/gates/connection-largeobject.hxx"
#include "pqxx/internal/compiler-internal-post.hxx"


namespace
Expand Down
56 changes: 31 additions & 25 deletions src/connection.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ extern "C"

using namespace std::literals;

std::string pqxx::encrypt_password(char const user[], char const password[])
std::string PQXX_COLD
pqxx::encrypt_password(char const user[], char const password[])
{
std::unique_ptr<char, std::function<void(char *)>> p{
PQencryptPassword(password, user), PQfreemem};
Expand Down Expand Up @@ -249,7 +250,7 @@ pqxx::result pqxx::connection::make_result(
}


int pqxx::connection::backendpid() const &noexcept
int PQXX_COLD pqxx::connection::backendpid() const &noexcept
{
return (m_conn == nullptr) ? 0 : PQbackendPID(m_conn);
}
Expand All @@ -270,13 +271,13 @@ int pqxx::connection::sock() const &noexcept
}


int pqxx::connection::protocol_version() const noexcept
int PQXX_COLD pqxx::connection::protocol_version() const noexcept
{
return (m_conn == nullptr) ? 0 : PQprotocolVersion(m_conn);
}


int pqxx::connection::server_version() const noexcept
int PQXX_COLD pqxx::connection::server_version() const noexcept
{
return PQserverVersion(m_conn);
}
Expand Down Expand Up @@ -384,7 +385,7 @@ void pqxx::connection::process_notice(zview msg) noexcept
}


void pqxx::connection::trace(FILE *out) noexcept
void PQXX_COLD pqxx::connection::trace(FILE *out) noexcept
{
if (m_conn)
{
Expand All @@ -396,7 +397,7 @@ void pqxx::connection::trace(FILE *out) noexcept
}


void pqxx::connection::add_receiver(pqxx::notification_receiver *n)
void PQXX_COLD pqxx::connection::add_receiver(pqxx::notification_receiver *n)
{
if (n == nullptr)
throw argument_error{"Null receiver registered"};
Expand All @@ -420,7 +421,8 @@ void pqxx::connection::add_receiver(pqxx::notification_receiver *n)
}


void pqxx::connection::remove_receiver(pqxx::notification_receiver *T) noexcept
void PQXX_COLD
pqxx::connection::remove_receiver(pqxx::notification_receiver *T) noexcept
{
if (T == nullptr)
return;
Expand Down Expand Up @@ -468,7 +470,7 @@ bool pqxx::connection::is_busy() const noexcept
}


void pqxx::connection::cancel_query()
void PQXX_COLD pqxx::connection::cancel_query()
{
using pointer = std::unique_ptr<PGcancel, std::function<void(PGcancel *)>>;
pointer cancel{PQgetCancel(m_conn), PQfreeCancel};
Expand All @@ -490,7 +492,8 @@ namespace
{
/// Get error string for a given @c errno value.
template<std::size_t BYTES>
char const *error_string(int err_num, std::array<char, BYTES> &buffer)
char const *PQXX_COLD
error_string(int err_num, std::array<char, BYTES> &buffer)
{
// Not entirely clear whether strerror_s will be in std or global namespace.
using namespace std;
Expand Down Expand Up @@ -564,7 +567,8 @@ void pqxx::connection::set_blocking(bool block) &
#endif // defined(_WIN32) || __has_include(<fcntl.h>)


void pqxx::connection::set_verbosity(error_verbosity verbosity) &noexcept
void PQXX_COLD
pqxx::connection::set_verbosity(error_verbosity verbosity) &noexcept
{
PQsetErrorVerbosity(m_conn, static_cast<PGVerbosity>(verbosity));
}
Expand Down Expand Up @@ -639,25 +643,25 @@ int pqxx::connection::get_notifs()
}


char const *pqxx::connection::dbname() const
char const *PQXX_COLD pqxx::connection::dbname() const
{
return PQdb(m_conn);
}


char const *pqxx::connection::username() const
char const *PQXX_COLD pqxx::connection::username() const
{
return PQuser(m_conn);
}


char const *pqxx::connection::hostname() const
char const *PQXX_COLD pqxx::connection::hostname() const
{
return PQhost(m_conn);
}


char const *pqxx::connection::port() const
char const *PQXX_COLD pqxx::connection::port() const
{
return PQport(m_conn);
}
Expand All @@ -670,7 +674,7 @@ char const *pqxx::connection::err_msg() const noexcept
}


void pqxx::connection::register_errorhandler(errorhandler *handler)
void PQXX_COLD pqxx::connection::register_errorhandler(errorhandler *handler)
{
// Set notice processor on demand, i.e. only when the caller actually
// registers an error handler.
Expand All @@ -687,7 +691,8 @@ void pqxx::connection::register_errorhandler(errorhandler *handler)
}


void pqxx::connection::unregister_errorhandler(errorhandler *handler) noexcept
void PQXX_COLD
pqxx::connection::unregister_errorhandler(errorhandler *handler) noexcept
{
// The errorhandler itself will take care of nulling its pointer to this
// connection.
Expand All @@ -697,7 +702,8 @@ void pqxx::connection::unregister_errorhandler(errorhandler *handler) noexcept
}


std::vector<pqxx::errorhandler *> pqxx::connection::get_errorhandlers() const
std::vector<pqxx::errorhandler *>
PQXX_COLD pqxx::connection::get_errorhandlers() const
{
return {std::begin(m_errorhandlers), std::end(m_errorhandlers)};
}
Expand Down Expand Up @@ -963,7 +969,7 @@ std::string pqxx::connection::esc(std::string_view text) const
}


std::string
std::string PQXX_COLD
pqxx::connection::esc_raw(unsigned char const bin[], std::size_t len) const
{
return pqxx::internal::esc_bin(binary_cast(bin, len));
Expand All @@ -977,7 +983,7 @@ pqxx::connection::esc_raw(std::basic_string_view<std::byte> bin) const
}


std::string pqxx::connection::unesc_raw(char const text[]) const
std::string PQXX_COLD pqxx::connection::unesc_raw(char const text[]) const
{
if (text[0] == '\\' and text[1] == 'x')
{
Expand All @@ -1002,7 +1008,7 @@ std::string pqxx::connection::unesc_raw(char const text[]) const
}


std::string
std::string PQXX_COLD
pqxx::connection::quote_raw(unsigned char const bin[], std::size_t len) const
{
return internal::concat("'", esc_raw(binary_cast(bin, len)), "'::bytea");
Expand All @@ -1016,7 +1022,7 @@ pqxx::connection::quote_raw(std::basic_string_view<std::byte> bytes) const
}


std::string pqxx::connection::quote(binarystring const &b) const
std::string PQXX_COLD pqxx::connection::quote(binarystring const &b) const
{
return quote(b.bytes_view());
}
Expand Down Expand Up @@ -1173,7 +1179,7 @@ std::string pqxx::connection::get_client_encoding() const
}


void pqxx::connection::set_client_encoding(char const encoding[]) &
void PQXX_COLD pqxx::connection::set_client_encoding(char const encoding[]) &
{
switch (auto const retval{PQsetClientEncoding(m_conn, encoding)}; retval)
{
Expand Down Expand Up @@ -1246,12 +1252,12 @@ char const *get_default(PQconninfoOption const &opt) noexcept
// As of C++11, std::getenv() uses thread-local storage, so it should be
// thread-safe. MSVC still warns about it though.
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable: 4996)
# pragma warning(push)
# pragma warning(disable : 4996)
#endif
char const *var{std::getenv(opt.envvar)};
#if defined(_MSC_VER)
#pragma warning(pop)
# pragma warning(pop)
#endif
if (var == nullptr)
{
Expand Down
2 changes: 1 addition & 1 deletion src/encodings.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@

#include "pqxx/except"

#include "pqxx/internal/compiler-internal-post.hxx"
#include "pqxx/internal/compiler-internal-pre.hxx"
#include "pqxx/internal/concat.hxx"
#include "pqxx/internal/encodings.hxx"
#include "pqxx/internal/compiler-internal-post.hxx"

#include "pqxx/strconv"

Expand Down
2 changes: 1 addition & 1 deletion src/field.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pqxx::field::field(pqxx::row const &r, pqxx::row::size_type c) noexcept :
{}


bool pqxx::field::operator==(field const &rhs) const
bool PQXX_COLD pqxx::field::operator==(field const &rhs) const
{
if (is_null() and rhs.is_null())
return true;
Expand Down
Loading

0 comments on commit fdb26ab

Please sign in to comment.