2015-06-30 22:03:45 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef MOZ_PROFILE_BUFFER_H
|
|
|
|
#define MOZ_PROFILE_BUFFER_H
|
|
|
|
|
|
|
|
#include "platform.h"
|
2017-04-27 00:36:22 +03:00
|
|
|
#include "ProfileBufferEntry.h"
|
|
|
|
#include "ProfilerMarker.h"
|
2015-06-30 22:03:45 +03:00
|
|
|
#include "ProfileJSONWriter.h"
|
2015-10-18 08:24:48 +03:00
|
|
|
#include "mozilla/RefPtr.h"
|
2015-09-23 04:27:34 +03:00
|
|
|
#include "mozilla/RefCounted.h"
|
2015-06-30 22:03:45 +03:00
|
|
|
|
2017-02-27 04:34:59 +03:00
|
|
|
class ProfileBuffer final
|
2017-02-21 02:18:51 +03:00
|
|
|
{
|
2015-06-30 22:03:45 +03:00
|
|
|
public:
|
|
|
|
explicit ProfileBuffer(int aEntrySize);
|
|
|
|
|
2017-02-27 04:34:59 +03:00
|
|
|
~ProfileBuffer();
|
2015-06-30 22:03:45 +03:00
|
|
|
|
2017-03-22 13:18:31 +03:00
|
|
|
// LastSample is used to record the buffer location of the most recent
|
2017-03-31 02:13:13 +03:00
|
|
|
// sample for each thread. It is used for periodic samples stored in the
|
|
|
|
// global ProfileBuffer, but *not* for synchronous samples.
|
2017-03-22 13:18:31 +03:00
|
|
|
struct LastSample {
|
2017-03-31 02:13:13 +03:00
|
|
|
LastSample()
|
|
|
|
: mGeneration(0)
|
2017-03-22 13:18:31 +03:00
|
|
|
, mPos(-1)
|
|
|
|
{}
|
|
|
|
|
|
|
|
// The profiler-buffer generation number at which the sample was created.
|
|
|
|
uint32_t mGeneration;
|
|
|
|
// And its position in the buffer, or -1 meaning "invalid".
|
|
|
|
int mPos;
|
|
|
|
};
|
|
|
|
|
2017-07-04 09:53:21 +03:00
|
|
|
// Add |aEntry| to the buffer, ignoring what kind of entry it is.
|
|
|
|
void addEntry(const ProfileBufferEntry& aEntry);
|
2017-03-22 13:18:31 +03:00
|
|
|
|
2017-03-31 02:13:13 +03:00
|
|
|
// Add to the buffer a sample start (ThreadId) entry for aThreadId. Also,
|
|
|
|
// record the resulting generation and index in |aLS| if it's non-null.
|
2017-07-04 09:53:21 +03:00
|
|
|
void addThreadIdEntry(int aThreadId, LastSample* aLS = nullptr);
|
2017-03-22 13:18:31 +03:00
|
|
|
|
2017-06-02 02:41:51 +03:00
|
|
|
void StreamSamplesToJSON(SpliceableJSONWriter& aWriter, int aThreadId,
|
|
|
|
double aSinceTime, JSContext* cx,
|
|
|
|
UniqueStacks& aUniqueStacks);
|
2017-02-27 05:52:58 +03:00
|
|
|
void StreamMarkersToJSON(SpliceableJSONWriter& aWriter, int aThreadId,
|
2017-06-02 02:41:51 +03:00
|
|
|
const mozilla::TimeStamp& aProcessStartTime,
|
2017-02-27 05:52:58 +03:00
|
|
|
double aSinceTime,
|
2015-06-30 22:03:45 +03:00
|
|
|
UniqueStacks& aUniqueStacks);
|
2017-03-22 13:18:31 +03:00
|
|
|
|
2017-03-31 02:13:13 +03:00
|
|
|
// Find (via |aLS|) the most recent sample for the thread denoted by
|
2017-06-02 02:41:51 +03:00
|
|
|
// |aThreadId| and clone it, patching in |aProcessStartTime| as appropriate.
|
|
|
|
bool DuplicateLastSample(int aThreadId,
|
|
|
|
const mozilla::TimeStamp& aProcessStartTime,
|
2017-03-22 13:18:31 +03:00
|
|
|
LastSample& aLS);
|
2015-06-30 22:03:45 +03:00
|
|
|
|
|
|
|
void addStoredMarker(ProfilerMarker* aStoredMarker);
|
|
|
|
|
|
|
|
// The following two methods are not signal safe! They delete markers.
|
|
|
|
void deleteExpiredStoredMarkers();
|
|
|
|
void reset();
|
|
|
|
|
2017-01-30 04:37:26 +03:00
|
|
|
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
|
|
|
|
2015-06-30 22:03:45 +03:00
|
|
|
protected:
|
2017-07-04 09:53:21 +03:00
|
|
|
char* processEmbeddedString(int aReadaheadPos, int* aEntriesConsumed,
|
|
|
|
char* aStrBuf);
|
2017-03-31 02:13:13 +03:00
|
|
|
int FindLastSampleOfThread(int aThreadId, const LastSample& aLS);
|
2015-06-30 22:03:45 +03:00
|
|
|
|
|
|
|
public:
|
|
|
|
// Circular buffer 'Keep One Slot Open' implementation for simplicity
|
2017-02-24 01:05:23 +03:00
|
|
|
mozilla::UniquePtr<ProfileBufferEntry[]> mEntries;
|
2015-06-30 22:03:45 +03:00
|
|
|
|
|
|
|
// Points to the next entry we will write to, which is also the one at which
|
|
|
|
// we need to stop reading.
|
|
|
|
int mWritePos;
|
|
|
|
|
|
|
|
// Points to the entry at which we can start reading.
|
|
|
|
int mReadPos;
|
|
|
|
|
|
|
|
// The number of entries in our buffer.
|
|
|
|
int mEntrySize;
|
|
|
|
|
|
|
|
// How many times mWritePos has wrapped around.
|
|
|
|
uint32_t mGeneration;
|
|
|
|
|
|
|
|
// Markers that marker entries in the buffer might refer to.
|
|
|
|
ProfilerMarkerLinkedList mStoredMarkers;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|