Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(902)

Unified Diff: base/debug/trace_event_value.h

Issue 19642005: Make TracedValue lower overhead. Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Validations for dictionary entries, CR comments, and additional check before writting. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/debug/trace_event_value.h
diff --git a/base/debug/trace_event_value.h b/base/debug/trace_event_value.h
new file mode 100644
index 0000000000000000000000000000000000000000..f2ed888620f989b53c8e08d85323548306d6aafd
--- /dev/null
+++ b/base/debug/trace_event_value.h
@@ -0,0 +1,160 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_DEBUG_TRACE_EVENT_VALUE_H_
+#define BASE_DEBUG_TRACE_EVENT_VALUE_H_
+
+#include <stack>
+#include <string>
+
+#include "base/debug/trace_event.h"
+#include "base/debug/trace_event_object.h"
+#include "base/format_macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/pickle.h"
+#include "base/threading/non_thread_safe.h"
+
+namespace base {
+namespace debug {
+
+// TracedValue has several functions to push data that will be converted to
+// trace event format without depending on base::Value objects.
+class BASE_EXPORT TracedValue : public base::debug::ConvertableToTraceFormat,
+ public base::NonThreadSafe {
+ public:
+ TracedValue();
+ virtual ~TracedValue();
+
+ virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE;
+
+ // Begin a dictionary, it can either be a top-level structure or a value in
+ // an array.
+ void BeginDictionary();
+ // Used for both BeginDictionary() and PushDictionary().
+ void EndDictionary();
+ // Begin an array, that is either a top-level structure or a value in an
+ // array.
+ void BeginArray();
+ // Used for both BeginArray() and PushArray().
+ void EndArray();
+
+ // Put stuff in dictionary using statically allocated string keys.
+ // Begins a dictionary, that is an entry within another dictionary.
+ void PushDictionary(const char* key_in_parent_dict);
+ // Begins an array, that is an entry within a dictonary.
+ void PushArray(const char* key_in_parent_dict);
+#define TRACE_PUSH(type) \
+ void Push(const char* key, type value) { \
+ DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top()); \
+ BeginDictionaryEntry(); \
+ PushKeyToPickle(key); \
+ PushValueToPickle(value); \
+ EndDictionaryEntry(); \
+ }
+TRACE_PUSH(const char*)
+TRACE_PUSH(const std::string&)
+TRACE_PUSH(int32)
+TRACE_PUSH(int64)
+TRACE_PUSH(uint32)
+TRACE_PUSH(uint64)
+TRACE_PUSH(float)
+TRACE_PUSH(bool)
+TRACE_PUSH(const TracedObject&)
+#undef TRACE_PUSH
+
+// Put stuff in an array.
+#define TRACE_PUSH(type) \
+ void Push(type value) { \
+ DCHECK_EQ(BEGIN_ARRAY, begin_opcodes_.top()); \
+ PushValueToPickle(value); \
+ }
+TRACE_PUSH(const char*)
+TRACE_PUSH(const std::string&)
+TRACE_PUSH(int32)
+TRACE_PUSH(int64)
+TRACE_PUSH(uint32)
+TRACE_PUSH(uint64)
+TRACE_PUSH(float)
+TRACE_PUSH(bool)
+TRACE_PUSH(const TracedObject&)
+#undef TRACE_PUSH
+
+ private:
+ // Begin and end dictionary entry methods allow us to know that we're writing
+ // a dictionary entry, this is needed for scenarios where we don't write the
+ // value write away, but defer to some other implementation how to write the
dsinclair 2013/08/12 13:34:40 s/write/right
+ // entry's value for example with TracedObject.PushInto().
+ void BeginDictionaryEntry();
+ void EndDictionaryEntry();
+ // Push key/value should not be exposed, instead, the Push methods are
+ // exposed, to have them assert that we are in the right state before writing
+ // to the pickle.
+ void PushKeyToPickle(const char* key);
+ void PushValueToPickle(const char* value);
+ void PushValueToPickle(const std::string& value);
+ void PushValueToPickle(int value);
+ void PushValueToPickle(int64 value);
+ void PushValueToPickle(uint32 value);
+ void PushValueToPickle(uint64 value);
+ void PushValueToPickle(float value);
+ void PushValueToPickle(bool value);
+ void PushValueToPickle(const TracedObject& value);
+
+ // Helper methods used in AppendAsTraceFormat().
+ void AppendKeyAsRawPointer(std::string* out, PickleIterator* iter) const;
+ void AppendValueAsRawPointer(std::string* out, PickleIterator* iter) const;
+ void AppendValueAsString(std::string* out, PickleIterator* iter) const;
+ void AppendValueAsInt32(std::string* out, PickleIterator* iter) const;
+ void AppendValueAsInt64(std::string* out, PickleIterator* iter) const;
+ void AppendValueAsUInt32(std::string* out, PickleIterator* iter) const;
+ void AppendValueAsUInt64(std::string* out, PickleIterator* iter) const;
+ void AppendValueAsFloat(std::string* out, PickleIterator* iter) const;
+ void AppendValueAsBool(std::string* out, PickleIterator* iter) const;
+
+ void CheckNotWithinDictionary();
+
+ Pickle pickle_;
+ enum Opcode {
+ BEGIN_DICTIONARY,
+ END_DICTIONARY,
+ BEGIN_ARRAY,
+ END_ARRAY,
+ KEY_AS_RAW_POINTER,
+ // BEGIN_DICTIONARY_ENTRY is only used to know that we are in the middle
+ // of writing a dictionary entry to the pickle, however, it is not
+ // written into the pickle, only into the stack where we keep track of
+ // the state.
+ BEGIN_DICTIONARY_ENTRY,
+ VALUE_AS_RAW_POINTER,
+ VALUE_AS_STRING,
+ INT32_VALUE,
+ INT64_VALUE,
+ UINT32_VALUE,
+ UINT64_VALUE,
+ FLOAT_VALUE,
+ BOOL_VALUE
+ };
+
+ // This method is in charge of preppending a comma before a value within an
+ // array, or a dictionary. If necessary, the element count will be
+ // incremented.
+ static void AppendComma(std::string* out, Opcode begin_opcode,
+ Opcode current_opcode, int* element_count);
+
+ // This is used to keep track of the operations that need to be closed, in
+ // in order to enforce consistency in the operations. The only opcodes that
+ // need to be kept in this datastructure are BEGIN_* opcodes, such as
+ // BEGIN_ARRAY or BEGIN_DICTIONARY, using this stack, we know that we can't
+ // do an array push, when we have a dictionary, and we end a dictionary, when
+ // we were working on an array.
+ std::stack<Opcode> begin_opcodes_;
+
+ DISALLOW_COPY_AND_ASSIGN(TracedValue);
+};
+
+} // namespace debug
+} // namespace base
+
+#endif
+

Powered by Google App Engine
This is Rietveld 408576698