server: un-inline various large functions

Save approximiately 70k (ARM32) of size from the generated library of
libphosphor-dbus.so by un-inlining various large functions.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ie238ca7807960bf1577dcbb272226f197de84b01
diff --git a/include/sdbusplus/bus.hpp b/include/sdbusplus/bus.hpp
index 2b676ae..0fe6df8 100644
--- a/include/sdbusplus/bus.hpp
+++ b/include/sdbusplus/bus.hpp
@@ -402,12 +402,7 @@
      *  @param[in] ifaces - The interfaces to forward.
      */
     void emit_interfaces_added(const char* path,
-                               const std::vector<std::string>& ifaces)
-    {
-        details::Strv s{ifaces};
-        _intf->sd_bus_emit_interfaces_added_strv(_bus.get(), path,
-                                                 static_cast<char**>(s));
-    }
+                               const std::vector<std::string>& ifaces);
 
     /** @brief Wrapper for sd_bus_emit_interfaces_removed_strv
      *
@@ -419,12 +414,7 @@
      *  @param[in] ifaces - The interfaces to forward.
      */
     void emit_interfaces_removed(const char* path,
-                                 const std::vector<std::string>& ifaces)
-    {
-        details::Strv s{ifaces};
-        _intf->sd_bus_emit_interfaces_removed_strv(_bus.get(), path,
-                                                   static_cast<char**>(s));
-    }
+                                 const std::vector<std::string>& ifaces);
 
     /** @brief Wrapper for sd_bus_emit_object_added
      *
diff --git a/include/sdbusplus/sdbuspp_support/server.hpp b/include/sdbusplus/sdbuspp_support/server.hpp
index 0044e0b..113fb5d 100644
--- a/include/sdbusplus/sdbuspp_support/server.hpp
+++ b/include/sdbusplus/sdbuspp_support/server.hpp
@@ -33,10 +33,7 @@
         auto m = message::message(msg, intf);
 
         // Set up the transaction.
-        auto tbus = m.get_bus();
-        sdbusplus::server::transaction::Transaction t(tbus, m);
-        sdbusplus::server::transaction::set_id(
-            std::hash<sdbusplus::server::transaction::Transaction>{}(t));
+        server::transaction::set_id(m);
 
         // Read arguments from the message.
         std::tuple<Args...> arg{};
@@ -90,10 +87,7 @@
         auto m = message::message(msg, intf);
 
         // Set up the transaction.
-        auto tbus = m.get_bus();
-        sdbusplus::server::transaction::Transaction t(tbus, m);
-        sdbusplus::server::transaction::set_id(
-            std::hash<sdbusplus::server::transaction::Transaction>{}(t));
+        server::transaction::set_id(m);
 
         // Read arguments from the message.
         std::tuple<Args...> arg{};
diff --git a/include/sdbusplus/server/interface.hpp b/include/sdbusplus/server/interface.hpp
index eb55792..f12270c 100644
--- a/include/sdbusplus/server/interface.hpp
+++ b/include/sdbusplus/server/interface.hpp
@@ -58,26 +58,9 @@
      *                       the interface implementation class.
      */
     interface(sdbusplus::bus::bus& bus, const char* path, const char* interf,
-              const sdbusplus::vtable::vtable_t* vtable, void* context) :
-        _bus(bus.get(), bus.getInterface()),
-        _path(path), _interf(interf), _slot(nullptr), _intf(bus.getInterface()),
-        _interface_added(false)
-    {
-        sd_bus_slot* slot = nullptr;
-        int r = _intf->sd_bus_add_object_vtable(
-            _bus.get(), &slot, _path.c_str(), _interf.c_str(), vtable, context);
-        if (r < 0)
-        {
-            throw exception::SdBusError(-r, "sd_bus_add_object_vtable");
-        }
+              const sdbusplus::vtable::vtable_t* vtable, void* context);
 
-        _slot = decltype(_slot){slot};
-    }
-
-    ~interface()
-    {
-        emit_removed();
-    }
+    ~interface();
 
     /** @brief Create a new signal message.
      *
@@ -92,15 +75,7 @@
      *
      *  @param[in] property - The property which changed.
      */
-    void property_changed(const char* property)
-    {
-        std::array<const char*, 2> values = {property, nullptr};
-
-        // Note: Converting to use _strv version, could also mock two pointer
-        // use-case explicitly.
-        _intf->sd_bus_emit_properties_changed_strv(
-            _bus.get(), _path.c_str(), _interf.c_str(), values.data());
-    }
+    void property_changed(const char* property);
 
     /** @brief Emit the interface is added on D-Bus */
     void emit_added()
