Bug 1492121 - MOZ_BASE_PROFILER may be defined in BaseProfiler.h to enable Base Profiler - r=njn

Added baseprofiler to mozglue/moz.build, so it will be built.
However all cpp files are dependent on `MOZ_BASE_PROFILER`, which is currently
not #defined by default (in public/BaseProfiler.h).

Differential Revision: https://phabricator.services.mozilla.com/D33258

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Gerald Squelart 2019-06-04 06:52:41 +00:00
Родитель 38eb2d609e
Коммит 494369648d
30 изменённых файлов: 991 добавлений и 811 удалений

Просмотреть файл

@ -22,34 +22,38 @@
* standard-layout rules in the former. * standard-layout rules in the former.
*/ */
#include "EHABIStackWalk.h" #include "BaseProfiler.h"
#include "BaseProfilerSharedLibraries.h" #ifdef MOZ_BASE_PROFILER
#include "platform.h"
#include "mozilla/Atomics.h" # include "EHABIStackWalk.h"
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/EndianUtils.h"
#include <algorithm> # include "BaseProfilerSharedLibraries.h"
#include <elf.h> # include "platform.h"
#include <stdint.h>
#include <vector>
#include <string>
#ifndef PT_ARM_EXIDX # include "mozilla/Atomics.h"
# define PT_ARM_EXIDX 0x70000001 # include "mozilla/Attributes.h"
#endif # include "mozilla/DebugOnly.h"
# include "mozilla/EndianUtils.h"
# include <algorithm>
# include <elf.h>
# include <stdint.h>
# include <vector>
# include <string>
# ifndef PT_ARM_EXIDX
# define PT_ARM_EXIDX 0x70000001
# endif
// Bug 1082817: ICS B2G has a buggy linker that doesn't always ensure // Bug 1082817: ICS B2G has a buggy linker that doesn't always ensure
// that the EXIDX is sorted by address, as the spec requires. So in // that the EXIDX is sorted by address, as the spec requires. So in
// that case we build and sort an array of pointers into the index, // that case we build and sort an array of pointers into the index,
// and binary-search that; otherwise, we search the index in place // and binary-search that; otherwise, we search the index in place
// (avoiding the time and space overhead of the indirection). // (avoiding the time and space overhead of the indirection).
#if defined(ANDROID_VERSION) && ANDROID_VERSION < 16 # if defined(ANDROID_VERSION) && ANDROID_VERSION < 16
# define HAVE_UNSORTED_EXIDX # define HAVE_UNSORTED_EXIDX
#endif # endif
namespace mozilla { namespace mozilla {
@ -90,7 +94,7 @@ class EHState {
enum { R_SP = 13, R_LR = 14, R_PC = 15 }; enum { R_SP = 13, R_LR = 14, R_PC = 15 };
#ifdef HAVE_UNSORTED_EXIDX # ifdef HAVE_UNSORTED_EXIDX
class EHEntryHandle { class EHEntryHandle {
const EHEntry* mValue; const EHEntry* mValue;
@ -102,13 +106,13 @@ class EHEntryHandle {
bool operator<(const EHEntryHandle& lhs, const EHEntryHandle& rhs) { bool operator<(const EHEntryHandle& lhs, const EHEntryHandle& rhs) {
return lhs.value()->startPC.compute() < rhs.value()->startPC.compute(); return lhs.value()->startPC.compute() < rhs.value()->startPC.compute();
} }
#endif # endif
class EHTable { class EHTable {
uint32_t mStartPC; uint32_t mStartPC;
uint32_t mEndPC; uint32_t mEndPC;
uint32_t mBaseAddress; uint32_t mBaseAddress;
#ifdef HAVE_UNSORTED_EXIDX # ifdef HAVE_UNSORTED_EXIDX
// In principle we should be able to binary-search the index section in // In principle we should be able to binary-search the index section in
// place, but the ICS toolchain's linker is noncompliant and produces // place, but the ICS toolchain's linker is noncompliant and produces
// indices that aren't entirely sorted (e.g., libc). So we have this: // indices that aren't entirely sorted (e.g., libc). So we have this:
@ -119,13 +123,13 @@ class EHTable {
static const EHEntry* entryGet(EntryIterator aEntry) { static const EHEntry* entryGet(EntryIterator aEntry) {
return aEntry->value(); return aEntry->value();
} }
#else # else
typedef const EHEntry* EntryIterator; typedef const EHEntry* EntryIterator;
EntryIterator mEntriesBegin, mEntriesEnd; EntryIterator mEntriesBegin, mEntriesEnd;
EntryIterator entriesBegin() const { return mEntriesBegin; } EntryIterator entriesBegin() const { return mEntriesBegin; }
EntryIterator entriesEnd() const { return mEntriesEnd; } EntryIterator entriesEnd() const { return mEntriesEnd; }
static const EHEntry* entryGet(EntryIterator aEntry) { return aEntry; } static const EHEntry* entryGet(EntryIterator aEntry) { return aEntry; }
#endif # endif
std::string mName; std::string mName;
public: public:
@ -330,9 +334,9 @@ bool EHInterp::unwind() {
checkStack(); checkStack();
while (!mFailed) { while (!mFailed) {
uint8_t insn = next(); uint8_t insn = next();
#if DEBUG_EHABI_UNWIND # if DEBUG_EHABI_UNWIND
LOG("unwind insn = %02x", (unsigned)insn); LOG("unwind insn = %02x", (unsigned)insn);
#endif # endif
// Try to put the common cases first. // Try to put the common cases first.
// 00xxxxxx: vsp = vsp + (xxxxxx << 2) + 4 // 00xxxxxx: vsp = vsp + (xxxxxx << 2) + 4
@ -456,9 +460,9 @@ bool EHInterp::unwind() {
} }
// unhandled instruction // unhandled instruction
#ifdef DEBUG_EHABI_UNWIND # ifdef DEBUG_EHABI_UNWIND
LOG("Unhandled EHABI instruction 0x%02x", insn); LOG("Unhandled EHABI instruction 0x%02x", insn);
#endif # endif
mFailed = true; mFailed = true;
} }
return false; return false;
@ -501,12 +505,12 @@ const EHEntry* EHTable::lookup(uint32_t aPC) const {
return nullptr; return nullptr;
while (end - begin > 1) { while (end - begin > 1) {
#ifdef EHABI_UNWIND_MORE_ASSERTS # ifdef EHABI_UNWIND_MORE_ASSERTS
if (entryGet(end - 1)->startPC.compute() < if (entryGet(end - 1)->startPC.compute() <
entryGet(begin)->startPC.compute()) { entryGet(begin)->startPC.compute()) {
MOZ_CRASH("unsorted exidx"); MOZ_CRASH("unsorted exidx");
} }
#endif # endif
EntryIterator mid = begin + (end - begin) / 2; EntryIterator mid = begin + (end - begin) / 2;
if (aPC < reinterpret_cast<uint32_t>(entryGet(mid)->startPC.compute())) if (aPC < reinterpret_cast<uint32_t>(entryGet(mid)->startPC.compute()))
end = mid; end = mid;
@ -516,22 +520,22 @@ const EHEntry* EHTable::lookup(uint32_t aPC) const {
return entryGet(begin); return entryGet(begin);
} }
#if MOZ_LITTLE_ENDIAN # if MOZ_LITTLE_ENDIAN
static const unsigned char hostEndian = ELFDATA2LSB; static const unsigned char hostEndian = ELFDATA2LSB;
#elif MOZ_BIG_ENDIAN # elif MOZ_BIG_ENDIAN
static const unsigned char hostEndian = ELFDATA2MSB; static const unsigned char hostEndian = ELFDATA2MSB;
#else # else
# error "No endian?" # error "No endian?"
#endif # endif
// Async signal unsafe: std::vector::reserve, std::string copy ctor. // Async signal unsafe: std::vector::reserve, std::string copy ctor.
EHTable::EHTable(const void* aELF, size_t aSize, const std::string& aName) EHTable::EHTable(const void* aELF, size_t aSize, const std::string& aName)
: mStartPC(~0), // largest uint32_t : mStartPC(~0), // largest uint32_t
mEndPC(0), mEndPC(0),
#ifndef HAVE_UNSORTED_EXIDX # ifndef HAVE_UNSORTED_EXIDX
mEntriesBegin(nullptr), mEntriesBegin(nullptr),
mEntriesEnd(nullptr), mEntriesEnd(nullptr),
#endif # endif
mName(aName) { mName(aName) {
const uint32_t fileHeaderAddr = reinterpret_cast<uint32_t>(aELF); const uint32_t fileHeaderAddr = reinterpret_cast<uint32_t>(aELF);
@ -574,14 +578,14 @@ EHTable::EHTable(const void* aELF, size_t aSize, const std::string& aName)
reinterpret_cast<const EHEntry*>(mBaseAddress + exidxHdr->p_vaddr); reinterpret_cast<const EHEntry*>(mBaseAddress + exidxHdr->p_vaddr);
const EHEntry* endTable = reinterpret_cast<const EHEntry*>( const EHEntry* endTable = reinterpret_cast<const EHEntry*>(
mBaseAddress + exidxHdr->p_vaddr + exidxHdr->p_memsz); mBaseAddress + exidxHdr->p_vaddr + exidxHdr->p_memsz);
#ifdef HAVE_UNSORTED_EXIDX # ifdef HAVE_UNSORTED_EXIDX
mEntries.reserve(endTable - startTable); mEntries.reserve(endTable - startTable);
for (const EHEntry* i = startTable; i < endTable; ++i) mEntries.push_back(i); for (const EHEntry* i = startTable; i < endTable; ++i) mEntries.push_back(i);
std::sort(mEntries.begin(), mEntries.end()); std::sort(mEntries.begin(), mEntries.end());
#else # else
mEntriesBegin = startTable; mEntriesBegin = startTable;
mEntriesEnd = endTable; mEntriesEnd = endTable;
#endif # endif
} }
mozilla::Atomic<const EHAddrSpace*> EHAddrSpace::sCurrent(nullptr); mozilla::Atomic<const EHAddrSpace*> EHAddrSpace::sCurrent(nullptr);
@ -616,7 +620,7 @@ void EHAddrSpace::Update() {
} }
EHState::EHState(const mcontext_t& context) { EHState::EHState(const mcontext_t& context) {
#ifdef linux # ifdef linux
mRegs[0] = context.arm_r0; mRegs[0] = context.arm_r0;
mRegs[1] = context.arm_r1; mRegs[1] = context.arm_r1;
mRegs[2] = context.arm_r2; mRegs[2] = context.arm_r2;
@ -633,9 +637,11 @@ EHState::EHState(const mcontext_t& context) {
mRegs[13] = context.arm_sp; mRegs[13] = context.arm_sp;
mRegs[14] = context.arm_lr; mRegs[14] = context.arm_lr;
mRegs[15] = context.arm_pc; mRegs[15] = context.arm_pc;
#else # else
# error "Unhandled OS for ARM EHABI unwinding" # error "Unhandled OS for ARM EHABI unwinding"
#endif # endif
} }
} // namespace mozilla } // namespace mozilla
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,9 +4,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PageInformation.h" #include "BaseProfiler.h"
#include "BaseProfileJSONWriter.h" #ifdef MOZ_BASE_PROFILER
# include "PageInformation.h"
# include "BaseProfileJSONWriter.h"
PageInformation::PageInformation(const nsID& aDocShellId, PageInformation::PageInformation(const nsID& aDocShellId,
uint32_t aDocShellHistoryId, uint32_t aDocShellHistoryId,
@ -35,3 +39,5 @@ size_t PageInformation::SizeOfIncludingThis(
mozilla::MallocSizeOf aMallocSizeOf) const { mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this); return aMallocSizeOf(this);
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,14 +4,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ProfileBuffer.h" #include "BaseProfiler.h"
#include "ProfilerMarker.h" #ifdef MOZ_BASE_PROFILER
#include "jsfriendapi.h" # include "ProfileBuffer.h"
#include "mozilla/MathAlgorithms.h"
#include "nsJSPrincipals.h" # include "ProfilerMarker.h"
#include "nsScriptSecurityManager.h"
# include "jsfriendapi.h"
# include "mozilla/MathAlgorithms.h"
# include "nsJSPrincipals.h"
# include "nsScriptSecurityManager.h"
using namespace mozilla; using namespace mozilla;
@ -188,3 +192,5 @@ void ProfileBufferCollector::CollectProfilingStackFrame(
mBuf.CollectCodeLocation(label, dynamicString, aFrame.flags(), line, column, mBuf.CollectCodeLocation(label, dynamicString, aFrame.flags(), line, column,
Some(aFrame.categoryPair())); Some(aFrame.categoryPair()));
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,21 +4,25 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ProfileBufferEntry.h" #include "BaseProfiler.h"
#include "platform.h" #ifdef MOZ_BASE_PROFILER
#include "ProfileBuffer.h"
#include "js/TrackedOptimizationInfo.h" # include "ProfileBufferEntry.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/Logging.h"
#include "mozilla/Sprintf.h"
#include "mozilla/StackWalk.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include <ostream> # include "platform.h"
# include "ProfileBuffer.h"
# include "js/TrackedOptimizationInfo.h"
# include "jsapi.h"
# include "jsfriendapi.h"
# include "mozilla/Logging.h"
# include "mozilla/Sprintf.h"
# include "mozilla/StackWalk.h"
# include "nsThreadUtils.h"
# include "nsXULAppAPI.h"
# include <ostream>
using namespace mozilla; using namespace mozilla;
@ -887,12 +891,12 @@ class EntryGetter {
// Because this is a format entirely internal to the Profiler, any parsing // Because this is a format entirely internal to the Profiler, any parsing
// error indicates a bug in the ProfileBuffer writing or the parser itself, // error indicates a bug in the ProfileBuffer writing or the parser itself,
// or possibly flaky hardware. // or possibly flaky hardware.
#define ERROR_AND_CONTINUE(msg) \ # define ERROR_AND_CONTINUE(msg) \
{ \ { \
fprintf(stderr, "ProfileBuffer parse error: %s", msg); \ fprintf(stderr, "ProfileBuffer parse error: %s", msg); \
MOZ_ASSERT(false, msg); \ MOZ_ASSERT(false, msg); \
continue; \ continue; \
} }
void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter, void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter,
int aThreadId, double aSinceTime, int aThreadId, double aSinceTime,
@ -1317,17 +1321,17 @@ void ProfileBuffer::StreamProfilerOverheadToJSON(
aWriter.DoubleProperty("overheadDurations", overheads.sum); aWriter.DoubleProperty("overheadDurations", overheads.sum);
aWriter.DoubleProperty("overheadPercentage", aWriter.DoubleProperty("overheadPercentage",
overheads.sum / (lastTime - firstTime)); overheads.sum / (lastTime - firstTime));
#define PROFILER_STATS(name, var) \ # define PROFILER_STATS(name, var) \
aWriter.DoubleProperty("mean" name, (var).sum / (var).n); \ aWriter.DoubleProperty("mean" name, (var).sum / (var).n); \
aWriter.DoubleProperty("min" name, (var).min); \ aWriter.DoubleProperty("min" name, (var).min); \
aWriter.DoubleProperty("max" name, (var).max); aWriter.DoubleProperty("max" name, (var).max);
PROFILER_STATS("Interval", intervals); PROFILER_STATS("Interval", intervals);
PROFILER_STATS("Overhead", overheads); PROFILER_STATS("Overhead", overheads);
PROFILER_STATS("Lockings", lockings); PROFILER_STATS("Lockings", lockings);
PROFILER_STATS("Cleaning", cleanings); PROFILER_STATS("Cleaning", cleanings);
PROFILER_STATS("Counter", counters); PROFILER_STATS("Counter", counters);
PROFILER_STATS("Thread", threads); PROFILER_STATS("Thread", threads);
#undef PROFILER_STATS # undef PROFILER_STATS
aWriter.EndObject(); // statistics aWriter.EndObject(); // statistics
} }
aWriter.EndObject(); // profilerOverhead aWriter.EndObject(); // profilerOverhead
@ -1572,7 +1576,7 @@ void ProfileBuffer::StreamMemoryToJSON(SpliceableJSONWriter& aWriter,
aWriter.EndObject(); // samples aWriter.EndObject(); // samples
aWriter.EndObject(); // memory aWriter.EndObject(); // memory
} }
#undef ERROR_AND_CONTINUE # undef ERROR_AND_CONTINUE
static void AddPausedRange(SpliceableJSONWriter& aWriter, const char* aReason, static void AddPausedRange(SpliceableJSONWriter& aWriter, const char* aReason,
const Maybe<double>& aStartTime, const Maybe<double>& aStartTime,
@ -1772,3 +1776,5 @@ void ProfileBuffer::DiscardSamplesBeforeTime(double aTime) {
// END ProfileBuffer // END ProfileBuffer
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -3,9 +3,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BaseProfileJSONWriter.h" #include "BaseProfiler.h"
#include "mozilla/HashFunctions.h" #ifdef MOZ_BASE_PROFILER
# include "BaseProfileJSONWriter.h"
# include "mozilla/HashFunctions.h"
void ChunkedJSONWriteFunc::Write(const char* aStr) { void ChunkedJSONWriteFunc::Write(const char* aStr) {
MOZ_ASSERT(mChunkPtr >= mChunkList.back().get() && mChunkPtr <= mChunkEnd); MOZ_ASSERT(mChunkPtr >= mChunkList.back().get() && mChunkPtr <= mChunkEnd);
@ -112,3 +116,5 @@ void SpliceableChunkedJSONWriter::TakeAndSplice(ChunkedJSONWriteFunc* aFunc) {
WriteFunc()->Take(std::move(*aFunc)); WriteFunc()->Take(std::move(*aFunc));
mNeedComma[mDepth] = true; mNeedComma[mDepth] = true;
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,17 +4,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ProfiledThreadData.h" #include "BaseProfiler.h"
#include "ProfileBuffer.h" #ifdef MOZ_BASE_PROFILER
#include "BaseProfileJSONWriter.h"
#include "js/TraceLoggerAPI.h" # include "ProfiledThreadData.h"
#include "mozilla/dom/ContentChild.h"
#if defined(GP_OS_darwin) # include "ProfileBuffer.h"
# include <pthread.h> # include "BaseProfileJSONWriter.h"
#endif
# include "js/TraceLoggerAPI.h"
# include "mozilla/dom/ContentChild.h"
# if defined(GP_OS_darwin)
# include <pthread.h>
# endif
ProfiledThreadData::ProfiledThreadData(ThreadInfo* aThreadInfo, ProfiledThreadData::ProfiledThreadData(ThreadInfo* aThreadInfo,
nsIEventTarget* aEventTarget, nsIEventTarget* aEventTarget,
@ -301,3 +305,5 @@ void ProfiledThreadData::NotifyAboutToLoseJSContext(
mJITFrameInfoForPreviousJSContexts = std::move(jitFrameInfo); mJITFrameInfoForPreviousJSContexts = std::move(jitFrameInfo);
mBufferPositionWhenReceivedJSContext = mozilla::Nothing(); mBufferPositionWhenReceivedJSContext = mozilla::Nothing();
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,12 +4,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ProfilerBacktrace.h" #include "BaseProfiler.h"
#include "ProfileBuffer.h" #ifdef MOZ_BASE_PROFILER
#include "ProfiledThreadData.h"
#include "BaseProfileJSONWriter.h" # include "ProfilerBacktrace.h"
#include "ThreadInfo.h"
# include "ProfileBuffer.h"
# include "ProfiledThreadData.h"
# include "BaseProfileJSONWriter.h"
# include "ThreadInfo.h"
ProfilerBacktrace::ProfilerBacktrace(const char* aName, int aThreadId, ProfilerBacktrace::ProfilerBacktrace(const char* aName, int aThreadId,
mozilla::UniquePtr<ProfileBuffer> aBuffer) mozilla::UniquePtr<ProfileBuffer> aBuffer)
@ -32,3 +36,5 @@ void ProfilerBacktrace::StreamJSON(SpliceableJSONWriter& aWriter,
/* aUnregisterTime */ mozilla::TimeStamp(), /* aUnregisterTime */ mozilla::TimeStamp(),
/* aSinceTime */ 0, aUniqueStacks); /* aSinceTime */ 0, aUniqueStacks);
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -3,20 +3,23 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BaseProfilerMarkerPayload.h"
#include "BaseProfiler.h" #include "BaseProfiler.h"
#include "ProfileBufferEntry.h"
#include "BaseProfileJSONWriter.h"
#include "ProfilerBacktrace.h"
#include "gfxASurface.h" #ifdef MOZ_BASE_PROFILER
#include "Layers.h"
#include "mozilla/Maybe.h"
#include "mozilla/net/HttpBaseChannel.h"
#include "mozilla/Sprintf.h"
#include <inttypes.h> # include "BaseProfilerMarkerPayload.h"
# include "ProfileBufferEntry.h"
# include "BaseProfileJSONWriter.h"
# include "ProfilerBacktrace.h"
# include "gfxASurface.h"
# include "Layers.h"
# include "mozilla/Maybe.h"
# include "mozilla/net/HttpBaseChannel.h"
# include "mozilla/Sprintf.h"
# include <inttypes.h>
using namespace mozilla; using namespace mozilla;
@ -296,3 +299,5 @@ void LongTaskMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
aUniqueStacks); aUniqueStacks);
aWriter.StringProperty("category", "LongTask"); aWriter.StringProperty("category", "LongTask");
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,28 +4,32 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "vm/GeckoProfiler-inl.h" #include "BaseProfiler.h"
#include "mozilla/ArrayUtils.h" #ifdef MOZ_BASE_PROFILER
#include "mozilla/DebugOnly.h"
#include "mozilla/Sprintf.h"
#include "jsnum.h" # include "vm/GeckoProfiler-inl.h"
#include "gc/GC.h" # include "mozilla/ArrayUtils.h"
#include "gc/PublicIterators.h" # include "mozilla/DebugOnly.h"
#include "jit/BaselineFrame.h" # include "mozilla/Sprintf.h"
#include "jit/BaselineJIT.h"
#include "jit/JitcodeMap.h"
#include "jit/JitFrames.h"
#include "jit/JitRealm.h"
#include "jit/JSJitFrameIter.h"
#include "js/TraceLoggerAPI.h"
#include "util/StringBuffer.h"
#include "vm/JSScript.h"
#include "gc/Marking-inl.h" # include "jsnum.h"
#include "vm/JSScript-inl.h"
# include "gc/GC.h"
# include "gc/PublicIterators.h"
# include "jit/BaselineFrame.h"
# include "jit/BaselineJIT.h"
# include "jit/JitcodeMap.h"
# include "jit/JitFrames.h"
# include "jit/JitRealm.h"
# include "jit/JSJitFrameIter.h"
# include "js/TraceLoggerAPI.h"
# include "util/StringBuffer.h"
# include "vm/JSScript.h"
# include "gc/Marking-inl.h"
# include "vm/JSScript-inl.h"
using namespace js; using namespace js;
@ -152,14 +156,14 @@ void GeckoProfilerRuntime::enable(bool enabled) {
r->wasm.ensureProfilingLabels(enabled); r->wasm.ensureProfilingLabels(enabled);
} }
#ifdef JS_STRUCTURED_SPEW # ifdef JS_STRUCTURED_SPEW
// Enable the structured spewer if the environment variable is set. // Enable the structured spewer if the environment variable is set.
if (enabled) { if (enabled) {
cx->spewer().enableSpewing(); cx->spewer().enableSpewing();
} else { } else {
cx->spewer().disableSpewing(); cx->spewer().disableSpewing();
} }
#endif # endif
} }
/* Lookup the string for the function/script, creating one if necessary */ /* Lookup the string for the function/script, creating one if necessary */
@ -209,7 +213,7 @@ bool GeckoProfilerThread::enter(JSContext* cx, JSScript* script) {
return false; return false;
} }
#ifdef DEBUG # ifdef DEBUG
// In debug builds, assert the JS profiling stack frames already on the // In debug builds, assert the JS profiling stack frames already on the
// stack have a non-null pc. Only look at the top frames to avoid quadratic // stack have a non-null pc. Only look at the top frames to avoid quadratic
// behavior. // behavior.
@ -221,7 +225,7 @@ bool GeckoProfilerThread::enter(JSContext* cx, JSScript* script) {
profilingStack_->frames[i].pc()); profilingStack_->frames[i].pc());
} }
} }
#endif # endif
profilingStack_->pushJsFrame("", dynamicString, script, script->code()); profilingStack_->pushJsFrame("", dynamicString, script, script->code());
return true; return true;
@ -230,7 +234,7 @@ bool GeckoProfilerThread::enter(JSContext* cx, JSScript* script) {
void GeckoProfilerThread::exit(JSContext* cx, JSScript* script) { void GeckoProfilerThread::exit(JSContext* cx, JSScript* script) {
profilingStack_->pop(); profilingStack_->pop();
#ifdef DEBUG # ifdef DEBUG
/* Sanity check to make sure push/pop balanced */ /* Sanity check to make sure push/pop balanced */
uint32_t sp = profilingStack_->stackPointer; uint32_t sp = profilingStack_->stackPointer;
if (sp < profilingStack_->stackCapacity()) { if (sp < profilingStack_->stackCapacity()) {
@ -260,7 +264,7 @@ void GeckoProfilerThread::exit(JSContext* cx, JSScript* script) {
MOZ_ASSERT(frame.script() == script); MOZ_ASSERT(frame.script() == script);
MOZ_ASSERT(strcmp((const char*)frame.dynamicString(), dynamicString) == 0); MOZ_ASSERT(strcmp((const char*)frame.dynamicString(), dynamicString) == 0);
} }
#endif # endif
} }
/* /*
@ -379,7 +383,7 @@ void GeckoProfilerRuntime::fixupStringsMapAfterMovingGC() {
} }
} }
#ifdef JSGC_HASH_TABLE_CHECKS # ifdef JSGC_HASH_TABLE_CHECKS
void GeckoProfilerRuntime::checkStringsMapAfterMovingGC() { void GeckoProfilerRuntime::checkStringsMapAfterMovingGC() {
for (auto r = strings().all(); !r.empty(); r.popFront()) { for (auto r = strings().all(); !r.empty(); r.popFront()) {
JSScript* script = r.front().key(); JSScript* script = r.front().key();
@ -388,7 +392,7 @@ void GeckoProfilerRuntime::checkStringsMapAfterMovingGC() {
MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front()); MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front());
} }
} }
#endif # endif
void ProfilingStackFrame::trace(JSTracer* trc) { void ProfilingStackFrame::trace(JSTracer* trc) {
if (isJsFrame()) { if (isJsFrame()) {
@ -571,3 +575,5 @@ JS_FRIEND_API const ProfilingCategoryPairInfo& GetProfilingCategoryPairInfo(
} }
} // namespace JS } // namespace JS
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,13 +4,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "js/ProfilingStack.h" #include "BaseProfiler.h"
#include "mozilla/IntegerRange.h" #ifdef MOZ_BASE_PROFILER
#include "mozilla/UniquePtr.h"
#include "mozilla/UniquePtrExtensions.h"
#include <algorithm> # include "js/ProfilingStack.h"
# include "mozilla/IntegerRange.h"
# include "mozilla/UniquePtr.h"
# include "mozilla/UniquePtrExtensions.h"
# include <algorithm>
using namespace js; using namespace js;
@ -44,3 +48,5 @@ void ProfilingStack::ensureCapacitySlow() {
capacity = newCapacity; capacity = newCapacity;
delete[] oldFrames; delete[] oldFrames;
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,7 +4,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RegisteredThread.h" #include "BaseProfiler.h"
#ifdef MOZ_BASE_PROFILER
# include "RegisteredThread.h"
RegisteredThread::RegisteredThread(ThreadInfo* aInfo, nsIEventTarget* aThread, RegisteredThread::RegisteredThread(ThreadInfo* aInfo, nsIEventTarget* aThread,
void* aStackTop) void* aStackTop)
@ -19,10 +23,10 @@ RegisteredThread::RegisteredThread(ThreadInfo* aInfo, nsIEventTarget* aThread,
MOZ_COUNT_CTOR(RegisteredThread); MOZ_COUNT_CTOR(RegisteredThread);
// We don't have to guess on mac // We don't have to guess on mac
#if defined(GP_OS_darwin) # if defined(GP_OS_darwin)
pthread_t self = pthread_self(); pthread_t self = pthread_self();
mStackTop = pthread_get_stackaddr_np(self); mStackTop = pthread_get_stackaddr_np(self);
#endif # endif
} }
RegisteredThread::~RegisteredThread() { MOZ_COUNT_DTOR(RegisteredThread); } RegisteredThread::~RegisteredThread() { MOZ_COUNT_DTOR(RegisteredThread); }
@ -41,3 +45,5 @@ size_t RegisteredThread::SizeOfIncludingThis(
return n; return n;
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,14 +4,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef XP_WIN #include "BaseProfiler.h"
# undef UNICODE
# undef _UNICODE
#endif
#include "VTuneProfiler.h" #ifdef MOZ_BASE_PROFILER
#include "mozilla/Bootstrap.h"
#include <memory> # ifdef XP_WIN
# undef UNICODE
# undef _UNICODE
# endif
# include "VTuneProfiler.h"
# include "mozilla/Bootstrap.h"
# include <memory>
using namespace std; using namespace std;
@ -80,3 +84,5 @@ void VTuneProfiler::RegisterThreadInternal(const char* aName) {
} }
__itt_thread_set_name(aName); __itt_thread_set_name(aName);
} }
#endif // MOZ_BASE_PROFILER

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -4,40 +4,44 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BaseProfilerSharedLibraries.h" #include "BaseProfiler.h"
#define PATH_MAX_TOSTRING(x) #x #ifdef MOZ_BASE_PROFILER
#define PATH_MAX_STRING(x) PATH_MAX_TOSTRING(x)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <fstream>
#include "platform.h"
#include "mozilla/Sprintf.h"
#include "mozilla/Unused.h"
#include "nsDebug.h"
#include "nsNativeCharsetUtils.h"
#include <nsTArray.h>
#include "common/linux/file_id.h" # include "BaseProfilerSharedLibraries.h"
#include <algorithm>
#include <dlfcn.h>
#include <features.h>
#include <sys/types.h>
#if defined(GP_OS_linux) # define PATH_MAX_TOSTRING(x) # x
# include <link.h> // dl_phdr_info # define PATH_MAX_STRING(x) PATH_MAX_TOSTRING(x)
#elif defined(GP_OS_android) # include <stdlib.h>
# include "AutoObjectMapper.h" # include <stdio.h>
# include "ElfLoader.h" // dl_phdr_info # include <string.h>
# include <limits.h>
# include <unistd.h>
# include <fstream>
# include "platform.h"
# include "mozilla/Sprintf.h"
# include "mozilla/Unused.h"
# include "nsDebug.h"
# include "nsNativeCharsetUtils.h"
# include <nsTArray.h>
# include "common/linux/file_id.h"
# include <algorithm>
# include <dlfcn.h>
# include <features.h>
# include <sys/types.h>
# if defined(GP_OS_linux)
# include <link.h> // dl_phdr_info
# elif defined(GP_OS_android)
# include "AutoObjectMapper.h"
# include "ElfLoader.h" // dl_phdr_info
extern "C" MOZ_EXPORT __attribute__((weak)) int dl_iterate_phdr( extern "C" MOZ_EXPORT __attribute__((weak)) int dl_iterate_phdr(
int (*callback)(struct dl_phdr_info* info, size_t size, void* data), int (*callback)(struct dl_phdr_info* info, size_t size, void* data),
void* data); void* data);
#else # else
# error "Unexpected configuration" # error "Unexpected configuration"
#endif # endif
struct LoadedLibraryInfo { struct LoadedLibraryInfo {
LoadedLibraryInfo(const char* aName, unsigned long aBaseAddress, LoadedLibraryInfo(const char* aName, unsigned long aBaseAddress,
@ -54,9 +58,9 @@ struct LoadedLibraryInfo {
unsigned long mLastMappingEnd; unsigned long mLastMappingEnd;
}; };
#if defined(GP_OS_android) # if defined(GP_OS_android)
static void outputMapperLog(const char* aBuf) { LOG("%s", aBuf); } static void outputMapperLog(const char* aBuf) { LOG("%s", aBuf); }
#endif # endif
static nsCString IDtoUUIDString( static nsCString IDtoUUIDString(
const google_breakpad::wasteful_vector<uint8_t>& aIdentifier) { const google_breakpad::wasteful_vector<uint8_t>& aIdentifier) {
@ -77,7 +81,7 @@ static nsCString getId(const char* bin_name) {
PageAllocator allocator; PageAllocator allocator;
auto_wasteful_vector<uint8_t, kDefaultBuildIdSize> identifier(&allocator); auto_wasteful_vector<uint8_t, kDefaultBuildIdSize> identifier(&allocator);
#if defined(GP_OS_android) # if defined(GP_OS_android)
if (nsDependentCString(bin_name).Find("!/") != kNotFound) { if (nsDependentCString(bin_name).Find("!/") != kNotFound) {
AutoObjectMapperFaultyLib mapper(outputMapperLog); AutoObjectMapperFaultyLib mapper(outputMapperLog);
void* image = nullptr; void* image = nullptr;
@ -88,7 +92,7 @@ static nsCString getId(const char* bin_name) {
} }
} }
} }
#endif # endif
FileID file_id(bin_name); FileID file_id(bin_name);
if (file_id.ElfFileIdentifier(identifier)) { if (file_id.ElfFileIdentifier(identifier)) {
@ -149,7 +153,7 @@ static int dl_iterate_callback(struct dl_phdr_info* dl_info, size_t size,
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() { SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
SharedLibraryInfo info; SharedLibraryInfo info;
#if defined(GP_OS_linux) # if defined(GP_OS_linux)
// We need to find the name of the executable (exeName, exeNameLen) and the // We need to find the name of the executable (exeName, exeNameLen) and the
// address of its executable section (exeExeAddr) in the running image. // address of its executable section (exeExeAddr) in the running image.
char exeName[PATH_MAX]; char exeName[PATH_MAX];
@ -168,9 +172,9 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
} }
unsigned long exeExeAddr = 0; unsigned long exeExeAddr = 0;
#endif # endif
#if defined(GP_OS_android) # if defined(GP_OS_android)
// If dl_iterate_phdr doesn't exist, we give up immediately. // If dl_iterate_phdr doesn't exist, we give up immediately.
if (!dl_iterate_phdr) { if (!dl_iterate_phdr) {
// On ARM Android, dl_iterate_phdr is provided by the custom linker. // On ARM Android, dl_iterate_phdr is provided by the custom linker.
@ -179,7 +183,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
// not call it. // not call it.
return info; return info;
} }
#endif # endif
// Read info from /proc/self/maps. We ignore most of it. // Read info from /proc/self/maps. We ignore most of it.
pid_t pid = profiler_current_process_id(); pid_t pid = profiler_current_process_id();
@ -207,12 +211,12 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
continue; continue;
} }
#if defined(GP_OS_linux) # if defined(GP_OS_linux)
// Try to establish the main executable's load address. // Try to establish the main executable's load address.
if (exeNameLen > 0 && strcmp(modulePath, exeName) == 0) { if (exeNameLen > 0 && strcmp(modulePath, exeName) == 0) {
exeExeAddr = start; exeExeAddr = start;
} }
#elif defined(GP_OS_android) # elif defined(GP_OS_android)
// Use /proc/pid/maps to get the dalvik-jit section since it has no // Use /proc/pid/maps to get the dalvik-jit section since it has no
// associated phdrs. // associated phdrs.
if (0 == strcmp(modulePath, "/dev/ashmem/dalvik-jit-code-cache")) { if (0 == strcmp(modulePath, "/dev/ashmem/dalvik-jit-code-cache")) {
@ -224,7 +228,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
break; break;
} }
} }
#endif # endif
} }
nsTArray<LoadedLibraryInfo> libInfoList; nsTArray<LoadedLibraryInfo> libInfoList;
@ -239,7 +243,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
libInfo.mFirstMappingStart - libInfo.mBaseAddress)); libInfo.mFirstMappingStart - libInfo.mBaseAddress));
} }
#if defined(GP_OS_linux) # if defined(GP_OS_linux)
// Make another pass over the information we just harvested from // Make another pass over the information we just harvested from
// dl_iterate_phdr. If we see a nameless object mapped at what we earlier // dl_iterate_phdr. If we see a nameless object mapped at what we earlier
// established to be the main executable's load address, attach the // established to be the main executable's load address, attach the
@ -254,10 +258,12 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
break; break;
} }
} }
#endif # endif
return info; return info;
} }
void SharedLibraryInfo::Initialize() { /* do nothing */ void SharedLibraryInfo::Initialize() { /* do nothing */
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -3,42 +3,46 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BaseProfilerSharedLibraries.h" #include "BaseProfiler.h"
#include "ClearOnShutdown.h" #ifdef MOZ_BASE_PROFILER
#include "mozilla/StaticMutex.h"
#include "mozilla/Unused.h"
#include "nsNativeCharsetUtils.h"
#include <AvailabilityMacros.h>
#include <dlfcn.h> # include "BaseProfilerSharedLibraries.h"
#include <mach-o/arch.h>
#include <mach-o/dyld_images.h> # include "ClearOnShutdown.h"
#include <mach-o/dyld.h> # include "mozilla/StaticMutex.h"
#include <mach-o/loader.h> # include "mozilla/Unused.h"
#include <mach/mach_init.h> # include "nsNativeCharsetUtils.h"
#include <mach/mach_traps.h> # include <AvailabilityMacros.h>
#include <mach/task_info.h>
#include <mach/task.h> # include <dlfcn.h>
#include <sstream> # include <mach-o/arch.h>
#include <stdlib.h> # include <mach-o/dyld_images.h>
#include <string.h> # include <mach-o/dyld.h>
#include <vector> # include <mach-o/loader.h>
# include <mach/mach_init.h>
# include <mach/mach_traps.h>
# include <mach/task_info.h>
# include <mach/task.h>
# include <sstream>
# include <stdlib.h>
# include <string.h>
# include <vector>
// Architecture specific abstraction. // Architecture specific abstraction.
#if defined(GP_ARCH_x86) # if defined(GP_ARCH_x86)
typedef mach_header platform_mach_header; typedef mach_header platform_mach_header;
typedef segment_command mach_segment_command_type; typedef segment_command mach_segment_command_type;
# define MACHO_MAGIC_NUMBER MH_MAGIC # define MACHO_MAGIC_NUMBER MH_MAGIC
# define CMD_SEGMENT LC_SEGMENT # define CMD_SEGMENT LC_SEGMENT
# define seg_size uint32_t # define seg_size uint32_t
#else # else
typedef mach_header_64 platform_mach_header; typedef mach_header_64 platform_mach_header;
typedef segment_command_64 mach_segment_command_type; typedef segment_command_64 mach_segment_command_type;
# define MACHO_MAGIC_NUMBER MH_MAGIC_64 # define MACHO_MAGIC_NUMBER MH_MAGIC_64
# define CMD_SEGMENT LC_SEGMENT_64 # define CMD_SEGMENT LC_SEGMENT_64
# define seg_size uint64_t # define seg_size uint64_t
#endif # endif
struct NativeSharedLibrary { struct NativeSharedLibrary {
const platform_mach_header* header; const platform_mach_header* header;
@ -183,3 +187,5 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
return sharedLibraryInfo; return sharedLibraryInfo;
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -3,20 +3,24 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <windows.h> #include "BaseProfiler.h"
#include <dbghelp.h>
#include <sstream>
#include <psapi.h>
#include "BaseProfilerSharedLibraries.h" #ifdef MOZ_BASE_PROFILER
#include "nsWindowsHelpers.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Unused.h"
#include "nsNativeCharsetUtils.h"
#include "nsPrintfCString.h"
#include "nsReadableUtils.h"
#define CV_SIGNATURE 0x53445352 // 'SDSR' # include <windows.h>
# include <dbghelp.h>
# include <sstream>
# include <psapi.h>
# include "BaseProfilerSharedLibraries.h"
# include "nsWindowsHelpers.h"
# include "mozilla/UniquePtr.h"
# include "mozilla/Unused.h"
# include "nsNativeCharsetUtils.h"
# include "nsPrintfCString.h"
# include "nsReadableUtils.h"
# define CV_SIGNATURE 0x53445352 // 'SDSR'
struct CodeViewRecord70 { struct CodeViewRecord70 {
uint32_t signature; uint32_t signature;
@ -207,3 +211,5 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
void SharedLibraryInfo::Initialize() { /* do nothing */ void SharedLibraryInfo::Initialize() { /* do nothing */
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,21 +4,25 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <sys/mman.h> #include "BaseProfiler.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "mozilla/Assertions.h" #ifdef MOZ_BASE_PROFILER
#include "mozilla/Sprintf.h"
#include "PlatformMacros.h" # include <sys/mman.h>
#include "AutoObjectMapper.h" # include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
#if defined(GP_OS_android) # include "mozilla/Assertions.h"
# include <dlfcn.h> # include "mozilla/Sprintf.h"
# include "mozilla/Types.h"
# include "PlatformMacros.h"
# include "AutoObjectMapper.h"
# if defined(GP_OS_android)
# include <dlfcn.h>
# include "mozilla/Types.h"
// FIXME move these out of mozglue/linker/ElfLoader.h into their // FIXME move these out of mozglue/linker/ElfLoader.h into their
// own header, so as to avoid conflicts arising from two definitions // own header, so as to avoid conflicts arising from two definitions
// of Array // of Array
@ -28,10 +32,10 @@ MFBT_API void* __dl_mmap(void* handle, void* addr, size_t length, off_t offset);
MFBT_API void __dl_munmap(void* handle, void* addr, size_t length); MFBT_API void __dl_munmap(void* handle, void* addr, size_t length);
} }
// The following are for get_installation_lib_dir() // The following are for get_installation_lib_dir()
# include "nsString.h" # include "nsString.h"
# include "nsDirectoryServiceUtils.h" # include "nsDirectoryServiceUtils.h"
# include "nsDirectoryServiceDefs.h" # include "nsDirectoryServiceDefs.h"
#endif # endif
// A helper function for creating failure error messages in // A helper function for creating failure error messages in
// AutoObjectMapper*::Map. // AutoObjectMapper*::Map.
@ -95,7 +99,7 @@ bool AutoObjectMapperPOSIX::Map(/*OUT*/ void** start, /*OUT*/ size_t* length,
return true; return true;
} }
#if defined(GP_OS_android) # if defined(GP_OS_android)
// A helper function for AutoObjectMapperFaultyLib::Map. Finds out // A helper function for AutoObjectMapperFaultyLib::Map. Finds out
// where the installation's lib directory is, since we'll have to look // where the installation's lib directory is, since we'll have to look
// in there to get hold of libmozglue.so. Returned C string is heap // in there to get hold of libmozglue.so. Returned C string is heap
@ -185,4 +189,6 @@ bool AutoObjectMapperFaultyLib::Map(/*OUT*/ void** start,
} }
} }
#endif // defined(GP_OS_android) # endif // defined(GP_OS_android)
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -37,15 +37,19 @@
// src/common/module.cc // src/common/module.cc
// src/common/unique_string.cc // src/common/unique_string.cc
#include "BaseProfiler.h"
#ifdef MOZ_BASE_PROFILER
// There's no internal-only interface for LulCommon. Hence include // There's no internal-only interface for LulCommon. Hence include
// the external interface directly. // the external interface directly.
#include "LulCommonExt.h" # include "LulCommonExt.h"
#include <stdlib.h> # include <stdlib.h>
#include <string.h> # include <string.h>
#include <string> # include <string>
#include <map> # include <map>
namespace lul { namespace lul {
@ -98,3 +102,5 @@ const UniqueString* UniqueStringUniverse::ToUniqueString(string str) {
} }
} // namespace lul } // namespace lul
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -41,23 +41,27 @@
// src/common/dwarf/dwarf2reader.cc // src/common/dwarf/dwarf2reader.cc
// src/common/dwarf_cfi_to_module.cc // src/common/dwarf_cfi_to_module.cc
#include <stdint.h> #include "BaseProfiler.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <map> #ifdef MOZ_BASE_PROFILER
#include <stack>
#include <string>
#include "mozilla/Assertions.h" # include <stdint.h>
#include "mozilla/Sprintf.h" # include <stdio.h>
# include <string.h>
# include <stdlib.h>
#include "LulCommonExt.h" # include <map>
#include "LulDwarfInt.h" # include <stack>
# include <string>
# include "mozilla/Assertions.h"
# include "mozilla/Sprintf.h"
# include "LulCommonExt.h"
# include "LulDwarfInt.h"
// Set this to 1 for verbose logging // Set this to 1 for verbose logging
#define DEBUG_DWARF 0 # define DEBUG_DWARF 0
namespace lul { namespace lul {
@ -2250,3 +2254,5 @@ void DwarfCFIToModule::Reporter::ExpressionCouldNotBeSummarised(
} }
} // namespace lul } // namespace lul
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,15 +4,19 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LulDwarfSummariser.h" #include "BaseProfiler.h"
#include "LulDwarfExt.h" #ifdef MOZ_BASE_PROFILER
#include "mozilla/Assertions.h" # include "LulDwarfSummariser.h"
#include "mozilla/Sprintf.h"
# include "LulDwarfExt.h"
# include "mozilla/Assertions.h"
# include "mozilla/Sprintf.h"
// Set this to 1 for verbose logging // Set this to 1 for verbose logging
#define DEBUG_SUMMARISER 0 # define DEBUG_SUMMARISER 0
namespace lul { namespace lul {
@ -124,7 +128,7 @@ void Summariser::Rule(uintptr_t aAddress, int aNewReg, LExprHow how,
// FIXME: factor out common parts of the arch-dependent summarisers. // FIXME: factor out common parts of the arch-dependent summarisers.
#if defined(GP_ARCH_arm) # if defined(GP_ARCH_arm)
// ----------------- arm ----------------- // // ----------------- arm ----------------- //
@ -246,7 +250,7 @@ void Summariser::Rule(uintptr_t aAddress, int aNewReg, LExprHow how,
mCurrRules.mR15expr = LExpr(NODEREF, DW_REG_ARM_R14, 0); mCurrRules.mR15expr = LExpr(NODEREF, DW_REG_ARM_R14, 0);
} }
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
// ----------------- arm64 ----------------- // // ----------------- arm64 ----------------- //
@ -327,7 +331,7 @@ void Summariser::Rule(uintptr_t aAddress, int aNewReg, LExprHow how,
if (mCurrRules.mSPexpr.mHow == UNKNOWN) { if (mCurrRules.mSPexpr.mHow == UNKNOWN) {
mCurrRules.mSPexpr = LExpr(NODEREF, DW_REG_CFA, 0); mCurrRules.mSPexpr = LExpr(NODEREF, DW_REG_CFA, 0);
} }
#elif defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) # elif defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
// ---------------- x64/x86 ---------------- // // ---------------- x64/x86 ---------------- //
@ -427,7 +431,7 @@ void Summariser::Rule(uintptr_t aAddress, int aNewReg, LExprHow how,
mCurrRules.mXbpExpr = LExpr(NODEREF, DW_REG_INTEL_XBP, 0); mCurrRules.mXbpExpr = LExpr(NODEREF, DW_REG_INTEL_XBP, 0);
} }
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
// ---------------- mips ---------------- // // ---------------- mips ---------------- //
// //
// Now, can we add the rule to our summary? This depends on whether // Now, can we add the rule to our summary? This depends on whether
@ -509,10 +513,10 @@ void Summariser::Rule(uintptr_t aAddress, int aNewReg, LExprHow how,
mCurrRules.mFPexpr = LExpr(NODEREF, DW_REG_MIPS_FP, 0); mCurrRules.mFPexpr = LExpr(NODEREF, DW_REG_MIPS_FP, 0);
} }
#else # else
# error "Unsupported arch" # error "Unsupported arch"
#endif # endif
return; return;
@ -551,3 +555,5 @@ void Summariser::End() {
} }
} // namespace lul } // namespace lul
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -45,37 +45,41 @@
// src/common/linux/elfutils.cc // src/common/linux/elfutils.cc
// src/common/linux/file_id.cc // src/common/linux/file_id.cc
#include <errno.h> #include "BaseProfiler.h"
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <set> #ifdef MOZ_BASE_PROFILER
#include <string>
#include <vector>
#include "mozilla/Assertions.h" # include <errno.h>
#include "mozilla/Sprintf.h" # include <fcntl.h>
# include <stdio.h>
# include <string.h>
# include <sys/mman.h>
# include <sys/stat.h>
# include <unistd.h>
# include <arpa/inet.h>
#include "PlatformMacros.h" # include <set>
#include "LulCommonExt.h" # include <string>
#include "LulDwarfExt.h" # include <vector>
#include "LulElfInt.h"
#include "LulMainInt.h"
#if defined(GP_PLAT_arm_android) && !defined(SHT_ARM_EXIDX) # include "mozilla/Assertions.h"
# include "mozilla/Sprintf.h"
# include "PlatformMacros.h"
# include "LulCommonExt.h"
# include "LulDwarfExt.h"
# include "LulElfInt.h"
# include "LulMainInt.h"
# if defined(GP_PLAT_arm_android) && !defined(SHT_ARM_EXIDX)
// bionic and older glibsc don't define it // bionic and older glibsc don't define it
# define SHT_ARM_EXIDX (SHT_LOPROC + 1) # define SHT_ARM_EXIDX (SHT_LOPROC + 1)
#endif # endif
// Old Linux header doesn't define EM_AARCH64 // Old Linux header doesn't define EM_AARCH64
#ifndef EM_AARCH64 # ifndef EM_AARCH64
# define EM_AARCH64 183 # define EM_AARCH64 183
#endif # endif
// This namespace contains helper functions. // This namespace contains helper functions.
namespace { namespace {
@ -744,7 +748,7 @@ bool FindElfSegment(const void* elf_mapped_base, uint32_t segment_type,
// //
// ELF note name and desc are 32-bits word padded. // ELF note name and desc are 32-bits word padded.
#define NOTE_PADDING(a) ((a + 3) & ~3) # define NOTE_PADDING(a) ((a + 3) & ~3)
// These functions are also used inside the crashed process, so be safe // These functions are also used inside the crashed process, so be safe
// and use the syscall/libc wrappers instead of direct syscalls or libc. // and use the syscall/libc wrappers instead of direct syscalls or libc.
@ -869,3 +873,5 @@ void FileID::ConvertIdentifierToString(const uint8_t identifier[kMDGUIDSize],
} }
} // namespace lul } // namespace lul
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -4,35 +4,37 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LulMain.h" #include "BaseProfiler.h"
#include <string.h> #ifdef MOZ_BASE_PROFILER
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h> // write(), only for testing LUL
#include <algorithm> // std::sort # include "LulMain.h"
#include <string>
#include "mozilla/Assertions.h" # include <string.h>
#include "mozilla/ArrayUtils.h" # include <stdlib.h>
#include "mozilla/CheckedInt.h" # include <stdio.h>
#include "mozilla/DebugOnly.h" # include <unistd.h> // write(), only for testing LUL
#include "mozilla/MemoryChecking.h"
#include "mozilla/Move.h"
#include "mozilla/Sprintf.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Unused.h"
#include "LulCommonExt.h" # include <algorithm> // std::sort
#include "LulElfExt.h" # include <string>
#include "LulMainInt.h" # include "mozilla/Assertions.h"
# include "mozilla/ArrayUtils.h"
# include "mozilla/CheckedInt.h"
# include "mozilla/DebugOnly.h"
# include "mozilla/MemoryChecking.h"
# include "mozilla/Move.h"
# include "mozilla/Sprintf.h"
# include "mozilla/UniquePtr.h"
# include "mozilla/Unused.h"
#include "BaseProfiler.h" // for profiler_current_thread_id() # include "LulCommonExt.h"
# include "LulElfExt.h"
# include "LulMainInt.h"
// Set this to 1 for verbose logging // Set this to 1 for verbose logging
#define DEBUG_MAIN 0 # define DEBUG_MAIN 0
namespace lul { namespace lul {
@ -62,14 +64,14 @@ static const char* NameOf_DW_REG(int16_t aReg) {
switch (aReg) { switch (aReg) {
case DW_REG_CFA: case DW_REG_CFA:
return "cfa"; return "cfa";
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) # if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
case DW_REG_INTEL_XBP: case DW_REG_INTEL_XBP:
return "xbp"; return "xbp";
case DW_REG_INTEL_XSP: case DW_REG_INTEL_XSP:
return "xsp"; return "xsp";
case DW_REG_INTEL_XIP: case DW_REG_INTEL_XIP:
return "xip"; return "xip";
#elif defined(GP_ARCH_arm) # elif defined(GP_ARCH_arm)
case DW_REG_ARM_R7: case DW_REG_ARM_R7:
return "r7"; return "r7";
case DW_REG_ARM_R11: case DW_REG_ARM_R11:
@ -82,23 +84,23 @@ static const char* NameOf_DW_REG(int16_t aReg) {
return "r14"; return "r14";
case DW_REG_ARM_R15: case DW_REG_ARM_R15:
return "r15"; return "r15";
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
case DW_REG_AARCH64_X29: case DW_REG_AARCH64_X29:
return "x29"; return "x29";
case DW_REG_AARCH64_X30: case DW_REG_AARCH64_X30:
return "x30"; return "x30";
case DW_REG_AARCH64_SP: case DW_REG_AARCH64_SP:
return "sp"; return "sp";
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
case DW_REG_MIPS_SP: case DW_REG_MIPS_SP:
return "sp"; return "sp";
case DW_REG_MIPS_FP: case DW_REG_MIPS_FP:
return "fp"; return "fp";
case DW_REG_MIPS_PC: case DW_REG_MIPS_PC:
return "pc"; return "pc";
#else # else
# error "Unsupported arch" # error "Unsupported arch"
#endif # endif
default: default:
return "???"; return "???";
} }
@ -138,28 +140,28 @@ void RuleSet::Print(void (*aLog)(const char*)) const {
res += mCfaExpr.ShowRule("cfa"); res += mCfaExpr.ShowRule("cfa");
res += " in"; res += " in";
// For each reg we care about, print the recovery expression. // For each reg we care about, print the recovery expression.
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) # if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
res += mXipExpr.ShowRule(" RA"); res += mXipExpr.ShowRule(" RA");
res += mXspExpr.ShowRule(" SP"); res += mXspExpr.ShowRule(" SP");
res += mXbpExpr.ShowRule(" BP"); res += mXbpExpr.ShowRule(" BP");
#elif defined(GP_ARCH_arm) # elif defined(GP_ARCH_arm)
res += mR15expr.ShowRule(" R15"); res += mR15expr.ShowRule(" R15");
res += mR7expr.ShowRule(" R7"); res += mR7expr.ShowRule(" R7");
res += mR11expr.ShowRule(" R11"); res += mR11expr.ShowRule(" R11");
res += mR12expr.ShowRule(" R12"); res += mR12expr.ShowRule(" R12");
res += mR13expr.ShowRule(" R13"); res += mR13expr.ShowRule(" R13");
res += mR14expr.ShowRule(" R14"); res += mR14expr.ShowRule(" R14");
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
res += mX29expr.ShowRule(" X29"); res += mX29expr.ShowRule(" X29");
res += mX30expr.ShowRule(" X30"); res += mX30expr.ShowRule(" X30");
res += mSPexpr.ShowRule(" SP"); res += mSPexpr.ShowRule(" SP");
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
res += mPCexpr.ShowRule(" PC"); res += mPCexpr.ShowRule(" PC");
res += mSPexpr.ShowRule(" SP"); res += mSPexpr.ShowRule(" SP");
res += mFPexpr.ShowRule(" FP"); res += mFPexpr.ShowRule(" FP");
#else # else
# error "Unsupported arch" # error "Unsupported arch"
#endif # endif
aLog(res.c_str()); aLog(res.c_str());
} }
@ -167,14 +169,14 @@ LExpr* RuleSet::ExprForRegno(DW_REG_NUMBER aRegno) {
switch (aRegno) { switch (aRegno) {
case DW_REG_CFA: case DW_REG_CFA:
return &mCfaExpr; return &mCfaExpr;
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) # if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
case DW_REG_INTEL_XIP: case DW_REG_INTEL_XIP:
return &mXipExpr; return &mXipExpr;
case DW_REG_INTEL_XSP: case DW_REG_INTEL_XSP:
return &mXspExpr; return &mXspExpr;
case DW_REG_INTEL_XBP: case DW_REG_INTEL_XBP:
return &mXbpExpr; return &mXbpExpr;
#elif defined(GP_ARCH_arm) # elif defined(GP_ARCH_arm)
case DW_REG_ARM_R15: case DW_REG_ARM_R15:
return &mR15expr; return &mR15expr;
case DW_REG_ARM_R14: case DW_REG_ARM_R14:
@ -187,23 +189,23 @@ LExpr* RuleSet::ExprForRegno(DW_REG_NUMBER aRegno) {
return &mR11expr; return &mR11expr;
case DW_REG_ARM_R7: case DW_REG_ARM_R7:
return &mR7expr; return &mR7expr;
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
case DW_REG_AARCH64_X29: case DW_REG_AARCH64_X29:
return &mX29expr; return &mX29expr;
case DW_REG_AARCH64_X30: case DW_REG_AARCH64_X30:
return &mX30expr; return &mX30expr;
case DW_REG_AARCH64_SP: case DW_REG_AARCH64_SP:
return &mSPexpr; return &mSPexpr;
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
case DW_REG_MIPS_SP: case DW_REG_MIPS_SP:
return &mSPexpr; return &mSPexpr;
case DW_REG_MIPS_FP: case DW_REG_MIPS_FP:
return &mFPexpr; return &mFPexpr;
case DW_REG_MIPS_PC: case DW_REG_MIPS_PC:
return &mPCexpr; return &mPCexpr;
#else # else
# error "Unknown arch" # error "Unknown arch"
#endif # endif
default: default:
return nullptr; return nullptr;
} }
@ -364,7 +366,7 @@ void SecMap::PrepareRuleSets(uintptr_t aStart, size_t aLen) {
size_t n = mRuleSets.size(); size_t n = mRuleSets.size();
#ifdef DEBUG # ifdef DEBUG
// Do a final check on the rules: their address ranges must be // Do a final check on the rules: their address ranges must be
// ascending, non overlapping, non zero sized. // ascending, non overlapping, non zero sized.
if (n > 0) { if (n > 0) {
@ -377,7 +379,7 @@ void SecMap::PrepareRuleSets(uintptr_t aStart, size_t aLen) {
MOZ_ASSERT(prev->mAddr + prev->mLen <= here->mAddr); MOZ_ASSERT(prev->mAddr + prev->mLen <= here->mAddr);
} }
} }
#endif # endif
// Set the summary min and max address values. // Set the summary min and max address values.
if (n == 0) { if (n == 0) {
@ -398,14 +400,14 @@ void SecMap::PrepareRuleSets(uintptr_t aStart, size_t aLen) {
// Is now usable for binary search. // Is now usable for binary search.
mUsable = true; mUsable = true;
#if 0 # if 0
mLog("\nRulesets after preening\n"); mLog("\nRulesets after preening\n");
for (size_t i = 0; i < mRuleSets.size(); ++i) { for (size_t i = 0; i < mRuleSets.size(); ++i) {
mRuleSets[i].Print(mLog); mRuleSets[i].Print(mLog);
mLog("\n"); mLog("\n");
} }
mLog("\n"); mLog("\n");
#endif # endif
} }
bool SecMap::IsEmpty() { return mRuleSets.empty(); } bool SecMap::IsEmpty() { return mRuleSets.empty(); }
@ -684,15 +686,15 @@ class PriMap {
// LUL // // LUL //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
#define LUL_LOG(_str) \ # define LUL_LOG(_str) \
do { \ do { \
char buf[200]; \ char buf[200]; \
SprintfLiteral(buf, "LUL: pid %d tid %d lul-obj %p: %s", \ SprintfLiteral(buf, "LUL: pid %d tid %d lul-obj %p: %s", \
profiler_current_process_id(), \ profiler_current_process_id(), \
profiler_current_thread_id(), this, (_str)); \ profiler_current_thread_id(), this, (_str)); \
buf[sizeof(buf) - 1] = 0; \ buf[sizeof(buf) - 1] = 0; \
mLog(buf); \ mLog(buf); \
} while (0) } while (0)
LUL::LUL(void (*aLog)(const char*)) LUL::LUL(void (*aLog)(const char*))
: mLog(aLog), : mLog(aLog),
@ -896,14 +898,14 @@ static TaggedUWord EvaluateReg(int16_t aReg, const UnwindRegs* aOldRegs,
switch (aReg) { switch (aReg) {
case DW_REG_CFA: case DW_REG_CFA:
return aCFA; return aCFA;
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) # if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
case DW_REG_INTEL_XBP: case DW_REG_INTEL_XBP:
return aOldRegs->xbp; return aOldRegs->xbp;
case DW_REG_INTEL_XSP: case DW_REG_INTEL_XSP:
return aOldRegs->xsp; return aOldRegs->xsp;
case DW_REG_INTEL_XIP: case DW_REG_INTEL_XIP:
return aOldRegs->xip; return aOldRegs->xip;
#elif defined(GP_ARCH_arm) # elif defined(GP_ARCH_arm)
case DW_REG_ARM_R7: case DW_REG_ARM_R7:
return aOldRegs->r7; return aOldRegs->r7;
case DW_REG_ARM_R11: case DW_REG_ARM_R11:
@ -916,23 +918,23 @@ static TaggedUWord EvaluateReg(int16_t aReg, const UnwindRegs* aOldRegs,
return aOldRegs->r14; return aOldRegs->r14;
case DW_REG_ARM_R15: case DW_REG_ARM_R15:
return aOldRegs->r15; return aOldRegs->r15;
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
case DW_REG_AARCH64_X29: case DW_REG_AARCH64_X29:
return aOldRegs->x29; return aOldRegs->x29;
case DW_REG_AARCH64_X30: case DW_REG_AARCH64_X30:
return aOldRegs->x30; return aOldRegs->x30;
case DW_REG_AARCH64_SP: case DW_REG_AARCH64_SP:
return aOldRegs->sp; return aOldRegs->sp;
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
case DW_REG_MIPS_SP: case DW_REG_MIPS_SP:
return aOldRegs->sp; return aOldRegs->sp;
case DW_REG_MIPS_FP: case DW_REG_MIPS_FP:
return aOldRegs->fp; return aOldRegs->fp;
case DW_REG_MIPS_PC: case DW_REG_MIPS_PC:
return aOldRegs->pc; return aOldRegs->pc;
#else # else
# error "Unsupported arch" # error "Unsupported arch"
#endif # endif
default: default:
MOZ_ASSERT(0); MOZ_ASSERT(0);
return TaggedUWord(); return TaggedUWord();
@ -951,17 +953,17 @@ TaggedUWord EvaluatePfxExpr(int32_t start, const UnwindRegs* aOldRegs,
int stackPointer = -1; int stackPointer = -1;
for (int i = 0; i < N_STACK; i++) stack[i] = TaggedUWord(); for (int i = 0; i < N_STACK; i++) stack[i] = TaggedUWord();
#define PUSH(_tuw) \ # define PUSH(_tuw) \
do { \ do { \
if (stackPointer >= N_STACK - 1) goto fail; /* overflow */ \ if (stackPointer >= N_STACK - 1) goto fail; /* overflow */ \
stack[++stackPointer] = (_tuw); \ stack[++stackPointer] = (_tuw); \
} while (0) } while (0)
#define POP(_lval) \ # define POP(_lval) \
do { \ do { \
if (stackPointer < 0) goto fail; /* underflow */ \ if (stackPointer < 0) goto fail; /* underflow */ \
_lval = stack[stackPointer--]; \ _lval = stack[stackPointer--]; \
} while (0) } while (0)
// Cursor in the instruction sequence. // Cursor in the instruction sequence.
size_t curr = start + 1; size_t curr = start + 1;
@ -1067,8 +1069,8 @@ TaggedUWord EvaluatePfxExpr(int32_t start, const UnwindRegs* aOldRegs,
fail: fail:
return TaggedUWord(); return TaggedUWord();
#undef PUSH # undef PUSH
#undef POP # undef POP
} }
// RUNS IN NO-MALLOC CONTEXT // RUNS IN NO-MALLOC CONTEXT
@ -1113,29 +1115,29 @@ static void UseRuleSet(/*MOD*/ UnwindRegs* aRegs, const StackImage* aStackImg,
// anew. If we don't even manage to compute a new PC value, then // anew. If we don't even manage to compute a new PC value, then
// the caller will have to abandon the unwind. // the caller will have to abandon the unwind.
// FIXME: Create and use instead: aRegs->SetAllInvalid(); // FIXME: Create and use instead: aRegs->SetAllInvalid();
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) # if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
aRegs->xbp = TaggedUWord(); aRegs->xbp = TaggedUWord();
aRegs->xsp = TaggedUWord(); aRegs->xsp = TaggedUWord();
aRegs->xip = TaggedUWord(); aRegs->xip = TaggedUWord();
#elif defined(GP_ARCH_arm) # elif defined(GP_ARCH_arm)
aRegs->r7 = TaggedUWord(); aRegs->r7 = TaggedUWord();
aRegs->r11 = TaggedUWord(); aRegs->r11 = TaggedUWord();
aRegs->r12 = TaggedUWord(); aRegs->r12 = TaggedUWord();
aRegs->r13 = TaggedUWord(); aRegs->r13 = TaggedUWord();
aRegs->r14 = TaggedUWord(); aRegs->r14 = TaggedUWord();
aRegs->r15 = TaggedUWord(); aRegs->r15 = TaggedUWord();
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
aRegs->x29 = TaggedUWord(); aRegs->x29 = TaggedUWord();
aRegs->x30 = TaggedUWord(); aRegs->x30 = TaggedUWord();
aRegs->sp = TaggedUWord(); aRegs->sp = TaggedUWord();
aRegs->pc = TaggedUWord(); aRegs->pc = TaggedUWord();
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
aRegs->sp = TaggedUWord(); aRegs->sp = TaggedUWord();
aRegs->fp = TaggedUWord(); aRegs->fp = TaggedUWord();
aRegs->pc = TaggedUWord(); aRegs->pc = TaggedUWord();
#else # else
# error "Unsupported arch" # error "Unsupported arch"
#endif # endif
// This is generally useful. // This is generally useful.
const TaggedUWord inval = TaggedUWord(); const TaggedUWord inval = TaggedUWord();
@ -1149,14 +1151,14 @@ static void UseRuleSet(/*MOD*/ UnwindRegs* aRegs, const StackImage* aStackImg,
// value rules mention the CFA. In any case, compute the new values // value rules mention the CFA. In any case, compute the new values
// for each register that we're tracking. // for each register that we're tracking.
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) # if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
aRegs->xbp = aRegs->xbp =
aRS->mXbpExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRS->mXbpExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->xsp = aRegs->xsp =
aRS->mXspExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRS->mXspExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->xip = aRegs->xip =
aRS->mXipExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRS->mXipExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
#elif defined(GP_ARCH_arm) # elif defined(GP_ARCH_arm)
aRegs->r7 = aRS->mR7expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRegs->r7 = aRS->mR7expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->r11 = aRegs->r11 =
aRS->mR11expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRS->mR11expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
@ -1168,19 +1170,19 @@ static void UseRuleSet(/*MOD*/ UnwindRegs* aRegs, const StackImage* aStackImg,
aRS->mR14expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRS->mR14expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->r15 = aRegs->r15 =
aRS->mR15expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRS->mR15expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
aRegs->x29 = aRegs->x29 =
aRS->mX29expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRS->mX29expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->x30 = aRegs->x30 =
aRS->mX30expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRS->mX30expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->sp = aRS->mSPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRegs->sp = aRS->mSPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
aRegs->sp = aRS->mSPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRegs->sp = aRS->mSPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->fp = aRS->mFPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRegs->fp = aRS->mFPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->pc = aRS->mPCexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs); aRegs->pc = aRS->mPCexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
#else # else
# error "Unsupported arch" # error "Unsupported arch"
#endif # endif
// We're done. Any regs for which we didn't manage to compute a // We're done. Any regs for which we didn't manage to compute a
// new value will now be marked as invalid. // new value will now be marked as invalid.
@ -1207,7 +1209,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
if (DEBUG_MAIN) { if (DEBUG_MAIN) {
char buf[300]; char buf[300];
mLog("\n"); mLog("\n");
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) # if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
SprintfLiteral( SprintfLiteral(
buf, "LoopTop: rip %d/%llx rsp %d/%llx rbp %d/%llx\n", buf, "LoopTop: rip %d/%llx rsp %d/%llx rbp %d/%llx\n",
(int)regs.xip.Valid(), (unsigned long long int)regs.xip.Value(), (int)regs.xip.Valid(), (unsigned long long int)regs.xip.Value(),
@ -1215,7 +1217,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
(int)regs.xbp.Valid(), (unsigned long long int)regs.xbp.Value()); (int)regs.xbp.Valid(), (unsigned long long int)regs.xbp.Value());
buf[sizeof(buf) - 1] = 0; buf[sizeof(buf) - 1] = 0;
mLog(buf); mLog(buf);
#elif defined(GP_ARCH_arm) # elif defined(GP_ARCH_arm)
SprintfLiteral( SprintfLiteral(
buf, buf,
"LoopTop: r15 %d/%llx r7 %d/%llx r11 %d/%llx" "LoopTop: r15 %d/%llx r7 %d/%llx r11 %d/%llx"
@ -1228,7 +1230,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
(int)regs.r14.Valid(), (unsigned long long int)regs.r14.Value()); (int)regs.r14.Valid(), (unsigned long long int)regs.r14.Value());
buf[sizeof(buf) - 1] = 0; buf[sizeof(buf) - 1] = 0;
mLog(buf); mLog(buf);
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
SprintfLiteral( SprintfLiteral(
buf, buf,
"LoopTop: pc %d/%llx x29 %d/%llx x30 %d/%llx" "LoopTop: pc %d/%llx x29 %d/%llx x30 %d/%llx"
@ -1239,7 +1241,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
(int)regs.sp.Valid(), (unsigned long long int)regs.sp.Value()); (int)regs.sp.Valid(), (unsigned long long int)regs.sp.Value());
buf[sizeof(buf) - 1] = 0; buf[sizeof(buf) - 1] = 0;
mLog(buf); mLog(buf);
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
SprintfLiteral( SprintfLiteral(
buf, "LoopTop: pc %d/%llx sp %d/%llx fp %d/%llx\n", buf, "LoopTop: pc %d/%llx sp %d/%llx fp %d/%llx\n",
(int)regs.pc.Valid(), (unsigned long long int)regs.pc.Value(), (int)regs.pc.Valid(), (unsigned long long int)regs.pc.Value(),
@ -1247,26 +1249,26 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
(int)regs.fp.Valid(), (unsigned long long int)regs.fp.Value()); (int)regs.fp.Valid(), (unsigned long long int)regs.fp.Value());
buf[sizeof(buf) - 1] = 0; buf[sizeof(buf) - 1] = 0;
mLog(buf); mLog(buf);
#else # else
# error "Unsupported arch" # error "Unsupported arch"
#endif # endif
} }
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) # if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
TaggedUWord ia = regs.xip; TaggedUWord ia = regs.xip;
TaggedUWord sp = regs.xsp; TaggedUWord sp = regs.xsp;
#elif defined(GP_ARCH_arm) # elif defined(GP_ARCH_arm)
TaggedUWord ia = (*aFramesUsed == 0 ? regs.r15 : regs.r14); TaggedUWord ia = (*aFramesUsed == 0 ? regs.r15 : regs.r14);
TaggedUWord sp = regs.r13; TaggedUWord sp = regs.r13;
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
TaggedUWord ia = (*aFramesUsed == 0 ? regs.pc : regs.x30); TaggedUWord ia = (*aFramesUsed == 0 ? regs.pc : regs.x30);
TaggedUWord sp = regs.sp; TaggedUWord sp = regs.sp;
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
TaggedUWord ia = regs.pc; TaggedUWord ia = regs.pc;
TaggedUWord sp = regs.sp; TaggedUWord sp = regs.sp;
#else # else
# error "Unsupported arch" # error "Unsupported arch"
#endif # endif
if (*aFramesUsed >= aFramesAvail) { if (*aFramesUsed >= aFramesAvail) {
break; break;
@ -1325,7 +1327,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
mLog(buf); mLog(buf);
} }
#if defined(GP_PLAT_x86_android) || defined(GP_PLAT_x86_linux) # if defined(GP_PLAT_x86_android) || defined(GP_PLAT_x86_linux)
///////////////////////////////////////////// /////////////////////////////////////////////
//// ////
// On 32 bit x86-linux, syscalls are often done via the VDSO // On 32 bit x86-linux, syscalls are often done via the VDSO
@ -1394,7 +1396,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
} }
//// ////
///////////////////////////////////////////// /////////////////////////////////////////////
#endif // defined(GP_PLAT_x86_android) || defined(GP_PLAT_x86_linux) # endif // defined(GP_PLAT_x86_android) || defined(GP_PLAT_x86_linux)
// So, do we have a ruleset for this address? If so, use it now. // So, do we have a ruleset for this address? If so, use it now.
if (ruleset) { if (ruleset) {
@ -1408,7 +1410,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
continue; continue;
} }
#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) # if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux)
// There's no RuleSet for the specified address. On amd64/x86_linux, see if // There's no RuleSet for the specified address. On amd64/x86_linux, see if
// it's possible to recover the caller's frame by using the frame pointer. // it's possible to recover the caller's frame by using the frame pointer.
@ -1457,7 +1459,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
} }
} }
} }
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
// Here is an example of generated code for prologue and epilogue.. // Here is an example of generated code for prologue and epilogue..
// //
// stp x29, x30, [sp, #-16]! // stp x29, x30, [sp, #-16]!
@ -1518,7 +1520,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
} }
} }
} }
#endif // defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) # endif // defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux)
// We failed to recover a frame either using CFI or FP chasing, and we // We failed to recover a frame either using CFI or FP chasing, and we
// have no other ways to recover the frame. So we have to give up. // have no other ways to recover the frame. So we have to give up.
@ -1536,13 +1538,13 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
static const int LUL_UNIT_TEST_STACK_SIZE = 32768; static const int LUL_UNIT_TEST_STACK_SIZE = 32768;
#if defined(GP_ARCH_mips64) # if defined(GP_ARCH_mips64)
static __attribute__((noinline)) unsigned long __getpc(void) { static __attribute__((noinline)) unsigned long __getpc(void) {
unsigned long rtaddr; unsigned long rtaddr;
__asm__ volatile("move %0, $31" : "=r"(rtaddr)); __asm__ volatile("move %0, $31" : "=r"(rtaddr));
return rtaddr; return rtaddr;
} }
#endif # endif
// This function is innermost in the test call sequence. It uses LUL // This function is innermost in the test call sequence. It uses LUL
// to unwind, and compares the result with the sequence specified in // to unwind, and compares the result with the sequence specified in
@ -1561,7 +1563,7 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
// Get hold of the current unwind-start registers. // Get hold of the current unwind-start registers.
UnwindRegs startRegs; UnwindRegs startRegs;
memset(&startRegs, 0, sizeof(startRegs)); memset(&startRegs, 0, sizeof(startRegs));
#if defined(GP_ARCH_amd64) # if defined(GP_ARCH_amd64)
volatile uintptr_t block[3]; volatile uintptr_t block[3];
MOZ_ASSERT(sizeof(block) == 24); MOZ_ASSERT(sizeof(block) == 24);
__asm__ __volatile__( __asm__ __volatile__(
@ -1581,7 +1583,7 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.xbp = TaggedUWord(block[2]); startRegs.xbp = TaggedUWord(block[2]);
const uintptr_t REDZONE_SIZE = 128; const uintptr_t REDZONE_SIZE = 128;
uintptr_t start = block[1] - REDZONE_SIZE; uintptr_t start = block[1] - REDZONE_SIZE;
#elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android) # elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
volatile uintptr_t block[3]; volatile uintptr_t block[3];
MOZ_ASSERT(sizeof(block) == 12); MOZ_ASSERT(sizeof(block) == 12);
__asm__ __volatile__( __asm__ __volatile__(
@ -1603,7 +1605,7 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.xbp = TaggedUWord(block[2]); startRegs.xbp = TaggedUWord(block[2]);
const uintptr_t REDZONE_SIZE = 0; const uintptr_t REDZONE_SIZE = 0;
uintptr_t start = block[1] - REDZONE_SIZE; uintptr_t start = block[1] - REDZONE_SIZE;
#elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android) # elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
volatile uintptr_t block[6]; volatile uintptr_t block[6];
MOZ_ASSERT(sizeof(block) == 24); MOZ_ASSERT(sizeof(block) == 24);
__asm__ __volatile__( __asm__ __volatile__(
@ -1632,7 +1634,7 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.r7 = TaggedUWord(block[5]); startRegs.r7 = TaggedUWord(block[5]);
const uintptr_t REDZONE_SIZE = 0; const uintptr_t REDZONE_SIZE = 0;
uintptr_t start = block[1] - REDZONE_SIZE; uintptr_t start = block[1] - REDZONE_SIZE;
#elif defined(GP_ARCH_arm64) # elif defined(GP_ARCH_arm64)
volatile uintptr_t block[4]; volatile uintptr_t block[4];
MOZ_ASSERT(sizeof(block) == 32); MOZ_ASSERT(sizeof(block) == 32);
__asm__ __volatile__( __asm__ __volatile__(
@ -1651,7 +1653,7 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.sp = TaggedUWord(block[3]); startRegs.sp = TaggedUWord(block[3]);
const uintptr_t REDZONE_SIZE = 0; const uintptr_t REDZONE_SIZE = 0;
uintptr_t start = block[1] - REDZONE_SIZE; uintptr_t start = block[1] - REDZONE_SIZE;
#elif defined(GP_ARCH_mips64) # elif defined(GP_ARCH_mips64)
volatile uintptr_t block[3]; volatile uintptr_t block[3];
MOZ_ASSERT(sizeof(block) == 24); MOZ_ASSERT(sizeof(block) == 24);
__asm__ __volatile__( __asm__ __volatile__(
@ -1666,9 +1668,9 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.fp = TaggedUWord(block[2]); startRegs.fp = TaggedUWord(block[2]);
const uintptr_t REDZONE_SIZE = 0; const uintptr_t REDZONE_SIZE = 0;
uintptr_t start = block[1] - REDZONE_SIZE; uintptr_t start = block[1] - REDZONE_SIZE;
#else # else
# error "Unsupported platform" # error "Unsupported platform"
#endif # endif
// Get hold of the innermost LUL_UNIT_TEST_STACK_SIZE bytes of the // Get hold of the innermost LUL_UNIT_TEST_STACK_SIZE bytes of the
// stack. // stack.
@ -1796,77 +1798,78 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
// results on |aLUL|'s logging sink, and also returns a boolean // results on |aLUL|'s logging sink, and also returns a boolean
// indicating whether or not the results are acceptable (correct). // indicating whether or not the results are acceptable (correct).
#define DECL_TEST_FN(NAME) \ # define DECL_TEST_FN(NAME) \
bool NAME(LUL* aLUL, const char* strPorig, const char* strP); bool NAME(LUL* aLUL, const char* strPorig, const char* strP);
#define GEN_TEST_FN(NAME, FRAMESIZE) \ # define GEN_TEST_FN(NAME, FRAMESIZE) \
bool NAME(LUL* aLUL, const char* strPorig, const char* strP) { \ bool NAME(LUL* aLUL, const char* strPorig, const char* strP) { \
/* Create a frame of size (at least) FRAMESIZE, so that the */ \ /* Create a frame of size (at least) FRAMESIZE, so that the */ \
/* 8 functions created by this macro offer some variation in frame */ \ /* 8 functions created by this macro offer some variation in frame */ \
/* sizes. This isn't as simple as it might seem, since a clever */ \ /* sizes. This isn't as simple as it might seem, since a clever */ \
/* optimizing compiler (eg, clang-5) detects that the array is unused */ \ /* optimizing compiler (eg, clang-5) detects that the array is unused */ \
/* and removes it. We try to defeat this by passing it to a function */ \ /* and removes it. We try to defeat this by passing it to a function */ \
/* in a different compilation unit, and hoping that clang does not */ \ /* in a different compilation unit, and hoping that clang does not */ \
/* notice that the call is a no-op. */ \ /* notice that the call is a no-op. */ \
char space[FRAMESIZE]; \ char space[FRAMESIZE]; \
Unused << write(1, space, 0); /* write zero bytes of |space| to stdout */ \ Unused << write(1, space, \
\ 0); /* write zero bytes of |space| to stdout */ \
if (*strP == '\0') { \ \
/* We've come to the end of the director string. */ \ if (*strP == '\0') { \
/* Take a stack snapshot. */ \ /* We've come to the end of the director string. */ \
return GetAndCheckStackTrace(aLUL, strPorig); \ /* Take a stack snapshot. */ \
} else { \ return GetAndCheckStackTrace(aLUL, strPorig); \
/* Recurse onwards. This is a bit subtle. The obvious */ \ } else { \
/* thing to do here is call onwards directly, from within the */ \ /* Recurse onwards. This is a bit subtle. The obvious */ \
/* arms of the case statement. That gives a problem in that */ \ /* thing to do here is call onwards directly, from within the */ \
/* there will be multiple return points inside each function when */ \ /* arms of the case statement. That gives a problem in that */ \
/* unwinding, so it will be difficult to check for consistency */ \ /* there will be multiple return points inside each function when */ \
/* against the director string. Instead, we make an indirect */ \ /* unwinding, so it will be difficult to check for consistency */ \
/* call, so as to guarantee that there is only one call site */ \ /* against the director string. Instead, we make an indirect */ \
/* within each function. This does assume that the compiler */ \ /* call, so as to guarantee that there is only one call site */ \
/* won't transform it back to the simple direct-call form. */ \ /* within each function. This does assume that the compiler */ \
/* To discourage it from doing so, the call is bracketed with */ \ /* won't transform it back to the simple direct-call form. */ \
/* __asm__ __volatile__ sections so as to make it not-movable. */ \ /* To discourage it from doing so, the call is bracketed with */ \
bool (*nextFn)(LUL*, const char*, const char*) = NULL; \ /* __asm__ __volatile__ sections so as to make it not-movable. */ \
switch (*strP) { \ bool (*nextFn)(LUL*, const char*, const char*) = NULL; \
case '1': \ switch (*strP) { \
nextFn = TestFn1; \ case '1': \
break; \ nextFn = TestFn1; \
case '2': \ break; \
nextFn = TestFn2; \ case '2': \
break; \ nextFn = TestFn2; \
case '3': \ break; \
nextFn = TestFn3; \ case '3': \
break; \ nextFn = TestFn3; \
case '4': \ break; \
nextFn = TestFn4; \ case '4': \
break; \ nextFn = TestFn4; \
case '5': \ break; \
nextFn = TestFn5; \ case '5': \
break; \ nextFn = TestFn5; \
case '6': \ break; \
nextFn = TestFn6; \ case '6': \
break; \ nextFn = TestFn6; \
case '7': \ break; \
nextFn = TestFn7; \ case '7': \
break; \ nextFn = TestFn7; \
case '8': \ break; \
nextFn = TestFn8; \ case '8': \
break; \ nextFn = TestFn8; \
default: \ break; \
nextFn = TestFn8; \ default: \
break; \ nextFn = TestFn8; \
} \ break; \
/* "use" |space| immediately after the recursive call, */ \ } \
/* so as to dissuade clang from deallocating the space while */ \ /* "use" |space| immediately after the recursive call, */ \
/* the call is active, or otherwise messing with the stack frame. */ \ /* so as to dissuade clang from deallocating the space while */ \
__asm__ __volatile__("" ::: "cc", "memory"); \ /* the call is active, or otherwise messing with the stack frame. */ \
bool passed = nextFn(aLUL, strPorig, strP + 1); \ __asm__ __volatile__("" ::: "cc", "memory"); \
Unused << write(1, space, 0); \ bool passed = nextFn(aLUL, strPorig, strP + 1); \
__asm__ __volatile__("" ::: "cc", "memory"); \ Unused << write(1, space, 0); \
return passed; \ __asm__ __volatile__("" ::: "cc", "memory"); \
} \ return passed; \
} } \
}
// The test functions are mutually recursive, so it is necessary to // The test functions are mutually recursive, so it is necessary to
// declare them before defining them. // declare them before defining them.
@ -1950,3 +1953,5 @@ void RunLulUnitTests(/*OUT*/ int* aNTests, /*OUT*/ int* aNTestsPassed,
} }
} // namespace lul } // namespace lul
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -3,17 +3,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdio.h> #include "BaseProfiler.h"
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "platform.h" #ifdef MOZ_BASE_PROFILER
#include "PlatformMacros.h"
#include "LulMain.h" # include <stdio.h>
#include "BaseProfilerSharedLibraries.h" # include <signal.h>
#include "AutoObjectMapper.h" # include <string.h>
# include <stdlib.h>
# include <time.h>
# include "platform.h"
# include "PlatformMacros.h"
# include "LulMain.h"
# include "BaseProfilerSharedLibraries.h"
# include "AutoObjectMapper.h"
// Contains miscellaneous helpers that are used to connect the Gecko Profiler // Contains miscellaneous helpers that are used to connect the Gecko Profiler
// and LUL. // and LUL.
@ -24,7 +28,7 @@
void read_procmaps(lul::LUL* aLUL) { void read_procmaps(lul::LUL* aLUL) {
MOZ_ASSERT(aLUL->CountMappings() == 0); MOZ_ASSERT(aLUL->CountMappings() == 0);
#if defined(GP_OS_linux) || defined(GP_OS_android) # if defined(GP_OS_linux) || defined(GP_OS_android)
SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf(); SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf();
for (size_t i = 0; i < info.GetSize(); i++) { for (size_t i = 0; i < info.GetSize(); i++) {
@ -32,13 +36,13 @@ void read_procmaps(lul::LUL* aLUL) {
std::string nativePath = lib.GetNativeDebugPath(); std::string nativePath = lib.GetNativeDebugPath();
# if defined(GP_OS_android) # if defined(GP_OS_android)
// We're using faulty.lib. Use a special-case object mapper. // We're using faulty.lib. Use a special-case object mapper.
AutoObjectMapperFaultyLib mapper(aLUL->mLog); AutoObjectMapperFaultyLib mapper(aLUL->mLog);
# else # else
// We can use the standard POSIX-based mapper. // We can use the standard POSIX-based mapper.
AutoObjectMapperPOSIX mapper(aLUL->mLog); AutoObjectMapperPOSIX mapper(aLUL->mLog);
# endif # endif
// Ask |mapper| to map the object. Then hand its mapped address // Ask |mapper| to map the object. Then hand its mapped address
// to NotifyAfterMap(). // to NotifyAfterMap().
@ -62,9 +66,9 @@ void read_procmaps(lul::LUL* aLUL) {
// unmaps the object. // unmaps the object.
} }
#else # else
# error "Unknown platform" # error "Unknown platform"
#endif # endif
} }
// LUL needs a callback for its logging sink. // LUL needs a callback for its logging sink.
@ -76,3 +80,5 @@ void logging_sink_for_LUL(const char* str) {
MOZ_LOG(gProfilerLog, mozilla::LogLevel::Verbose, MOZ_LOG(gProfilerLog, mozilla::LogLevel::Verbose,
("[%d] %s", profiler_current_process_id(), str)); ("[%d] %s", profiler_current_process_id(), str));
} }
#endif // MOZ_BASE_PROFILER

Просмотреть файл

@ -6,6 +6,12 @@
#ifndef PROFILEJSONWRITER_H #ifndef PROFILEJSONWRITER_H
#define PROFILEJSONWRITER_H #define PROFILEJSONWRITER_H
#include "BaseProfiler.h"
#ifndef MOZ_BASE_PROFILER
# error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
#endif
#include "mozilla/JSONWriter.h" #include "mozilla/JSONWriter.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"

Просмотреть файл

@ -16,8 +16,26 @@
#ifndef GeckoProfiler_h #ifndef GeckoProfiler_h
#define GeckoProfiler_h #define GeckoProfiler_h
// everything in here is also safe to include unconditionally, and only defines // Everything in here is also safe to include unconditionally, and only defines
// empty macros if MOZ_BASE_PROFILER is unset // empty macros if MOZ_GECKO_PROFILER or MOZ_BASE_PROFILER is unset.
// MOZ_BASE_PROFILER is #defined (or not) in this header, so it should be
// #included wherever Base Profiler may be used.
#ifdef MOZ_GECKO_PROFILER
// Disable Base Profiler for now; will be enabled on supported platforms in
// later patches.
# if 0
# define MOZ_BASE_PROFILER
# else
// Other platforms are currently not supported. But you may uncomment the
// following line to enable Base Profiler in your build.
//# define MOZ_BASE_PROFILER
# endif
#endif // MOZ_GECKO_PROFILER
// BaseProfilerCounts.h is also safe to include unconditionally, with empty
// macros if MOZ_BASE_PROFILER is unset.
#include "mozilla/BaseProfilerCounts.h" #include "mozilla/BaseProfilerCounts.h"
#ifndef MOZ_BASE_PROFILER #ifndef MOZ_BASE_PROFILER

Просмотреть файл

@ -7,6 +7,12 @@
#ifndef ProfilerMarkerPayload_h #ifndef ProfilerMarkerPayload_h
#define ProfilerMarkerPayload_h #define ProfilerMarkerPayload_h
#include "BaseProfiler.h"
#ifndef MOZ_BASE_PROFILER
# error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
#endif
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
@ -16,7 +22,6 @@
#include "mozilla/net/TimingStruct.h" #include "mozilla/net/TimingStruct.h"
#include "nsString.h" #include "nsString.h"
#include "BaseProfiler.h"
#include "js/Utility.h" #include "js/Utility.h"
#include "gfxASurface.h" #include "gfxASurface.h"

Просмотреть файл

@ -7,8 +7,10 @@
#ifndef BASE_PROFILER_SHARED_LIBRARIES_H_ #ifndef BASE_PROFILER_SHARED_LIBRARIES_H_
#define BASE_PROFILER_SHARED_LIBRARIES_H_ #define BASE_PROFILER_SHARED_LIBRARIES_H_
#include "BaseProfiler.h"
#ifndef MOZ_BASE_PROFILER #ifndef MOZ_BASE_PROFILER
# error This header does not have a useful implementation on your platform! # error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
#endif #endif
#include "nsNativeCharsetUtils.h" #include "nsNativeCharsetUtils.h"

Просмотреть файл

@ -7,6 +7,12 @@
#ifndef js_ProfilingCategory_h #ifndef js_ProfilingCategory_h
#define js_ProfilingCategory_h #define js_ProfilingCategory_h
#include "BaseProfiler.h"
#ifndef MOZ_BASE_PROFILER
# error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
#endif
#include "jstypes.h" // JS_FRIEND_API #include "jstypes.h" // JS_FRIEND_API
// clang-format off // clang-format off

Просмотреть файл

@ -7,6 +7,12 @@
#ifndef js_ProfilingStack_h #ifndef js_ProfilingStack_h
#define js_ProfilingStack_h #define js_ProfilingStack_h
#include "BaseProfiler.h"
#ifndef MOZ_BASE_PROFILER
# error Do not #include this header when MOZ_BASE_PROFILER is not #defined.
#endif
#include <algorithm> #include <algorithm>
#include <stdint.h> #include <stdint.h>

Просмотреть файл

@ -14,6 +14,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
DIRS += ['android'] DIRS += ['android']
DIRS += [ DIRS += [
'baseprofiler',
'build', 'build',
'misc', 'misc',
] ]