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

Side by Side Diff: components/tracing/core/proto_zero_message.cc

Issue 2134683002: tracing v2: Add base class for zero-copy protobuf (ProtoZero) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@proto_utils
Patch Set: add comments Created 4 years, 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/tracing/core/proto_zero_message.h"
6
7 #include <string.h>
8
9 #include "build/build_config.h"
10 #include "components/tracing/core/proto_utils.h"
11
12 #if !defined(ARCH_CPU_LITTLE_ENDIAN)
13 // The memcpy() for float and double below needs to be adjusted if we want to
14 // support big endian CPUs. There doesn't seem to be a compelling need today.
15 #error big-endian CPUs not supported by this translation unit.
16 #endif
17
18 namespace tracing {
19 namespace v2 {
20
21 ProtoZeroMessage::ProtoZeroMessage() {
22 // Do add any code here, use the Reset() method below.
petrcermak 2016/07/12 10:18:46 s/Do/Don't/ ?
petrcermak 2016/07/12 10:18:46 nit: s/below/below instead/
Primiano Tucci (use gerrit) 2016/07/12 17:25:16 Done.
Primiano Tucci (use gerrit) 2016/07/12 17:25:16 EHm, yeah :)
23 // Ctor and Dtor of ProtoZeroMessage are never called, with the exeception
24 // of root (non-nested) messages. Nested messages are allocated into the
petrcermak 2016/07/12 10:18:46 nit: s/into/in/ (I've never heard "allocated into"
Primiano Tucci (use gerrit) 2016/07/12 17:25:16 In my mind "allocated into" is about the actual st
petrcermak 2016/07/12 17:41:17 Acknowledged.
25 // |nested_messages_arena_| and implictly destroyed when the arena of the
26 // root message goes away. This is fine as long as all the fields are PODs,
27 // hence the static_assert below.
28 static_assert(base::is_trivially_destructible<ProtoZeroMessage>::value,
29 "ProtoZeroMessageIsTriviallyDestructible");
30
31 static_assert(
32 sizeof(ProtoZeroMessage::nested_messages_arena_) >=
33 kMaxNestingDepth * (sizeof(ProtoZeroMessage) -
alph 2016/07/12 00:20:42 nit: offsetof
Primiano Tucci (use gerrit) 2016/07/12 10:15:32 Hmm if you don't mind I'd leave this as it is. The
34 sizeof(ProtoZeroMessage::nested_messages_arena_)),
35 "NestedMessagesAreaTooSmall");
36 }
37
38 // This method is called to initialize both root and nested messages.
39 void ProtoZeroMessage::Reset(ScatteredStreamWriter* stream_writer) {
40 stream_writer_ = stream_writer;
41 size_ = 0;
42 size_field_.reset();
43 size_already_written_ = 0;
44 nested_message_ = nullptr;
45 nesting_depth_ = 0;
46 #if DCHECK_IS_ON()
47 sealed_ = false;
petrcermak 2016/07/12 10:18:47 You don't actually DCHECK this anywhere. Shouldn't
Primiano Tucci (use gerrit) 2016/07/12 17:25:16 EPIC FAIL. good spot, yes. :P
48 #endif
49 }
50
51 void ProtoZeroMessage::AppendVarIntU64(uint32_t field_id, uint64_t value) {
52 if (nested_message_)
petrcermak 2016/07/12 10:18:47 You do this a lot. How about EndNestedMessageIfNec
Primiano Tucci (use gerrit) 2016/07/12 17:25:16 I knew that you were going to suggest it. I though
petrcermak 2016/07/12 17:41:17 And I knew this was going to be your reply :-P
53 EndNestedMessage();
54
55 uint8_t data[proto::GetMaxVarIntEncodedSize<uint32_t>() +
56 proto::GetMaxVarIntEncodedSize<uint64_t>()];
57 uint8_t* data_end;
58 data_end = proto::WriteVarIntU32(proto::MakeTagVarInt(field_id), data);
59 data_end = proto::WriteVarIntU64(value, data_end);
60 WriteToStream(data, data_end);
61 }
62
63 void ProtoZeroMessage::AppendVarIntU32(uint32_t field_id, uint32_t value) {
64 // TODO(kraynov): this could be perf-optimized. See http://crbug.com/624311 .
petrcermak 2016/07/12 10:18:46 nit: remove unnecessary space before period.
Primiano Tucci (use gerrit) 2016/07/12 17:25:16 It's on purpose, so that the clickable link does n
petrcermak 2016/07/12 17:41:17 Acknowledged.
65 AppendVarIntU64(field_id, value);
66 }
67
68 void ProtoZeroMessage::AppendFloat(uint32_t field_id, float value) {
69 if (nested_message_)
70 EndNestedMessage();
71
72 uint8_t data[proto::GetMaxVarIntEncodedSize<uint32_t>() + sizeof(value)];
73 uint8_t* data_end;
74 data_end = proto::WriteVarIntU32(proto::MakeTagFixed32(field_id), data);
75 memcpy(data_end, &value, sizeof(value));
76 data_end += sizeof(value);
77 WriteToStream(data, data_end);
78 }
79
80 void ProtoZeroMessage::AppendDouble(uint32_t field_id, double value) {
81 if (nested_message_)
82 EndNestedMessage();
83
84 uint8_t data[proto::GetMaxVarIntEncodedSize<uint32_t>() + sizeof(value)];
85 uint8_t* data_end;
86 data_end = proto::WriteVarIntU32(proto::MakeTagFixed64(field_id), data);
87 memcpy(data_end, &value, sizeof(value));
88 data_end += sizeof(value);
89 WriteToStream(data, data_end);
90 }
91
92 void ProtoZeroMessage::AppendString(uint32_t field_id, const char* str) {
93 AppendBytes(field_id, str, strlen(str));
94 }
95
96 void ProtoZeroMessage::AppendBytes(uint32_t field_id,
97 const void* src,
98 size_t size) {
99 if (nested_message_)
100 EndNestedMessage();
101
102 // Write the proto preamble (field id, type and length of the buffer).
103 DCHECK_LT(size, proto::kMaxMessageLength);
104 uint8_t data[2 * proto::GetMaxVarIntEncodedSize<uint32_t>()];
105 uint8_t* data_end =
petrcermak 2016/07/12 10:18:47 In most other methods you declare and assign to |d
Primiano Tucci (use gerrit) 2016/07/12 17:25:16 I knew also this :P There is a reason. In the othe
petrcermak 2016/07/12 17:41:17 Acknowledged.
106 proto::WriteVarIntU32(proto::MakeTagLengthDelimited(field_id), data);
107 data_end = proto::WriteVarIntU32(static_cast<uint32_t>(size), data_end);
108 WriteToStream(data, data_end);
109 const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
110 WriteToStream(src_u8, src_u8 + size);
111 }
112
113 size_t ProtoZeroMessage::Finalize() {
114 if (nested_message_)
115 EndNestedMessage();
116
117 if (size_field_.is_valid()) {
118 // Write the length of the nested message a posteriori, using a leading-zero
119 // redundant varint encoding.
120 DCHECK_LT(size_, proto::kMaxMessageLength);
121 DCHECK_EQ(proto::kMessageLengthFieldSize, size_field_.size());
122 proto::WriteRedundantVarIntU32<proto::kMessageLengthFieldSize>(
123 static_cast<uint32_t>(size_ - size_already_written_),
124 size_field_.begin);
125 size_field_.reset();
126 }
127
128 #if DCHECK_IS_ON()
129 sealed_ = true;
130 #endif
131
132 return size_;
133 }
134
135 void ProtoZeroMessage::BeginNestedMessageInternal(uint32_t field_id,
136 ProtoZeroMessage* message) {
137 if (nested_message_)
138 EndNestedMessage();
139
140 // Write the proto preamble for the nested message.
141 uint8_t data[proto::GetMaxVarIntEncodedSize<uint32_t>()];
142 uint8_t* data_end =
petrcermak 2016/07/12 10:18:46 ditto (separate declaration and assignment)
Primiano Tucci (use gerrit) 2016/07/12 17:25:16 ditto (assignment doesn't fit in one line)
petrcermak 2016/07/12 17:41:17 Acknowledged.
143 proto::WriteVarIntU32(proto::MakeTagLengthDelimited(field_id), data);
144 WriteToStream(data, data_end);
145
146 message->Reset(stream_writer_);
147 CHECK_LT(nesting_depth_, kMaxNestingDepth);
148 message->nesting_depth_ = nesting_depth_ + 1;
149
150 // The length of the nested message cannot be known upfront. So right now
151 // just reserve the bytes to encode the size after the nested message is done.
152 message->set_size_field(
153 stream_writer_->ReserveBytes(proto::kMessageLengthFieldSize));
154 size_ += proto::kMessageLengthFieldSize;
155 nested_message_ = message;
156 }
157
158 void ProtoZeroMessage::EndNestedMessage() {
159 size_ += nested_message_->Finalize();
160 nested_message_ = nullptr;
161 }
162
163 } // namespace v2
164 } // namespace tracing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698