Index: Source/platform/TraceEvent.h |
diff --git a/Source/platform/TraceEvent.h b/Source/platform/TraceEvent.h |
index 5c3589342823d0e9d72c6ade1cb61ce2cee2c382..fd6d2101632f6c6b9a2e9cfaf5806be151a332c3 100644 |
--- a/Source/platform/TraceEvent.h |
+++ b/Source/platform/TraceEvent.h |
@@ -125,15 +125,18 @@ |
// macros. |
// |
// When are string argument values copied: |
-// const char* arg_values are only referenced by default: |
+// - Literal string is always allowed: |
+// TRACE_EVENT1("category", "name", "arg1", "literal string"); |
+// - Use TRACE_STR_COPY to force copying of a const char*: |
// TRACE_EVENT1("category", "name", |
-// "arg1", "literal string is only referenced"); |
-// Use TRACE_STR_COPY to force copying of a const char*: |
+// "arg1", TRACE_STR_COPY(string_will_be_copied)); |
+// - Use TRACE_STR_NO_COPY to explicitly pass a const char* that is ensured |
+// long-lived without copy: |
// TRACE_EVENT1("category", "name", |
-// "arg1", TRACE_STR_COPY("string will be copied")); |
-// std::string arg_values are always copied: |
+// "arg1", TRACE_STR_NO_COPY(long_lived_string)); |
+// - std::string arg_values are always copied: |
// TRACE_EVENT1("category", "name", |
-// "arg1", std::string("string will be copied")); |
+// "arg1", std::string(string_will_be_copied)); |
// |
// |
// Thread Safety: |
@@ -169,10 +172,13 @@ |
#include "wtf/PassRefPtr.h" |
#include "wtf/text/CString.h" |
-// By default, const char* argument values are assumed to have long-lived scope |
-// and will not be copied. Use this macro to force a const char* to be copied. |
+// Non-literal const char* argument values are not allowed. |
+// Use this macro to force a const char* to be copied. |
#define TRACE_STR_COPY(str) \ |
- WebCore::TraceEvent::TraceStringWithCopy(str) |
+ WebCore::TraceEvent::TraceStringWrapper<true>(str) |
+// And use this macro to explicitly pass a long-lived const char*. |
+#define TRACE_STR_NO_COPY(str) \ |
+ WebCore::TraceEvent::TraceStringWrapper<false>(str) |
// By default, uint64 ID argument values are not mangled with the Process ID in |
// TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling. |
@@ -734,11 +740,13 @@ union TraceValueUnion { |
const char* m_string; |
}; |
-// Simple container for const char* that should be copied instead of retained. |
-class TraceStringWithCopy { |
+// Simple container for const char*. The string will be copied or retained |
+// according to the Copy template parameter. |
+template <bool Copy> |
dsinclair
2014/06/17 20:47:16
Can we make the template parameter an enum? CopySt
Xianzhu
2014/06/17 21:27:35
Done with a slightly different method using TraceS
|
+class TraceStringWrapper { |
public: |
- explicit TraceStringWithCopy(const char* str) : m_str(str) { } |
- operator const char* () const { return m_str; } |
+ explicit TraceStringWrapper(const char* str) : m_str(str) { } |
+ const char* str() const { return m_str; } |
private: |
const char* m_str; |
}; |
@@ -746,24 +754,17 @@ private: |
// Define setTraceValue for each allowed type. It stores the type and |
// value in the return arguments. This allows this API to avoid declaring any |
// structures so that it is portable to third_party libraries. |
-#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \ |
- union_member, \ |
- value_type_id) \ |
- static inline void setTraceValue(actual_type arg, \ |
- unsigned char* type, \ |
- unsigned long long* value) { \ |
+#define INTERNAL_DECLARE_SET_TRACE_VALUE(actualType, argExpression, unionMember, valueTypeId) \ |
+ static inline void setTraceValue(actualType arg, unsigned char* type, unsigned long long* value) { \ |
TraceValueUnion typeValue; \ |
- typeValue.union_member = arg; \ |
- *type = value_type_id; \ |
+ typeValue.unionMember = argExpression; \ |
+ *type = valueTypeId; \ |
*value = typeValue.m_uint; \ |
} |
// Simpler form for int types that can be safely casted. |
-#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \ |
- value_type_id) \ |
- static inline void setTraceValue(actual_type arg, \ |
- unsigned char* type, \ |
- unsigned long long* value) { \ |
- *type = value_type_id; \ |
+#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actualType, valueTypeId) \ |
+ static inline void setTraceValue(actualType arg, unsigned char* type, unsigned long long* value) { \ |
+ *type = valueTypeId; \ |
*value = static_cast<unsigned long long>(arg); \ |
} |
@@ -775,19 +776,44 @@ INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT) |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT) |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT) |
INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT) |
-INTERNAL_DECLARE_SET_TRACE_VALUE(bool, m_bool, TRACE_VALUE_TYPE_BOOL) |
-INTERNAL_DECLARE_SET_TRACE_VALUE(double, m_double, TRACE_VALUE_TYPE_DOUBLE) |
-INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, m_pointer, |
- TRACE_VALUE_TYPE_POINTER) |
-INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, m_string, |
- TRACE_VALUE_TYPE_STRING) |
-INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, m_string, |
- TRACE_VALUE_TYPE_COPY_STRING) |
+INTERNAL_DECLARE_SET_TRACE_VALUE(bool, arg, m_bool, TRACE_VALUE_TYPE_BOOL) |
+INTERNAL_DECLARE_SET_TRACE_VALUE(double, arg, m_double, TRACE_VALUE_TYPE_DOUBLE) |
+INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWrapper<false>&, arg.str(), m_string, TRACE_VALUE_TYPE_STRING) |
+INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWrapper<true>&, arg.str(), m_string, TRACE_VALUE_TYPE_COPY_STRING) |
#undef INTERNAL_DECLARE_SET_TRACE_VALUE |
#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT |
-// WTF::String version of setTraceValue so that trace arguments can be strings. |
+template <typename T> |
+struct TraceValuePointerTypeAllowed { |
+ static const bool allowed = true; |
+}; |
+ |
+template <> |
+struct TraceValuePointerTypeAllowed<char> { |
+ static const bool allowed = false; |
+}; |
+ |
+// Pointer version of SetTraceValue, but const char* is not allowed. |
+template <typename T> |
+static inline void setTraceValue(const T* arg, unsigned char* type, unsigned long long* value) |
+{ |
+ COMPILE_ASSERT(TraceValuePointerTypeAllowed<T>::allowed, invalid_pointer_type); |
+ TraceValueUnion typeValue; |
+ typeValue.m_pointer = arg; |
+ *type = TRACE_VALUE_TYPE_POINTER; |
+ *value = typeValue.m_uint; |
+} |
+ |
+// Allow literal string. |
+// FIXME: This will also allow passing local char arrays. Is it possible to avoid? |
+template <size_t N> |
+static inline void setTraceValue(const char (&arg)[N], unsigned char* type, unsigned long long* value) |
dsinclair
2014/06/17 20:47:16
This is going to end up stamping out a function fo
Xianzhu
2014/06/17 21:27:35
There should be no difference before and after the
|
+{ |
+ setTraceValue(TRACE_STR_NO_COPY(arg), type, value); |
+} |
+ |
+// WTF::CString version of setTraceValue so that trace arguments can be strings. |
static inline void setTraceValue(const WTF::CString& arg, unsigned char* type, unsigned long long* value) |
{ |
TraceValueUnion typeValue; |