Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef MOZ_PROFILE_BUFFER_H
7 : #define MOZ_PROFILE_BUFFER_H
8 :
9 : #include "platform.h"
10 : #include "ProfileBufferEntry.h"
11 : #include "ProfilerMarker.h"
12 : #include "ProfileJSONWriter.h"
13 : #include "mozilla/RefPtr.h"
14 : #include "mozilla/RefCounted.h"
15 :
16 : class ProfileBuffer final
17 : {
18 : public:
19 : explicit ProfileBuffer(int aEntrySize);
20 :
21 : ~ProfileBuffer();
22 :
23 : // LastSample is used to record the buffer location of the most recent
24 : // sample for each thread. It is used for periodic samples stored in the
25 : // global ProfileBuffer, but *not* for synchronous samples.
26 : struct LastSample {
27 75 : LastSample()
28 75 : : mGeneration(0)
29 75 : , mPos(-1)
30 75 : {}
31 :
32 : // The profiler-buffer generation number at which the sample was created.
33 : uint32_t mGeneration;
34 : // And its position in the buffer, or -1 meaning "invalid".
35 : int mPos;
36 : };
37 :
38 : // Add |aEntry| to the buffer, ignoring what kind of entry it is.
39 : void AddEntry(const ProfileBufferEntry& aEntry);
40 :
41 : // Add to the buffer a sample start (ThreadId) entry for aThreadId. Also,
42 : // record the resulting generation and index in |aLS| if it's non-null.
43 : void AddThreadIdEntry(int aThreadId, LastSample* aLS = nullptr);
44 :
45 : // Add to the buffer a dynamic string. It'll be spread across one or more
46 : // DynamicStringFragment entries.
47 : void AddDynamicStringEntry(const char* aStr);
48 :
49 : // Maximum size of a frameKey string that we'll handle.
50 : static const size_t kMaxFrameKeyLength = 512;
51 :
52 : void StreamSamplesToJSON(SpliceableJSONWriter& aWriter, int aThreadId,
53 : double aSinceTime, JSContext* cx,
54 : UniqueStacks& aUniqueStacks) const;
55 : void StreamMarkersToJSON(SpliceableJSONWriter& aWriter, int aThreadId,
56 : const mozilla::TimeStamp& aProcessStartTime,
57 : double aSinceTime,
58 : UniqueStacks& aUniqueStacks) const;
59 :
60 : // Find (via |aLS|) the most recent sample for the thread denoted by
61 : // |aThreadId| and clone it, patching in |aProcessStartTime| as appropriate.
62 : bool DuplicateLastSample(int aThreadId,
63 : const mozilla::TimeStamp& aProcessStartTime,
64 : LastSample& aLS);
65 :
66 : void AddStoredMarker(ProfilerMarker* aStoredMarker);
67 :
68 : // The following two methods are not signal safe! They delete markers.
69 : void DeleteExpiredStoredMarkers();
70 : void Reset();
71 :
72 : size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
73 :
74 : private:
75 : int FindLastSampleOfThread(int aThreadId, const LastSample& aLS) const;
76 :
77 : public:
78 : // Circular buffer 'Keep One Slot Open' implementation for simplicity
79 : mozilla::UniquePtr<ProfileBufferEntry[]> mEntries;
80 :
81 : // Points to the next entry we will write to, which is also the one at which
82 : // we need to stop reading.
83 : int mWritePos;
84 :
85 : // Points to the entry at which we can start reading.
86 : int mReadPos;
87 :
88 : // The number of entries in our buffer.
89 : int mEntrySize;
90 :
91 : // How many times mWritePos has wrapped around.
92 : uint32_t mGeneration;
93 :
94 : // Markers that marker entries in the buffer might refer to.
95 : ProfilerMarkerLinkedList mStoredMarkers;
96 : };
97 :
98 : #endif
|