summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/ipc_message_impl_macros.h2
-rw-r--r--ipc/ipc_message_utils.h44
-rw-r--r--ipc/ipc_message_utils_impl.h25
3 files changed, 42 insertions, 29 deletions
diff --git a/ipc/ipc_message_impl_macros.h b/ipc/ipc_message_impl_macros.h
index 1098357..f9eede9 100644
--- a/ipc/ipc_message_impl_macros.h
+++ b/ipc/ipc_message_impl_macros.h
@@ -200,7 +200,7 @@
\
void msg_class::Log(const Message* msg, std::wstring* l) { \
if (msg->is_sync()) { \
- SendParam p; \
+ TupleTypes<SendParam>::ValueTuple p; \
if (ReadSendParam(msg, &p)) \
IPC::LogParam(p, l); \
\
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index 12eb02f..05d3916 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -20,6 +20,21 @@
#include "base/utf_string_conversions.h"
#include "ipc/ipc_sync_message.h"
+#if defined(COMPILER_GCC)
+// GCC "helpfully" tries to inline template methods in release mode. Except we
+// want the majority of the template junk being expanded once in the
+// implementation file (and only provide the definitions in
+// ipc_message_utils_impl.h in those files) and exported, instead of expanded
+// at every call site. Special note: GCC happily accepts the attribute before
+// the method declaration, but only acts on it if it is after.
+#define IPC_MSG_NOINLINE __attribute__((noinline));
+#elif defined(COMPILER_MSVC)
+// MSVC++ doesn't do this.
+#define IPC_MSG_NOINLINE
+#else
+#error "Please add the noinline property for your new compiler here."
+#endif
+
// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
// base. Messages have unique IDs across channels in order for the IPC logging
// code to figure out the message class from its ID.
@@ -960,16 +975,7 @@ class MessageWithTuple : public Message {
// those translation units.
MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
- // TODO(erg): Migrate this method into ipc_message_utils_impl.h once I figure
- // out why just having the template in that file and the forward declaration
- // here breaks the release build.
- static bool Read(const Message* msg, Param* p) {
- void* iter = NULL;
- if (ReadParam(msg, &iter, p))
- return true;
- NOTREACHED() << "Error deserializing message " << msg->type();
- return false;
- }
+ static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
// Generic dispatcher. Should cover most cases.
template<class T, class Method>
@@ -1160,20 +1166,10 @@ class MessageWithReply : public SyncMessage {
MessageWithReply(int32 routing_id, uint32 type,
const RefSendParam& send, const ReplyParam& reply);
-
- // TODO(erg): Migrate these ReadSendParam/ReadReplyParam() methods to
- // ipc_message_utils_impl.h once I figure out how to get the linkage correct
- // in the release builds.
- static bool ReadSendParam(const Message* msg, SendParam* p) {
- void* iter = SyncMessage::GetDataIterator(msg);
- return ReadParam(msg, &iter, p);
- }
-
- static bool ReadReplyParam(const Message* msg,
- typename TupleTypes<ReplyParam>::ValueTuple* p) {
- void* iter = SyncMessage::GetDataIterator(msg);
- return ReadParam(msg, &iter, p);
- }
+ static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
+ static bool ReadReplyParam(
+ const Message* msg,
+ typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
template<class T, class Method>
static bool Dispatch(const Message* msg, T* obj, Method func) {
diff --git a/ipc/ipc_message_utils_impl.h b/ipc/ipc_message_utils_impl.h
index 53c7986..715df8f 100644
--- a/ipc/ipc_message_utils_impl.h
+++ b/ipc/ipc_message_utils_impl.h
@@ -18,8 +18,14 @@ MessageWithTuple<ParamType>::MessageWithTuple(
WriteParam(this, p);
}
-// TODO(erg): Migrate MessageWithTuple<ParamType>::Read() here once I figure
-// out why having the definition here doesn't export the symbols.
+template <class ParamType>
+bool MessageWithTuple<ParamType>::Read(const Message* msg, Param* p) {
+ void* iter = NULL;
+ if (ReadParam(msg, &iter, p))
+ return true;
+ NOTREACHED() << "Error deserializing message " << msg->type();
+ return false;
+}
// We can't migrate the template for Log() to MessageWithTuple, because each
// subclass needs to have Log() to call Read(), which instantiates the above
@@ -35,8 +41,19 @@ MessageWithReply<SendParamType, ReplyParamType>::MessageWithReply(
WriteParam(this, send);
}
-// TODO(erg): Migrate ReadSendParam()/ReadReplyParam() here when we can force
-// the visibility/linkage.
+template <class SendParamType, class ReplyParamType>
+bool MessageWithReply<SendParamType, ReplyParamType>::ReadSendParam(
+ const Message* msg, SendParam* p) {
+ void* iter = SyncMessage::GetDataIterator(msg);
+ return ReadParam(msg, &iter, p);
+}
+
+template <class SendParamType, class ReplyParamType>
+bool MessageWithReply<SendParamType, ReplyParamType>::ReadReplyParam(
+ const Message* msg, typename TupleTypes<ReplyParam>::ValueTuple* p) {
+ void* iter = SyncMessage::GetDataIterator(msg);
+ return ReadParam(msg, &iter, p);
+}
} // namespace IPC