@@ -214,21 +214,60 @@ struct SizeCollector {
214
214
};
215
215
216
216
struct MemWriter {
217
- explicit MemWriter (char * aPtr) : mPtr(aPtr) {}
217
+ constexpr explicit MemWriter (char * aPtr) : mPtr(aPtr) {}
218
218
void write (const char * aData, size_t aSize) {
219
219
memcpy (mPtr , aData, aSize);
220
220
mPtr += aSize;
221
221
}
222
222
char * mPtr ;
223
223
};
224
224
225
- // This is a simple interface for an EventRingBuffer, so we can use it in the
226
- // RecordedEvent reading and writing machinery.
227
- class EventRingBuffer {
225
+ // An istream like class for reading from memory
226
+ struct MemReader {
227
+ constexpr MemReader (char * aData, size_t aLen)
228
+ : mData(aData), mEnd(aData + aLen) {}
229
+ void read (char * s, std::streamsize n) {
230
+ if (n <= (mEnd - mData )) {
231
+ memcpy (s, mData , n);
232
+ mData += n;
233
+ } else {
234
+ // We've requested more data than is available
235
+ // set the Reader into an eof state
236
+ SetIsBad ();
237
+ }
238
+ }
239
+ bool eof () { return mData > mEnd ; }
240
+ bool good () { return !eof (); }
241
+ void SetIsBad () { mData = mEnd + 1 ; }
242
+
243
+ char * mData ;
244
+ char * mEnd ;
245
+ };
246
+
247
+ class ContiguousBuffer {
248
+ public:
249
+ ContiguousBuffer (char * aStart, size_t aSize)
250
+ : mWriter (aStart), mEnd (aStart + aSize) {}
251
+
252
+ constexpr MOZ_IMPLICIT ContiguousBuffer (std::nullptr_t ) : mWriter(nullptr ) {}
253
+
254
+ MemWriter& Writer () { return mWriter ; }
255
+
256
+ size_t SizeRemaining () { return mWriter .mPtr ? mEnd - mWriter .mPtr : 0 ; }
257
+
258
+ bool IsValid () { return !!mWriter .mPtr ; }
259
+
260
+ private:
261
+ MemWriter mWriter ;
262
+ char * mEnd = nullptr ;
263
+ };
264
+
265
+ // Allows a derived class to provide guaranteed contiguous buffer.
266
+ class ContiguousBufferStream {
228
267
public:
229
268
/* *
230
- * Templated RecordEvent function so that when we have enough contiguous
231
- * space we can record into the buffer quickly using MemWriter.
269
+ * Templated RecordEvent function so that we can record into the buffer
270
+ * quickly using MemWriter.
232
271
*
233
272
* @param aRecordedEvent the event to record
234
273
*/
@@ -237,56 +276,25 @@ class EventRingBuffer {
237
276
SizeCollector size;
238
277
WriteElement (size, aRecordedEvent->GetType ());
239
278
aRecordedEvent->Record (size);
240
- if (size.mTotalSize > mAvailable ) {
241
- WaitForAndRecalculateAvailableSpace ();
242
- }
243
- if (size.mTotalSize <= mAvailable ) {
244
- MemWriter writer (mBufPos );
245
- WriteElement (writer, aRecordedEvent->GetType ());
246
- aRecordedEvent->Record (writer);
247
- UpdateWriteTotalsBy (size.mTotalSize );
248
- } else {
249
- WriteElement (*this , aRecordedEvent->GetType ());
250
- aRecordedEvent->Record (*this );
279
+ auto & buffer = GetContiguousBuffer (size.mTotalSize );
280
+ if (!buffer.IsValid ()) {
281
+ return ;
251
282
}
252
- }
253
283
254
- /* *
255
- * Simple write function required by WriteElement.
256
- *
257
- * @param aData the data to be written to the buffer
258
- * @param aSize the number of chars to write
259
- */
260
- virtual void write (const char * const aData, const size_t aSize) = 0;
261
-
262
- /* *
263
- * Simple read function required by ReadElement.
264
- *
265
- * @param aOut the pointer to read into
266
- * @param aSize the number of chars to read
267
- */
268
- virtual void read (char * const aOut, const size_t aSize) = 0;
284
+ MOZ_ASSERT (size.mTotalSize <= buffer.SizeRemaining ());
269
285
270
- virtual bool good () const = 0;
271
-
272
- virtual void SetIsBad () = 0;
286
+ WriteElement (buffer.Writer (), aRecordedEvent->GetType ());
287
+ aRecordedEvent->Record (buffer.Writer ());
288
+ IncrementEventCount ();
289
+ }
273
290
274
291
protected:
275
292
/* *
276
- * Wait until space is available for writing and then set mBufPos and
277
- * mAvailable.
278
- */
279
- virtual bool WaitForAndRecalculateAvailableSpace () = 0;
280
-
281
- /* *
282
- * Update write count, mBufPos and mAvailable.
283
- *
284
- * @param aCount number of bytes written
293
+ * Provide a contiguous buffer with at least aSize remaining.
285
294
*/
286
- virtual void UpdateWriteTotalsBy ( uint32_t aCount ) = 0;
295
+ virtual ContiguousBuffer& GetContiguousBuffer ( size_t aSize ) = 0;
287
296
288
- char * mBufPos = nullptr ;
289
- uint32_t mAvailable = 0 ;
297
+ virtual void IncrementEventCount () = 0;
290
298
};
291
299
292
300
struct MemStream {
@@ -430,7 +438,7 @@ class RecordedEvent {
430
438
431
439
virtual void RecordToStream (std::ostream& aStream) const = 0;
432
440
virtual void RecordToStream (EventStream& aStream) const = 0;
433
- virtual void RecordToStream (EventRingBuffer & aStream) const = 0;
441
+ virtual void RecordToStream (ContiguousBufferStream & aStream) const = 0;
434
442
virtual void RecordToStream (MemStream& aStream) const = 0;
435
443
436
444
virtual void OutputSimpleEventInfo (std::stringstream& aStringStream) const {}
@@ -460,8 +468,8 @@ class RecordedEvent {
460
468
static bool DoWithEventFromStream (
461
469
EventStream& aStream, EventType aType,
462
470
const std::function<bool (RecordedEvent*)>& aAction);
463
- static bool DoWithEventFromStream (
464
- EventRingBuffer& aStream , EventType aType,
471
+ static bool DoWithEventFromReader (
472
+ MemReader& aReader , EventType aType,
465
473
const std::function<bool (RecordedEvent*)>& aAction);
466
474
467
475
EventType GetType () const { return (EventType)mType ; }
@@ -495,7 +503,7 @@ class RecordedEventDerived : public RecordedEvent {
495
503
WriteElement (aStream, this ->mType );
496
504
static_cast <const Derived*>(this )->Record (aStream);
497
505
}
498
- void RecordToStream (EventRingBuffer & aStream) const final {
506
+ void RecordToStream (ContiguousBufferStream & aStream) const final {
499
507
aStream.RecordEvent (static_cast <const Derived*>(this ));
500
508
}
501
509
void RecordToStream (MemStream& aStream) const override {
0 commit comments