Chromium Code Reviews| Index: components/tracing/core/string_interning.h |
| diff --git a/components/tracing/core/string_interning.h b/components/tracing/core/string_interning.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..67840a5a9aa230be74e127899d65af57d0457fcd |
| --- /dev/null |
| +++ b/components/tracing/core/string_interning.h |
| @@ -0,0 +1,56 @@ |
| +// Copyright 2016 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 COMPONENTS_TRACING_CORE_STRING_INTERNING_H_ |
| +#define COMPONENTS_TRACING_CORE_STRING_INTERNING_H_ |
| + |
| +#include <stddef.h> |
| +#include <stdint.h> |
| + |
| +#include <limits> |
| + |
| +#include "base/logging.h" |
| +#include "components/tracing/tracing_export.h" |
| + |
| +// All non-copied strings in tracing are, by API contract, long lived |
| +// const char* pointers. In order to save trace buffer size (and performance), |
| +// tracing doesn't copy those strings, but keeps only an index for each event. |
| +// The way these strings are interned is pretty straightforward: we encode the |
| +// ptr distance from a known constant in the binary (kInternedStringBase) and |
| +// use that as string index. |
| +// There are two use cases for interned strings: |
| +// 1. In the most common cases they are looked up in group when the trace is |
| +// finalized and trace metadata is written, to produce the final string |
| +// table. This case works always (as long as the strings are long lived) |
|
oystein (OOO til 10th of July)
2016/09/09 00:27:34
s/works always/always works/
Primiano Tucci (use gerrit)
2016/09/13 14:40:24
Done.
|
| +// in both component and static builds. We just need to do the reverse math |
| +// to work out the const char* from the offset at finalization time. |
| +// 2. In future, when supporting the recovery of non-finalized traces from a |
| +// crahed process, the same principle can be applied, but only in the case |
| +// of non-component builds. In a monolithic build string offset is constatnt |
|
oystein (OOO til 10th of July)
2016/09/09 00:27:34
s/build string offset is constatnt/build the strin
Primiano Tucci (use gerrit)
2016/09/13 14:40:24
Done.
|
| +// regardless of ASLR. |
| + |
| +namespace tracing { |
| +namespace v2 { |
| + |
| +TRACING_EXPORT extern const char kInternedStringBase[]; |
| + |
| +inline int64_t InternString(const char* str) { |
| + ptrdiff_t offset = reinterpret_cast<intptr_t>(str) - |
| + reinterpret_cast<intptr_t>(kInternedStringBase); |
| + // keeping the diff of two arbitrary pointers into a int64_t is safe as the |
| + // virtual address space of all the architectures we care about is << 64 bits. |
| + DCHECK(offset >= std::numeric_limits<int64_t>::min() && |
|
kraynov
2016/09/08 16:10:01
Static assert sizeof(ptrdiff_t) <= 8
Primiano Tucci (use gerrit)
2016/09/13 14:40:24
I had to remove this DCHECK completely as it was a
|
| + offset <= std::numeric_limits<int64_t>::max()); |
| + return static_cast<int64_t>(offset); |
| +} |
| + |
| +inline const char* GetInternedStringValue(int64_t offset) { |
| + intptr_t ptr = reinterpret_cast<intptr_t>(kInternedStringBase) + offset; |
| + return reinterpret_cast<const char*>(ptr); |
| +} |
| + |
| +} // namespace v2 |
| +} // namespace tracing |
| + |
| +#endif // COMPONENTS_TRACING_CORE_STRING_INTERNING_H_ |