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

Side by Side Diff: base/trace_event/v2/append_only_proto_message.cc

Issue 1947373002: Tracing V2 prototype [NOT FOR REVIEW] Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: WORKS Created 4 years, 7 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 "base/trace_event/v2/append_only_proto_message.h"
6
7 #include "base/logging.h"
8 #include "base/trace_event/v2/proto_utils.h"
9 #include "build/build_config.h"
10
11
12 // TODO size vs length naming inconsistency.
13 // TODO bitmap for mandatory / optional fields
14
15 namespace {
16
17 enum {
18 PROTO_VARINT = 0,
19 PROTO_FIXED_64BIT = 1,
20 PROTO_LENGTH_LIMITED = 2,
21 PROTO_FIXED_32BIT = 5,
22 };
23
24 } // namespace
25
26 namespace base {
27 namespace trace_event {
28 namespace v2 {
29
30 // static
31 const size_t AppendOnlyProtoMessage::kMaxMessageLength =
32 1ul << (AppendOnlyProtoMessage::kMaxMessageLengthFieldSize * 7);
33
34 AppendOnlyProtoMessage::AppendOnlyProtoMessage()
35 : buffer_(nullptr),
36 size_(0),
37 write_size_field_on_finalization_(false),
38 size_already_written_(0),
39 current_nested_message_(nullptr),
40 sealed_(false) {}
41
42 AppendOnlyProtoMessage::~AppendOnlyProtoMessage() {}
43
44 size_t AppendOnlyProtoMessage::Finalize() {
45 if (sealed_)
46 return size_;
47
48 if (current_nested_message_)
49 EndNestedMessage();
50
51 if (write_size_field_on_finalization_) {
52 // Write the length of the nested message a posteriori, forcing a 32-bit
53 // leading-zero varint. This is a slight bending of the proto encoding,
54 // essentially size = 7 gets encoded as 0x87,0x80,0x80,0x00 instead of 0x07.
55 // The problem here is that we cannot know upfront how big the nested messag e
56 // was. There is precedent for this (TODO link internal bug).
57 // TODO optimization: upon beginmessage we could get a promise of the max
58 // length of the submessage to avoid wasting 2 bytes if we know upfront that
59 // the message is going to be always < 64k.
60 DCHECK_LT(size_, kMaxMessageLength);
61 uint8_t word[kMaxMessageLengthFieldSize];
62 ProtoUtils::EncodeRedundantVarIntUnsigned(size_ - size_already_written_,
63 kMaxMessageLengthFieldSize,
64 word);
65 buffer_->WriteReservedBytes(size_field_, word, kMaxMessageLengthFieldSize);
66 }
67
68 // No more changes allowed.
69 sealed_ = true;
70 return size_;
71 }
72
73 void AppendOnlyProtoMessage::WriteToBuffer(const uint8_t* src, size_t size) {
74 buffer_->WriteBytes(src, size);
75 size_ += size;
76 }
77
78 void AppendOnlyProtoMessage::AppendVarIntSigned(uint32_t field_id,
79 int64_t value) {
80 // TODO ZigZag encoding.
81 AppendVarIntUnsigned(field_id, value); // HACK, this is not supporting signed .
82 }
83
84 void AppendOnlyProtoMessage::AppendVarIntUnsigned(uint32_t field_id,
85 uint64_t value) {
86 if (current_nested_message_)
87 EndNestedMessage();
88
89 uint8_t data[32];
90 size_t data_size;
91 data_size = ProtoUtils::EncodeVarIntUnsigned(ProtoUtils::GetVarIntFieldHeader( field_id), data);
92 data_size += ProtoUtils::EncodeVarIntUnsigned(value, &data[data_size]);
93 WriteToBuffer(data, data_size);
94 }
95
96 void AppendOnlyProtoMessage::AppendFloat(uint32_t field_id, float value) {
97 if (current_nested_message_)
98 EndNestedMessage();
99
100 uint8_t data[32];
101 size_t data_size;
102 data_size = ProtoUtils::EncodeVarIntUnsigned(ProtoUtils::GetFixed32FieldHeader (field_id), data);
103
104 #if defined(ARCH_CPU_LITTLE_ENDIAN)
105 memcpy(&data[data_size], &value, sizeof(value));
106 #else
107 #error big-endian encoding not implemented.
108 #endif
109
110 data_size += sizeof(value);
111 WriteToBuffer(data, data_size);
112 }
113
114 void AppendOnlyProtoMessage::AppendDouble(uint32_t field_id, double value) {
115 if (current_nested_message_)
116 EndNestedMessage();
117
118 uint8_t data[32];
119 size_t data_size;
120 data_size = ProtoUtils::EncodeVarIntUnsigned(ProtoUtils::GetFixed64FieldHeader (field_id), data);
121 memcpy(&data[data_size], &value, sizeof(value));
122 data_size += sizeof(value);
123 WriteToBuffer(data, data_size);
124 }
125
126 void AppendOnlyProtoMessage::AppendString(uint32_t field_id, const char* str) {
127 if (current_nested_message_)
128 EndNestedMessage();
129
130 const size_t str_length = strlen(str);
131 AppendBytes(field_id, str, str_length);
132 }
133
134 void AppendOnlyProtoMessage::AppendBytes(uint32_t field_id, const void* value, s ize_t size) {
135 if (current_nested_message_)
136 EndNestedMessage();
137
138 // Write the proto preamble (field id, type and length of the buffer).
139 uint8_t data[32];
140 size_t data_size;
141 data_size = ProtoUtils::EncodeVarIntUnsigned(ProtoUtils::GetLengthLimitedField Header(field_id), data);
142 data_size += ProtoUtils::EncodeVarIntUnsigned(size, &data[data_size]);
143 WriteToBuffer(data, data_size);
144
145 // Write the actual buffer.
146 WriteToBuffer(reinterpret_cast<const uint8_t*>(value), size);
147 }
148
149 void AppendOnlyProtoMessage::BeginNestedMessage(
150 uint32_t field_id,
151 AppendOnlyProtoMessage* message) {
152 if (current_nested_message_)
153 EndNestedMessage();
154
155 message->set_buffer_writer(buffer_writer());
156 uint8_t data[32];
157 size_t data_size;
158 data_size = ProtoUtils::EncodeVarIntUnsigned(ProtoUtils::GetLengthLimitedField Header(field_id), data);
159 WriteToBuffer(data, data_size);
160
161 // The length of the nested message cannot be known upfront. So right now
162 // just reserve the bytes to encode the size after the nested message is done.
163 message->set_write_size_field_on_finalization(buffer_->ReserveBytes(kMaxMessag eLengthFieldSize));
164 current_nested_message_ = message;
165 }
166
167 void AppendOnlyProtoMessage::EndNestedMessage() {
168 size_ += current_nested_message_->Finalize();
169 current_nested_message_ = nullptr;
170 }
171
172 } // namespace v2
173 } // namespace trace_event
174 } // namespace base
OLDNEW
« no previous file with comments | « base/trace_event/v2/append_only_proto_message.h ('k') | base/trace_event/v2/append_only_proto_message_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698