зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1317771 (part 1) - Remove SPS_STANDALONE. r=mstange.
This patch removes all the |#ifndef SPS_STANDALONE| guards. --HG-- extra : rebase_source : af03e38e521d7ef0c3c920209cc8330a40d9b007
This commit is contained in:
Родитель
d7d1bbbb95
Коммит
4a820fa2dd
|
@ -9,13 +9,11 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "GeckoProfiler.h"
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "SaveProfileTask.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "prenv.h"
|
||||
#include "prtime.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#endif
|
||||
#include "ProfileEntry.h"
|
||||
#include "SyncProfile.h"
|
||||
#include "platform.h"
|
||||
|
@ -26,7 +24,6 @@
|
|||
// JSON
|
||||
#include "ProfileJSONWriter.h"
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
// Meta
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
|
@ -43,17 +40,14 @@
|
|||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/ProfileGatherer.h"
|
||||
#endif
|
||||
|
||||
#if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
|
||||
#include "FennecJNIWrappers.h"
|
||||
#endif
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
// JS
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/ProfilingFrameIterator.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_PROFILING) && (defined(XP_MACOSX) || defined(XP_WIN))
|
||||
#define USE_NS_STACKWALK
|
||||
|
@ -74,13 +68,11 @@ typedef ucontext_t tickcontext_t;
|
|||
#include "EHABIStackWalk.h"
|
||||
#endif
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
#if defined(SPS_PLAT_amd64_linux) || defined(SPS_PLAT_x86_linux)
|
||||
# define USE_LUL_STACKWALK
|
||||
# include "lul/LulMain.h"
|
||||
# include "lul/platform-linux-lul.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using std::string;
|
||||
using namespace mozilla;
|
||||
|
@ -281,12 +273,10 @@ void GeckoSampler::HandleSaveRequest()
|
|||
return;
|
||||
mSaveRequested = false;
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
// TODO: Use use the ipc/chromium Tasks here to support processes
|
||||
// without XPCOM.
|
||||
nsCOMPtr<nsIRunnable> runnable = new SaveProfileTask();
|
||||
NS_DispatchToMainThread(runnable);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GeckoSampler::DeleteExpiredMarkers()
|
||||
|
@ -338,7 +328,6 @@ void GeckoSampler::StreamMetaJSCustomObject(SpliceableJSONWriter& aWriter)
|
|||
aWriter.IntProperty("debug", 0);
|
||||
#endif
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
aWriter.IntProperty("gcpoison", JS::IsGCPoisoning() ? 1 : 0);
|
||||
|
||||
bool asyncStacks = Preferences::GetBool("javascript.options.asyncstack");
|
||||
|
@ -388,7 +377,6 @@ void GeckoSampler::StreamMetaJSCustomObject(SpliceableJSONWriter& aWriter)
|
|||
if (!NS_FAILED(res))
|
||||
aWriter.StringProperty("product", string.Data());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GeckoSampler::ToStreamAsJSON(std::ostream& stream, double aSinceTime)
|
||||
|
@ -397,7 +385,6 @@ void GeckoSampler::ToStreamAsJSON(std::ostream& stream, double aSinceTime)
|
|||
StreamJSON(b, aSinceTime);
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
JSObject* GeckoSampler::ToJSObject(JSContext *aCx, double aSinceTime)
|
||||
{
|
||||
JS::RootedValue val(aCx);
|
||||
|
@ -417,7 +404,6 @@ void GeckoSampler::GetGatherer(nsISupports** aRetVal)
|
|||
}
|
||||
NS_ADDREF(*aRetVal = mGatherer);
|
||||
}
|
||||
#endif
|
||||
|
||||
UniquePtr<char[]> GeckoSampler::ToJSON(double aSinceTime)
|
||||
{
|
||||
|
@ -557,7 +543,6 @@ void GeckoSampler::StreamJSON(SpliceableJSONWriter& aWriter, double aSinceTime)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
if (Sampler::CanNotifyObservers()) {
|
||||
// Send a event asking any subprocesses (plugins) to
|
||||
// give us their information
|
||||
|
@ -582,7 +567,6 @@ void GeckoSampler::StreamJSON(SpliceableJSONWriter& aWriter, double aSinceTime)
|
|||
java::GeckoJavaSampler::Unpause();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SetPaused(false);
|
||||
}
|
||||
|
@ -593,7 +577,6 @@ void GeckoSampler::StreamJSON(SpliceableJSONWriter& aWriter, double aSinceTime)
|
|||
|
||||
void GeckoSampler::FlushOnJSShutdown(JSContext* aContext)
|
||||
{
|
||||
#ifndef SPS_STANDALONE
|
||||
SetPaused(true);
|
||||
|
||||
{
|
||||
|
@ -617,18 +600,15 @@ void GeckoSampler::FlushOnJSShutdown(JSContext* aContext)
|
|||
}
|
||||
|
||||
SetPaused(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PseudoStack::flushSamplerOnJSShutdown()
|
||||
{
|
||||
#ifndef SPS_STANDALONE
|
||||
MOZ_ASSERT(mContext);
|
||||
GeckoSampler* t = tlsTicker.get();
|
||||
if (t) {
|
||||
t->FlushOnJSShutdown(mContext);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// END SaveProfileTask et al
|
||||
|
@ -673,7 +653,6 @@ void addPseudoEntry(volatile StackEntry &entry, ThreadProfile &aProfile,
|
|||
// that will happen to the preceding tag
|
||||
|
||||
addDynamicTag(aProfile, 'c', sampleLabel);
|
||||
#ifndef SPS_STANDALONE
|
||||
if (entry.isJs()) {
|
||||
JSScript* script = entry.script();
|
||||
if (script) {
|
||||
|
@ -695,7 +674,6 @@ void addPseudoEntry(volatile StackEntry &entry, ThreadProfile &aProfile,
|
|||
} else {
|
||||
lineno = entry.line();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
aProfile.addTag(ProfileEntry('c', sampleLabel));
|
||||
|
||||
|
@ -764,7 +742,6 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
|
|||
startBufferGen = aProfile.bufferGeneration();
|
||||
}
|
||||
uint32_t jsCount = 0;
|
||||
#ifndef SPS_STANDALONE
|
||||
JS::ProfilingFrameIterator::Frame jsFrames[1000];
|
||||
// Only walk jit stack if profiling frame iterator is turned on.
|
||||
if (pseudoStack->mContext && JS::IsProfilingEnabledForContext(pseudoStack->mContext)) {
|
||||
|
@ -798,7 +775,6 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Start the sample with a root entry.
|
||||
aProfile.addTag(ProfileEntry('s', "(root)"));
|
||||
|
@ -828,7 +804,6 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
|
|||
if (pseudoFrame.isCpp())
|
||||
lastPseudoCppStackAddr = (uint8_t *) pseudoFrame.stackAddress();
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
// Skip any pseudo-stack JS frames which are marked isOSR
|
||||
// Pseudostack frames are marked isOSR when the JS interpreter
|
||||
// enters a jit frame on a loop edge (via on-stack-replacement,
|
||||
|
@ -840,16 +815,13 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
|
|||
pseudoIndex++;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(lastPseudoCppStackAddr);
|
||||
pseudoStackAddr = lastPseudoCppStackAddr;
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
if (jsIndex >= 0)
|
||||
jsStackAddr = (uint8_t *) jsFrames[jsIndex].stackAddress;
|
||||
#endif
|
||||
|
||||
if (nativeIndex >= 0)
|
||||
nativeStackAddr = (uint8_t *) aNativeStack.sp_array[nativeIndex];
|
||||
|
@ -882,7 +854,6 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
|
|||
continue;
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
// Check to see if JS jit stack frame is top-most
|
||||
if (jsStackAddr > nativeStackAddr) {
|
||||
MOZ_ASSERT(jsIndex >= 0);
|
||||
|
@ -913,7 +884,6 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
|
|||
jsIndex--;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we reach here, there must be a native stack entry and it must be the
|
||||
// greatest entry.
|
||||
|
@ -927,7 +897,6 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
// Update the JS context with the current profile sample buffer generation.
|
||||
//
|
||||
// Do not do this for synchronous sampling, which create their own
|
||||
|
@ -939,7 +908,6 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
|
|||
aProfile.bufferGeneration(),
|
||||
lapCount);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_NS_STACKWALK
|
||||
|
@ -1225,12 +1193,10 @@ void GeckoSampler::InplaceTick(TickSample* sample)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
if (sample && currThreadProfile.GetThreadResponsiveness()->HasData()) {
|
||||
mozilla::TimeDuration delta = currThreadProfile.GetThreadResponsiveness()->GetUnresponsiveDuration(sample->timestamp);
|
||||
currThreadProfile.addTag(ProfileEntry('r', delta.ToMilliseconds()));
|
||||
}
|
||||
#endif
|
||||
|
||||
// rssMemory is equal to 0 when we are not recording.
|
||||
if (sample && sample->rssMemory != 0) {
|
||||
|
|
|
@ -86,10 +86,8 @@ class GeckoSampler: public Sampler {
|
|||
virtual void DeleteExpiredMarkers() override;
|
||||
|
||||
void ToStreamAsJSON(std::ostream& stream, double aSinceTime = 0);
|
||||
#ifndef SPS_STANDALONE
|
||||
virtual JSObject *ToJSObject(JSContext *aCx, double aSinceTime = 0);
|
||||
void GetGatherer(nsISupports** aRetVal);
|
||||
#endif
|
||||
mozilla::UniquePtr<char[]> ToJSON(double aSinceTime = 0);
|
||||
virtual void ToJSObjectAsync(double aSinceTime = 0, mozilla::dom::Promise* aPromise = 0);
|
||||
void ToFileAsync(const nsACString& aFileName, double aSinceTime = 0);
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "platform.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
|
@ -15,7 +14,6 @@
|
|||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/TrackedOptimizationInfo.h"
|
||||
#endif
|
||||
|
||||
// Self
|
||||
#include "ProfileEntry.h"
|
||||
|
@ -119,7 +117,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
class StreamOptimizationTypeInfoOp : public JS::ForEachTrackedOptimizationTypeInfoOp
|
||||
{
|
||||
JSONWriter& mWriter;
|
||||
|
@ -295,7 +292,6 @@ public:
|
|||
mDepth++;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
uint32_t UniqueJSONStrings::GetOrAddIndex(const char* aStr)
|
||||
{
|
||||
|
@ -526,11 +522,7 @@ void UniqueStacks::StreamFrame(const OnStackFrameKey& aFrame)
|
|||
|
||||
AutoArraySchemaWriter writer(mFrameTableWriter, mUniqueStrings);
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
if (!aFrame.mJITFrameHandle) {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
#ifdef SPS_STANDALONE
|
||||
writer.StringElement(LOCATION, aFrame.mLocation.c_str());
|
||||
#else
|
||||
|
@ -542,9 +534,7 @@ void UniqueStacks::StreamFrame(const OnStackFrameKey& aFrame)
|
|||
if (aFrame.mCategory.isSome()) {
|
||||
writer.IntElement(CATEGORY, *aFrame.mCategory);
|
||||
}
|
||||
}
|
||||
#ifndef SPS_STANDALONE
|
||||
else {
|
||||
} else {
|
||||
const JS::ForEachProfiledFrameOp::FrameHandle& jitFrame = *aFrame.mJITFrameHandle;
|
||||
|
||||
writer.StringElement(LOCATION, jitFrame.label());
|
||||
|
@ -601,7 +591,6 @@ void UniqueStacks::StreamFrame(const OnStackFrameKey& aFrame)
|
|||
mFrameTableWriter.EndObject();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct ProfileSample
|
||||
|
@ -757,7 +746,6 @@ void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter, int aThre
|
|||
incBy++;
|
||||
}
|
||||
stack.AppendFrame(frameKey);
|
||||
#ifndef SPS_STANDALONE
|
||||
} else if (frame.mTagName == 'J') {
|
||||
// A JIT frame may expand to multiple frames due to inlining.
|
||||
void* pc = frame.mTagPtr;
|
||||
|
@ -772,7 +760,6 @@ void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter, int aThre
|
|||
stack.AppendFrame(inlineFrameKey);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
framePos = (framePos + incBy) % mEntrySize;
|
||||
}
|
||||
|
|
|
@ -15,19 +15,13 @@
|
|||
#include "mozilla/RefPtr.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "js/ProfilingFrameIterator.h"
|
||||
#include "js/TrackedOptimizationInfo.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#endif
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/Vector.h"
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "gtest/MozGtestFriend.h"
|
||||
#else
|
||||
#define FRIEND_TEST(a, b) // TODO Support standalone gtest
|
||||
#endif
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
|
@ -197,19 +191,14 @@ public:
|
|||
struct MOZ_STACK_CLASS OnStackFrameKey : public FrameKey {
|
||||
explicit OnStackFrameKey(const char* aLocation)
|
||||
: FrameKey(aLocation)
|
||||
#ifndef SPS_STANDALONE
|
||||
, mJITFrameHandle(nullptr)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
OnStackFrameKey(const OnStackFrameKey& aToCopy)
|
||||
: FrameKey(aToCopy)
|
||||
#ifndef SPS_STANDALONE
|
||||
, mJITFrameHandle(aToCopy.mJITFrameHandle)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
const JS::ForEachProfiledFrameOp::FrameHandle* mJITFrameHandle;
|
||||
|
||||
OnStackFrameKey(void* aJITAddress, unsigned aJITDepth)
|
||||
|
@ -222,7 +211,6 @@ public:
|
|||
: FrameKey(aJITAddress, aJITDepth)
|
||||
, mJITFrameHandle(&aJITFrameHandle)
|
||||
{ }
|
||||
#endif
|
||||
};
|
||||
|
||||
struct StackKey {
|
||||
|
|
|
@ -7,11 +7,9 @@
|
|||
#include "ProfilerBacktrace.h"
|
||||
#include "ProfilerMarkers.h"
|
||||
#include "SyncProfile.h"
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "gfxASurface.h"
|
||||
#include "Layers.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#endif
|
||||
|
||||
ProfilerMarkerPayload::ProfilerMarkerPayload(UniqueProfilerBacktrace aStack)
|
||||
: mStack(mozilla::Move(aStack))
|
||||
|
@ -88,7 +86,6 @@ ProfilerMarkerTracing::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
GPUMarkerPayload::GPUMarkerPayload(
|
||||
const mozilla::TimeStamp& aCpuTimeStart,
|
||||
const mozilla::TimeStamp& aCpuTimeEnd,
|
||||
|
@ -228,4 +225,3 @@ VsyncPayload::StreamPayload(SpliceableJSONWriter& aWriter, UniqueStacks& aUnique
|
|||
aWriter.DoubleProperty("vsync", profiler_time(mVsyncTimestamp));
|
||||
aWriter.StringProperty("category", "VsyncTimestamp");
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -21,9 +21,7 @@ ThreadInfo::ThreadInfo(const char* aName, int aThreadId,
|
|||
, mPendingDelete(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ThreadInfo);
|
||||
#ifndef SPS_STANDALONE
|
||||
mThread = NS_GetCurrentThread();
|
||||
#endif
|
||||
|
||||
// We don't have to guess on mac
|
||||
#ifdef XP_MACOSX
|
||||
|
|
|
@ -35,14 +35,11 @@ class ThreadInfo {
|
|||
virtual void SetPendingDelete();
|
||||
bool IsPendingDelete() const { return mPendingDelete; }
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
/**
|
||||
* May be null for the main thread if the profiler was started during startup
|
||||
*/
|
||||
nsIThread* GetThread() const { return mThread.get(); }
|
||||
|
||||
#endif
|
||||
|
||||
bool CanInvokeJS() const;
|
||||
|
||||
private:
|
||||
|
@ -53,9 +50,7 @@ class ThreadInfo {
|
|||
Sampler::UniquePlatformData mPlatformData;
|
||||
mozilla::UniquePtr<ThreadProfile> mProfile;
|
||||
void* mStackTop;
|
||||
#ifndef SPS_STANDALONE
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
#endif
|
||||
bool mPendingDelete;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,9 +13,7 @@ ThreadProfile::ThreadProfile(ThreadInfo* aInfo, ProfileBuffer* aBuffer)
|
|||
, mIsMainThread(aInfo->IsMainThread())
|
||||
, mPlatformData(aInfo->GetPlatformData())
|
||||
, mStackTop(aInfo->StackTop())
|
||||
#ifndef SPS_STANDALONE
|
||||
, mRespInfo(this)
|
||||
#endif
|
||||
#ifdef XP_LINUX
|
||||
, mRssMemory(0)
|
||||
, mUssMemory(0)
|
||||
|
@ -47,11 +45,7 @@ void ThreadProfile::StreamJSON(SpliceableJSONWriter& aWriter, double aSinceTime)
|
|||
{
|
||||
// mUniqueStacks may already be emplaced from FlushSamplesAndMarkers.
|
||||
if (!mUniqueStacks.isSome()) {
|
||||
#ifndef SPS_STANDALONE
|
||||
mUniqueStacks.emplace(mPseudoStack->mContext);
|
||||
#else
|
||||
mUniqueStacks.emplace(nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
aWriter.Start(SpliceableJSONWriter::SingleLineStyle);
|
||||
|
@ -107,9 +101,7 @@ void ThreadProfile::StreamJSON(SpliceableJSONWriter& aWriter, double aSinceTime)
|
|||
void ThreadProfile::StreamSamplesAndMarkers(SpliceableJSONWriter& aWriter, double aSinceTime,
|
||||
UniqueStacks& aUniqueStacks)
|
||||
{
|
||||
#ifndef SPS_STANDALONE
|
||||
aWriter.StringProperty("processType", XRE_ChildProcessTypeToString(XRE_GetProcessType()));
|
||||
#endif
|
||||
|
||||
aWriter.StringProperty("name", Name());
|
||||
aWriter.IntProperty("tid", static_cast<int>(mThreadId));
|
||||
|
@ -137,12 +129,7 @@ void ThreadProfile::StreamSamplesAndMarkers(SpliceableJSONWriter& aWriter, doubl
|
|||
mSavedStreamedSamples.reset();
|
||||
}
|
||||
mBuffer->StreamSamplesToJSON(aWriter, mThreadId, aSinceTime,
|
||||
#ifndef SPS_STANDALONE
|
||||
mPseudoStack->mContext,
|
||||
#else
|
||||
nullptr,
|
||||
#endif
|
||||
aUniqueStacks);
|
||||
mPseudoStack->mContext, aUniqueStacks);
|
||||
}
|
||||
aWriter.EndArray();
|
||||
}
|
||||
|
@ -184,23 +171,14 @@ void ThreadProfile::FlushSamplesAndMarkers()
|
|||
//
|
||||
// Note that the UniqueStacks instance is persisted so that the frame-index
|
||||
// mapping is stable across JS shutdown.
|
||||
#ifndef SPS_STANDALONE
|
||||
mUniqueStacks.emplace(mPseudoStack->mContext);
|
||||
#else
|
||||
mUniqueStacks.emplace(nullptr);
|
||||
#endif
|
||||
|
||||
{
|
||||
SpliceableChunkedJSONWriter b;
|
||||
b.StartBareList();
|
||||
{
|
||||
mBuffer->StreamSamplesToJSON(b, mThreadId, /* aSinceTime = */ 0,
|
||||
#ifndef SPS_STANDALONE
|
||||
mPseudoStack->mContext,
|
||||
#else
|
||||
nullptr,
|
||||
#endif
|
||||
*mUniqueStacks);
|
||||
mPseudoStack->mContext, *mUniqueStacks);
|
||||
}
|
||||
b.EndBareList();
|
||||
mSavedStreamedSamples = b.WriteFunc()->CopyData();
|
||||
|
|
|
@ -46,9 +46,7 @@ public:
|
|||
void DuplicateLastSample();
|
||||
|
||||
ThreadInfo* GetThreadInfo() const { return mThreadInfo; }
|
||||
#ifndef SPS_STANDALONE
|
||||
ThreadResponsiveness* GetThreadResponsiveness() { return &mRespInfo; }
|
||||
#endif
|
||||
|
||||
bool CanInvokeJS() const { return mThreadInfo->CanInvokeJS(); }
|
||||
|
||||
|
@ -90,9 +88,7 @@ private:
|
|||
bool mIsMainThread;
|
||||
PlatformData* mPlatformData; // Platform specific data.
|
||||
void* const mStackTop;
|
||||
#ifndef SPS_STANDALONE
|
||||
ThreadResponsiveness mRespInfo;
|
||||
#endif
|
||||
|
||||
// Only Linux is using a signal sender, instead of stopping the thread, so we
|
||||
// need some space to store the data which cannot be collected in the signal
|
||||
|
|
|
@ -29,13 +29,11 @@
|
|||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "ThreadResponsiveness.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
// Memory profile
|
||||
#include "nsMemoryReporterManager.h"
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
#include "GeckoSampler.h"
|
||||
|
@ -227,9 +225,7 @@ class SamplerThread : public Thread {
|
|||
continue;
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
info->Profile()->GetThreadResponsiveness()->Update();
|
||||
#endif
|
||||
|
||||
ThreadProfile* thread_profile = info->Profile();
|
||||
|
||||
|
@ -262,11 +258,9 @@ class SamplerThread : public Thread {
|
|||
sample->ussMemory = 0;
|
||||
sample->rssMemory = 0;
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
if (isFirstProfiledThread && Sampler::GetActiveSampler()->ProfileMemory()) {
|
||||
sample->rssMemory = nsMemoryReporterManager::ResidentFast();
|
||||
}
|
||||
#endif
|
||||
|
||||
// We're using thread_suspend on OS X because pthread_kill (which is what
|
||||
// we're using on Linux) has less consistent performance and causes
|
||||
|
|
|
@ -14,16 +14,13 @@
|
|||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "ProfilerIOInterposeObserver.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#endif
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "PseudoStack.h"
|
||||
#include "GeckoSampler.h"
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
|
@ -31,7 +28,6 @@
|
|||
#include "nsProfilerStartParams.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#endif
|
||||
#include "ProfilerMarkers.h"
|
||||
|
||||
#ifdef MOZ_TASK_TRACER
|
||||
|
@ -46,13 +42,11 @@
|
|||
#include "FennecJNINatives.h"
|
||||
#endif
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
#if defined(SPS_PLAT_amd64_linux) || defined(SPS_PLAT_x86_linux)
|
||||
# define USE_LUL_STACKWALK
|
||||
# include "lul/LulMain.h"
|
||||
# include "lul/platform-linux-lul.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
|
||||
class GeckoJavaSampler : public java::GeckoJavaSampler::Natives<GeckoJavaSampler>
|
||||
|
@ -112,10 +106,8 @@ mozilla::UniquePtr< ::Mutex> Sampler::sRegisteredThreadsMutex;
|
|||
|
||||
GeckoSampler* Sampler::sActiveSampler;
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
static mozilla::StaticAutoPtr<mozilla::ProfilerIOInterposeObserver>
|
||||
sInterposeObserver;
|
||||
#endif
|
||||
|
||||
// The name that identifies the gecko thread for calls to
|
||||
// profiler_register_thread.
|
||||
|
@ -480,7 +472,6 @@ bool is_main_thread_name(const char* aName) {
|
|||
return strcmp(aName, gGeckoThreadName) == 0;
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
#ifdef HAVE_VA_COPY
|
||||
#define VARARGS_ASSIGN(foo, bar) VA_COPY(foo,bar)
|
||||
#elif defined(HAVE_VA_LIST_AS_ARRAY)
|
||||
|
@ -519,7 +510,6 @@ mozilla_sampler_log(const char *fmt, va_list args)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// BEGIN externally visible functions
|
||||
|
@ -566,9 +556,7 @@ void mozilla_sampler_init(void* stackTop)
|
|||
// platform specific initialization
|
||||
OS::Startup();
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
set_stderr_callback(mozilla_sampler_log);
|
||||
#endif
|
||||
|
||||
#if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
|
||||
if (mozilla::jni::IsFennec()) {
|
||||
|
@ -628,9 +616,7 @@ void mozilla_sampler_shutdown()
|
|||
|
||||
profiler_stop();
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
set_stderr_callback(nullptr);
|
||||
#endif
|
||||
|
||||
Sampler::Shutdown();
|
||||
|
||||
|
@ -670,7 +656,6 @@ mozilla::UniquePtr<char[]> mozilla_sampler_get_profile(double aSinceTime)
|
|||
return t->ToJSON(aSinceTime);
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
JSObject *mozilla_sampler_get_profile_data(JSContext *aCx, double aSinceTime)
|
||||
{
|
||||
GeckoSampler *t = tlsTicker.get();
|
||||
|
@ -757,8 +742,6 @@ void mozilla_sampler_get_gatherer(nsISupports** aRetVal)
|
|||
t->GetGatherer(aRetVal);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void mozilla_sampler_save_profile_to_file(const char* aFilename)
|
||||
{
|
||||
GeckoSampler *t = tlsTicker.get();
|
||||
|
@ -886,14 +869,12 @@ void mozilla_sampler_start(int aProfileEntries, double aInterval,
|
|||
continue;
|
||||
}
|
||||
thread_profile->GetPseudoStack()->reinitializeOnResume();
|
||||
#ifndef SPS_STANDALONE
|
||||
if (t->ProfileJS()) {
|
||||
thread_profile->GetPseudoStack()->enableJSSampling();
|
||||
}
|
||||
if (t->InPrivacyMode()) {
|
||||
thread_profile->GetPseudoStack()->mPrivacyMode = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -908,7 +889,6 @@ void mozilla_sampler_start(int aProfileEntries, double aInterval,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
if (t->AddMainThreadIO()) {
|
||||
if (!sInterposeObserver) {
|
||||
// Lazily create IO interposer observer
|
||||
|
@ -917,10 +897,8 @@ void mozilla_sampler_start(int aProfileEntries, double aInterval,
|
|||
mozilla::IOInterposer::Register(mozilla::IOInterposeObserver::OpAll,
|
||||
sInterposeObserver);
|
||||
}
|
||||
#endif
|
||||
|
||||
sIsProfiling = true;
|
||||
#ifndef SPS_STANDALONE
|
||||
sIsGPUProfiling = t->ProfileGPU();
|
||||
sIsLayersDump = t->LayersDump();
|
||||
sIsDisplayListDump = t->DisplayListDump();
|
||||
|
@ -947,7 +925,6 @@ void mozilla_sampler_start(int aProfileEntries, double aInterval,
|
|||
os->NotifyObservers(params, "profiler-started", nullptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG("END mozilla_sampler_start");
|
||||
}
|
||||
|
@ -971,7 +948,6 @@ void mozilla_sampler_stop()
|
|||
delete t;
|
||||
tlsTicker.set(nullptr);
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
if (disableJS) {
|
||||
PseudoStack *stack = tlsPseudoStack.get();
|
||||
ASSERT(stack != nullptr);
|
||||
|
@ -981,10 +957,8 @@ void mozilla_sampler_stop()
|
|||
mozilla::IOInterposer::Unregister(mozilla::IOInterposeObserver::OpAll,
|
||||
sInterposeObserver);
|
||||
sInterposeObserver = nullptr;
|
||||
#endif
|
||||
|
||||
sIsProfiling = false;
|
||||
#ifndef SPS_STANDALONE
|
||||
sIsGPUProfiling = false;
|
||||
sIsLayersDump = false;
|
||||
sIsDisplayListDump = false;
|
||||
|
@ -995,7 +969,6 @@ void mozilla_sampler_stop()
|
|||
if (os)
|
||||
os->NotifyObservers(nullptr, "profiler-stopped", nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG("END mozilla_sampler_stop");
|
||||
}
|
||||
|
@ -1011,26 +984,22 @@ bool mozilla_sampler_is_paused() {
|
|||
void mozilla_sampler_pause() {
|
||||
if (Sampler::GetActiveSampler()) {
|
||||
Sampler::GetActiveSampler()->SetPaused(true);
|
||||
#ifndef SPS_STANDALONE
|
||||
if (Sampler::CanNotifyObservers()) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->NotifyObservers(nullptr, "profiler-paused", nullptr);
|
||||
}
|
||||
#endif
|
||||
if (Sampler::CanNotifyObservers()) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->NotifyObservers(nullptr, "profiler-paused", nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mozilla_sampler_resume() {
|
||||
if (Sampler::GetActiveSampler()) {
|
||||
Sampler::GetActiveSampler()->SetPaused(false);
|
||||
#ifndef SPS_STANDALONE
|
||||
if (Sampler::CanNotifyObservers()) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->NotifyObservers(nullptr, "profiler-resumed", nullptr);
|
||||
}
|
||||
#endif
|
||||
if (Sampler::CanNotifyObservers()) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->NotifyObservers(nullptr, "profiler-resumed", nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1077,20 +1046,16 @@ void mozilla_sampler_frame_number(int frameNumber)
|
|||
void mozilla_sampler_lock()
|
||||
{
|
||||
profiler_stop();
|
||||
#ifndef SPS_STANDALONE
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->NotifyObservers(nullptr, "profiler-locked", nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mozilla_sampler_unlock()
|
||||
{
|
||||
#ifndef SPS_STANDALONE
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->NotifyObservers(nullptr, "profiler-unlocked", nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool mozilla_sampler_register_thread(const char* aName, void* aGuessStackTop)
|
||||
|
@ -1281,7 +1246,6 @@ void mozilla_sampler_add_marker(const char *aMarker, ProfilerMarkerPayload *aPay
|
|||
stack->addMarker(aMarker, payload.release(), delta.ToMilliseconds());
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
class GeckoMutex : public ::Mutex {
|
||||
|
@ -1310,37 +1274,5 @@ mozilla::UniquePtr< ::Mutex> OS::CreateMutex(const char* aDesc) {
|
|||
return mozilla::MakeUnique<GeckoMutex>(aDesc);
|
||||
}
|
||||
|
||||
#else
|
||||
// Otherwise use c++11 Mutex
|
||||
#include <mutex>
|
||||
|
||||
class OSXMutex : public ::Mutex {
|
||||
public:
|
||||
OSXMutex(const char* aDesc) :
|
||||
mMutex()
|
||||
{}
|
||||
|
||||
virtual ~OSXMutex() {}
|
||||
|
||||
virtual int Lock() {
|
||||
mMutex.lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int Unlock() {
|
||||
mMutex.unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex mMutex;
|
||||
};
|
||||
|
||||
mozilla::UniquePtr< ::Mutex> OS::CreateMutex(const char* aDesc) {
|
||||
return mozilla::MakeUnique<GeckoMutex>(aDesc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// END externally visible functions
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -46,11 +46,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "ThreadResponsiveness.h"
|
||||
#endif
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
|
|
@ -51,9 +51,7 @@
|
|||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "js/TypeDecls.h"
|
||||
#endif
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
@ -68,9 +66,7 @@ class Promise;
|
|||
|
||||
} // namespace mozilla
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
class nsIProfilerStartParams;
|
||||
#endif
|
||||
|
||||
enum TracingMetadata {
|
||||
TRACING_DEFAULT,
|
||||
|
@ -185,7 +181,6 @@ static inline JSObject* profiler_get_profile_jsobject(JSContext* aCx,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
// Get the profile encoded as a JSON object.
|
||||
static inline void profiler_get_profile_jsobject_async(double aSinceTime = 0,
|
||||
mozilla::dom::Promise* = 0) {}
|
||||
|
@ -193,7 +188,6 @@ static inline void profiler_get_start_params(int* aEntrySize,
|
|||
double* aInterval,
|
||||
mozilla::Vector<const char*>* aFilters,
|
||||
mozilla::Vector<const char*>* aFeatures) {}
|
||||
#endif
|
||||
|
||||
// Get the profile and write it into a file
|
||||
static inline void profiler_save_profile_to_file(char* aFilename) { }
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
#ifndef PROFILER_FUNCS_H
|
||||
#define PROFILER_FUNCS_H
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "js/TypeDecls.h"
|
||||
#endif
|
||||
#include "js/ProfilingStack.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
@ -67,7 +65,6 @@ void mozilla_sampler_save();
|
|||
|
||||
mozilla::UniquePtr<char[]> mozilla_sampler_get_profile(double aSinceTime);
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
JSObject *mozilla_sampler_get_profile_data(JSContext* aCx, double aSinceTime);
|
||||
void mozilla_sampler_get_profile_data_async(double aSinceTime,
|
||||
mozilla::dom::Promise* aPromise);
|
||||
|
@ -79,7 +76,6 @@ void mozilla_sampler_get_profiler_start_params(int* aEntrySize,
|
|||
mozilla::Vector<const char*>* aFilters,
|
||||
mozilla::Vector<const char*>* aFeatures);
|
||||
void mozilla_sampler_get_gatherer(nsISupports** aRetVal);
|
||||
#endif
|
||||
|
||||
// Make this function easily callable from a debugger in a build without
|
||||
// debugging information (work around http://llvm.org/bugs/show_bug.cgi?id=22211)
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "nscore.h"
|
||||
#include "nsISupports.h"
|
||||
#endif
|
||||
#include "GeckoProfilerFunc.h"
|
||||
#include "PseudoStack.h"
|
||||
#include "ProfilerBacktrace.h"
|
||||
|
@ -135,7 +133,6 @@ mozilla::UniquePtr<char[]> profiler_get_profile(double aSinceTime = 0)
|
|||
return mozilla_sampler_get_profile(aSinceTime);
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
static inline
|
||||
JSObject* profiler_get_profile_jsobject(JSContext* aCx, double aSinceTime = 0)
|
||||
{
|
||||
|
@ -164,8 +161,6 @@ void profiler_get_gatherer(nsISupports** aRetVal)
|
|||
mozilla_sampler_get_gatherer(aRetVal);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline
|
||||
void profiler_save_profile_to_file(const char* aFilename)
|
||||
{
|
||||
|
@ -227,7 +222,6 @@ bool profiler_is_sleeping()
|
|||
return mozilla_sampler_is_sleeping();
|
||||
}
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
static inline
|
||||
void profiler_js_operation_callback()
|
||||
{
|
||||
|
@ -238,7 +232,6 @@ void profiler_js_operation_callback()
|
|||
|
||||
stack->jsOperationCallback();
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline
|
||||
double profiler_time()
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class Layer;
|
||||
|
@ -86,9 +88,6 @@ private:
|
|||
TracingMetadata mMetaData;
|
||||
};
|
||||
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "gfxASurface.h"
|
||||
class ProfilerMarkerImagePayload : public ProfilerMarkerPayload
|
||||
{
|
||||
public:
|
||||
|
@ -204,6 +203,5 @@ private:
|
|||
uint64_t mGpuTimeStart;
|
||||
uint64_t mGpuTimeEnd;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // PROFILER_MARKERS_H
|
||||
|
|
|
@ -11,9 +11,7 @@
|
|||
#include "js/ProfilingStack.h"
|
||||
#include <stdlib.h>
|
||||
#include "mozilla/Atomics.h"
|
||||
#ifndef SPS_STANDALONE
|
||||
#include "nsISupportsImpl.h"
|
||||
#endif
|
||||
|
||||
/* we duplicate this code here to avoid header dependencies
|
||||
* which make it more difficult to include in other places */
|
||||
|
@ -316,7 +314,6 @@ public:
|
|||
}
|
||||
|
||||
void sampleContext(JSContext* context) {
|
||||
#ifndef SPS_STANDALONE
|
||||
if (mContext && !context) {
|
||||
// On JS shut down, flush the current buffer as stringifying JIT samples
|
||||
// requires a live JSContext.
|
||||
|
@ -337,9 +334,7 @@ public:
|
|||
(uint32_t) mozilla::ArrayLength(mStack));
|
||||
if (mStartJSSampling)
|
||||
enableJSSampling();
|
||||
#endif
|
||||
}
|
||||
#ifndef SPS_STANDALONE
|
||||
void enableJSSampling() {
|
||||
if (mContext) {
|
||||
js::EnableContextProfilingStack(mContext, true);
|
||||
|
@ -358,7 +353,6 @@ public:
|
|||
if (mContext)
|
||||
js::EnableContextProfilingStack(mContext, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Keep a list of active checkpoints
|
||||
StackEntry volatile mStack[1024];
|
||||
|
@ -371,9 +365,7 @@ public:
|
|||
, mSleepIdObserved(0)
|
||||
, mSleeping(false)
|
||||
, mRefCnt(1)
|
||||
#ifndef SPS_STANDALONE
|
||||
, mContext(nullptr)
|
||||
#endif
|
||||
, mStartJSSampling(false)
|
||||
, mPrivacyMode(false)
|
||||
{
|
||||
|
@ -416,10 +408,8 @@ public:
|
|||
mozilla::Atomic<int> mRefCnt;
|
||||
|
||||
public:
|
||||
#ifndef SPS_STANDALONE
|
||||
// The context which is being sampled
|
||||
JSContext *mContext;
|
||||
#endif
|
||||
// Start JS Profiling when possible
|
||||
bool mStartJSSampling;
|
||||
bool mPrivacyMode;
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#ifndef SPS_STANDALONE
|
||||
#include <nsID.h>
|
||||
#endif
|
||||
|
||||
class SharedLibrary {
|
||||
public:
|
||||
|
|
Загрузка…
Ссылка в новой задаче