diff --git a/include/sdbusplus/server/transaction.hpp b/include/sdbusplus/server/transaction.hpp
index 0cdea88..0ec39f0 100644
--- a/include/sdbusplus/server/transaction.hpp
+++ b/include/sdbusplus/server/transaction.hpp
@@ -52,72 +52,30 @@
 template <>
 struct hash<sdbusplus::bus::bus>
 {
-    auto operator()(sdbusplus::bus::bus& b) const
-    {
-        auto name = b.get_unique_name();
-        return std::hash<std::string>{}(name);
-    }
+    size_t operator()(sdbusplus::bus::bus& b) const;
 };
 
 /** @ brief Overload of std::hash for sdbusplus::message::message */
 template <>
 struct hash<sdbusplus::message::message>
 {
-    auto operator()(sdbusplus::message::message& m) const
-    {
-        switch (m.get_type())
-        {
-            // Reply messages will always embed the cookie of the original
-            // message in a separate location. We want to use this cookie
-            // to correlate messages as one transaction.
-            case SD_BUS_MESSAGE_METHOD_RETURN:
-            case SD_BUS_MESSAGE_METHOD_ERROR:
-                return std::hash<uint64_t>{}(m.get_reply_cookie());
-            // Method calls will have the cookie in the header when sealed.
-            // Since we are on the server side that should always be the case.
-            case SD_BUS_MESSAGE_METHOD_CALL:
-                return std::hash<uint64_t>{}(m.get_cookie());
-            // Outgoing signals don't have a cookie so we need to use
-            // something else as an id. Just use a monotonic unique one.
-            case SD_BUS_MESSAGE_SIGNAL:
-                return std::hash<uint64_t>{}(std::chrono::steady_clock::now()
-                                                 .time_since_epoch()
-                                                 .count());
-            default:
-                throw std::runtime_error("hash message: Unknown message type");
-        }
-    }
+    size_t operator()(sdbusplus::message::message& m) const;
 };
 
 /** @ brief Overload of std::hash for Transaction */
 template <>
 struct hash<sdbusplus::server::transaction::Transaction>
 {
-    auto operator()(sdbusplus::server::transaction::Transaction const& t) const
-    {
-        auto hash1 = std::hash<sdbusplus::bus::bus>{}(t.bus);
-        auto hash2 = std::hash<sdbusplus::message::message>{}(t.msg);
-
-        // boost::hash_combine() algorithm.
-        return static_cast<size_t>(
-            hash1 ^ (hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2)));
-    }
+    size_t
+        operator()(sdbusplus::server::transaction::Transaction const& t) const;
 };
 
 /** @ brief Overload of std::hash for details::Transaction */
 template <>
 struct hash<sdbusplus::server::transaction::details::Transaction>
 {
-    auto operator()(
-        sdbusplus::server::transaction::details::Transaction const& t) const
-    {
-        auto hash1 = std::hash<int>{}(t.time);
-        auto hash2 = std::hash<std::thread::id>{}(t.thread);
-
-        // boost::hash_combine() algorithm.
-        return static_cast<size_t>(
-            hash1 ^ (hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2)));
-    }
+    size_t operator()(
+        sdbusplus::server::transaction::details::Transaction const& t) const;
 };
 
 } // namespace std
@@ -133,25 +91,19 @@
  *
  * @return The value of the transaction id
  */
-inline uint64_t get_id()
-{
-    // If the transaction id has not been initialized, generate one.
-    if (!details::id)
-    {
-        details::Transaction t;
-        details::id = std::hash<details::Transaction>{}(t);
-    }
-    return details::id;
-}
+uint64_t get_id();
 
 /** @brief Set transaction id
  *
  * @param[in] value - Desired value for the transaction id
  */
-inline void set_id(uint64_t value)
-{
-    details::id = value;
-}
+void set_id(uint64_t value);
+
+/** @brief Set transaction from message.
+ *
+ * @param[in] msg - The message to create the transaction from.
+ */
+void set_id(message::message& msg);
 
 } // namespace transaction
 } // namespace server
diff --git a/meson.build b/meson.build
index e089391..1a48479 100644
--- a/meson.build
+++ b/meson.build
@@ -15,7 +15,9 @@
 
 libsdbusplus_src = files(
     'src/exception.cpp',
+    'src/bus.cpp',
     'src/sdbus.cpp',
+    'src/server/interface.cpp',
     'src/server/transaction.cpp',
 )
 
diff --git a/src/bus.cpp b/src/bus.cpp
new file mode 100644
index 0000000..6dc2309
--- /dev/null
+++ b/src/bus.cpp
@@ -0,0 +1,25 @@
+#include <sdbusplus/bus.hpp>
+
+namespace sdbusplus
+{
+namespace bus
+{
+
+void bus::emit_interfaces_added(const char* path,
+                                const std::vector<std::string>& ifaces)
+{
+    details::Strv s{ifaces};
+    _intf->sd_bus_emit_interfaces_added_strv(_bus.get(), path,
+                                             static_cast<char**>(s));
+}
+
+void bus::emit_interfaces_removed(const char* path,
+                                  const std::vector<std::string>& ifaces)
+{
+    details::Strv s{ifaces};
+    _intf->sd_bus_emit_interfaces_removed_strv(_bus.get(), path,
+                                               static_cast<char**>(s));
+}
+
+} // namespace bus
+} // namespace sdbusplus
diff --git a/src/server/interface.cpp b/src/server/interface.cpp
new file mode 100644
index 0000000..a72c656
--- /dev/null
+++ b/src/server/interface.cpp
@@ -0,0 +1,47 @@
+#include <sdbusplus/server/interface.hpp>
+
+namespace sdbusplus
+{
+
+namespace server
+{
+
+namespace interface
+{
+
+interface::interface(sdbusplus::bus::bus& bus, const char* path,
+                     const char* interf,
+                     const sdbusplus::vtable::vtable_t* vtable, void* context) :
+    _bus(bus.get(), bus.getInterface()),
+    _path(path), _interf(interf), _slot(nullptr), _intf(bus.getInterface()),
+    _interface_added(false)
+{
+    sd_bus_slot* slot = nullptr;
+    int r = _intf->sd_bus_add_object_vtable(_bus.get(), &slot, _path.c_str(),
+                                            _interf.c_str(), vtable, context);
+    if (r < 0)
+    {
+        throw exception::SdBusError(-r, "sd_bus_add_object_vtable");
+    }
+
+    _slot = decltype(_slot){slot};
+}
+
+interface::~interface()
+{
+    emit_removed();
+}
+
+void interface::property_changed(const char* property)
+{
+    std::array<const char*, 2> values = {property, nullptr};
+
+    // Note: Converting to use _strv version, could also mock two pointer
+    // use-case explicitly.
+    _intf->sd_bus_emit_properties_changed_strv(_bus.get(), _path.c_str(),
+                                               _interf.c_str(), values.data());
+}
+
+} // namespace interface
+} // namespace server
+} // namespace sdbusplus
diff --git a/src/server/transaction.cpp b/src/server/transaction.cpp
index 2a9697f..52f9043 100644
--- a/src/server/transaction.cpp
+++ b/src/server/transaction.cpp
@@ -13,6 +13,87 @@
 thread_local uint64_t id = 0;
 
 } // namespace details
+
+uint64_t get_id()
+{
+    // If the transaction id has not been initialized, generate one.
+    if (!details::id)
+    {
+        details::Transaction t;
+        details::id = std::hash<details::Transaction>{}(t);
+    }
+    return details::id;
+}
+
+void set_id(uint64_t value)
+{
+    details::id = value;
+}
+
+void set_id(message::message& msg)
+{
+    auto tbus = msg.get_bus();
+    auto t = Transaction(tbus, msg);
+    set_id(std::hash<Transaction>{}(t));
+}
+
 } // namespace transaction
 } // namespace server
 } // namespace sdbusplus
+
+namespace std
+{
+
+size_t hash<sdbusplus::bus::bus>::operator()(sdbusplus::bus::bus& b) const
+{
+    auto name = b.get_unique_name();
+    return std::hash<std::string>{}(name);
+}
+
+size_t hash<sdbusplus::message::message>::operator()(
+    sdbusplus::message::message& m) const
+{
+    switch (m.get_type())
+    {
+        // Reply messages will always embed the cookie of the original
+        // message in a separate location. We want to use this cookie
+        // to correlate messages as one transaction.
+        case SD_BUS_MESSAGE_METHOD_RETURN:
+        case SD_BUS_MESSAGE_METHOD_ERROR:
+            return std::hash<uint64_t>{}(m.get_reply_cookie());
+        // Method calls will have the cookie in the header when sealed.
+        // Since we are on the server side that should always be the case.
+        case SD_BUS_MESSAGE_METHOD_CALL:
+            return std::hash<uint64_t>{}(m.get_cookie());
+        // Outgoing signals don't have a cookie so we need to use
+        // something else as an id. Just use a monotonic unique one.
+        case SD_BUS_MESSAGE_SIGNAL:
+            return std::hash<uint64_t>{}(
+                std::chrono::steady_clock::now().time_since_epoch().count());
+        default:
+            throw std::runtime_error("hash message: Unknown message type");
+    }
+}
+
+size_t hash<sdbusplus::server::transaction::Transaction>::operator()(
+    sdbusplus::server::transaction::Transaction const& t) const
+{
+    auto hash1 = std::hash<sdbusplus::bus::bus>{}(t.bus);
+    auto hash2 = std::hash<sdbusplus::message::message>{}(t.msg);
+
+    // boost::hash_combine() algorithm.
+    return static_cast<size_t>(
+        hash1 ^ (hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2)));
+}
+
+size_t hash<sdbusplus::server::transaction::details::Transaction>::operator()(
+    sdbusplus::server::transaction::details::Transaction const& t) const
+{
+    auto hash1 = std::hash<int>{}(t.time);
+    auto hash2 = std::hash<std::thread::id>{}(t.thread);
+
+    // boost::hash_combine() algorithm.
+    return static_cast<size_t>(
+        hash1 ^ (hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2)));
+}
+} // namespace std