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.
*/
#include "EHABIStackWalk.h"
#include "BaseProfiler.h"
#include "BaseProfilerSharedLibraries.h"
#include "platform.h"
#ifdef MOZ_BASE_PROFILER
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/EndianUtils.h"
# include "EHABIStackWalk.h"
#include <algorithm>
#include <elf.h>
#include <stdint.h>
#include <vector>
#include <string>
# include "BaseProfilerSharedLibraries.h"
# include "platform.h"
#ifndef PT_ARM_EXIDX
# define PT_ARM_EXIDX 0x70000001
#endif
# include "mozilla/Atomics.h"
# include "mozilla/Attributes.h"
# 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
// 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,
// and binary-search that; otherwise, we search the index in place
// (avoiding the time and space overhead of the indirection).
#if defined(ANDROID_VERSION) && ANDROID_VERSION < 16
# define HAVE_UNSORTED_EXIDX
#endif
# if defined(ANDROID_VERSION) && ANDROID_VERSION < 16
# define HAVE_UNSORTED_EXIDX
# endif
namespace mozilla {
@ -90,7 +94,7 @@ class EHState {
enum { R_SP = 13, R_LR = 14, R_PC = 15 };
#ifdef HAVE_UNSORTED_EXIDX
# ifdef HAVE_UNSORTED_EXIDX
class EHEntryHandle {
const EHEntry* mValue;
@ -102,13 +106,13 @@ class EHEntryHandle {
bool operator<(const EHEntryHandle& lhs, const EHEntryHandle& rhs) {
return lhs.value()->startPC.compute() < rhs.value()->startPC.compute();
}
#endif
# endif
class EHTable {
uint32_t mStartPC;
uint32_t mEndPC;
uint32_t mBaseAddress;
#ifdef HAVE_UNSORTED_EXIDX
# ifdef HAVE_UNSORTED_EXIDX
// In principle we should be able to binary-search the index section in
// place, but the ICS toolchain's linker is noncompliant and produces
// 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) {
return aEntry->value();
}
#else
# else
typedef const EHEntry* EntryIterator;
EntryIterator mEntriesBegin, mEntriesEnd;
EntryIterator entriesBegin() const { return mEntriesBegin; }
EntryIterator entriesEnd() const { return mEntriesEnd; }
static const EHEntry* entryGet(EntryIterator aEntry) { return aEntry; }
#endif
# endif
std::string mName;
public:
@ -330,9 +334,9 @@ bool EHInterp::unwind() {
checkStack();
while (!mFailed) {
uint8_t insn = next();
#if DEBUG_EHABI_UNWIND
# if DEBUG_EHABI_UNWIND
LOG("unwind insn = %02x", (unsigned)insn);
#endif
# endif
// Try to put the common cases first.
// 00xxxxxx: vsp = vsp + (xxxxxx << 2) + 4
@ -456,9 +460,9 @@ bool EHInterp::unwind() {
}
// unhandled instruction
#ifdef DEBUG_EHABI_UNWIND
# ifdef DEBUG_EHABI_UNWIND
LOG("Unhandled EHABI instruction 0x%02x", insn);
#endif
# endif
mFailed = true;
}
return false;
@ -501,12 +505,12 @@ const EHEntry* EHTable::lookup(uint32_t aPC) const {
return nullptr;
while (end - begin > 1) {
#ifdef EHABI_UNWIND_MORE_ASSERTS
# ifdef EHABI_UNWIND_MORE_ASSERTS
if (entryGet(end - 1)->startPC.compute() <
entryGet(begin)->startPC.compute()) {
MOZ_CRASH("unsorted exidx");
}
#endif
# endif
EntryIterator mid = begin + (end - begin) / 2;
if (aPC < reinterpret_cast<uint32_t>(entryGet(mid)->startPC.compute()))
end = mid;
@ -516,22 +520,22 @@ const EHEntry* EHTable::lookup(uint32_t aPC) const {
return entryGet(begin);
}
#if MOZ_LITTLE_ENDIAN
# if MOZ_LITTLE_ENDIAN
static const unsigned char hostEndian = ELFDATA2LSB;
#elif MOZ_BIG_ENDIAN
# elif MOZ_BIG_ENDIAN
static const unsigned char hostEndian = ELFDATA2MSB;
#else
# error "No endian?"
#endif
# else
# error "No endian?"
# endif
// Async signal unsafe: std::vector::reserve, std::string copy ctor.
EHTable::EHTable(const void* aELF, size_t aSize, const std::string& aName)
: mStartPC(~0), // largest uint32_t
mEndPC(0),
#ifndef HAVE_UNSORTED_EXIDX
# ifndef HAVE_UNSORTED_EXIDX
mEntriesBegin(nullptr),
mEntriesEnd(nullptr),
#endif
# endif
mName(aName) {
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);
const EHEntry* endTable = reinterpret_cast<const EHEntry*>(
mBaseAddress + exidxHdr->p_vaddr + exidxHdr->p_memsz);
#ifdef HAVE_UNSORTED_EXIDX
# ifdef HAVE_UNSORTED_EXIDX
mEntries.reserve(endTable - startTable);
for (const EHEntry* i = startTable; i < endTable; ++i) mEntries.push_back(i);
std::sort(mEntries.begin(), mEntries.end());
#else
# else
mEntriesBegin = startTable;
mEntriesEnd = endTable;
#endif
# endif
}
mozilla::Atomic<const EHAddrSpace*> EHAddrSpace::sCurrent(nullptr);
@ -616,7 +620,7 @@ void EHAddrSpace::Update() {
}
EHState::EHState(const mcontext_t& context) {
#ifdef linux
# ifdef linux
mRegs[0] = context.arm_r0;
mRegs[1] = context.arm_r1;
mRegs[2] = context.arm_r2;
@ -633,9 +637,11 @@ EHState::EHState(const mcontext_t& context) {
mRegs[13] = context.arm_sp;
mRegs[14] = context.arm_lr;
mRegs[15] = context.arm_pc;
#else
# error "Unhandled OS for ARM EHABI unwinding"
#endif
# else
# error "Unhandled OS for ARM EHABI unwinding"
# endif
}
} // 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
* 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,
uint32_t aDocShellHistoryId,
@ -35,3 +39,5 @@ size_t PageInformation::SizeOfIncludingThis(
mozilla::MallocSizeOf aMallocSizeOf) const {
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
* 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 "mozilla/MathAlgorithms.h"
#include "nsJSPrincipals.h"
#include "nsScriptSecurityManager.h"
# include "ProfileBuffer.h"
# include "ProfilerMarker.h"
# include "jsfriendapi.h"
# include "mozilla/MathAlgorithms.h"
# include "nsJSPrincipals.h"
# include "nsScriptSecurityManager.h"
using namespace mozilla;
@ -188,3 +192,5 @@ void ProfileBufferCollector::CollectProfilingStackFrame(
mBuf.CollectCodeLocation(label, dynamicString, aFrame.flags(), line, column,
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ProfileBufferEntry.h"
#include "BaseProfiler.h"
#include "platform.h"
#include "ProfileBuffer.h"
#ifdef MOZ_BASE_PROFILER
#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 "ProfileBufferEntry.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;
@ -887,12 +891,12 @@ class EntryGetter {
// Because this is a format entirely internal to the Profiler, any parsing
// error indicates a bug in the ProfileBuffer writing or the parser itself,
// or possibly flaky hardware.
#define ERROR_AND_CONTINUE(msg) \
{ \
fprintf(stderr, "ProfileBuffer parse error: %s", msg); \
MOZ_ASSERT(false, msg); \
continue; \
}
# define ERROR_AND_CONTINUE(msg) \
{ \
fprintf(stderr, "ProfileBuffer parse error: %s", msg); \
MOZ_ASSERT(false, msg); \
continue; \
}
void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter,
int aThreadId, double aSinceTime,
@ -1317,17 +1321,17 @@ void ProfileBuffer::StreamProfilerOverheadToJSON(
aWriter.DoubleProperty("overheadDurations", overheads.sum);
aWriter.DoubleProperty("overheadPercentage",
overheads.sum / (lastTime - firstTime));
#define PROFILER_STATS(name, var) \
aWriter.DoubleProperty("mean" name, (var).sum / (var).n); \
aWriter.DoubleProperty("min" name, (var).min); \
aWriter.DoubleProperty("max" name, (var).max);
# define PROFILER_STATS(name, var) \
aWriter.DoubleProperty("mean" name, (var).sum / (var).n); \
aWriter.DoubleProperty("min" name, (var).min); \
aWriter.DoubleProperty("max" name, (var).max);
PROFILER_STATS("Interval", intervals);
PROFILER_STATS("Overhead", overheads);
PROFILER_STATS("Lockings", lockings);
PROFILER_STATS("Cleaning", cleanings);
PROFILER_STATS("Counter", counters);
PROFILER_STATS("Thread", threads);
#undef PROFILER_STATS
# undef PROFILER_STATS
aWriter.EndObject(); // statistics
}
aWriter.EndObject(); // profilerOverhead
@ -1572,7 +1576,7 @@ void ProfileBuffer::StreamMemoryToJSON(SpliceableJSONWriter& aWriter,
aWriter.EndObject(); // samples
aWriter.EndObject(); // memory
}
#undef ERROR_AND_CONTINUE
# undef ERROR_AND_CONTINUE
static void AddPausedRange(SpliceableJSONWriter& aWriter, const char* aReason,
const Maybe<double>& aStartTime,
@ -1772,3 +1776,5 @@ void ProfileBuffer::DiscardSamplesBeforeTime(double aTime) {
// 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
* 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) {
MOZ_ASSERT(mChunkPtr >= mChunkList.back().get() && mChunkPtr <= mChunkEnd);
@ -112,3 +116,5 @@ void SpliceableChunkedJSONWriter::TakeAndSplice(ChunkedJSONWriteFunc* aFunc) {
WriteFunc()->Take(std::move(*aFunc));
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ProfiledThreadData.h"
#include "BaseProfiler.h"
#include "ProfileBuffer.h"
#include "BaseProfileJSONWriter.h"
#ifdef MOZ_BASE_PROFILER
#include "js/TraceLoggerAPI.h"
#include "mozilla/dom/ContentChild.h"
# include "ProfiledThreadData.h"
#if defined(GP_OS_darwin)
# include <pthread.h>
#endif
# include "ProfileBuffer.h"
# include "BaseProfileJSONWriter.h"
# include "js/TraceLoggerAPI.h"
# include "mozilla/dom/ContentChild.h"
# if defined(GP_OS_darwin)
# include <pthread.h>
# endif
ProfiledThreadData::ProfiledThreadData(ThreadInfo* aThreadInfo,
nsIEventTarget* aEventTarget,
@ -301,3 +305,5 @@ void ProfiledThreadData::NotifyAboutToLoseJSContext(
mJITFrameInfoForPreviousJSContexts = std::move(jitFrameInfo);
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ProfilerBacktrace.h"
#include "BaseProfiler.h"
#include "ProfileBuffer.h"
#include "ProfiledThreadData.h"
#include "BaseProfileJSONWriter.h"
#include "ThreadInfo.h"
#ifdef MOZ_BASE_PROFILER
# include "ProfilerBacktrace.h"
# include "ProfileBuffer.h"
# include "ProfiledThreadData.h"
# include "BaseProfileJSONWriter.h"
# include "ThreadInfo.h"
ProfilerBacktrace::ProfilerBacktrace(const char* aName, int aThreadId,
mozilla::UniquePtr<ProfileBuffer> aBuffer)
@ -32,3 +36,5 @@ void ProfilerBacktrace::StreamJSON(SpliceableJSONWriter& aWriter,
/* aUnregisterTime */ mozilla::TimeStamp(),
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BaseProfilerMarkerPayload.h"
#include "BaseProfiler.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"
#ifdef MOZ_BASE_PROFILER
#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;
@ -296,3 +299,5 @@ void LongTaskMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
aUniqueStacks);
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "vm/GeckoProfiler-inl.h"
#include "BaseProfiler.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Sprintf.h"
#ifdef MOZ_BASE_PROFILER
#include "jsnum.h"
# include "vm/GeckoProfiler-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 "mozilla/ArrayUtils.h"
# include "mozilla/DebugOnly.h"
# include "mozilla/Sprintf.h"
#include "gc/Marking-inl.h"
#include "vm/JSScript-inl.h"
# include "jsnum.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;
@ -152,14 +156,14 @@ void GeckoProfilerRuntime::enable(bool enabled) {
r->wasm.ensureProfilingLabels(enabled);
}
#ifdef JS_STRUCTURED_SPEW
# ifdef JS_STRUCTURED_SPEW
// Enable the structured spewer if the environment variable is set.
if (enabled) {
cx->spewer().enableSpewing();
} else {
cx->spewer().disableSpewing();
}
#endif
# endif
}
/* Lookup the string for the function/script, creating one if necessary */
@ -209,7 +213,7 @@ bool GeckoProfilerThread::enter(JSContext* cx, JSScript* script) {
return false;
}
#ifdef DEBUG
# ifdef DEBUG
// 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
// behavior.
@ -221,7 +225,7 @@ bool GeckoProfilerThread::enter(JSContext* cx, JSScript* script) {
profilingStack_->frames[i].pc());
}
}
#endif
# endif
profilingStack_->pushJsFrame("", dynamicString, script, script->code());
return true;
@ -230,7 +234,7 @@ bool GeckoProfilerThread::enter(JSContext* cx, JSScript* script) {
void GeckoProfilerThread::exit(JSContext* cx, JSScript* script) {
profilingStack_->pop();
#ifdef DEBUG
# ifdef DEBUG
/* Sanity check to make sure push/pop balanced */
uint32_t sp = profilingStack_->stackPointer;
if (sp < profilingStack_->stackCapacity()) {
@ -260,7 +264,7 @@ void GeckoProfilerThread::exit(JSContext* cx, JSScript* script) {
MOZ_ASSERT(frame.script() == script);
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() {
for (auto r = strings().all(); !r.empty(); r.popFront()) {
JSScript* script = r.front().key();
@ -388,7 +392,7 @@ void GeckoProfilerRuntime::checkStringsMapAfterMovingGC() {
MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front());
}
}
#endif
# endif
void ProfilingStackFrame::trace(JSTracer* trc) {
if (isJsFrame()) {
@ -571,3 +575,5 @@ JS_FRIEND_API const ProfilingCategoryPairInfo& GetProfilingCategoryPairInfo(
}
} // 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "js/ProfilingStack.h"
#include "BaseProfiler.h"
#include "mozilla/IntegerRange.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/UniquePtrExtensions.h"
#ifdef MOZ_BASE_PROFILER
#include <algorithm>
# include "js/ProfilingStack.h"
# include "mozilla/IntegerRange.h"
# include "mozilla/UniquePtr.h"
# include "mozilla/UniquePtrExtensions.h"
# include <algorithm>
using namespace js;
@ -44,3 +48,5 @@ void ProfilingStack::ensureCapacitySlow() {
capacity = newCapacity;
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
* 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,
void* aStackTop)
@ -19,10 +23,10 @@ RegisteredThread::RegisteredThread(ThreadInfo* aInfo, nsIEventTarget* aThread,
MOZ_COUNT_CTOR(RegisteredThread);
// We don't have to guess on mac
#if defined(GP_OS_darwin)
# if defined(GP_OS_darwin)
pthread_t self = pthread_self();
mStackTop = pthread_get_stackaddr_np(self);
#endif
# endif
}
RegisteredThread::~RegisteredThread() { MOZ_COUNT_DTOR(RegisteredThread); }
@ -41,3 +45,5 @@ size_t RegisteredThread::SizeOfIncludingThis(
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef XP_WIN
# undef UNICODE
# undef _UNICODE
#endif
#include "BaseProfiler.h"
#include "VTuneProfiler.h"
#include "mozilla/Bootstrap.h"
#include <memory>
#ifdef MOZ_BASE_PROFILER
# ifdef XP_WIN
# undef UNICODE
# undef _UNICODE
# endif
# include "VTuneProfiler.h"
# include "mozilla/Bootstrap.h"
# include <memory>
using namespace std;
@ -80,3 +84,5 @@ void VTuneProfiler::RegisterThreadInternal(const char* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BaseProfilerSharedLibraries.h"
#include "BaseProfiler.h"
#define PATH_MAX_TOSTRING(x) #x
#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>
#ifdef MOZ_BASE_PROFILER
#include "common/linux/file_id.h"
#include <algorithm>
#include <dlfcn.h>
#include <features.h>
#include <sys/types.h>
# include "BaseProfilerSharedLibraries.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
# define PATH_MAX_TOSTRING(x) # x
# 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 <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(
int (*callback)(struct dl_phdr_info* info, size_t size, void* data),
void* data);
#else
# error "Unexpected configuration"
#endif
# else
# error "Unexpected configuration"
# endif
struct LoadedLibraryInfo {
LoadedLibraryInfo(const char* aName, unsigned long aBaseAddress,
@ -54,9 +58,9 @@ struct LoadedLibraryInfo {
unsigned long mLastMappingEnd;
};
#if defined(GP_OS_android)
# if defined(GP_OS_android)
static void outputMapperLog(const char* aBuf) { LOG("%s", aBuf); }
#endif
# endif
static nsCString IDtoUUIDString(
const google_breakpad::wasteful_vector<uint8_t>& aIdentifier) {
@ -77,7 +81,7 @@ static nsCString getId(const char* bin_name) {
PageAllocator 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) {
AutoObjectMapperFaultyLib mapper(outputMapperLog);
void* image = nullptr;
@ -88,7 +92,7 @@ static nsCString getId(const char* bin_name) {
}
}
}
#endif
# endif
FileID file_id(bin_name);
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 info;
#if defined(GP_OS_linux)
# if defined(GP_OS_linux)
// We need to find the name of the executable (exeName, exeNameLen) and the
// address of its executable section (exeExeAddr) in the running image.
char exeName[PATH_MAX];
@ -168,9 +172,9 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
}
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) {
// On ARM Android, dl_iterate_phdr is provided by the custom linker.
@ -179,7 +183,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
// not call it.
return info;
}
#endif
# endif
// Read info from /proc/self/maps. We ignore most of it.
pid_t pid = profiler_current_process_id();
@ -207,12 +211,12 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
continue;
}
#if defined(GP_OS_linux)
# if defined(GP_OS_linux)
// Try to establish the main executable's load address.
if (exeNameLen > 0 && strcmp(modulePath, exeName) == 0) {
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
// associated phdrs.
if (0 == strcmp(modulePath, "/dev/ashmem/dalvik-jit-code-cache")) {
@ -224,7 +228,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
break;
}
}
#endif
# endif
}
nsTArray<LoadedLibraryInfo> libInfoList;
@ -239,7 +243,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
libInfo.mFirstMappingStart - libInfo.mBaseAddress));
}
#if defined(GP_OS_linux)
# if defined(GP_OS_linux)
// Make another pass over the information we just harvested from
// 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
@ -254,10 +258,12 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
break;
}
}
#endif
# endif
return info;
}
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BaseProfilerSharedLibraries.h"
#include "BaseProfiler.h"
#include "ClearOnShutdown.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/Unused.h"
#include "nsNativeCharsetUtils.h"
#include <AvailabilityMacros.h>
#ifdef MOZ_BASE_PROFILER
#include <dlfcn.h>
#include <mach-o/arch.h>
#include <mach-o/dyld_images.h>
#include <mach-o/dyld.h>
#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>
# include "BaseProfilerSharedLibraries.h"
# include "ClearOnShutdown.h"
# include "mozilla/StaticMutex.h"
# include "mozilla/Unused.h"
# include "nsNativeCharsetUtils.h"
# include <AvailabilityMacros.h>
# include <dlfcn.h>
# include <mach-o/arch.h>
# include <mach-o/dyld_images.h>
# include <mach-o/dyld.h>
# 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.
#if defined(GP_ARCH_x86)
# if defined(GP_ARCH_x86)
typedef mach_header platform_mach_header;
typedef segment_command mach_segment_command_type;
# define MACHO_MAGIC_NUMBER MH_MAGIC
# define CMD_SEGMENT LC_SEGMENT
# define seg_size uint32_t
#else
# define MACHO_MAGIC_NUMBER MH_MAGIC
# define CMD_SEGMENT LC_SEGMENT
# define seg_size uint32_t
# else
typedef mach_header_64 platform_mach_header;
typedef segment_command_64 mach_segment_command_type;
# define MACHO_MAGIC_NUMBER MH_MAGIC_64
# define CMD_SEGMENT LC_SEGMENT_64
# define seg_size uint64_t
#endif
# define MACHO_MAGIC_NUMBER MH_MAGIC_64
# define CMD_SEGMENT LC_SEGMENT_64
# define seg_size uint64_t
# endif
struct NativeSharedLibrary {
const platform_mach_header* header;
@ -183,3 +187,5 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <windows.h>
#include <dbghelp.h>
#include <sstream>
#include <psapi.h>
#include "BaseProfiler.h"
#include "BaseProfilerSharedLibraries.h"
#include "nsWindowsHelpers.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Unused.h"
#include "nsNativeCharsetUtils.h"
#include "nsPrintfCString.h"
#include "nsReadableUtils.h"
#ifdef MOZ_BASE_PROFILER
#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 {
uint32_t signature;
@ -207,3 +211,5 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "BaseProfiler.h"
#include "mozilla/Assertions.h"
#include "mozilla/Sprintf.h"
#ifdef MOZ_BASE_PROFILER
#include "PlatformMacros.h"
#include "AutoObjectMapper.h"
# include <sys/mman.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
#if defined(GP_OS_android)
# include <dlfcn.h>
# include "mozilla/Types.h"
# include "mozilla/Assertions.h"
# include "mozilla/Sprintf.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
// own header, so as to avoid conflicts arising from two definitions
// 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);
}
// The following are for get_installation_lib_dir()
# include "nsString.h"
# include "nsDirectoryServiceUtils.h"
# include "nsDirectoryServiceDefs.h"
#endif
# include "nsString.h"
# include "nsDirectoryServiceUtils.h"
# include "nsDirectoryServiceDefs.h"
# endif
// A helper function for creating failure error messages in
// AutoObjectMapper*::Map.
@ -95,7 +99,7 @@ bool AutoObjectMapperPOSIX::Map(/*OUT*/ void** start, /*OUT*/ size_t* length,
return true;
}
#if defined(GP_OS_android)
# if defined(GP_OS_android)
// A helper function for AutoObjectMapperFaultyLib::Map. Finds out
// 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
@ -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/unique_string.cc
#include "BaseProfiler.h"
#ifdef MOZ_BASE_PROFILER
// There's no internal-only interface for LulCommon. Hence include
// the external interface directly.
#include "LulCommonExt.h"
# include "LulCommonExt.h"
#include <stdlib.h>
#include <string.h>
# include <stdlib.h>
# include <string.h>
#include <string>
#include <map>
# include <string>
# include <map>
namespace lul {
@ -98,3 +102,5 @@ const UniqueString* UniqueStringUniverse::ToUniqueString(string str) {
}
} // namespace lul
#endif // MOZ_BASE_PROFILER

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

@ -41,23 +41,27 @@
// src/common/dwarf/dwarf2reader.cc
// src/common/dwarf_cfi_to_module.cc
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "BaseProfiler.h"
#include <map>
#include <stack>
#include <string>
#ifdef MOZ_BASE_PROFILER
#include "mozilla/Assertions.h"
#include "mozilla/Sprintf.h"
# include <stdint.h>
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
#include "LulCommonExt.h"
#include "LulDwarfInt.h"
# include <map>
# 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
#define DEBUG_DWARF 0
# define DEBUG_DWARF 0
namespace lul {
@ -2250,3 +2254,5 @@ void DwarfCFIToModule::Reporter::ExpressionCouldNotBeSummarised(
}
} // 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
* 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 "mozilla/Sprintf.h"
# include "LulDwarfSummariser.h"
# include "LulDwarfExt.h"
# include "mozilla/Assertions.h"
# include "mozilla/Sprintf.h"
// Set this to 1 for verbose logging
#define DEBUG_SUMMARISER 0
# define DEBUG_SUMMARISER 0
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.
#if defined(GP_ARCH_arm)
# if defined(GP_ARCH_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);
}
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
// ----------------- arm64 ----------------- //
@ -327,7 +331,7 @@ void Summariser::Rule(uintptr_t aAddress, int aNewReg, LExprHow how,
if (mCurrRules.mSPexpr.mHow == UNKNOWN) {
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 ---------------- //
@ -427,7 +431,7 @@ void Summariser::Rule(uintptr_t aAddress, int aNewReg, LExprHow how,
mCurrRules.mXbpExpr = LExpr(NODEREF, DW_REG_INTEL_XBP, 0);
}
#elif defined(GP_ARCH_mips64)
# elif defined(GP_ARCH_mips64)
// ---------------- mips ---------------- //
//
// 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);
}
#else
# else
# error "Unsupported arch"
#endif
# error "Unsupported arch"
# endif
return;
@ -551,3 +555,5 @@ void Summariser::End() {
}
} // namespace lul
#endif // MOZ_BASE_PROFILER

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

@ -45,37 +45,41 @@
// src/common/linux/elfutils.cc
// src/common/linux/file_id.cc
#include <errno.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 "BaseProfiler.h"
#include <set>
#include <string>
#include <vector>
#ifdef MOZ_BASE_PROFILER
#include "mozilla/Assertions.h"
#include "mozilla/Sprintf.h"
# include <errno.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 "LulCommonExt.h"
#include "LulDwarfExt.h"
#include "LulElfInt.h"
#include "LulMainInt.h"
# include <set>
# include <string>
# include <vector>
#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
# define SHT_ARM_EXIDX (SHT_LOPROC + 1)
#endif
# define SHT_ARM_EXIDX (SHT_LOPROC + 1)
# endif
// Old Linux header doesn't define EM_AARCH64
#ifndef EM_AARCH64
# define EM_AARCH64 183
#endif
# ifndef EM_AARCH64
# define EM_AARCH64 183
# endif
// This namespace contains helper functions.
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.
#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
// 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
#endif // MOZ_BASE_PROFILER

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

@ -4,35 +4,37 @@
* 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/. */
#include "LulMain.h"
#include "BaseProfiler.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h> // write(), only for testing LUL
#ifdef MOZ_BASE_PROFILER
#include <algorithm> // std::sort
#include <string>
# include "LulMain.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 <string.h>
# include <stdlib.h>
# include <stdio.h>
# include <unistd.h> // write(), only for testing LUL
#include "LulCommonExt.h"
#include "LulElfExt.h"
# include <algorithm> // std::sort
# 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
#define DEBUG_MAIN 0
# define DEBUG_MAIN 0
namespace lul {
@ -62,14 +64,14 @@ static const char* NameOf_DW_REG(int16_t aReg) {
switch (aReg) {
case DW_REG_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:
return "xbp";
case DW_REG_INTEL_XSP:
return "xsp";
case DW_REG_INTEL_XIP:
return "xip";
#elif defined(GP_ARCH_arm)
# elif defined(GP_ARCH_arm)
case DW_REG_ARM_R7:
return "r7";
case DW_REG_ARM_R11:
@ -82,23 +84,23 @@ static const char* NameOf_DW_REG(int16_t aReg) {
return "r14";
case DW_REG_ARM_R15:
return "r15";
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
case DW_REG_AARCH64_X29:
return "x29";
case DW_REG_AARCH64_X30:
return "x30";
case DW_REG_AARCH64_SP:
return "sp";
#elif defined(GP_ARCH_mips64)
# elif defined(GP_ARCH_mips64)
case DW_REG_MIPS_SP:
return "sp";
case DW_REG_MIPS_FP:
return "fp";
case DW_REG_MIPS_PC:
return "pc";
#else
# error "Unsupported arch"
#endif
# else
# error "Unsupported arch"
# endif
default:
return "???";
}
@ -138,28 +140,28 @@ void RuleSet::Print(void (*aLog)(const char*)) const {
res += mCfaExpr.ShowRule("cfa");
res += " in";
// 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 += mXspExpr.ShowRule(" SP");
res += mXbpExpr.ShowRule(" BP");
#elif defined(GP_ARCH_arm)
# elif defined(GP_ARCH_arm)
res += mR15expr.ShowRule(" R15");
res += mR7expr.ShowRule(" R7");
res += mR11expr.ShowRule(" R11");
res += mR12expr.ShowRule(" R12");
res += mR13expr.ShowRule(" R13");
res += mR14expr.ShowRule(" R14");
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
res += mX29expr.ShowRule(" X29");
res += mX30expr.ShowRule(" X30");
res += mSPexpr.ShowRule(" SP");
#elif defined(GP_ARCH_mips64)
# elif defined(GP_ARCH_mips64)
res += mPCexpr.ShowRule(" PC");
res += mSPexpr.ShowRule(" SP");
res += mFPexpr.ShowRule(" FP");
#else
# error "Unsupported arch"
#endif
# else
# error "Unsupported arch"
# endif
aLog(res.c_str());
}
@ -167,14 +169,14 @@ LExpr* RuleSet::ExprForRegno(DW_REG_NUMBER aRegno) {
switch (aRegno) {
case DW_REG_CFA:
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:
return &mXipExpr;
case DW_REG_INTEL_XSP:
return &mXspExpr;
case DW_REG_INTEL_XBP:
return &mXbpExpr;
#elif defined(GP_ARCH_arm)
# elif defined(GP_ARCH_arm)
case DW_REG_ARM_R15:
return &mR15expr;
case DW_REG_ARM_R14:
@ -187,23 +189,23 @@ LExpr* RuleSet::ExprForRegno(DW_REG_NUMBER aRegno) {
return &mR11expr;
case DW_REG_ARM_R7:
return &mR7expr;
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
case DW_REG_AARCH64_X29:
return &mX29expr;
case DW_REG_AARCH64_X30:
return &mX30expr;
case DW_REG_AARCH64_SP:
return &mSPexpr;
#elif defined(GP_ARCH_mips64)
# elif defined(GP_ARCH_mips64)
case DW_REG_MIPS_SP:
return &mSPexpr;
case DW_REG_MIPS_FP:
return &mFPexpr;
case DW_REG_MIPS_PC:
return &mPCexpr;
#else
# error "Unknown arch"
#endif
# else
# error "Unknown arch"
# endif
default:
return nullptr;
}
@ -364,7 +366,7 @@ void SecMap::PrepareRuleSets(uintptr_t aStart, size_t aLen) {
size_t n = mRuleSets.size();
#ifdef DEBUG
# ifdef DEBUG
// Do a final check on the rules: their address ranges must be
// ascending, non overlapping, non zero sized.
if (n > 0) {
@ -377,7 +379,7 @@ void SecMap::PrepareRuleSets(uintptr_t aStart, size_t aLen) {
MOZ_ASSERT(prev->mAddr + prev->mLen <= here->mAddr);
}
}
#endif
# endif
// Set the summary min and max address values.
if (n == 0) {
@ -398,14 +400,14 @@ void SecMap::PrepareRuleSets(uintptr_t aStart, size_t aLen) {
// Is now usable for binary search.
mUsable = true;
#if 0
# if 0
mLog("\nRulesets after preening\n");
for (size_t i = 0; i < mRuleSets.size(); ++i) {
mRuleSets[i].Print(mLog);
mLog("\n");
}
mLog("\n");
#endif
# endif
}
bool SecMap::IsEmpty() { return mRuleSets.empty(); }
@ -684,15 +686,15 @@ class PriMap {
// LUL //
////////////////////////////////////////////////////////////////
#define LUL_LOG(_str) \
do { \
char buf[200]; \
SprintfLiteral(buf, "LUL: pid %d tid %d lul-obj %p: %s", \
profiler_current_process_id(), \
profiler_current_thread_id(), this, (_str)); \
buf[sizeof(buf) - 1] = 0; \
mLog(buf); \
} while (0)
# define LUL_LOG(_str) \
do { \
char buf[200]; \
SprintfLiteral(buf, "LUL: pid %d tid %d lul-obj %p: %s", \
profiler_current_process_id(), \
profiler_current_thread_id(), this, (_str)); \
buf[sizeof(buf) - 1] = 0; \
mLog(buf); \
} while (0)
LUL::LUL(void (*aLog)(const char*))
: mLog(aLog),
@ -896,14 +898,14 @@ static TaggedUWord EvaluateReg(int16_t aReg, const UnwindRegs* aOldRegs,
switch (aReg) {
case DW_REG_CFA:
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:
return aOldRegs->xbp;
case DW_REG_INTEL_XSP:
return aOldRegs->xsp;
case DW_REG_INTEL_XIP:
return aOldRegs->xip;
#elif defined(GP_ARCH_arm)
# elif defined(GP_ARCH_arm)
case DW_REG_ARM_R7:
return aOldRegs->r7;
case DW_REG_ARM_R11:
@ -916,23 +918,23 @@ static TaggedUWord EvaluateReg(int16_t aReg, const UnwindRegs* aOldRegs,
return aOldRegs->r14;
case DW_REG_ARM_R15:
return aOldRegs->r15;
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
case DW_REG_AARCH64_X29:
return aOldRegs->x29;
case DW_REG_AARCH64_X30:
return aOldRegs->x30;
case DW_REG_AARCH64_SP:
return aOldRegs->sp;
#elif defined(GP_ARCH_mips64)
# elif defined(GP_ARCH_mips64)
case DW_REG_MIPS_SP:
return aOldRegs->sp;
case DW_REG_MIPS_FP:
return aOldRegs->fp;
case DW_REG_MIPS_PC:
return aOldRegs->pc;
#else
# error "Unsupported arch"
#endif
# else
# error "Unsupported arch"
# endif
default:
MOZ_ASSERT(0);
return TaggedUWord();
@ -951,17 +953,17 @@ TaggedUWord EvaluatePfxExpr(int32_t start, const UnwindRegs* aOldRegs,
int stackPointer = -1;
for (int i = 0; i < N_STACK; i++) stack[i] = TaggedUWord();
#define PUSH(_tuw) \
do { \
if (stackPointer >= N_STACK - 1) goto fail; /* overflow */ \
stack[++stackPointer] = (_tuw); \
} while (0)
# define PUSH(_tuw) \
do { \
if (stackPointer >= N_STACK - 1) goto fail; /* overflow */ \
stack[++stackPointer] = (_tuw); \
} while (0)
#define POP(_lval) \
do { \
if (stackPointer < 0) goto fail; /* underflow */ \
_lval = stack[stackPointer--]; \
} while (0)
# define POP(_lval) \
do { \
if (stackPointer < 0) goto fail; /* underflow */ \
_lval = stack[stackPointer--]; \
} while (0)
// Cursor in the instruction sequence.
size_t curr = start + 1;
@ -1067,8 +1069,8 @@ TaggedUWord EvaluatePfxExpr(int32_t start, const UnwindRegs* aOldRegs,
fail:
return TaggedUWord();
#undef PUSH
#undef POP
# undef PUSH
# undef POP
}
// 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
// the caller will have to abandon the unwind.
// 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->xsp = TaggedUWord();
aRegs->xip = TaggedUWord();
#elif defined(GP_ARCH_arm)
# elif defined(GP_ARCH_arm)
aRegs->r7 = TaggedUWord();
aRegs->r11 = TaggedUWord();
aRegs->r12 = TaggedUWord();
aRegs->r13 = TaggedUWord();
aRegs->r14 = TaggedUWord();
aRegs->r15 = TaggedUWord();
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
aRegs->x29 = TaggedUWord();
aRegs->x30 = TaggedUWord();
aRegs->sp = TaggedUWord();
aRegs->pc = TaggedUWord();
#elif defined(GP_ARCH_mips64)
# elif defined(GP_ARCH_mips64)
aRegs->sp = TaggedUWord();
aRegs->fp = TaggedUWord();
aRegs->pc = TaggedUWord();
#else
# error "Unsupported arch"
#endif
# else
# error "Unsupported arch"
# endif
// This is generally useful.
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
// 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 =
aRS->mXbpExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->xsp =
aRS->mXspExpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->xip =
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->r11 =
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);
aRegs->r15 =
aRS->mR15expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
aRegs->x29 =
aRS->mX29expr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->x30 =
aRS->mX30expr.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->fp = aRS->mFPexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
aRegs->pc = aRS->mPCexpr.EvaluateExpr(&old_regs, cfa, aStackImg, aPfxInstrs);
#else
# error "Unsupported arch"
#endif
# else
# error "Unsupported arch"
# endif
// We're done. Any regs for which we didn't manage to compute a
// new value will now be marked as invalid.
@ -1207,7 +1209,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
if (DEBUG_MAIN) {
char buf[300];
mLog("\n");
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
# if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
SprintfLiteral(
buf, "LoopTop: rip %d/%llx rsp %d/%llx rbp %d/%llx\n",
(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());
buf[sizeof(buf) - 1] = 0;
mLog(buf);
#elif defined(GP_ARCH_arm)
# elif defined(GP_ARCH_arm)
SprintfLiteral(
buf,
"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());
buf[sizeof(buf) - 1] = 0;
mLog(buf);
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
SprintfLiteral(
buf,
"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());
buf[sizeof(buf) - 1] = 0;
mLog(buf);
#elif defined(GP_ARCH_mips64)
# elif defined(GP_ARCH_mips64)
SprintfLiteral(
buf, "LoopTop: pc %d/%llx sp %d/%llx fp %d/%llx\n",
(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());
buf[sizeof(buf) - 1] = 0;
mLog(buf);
#else
# error "Unsupported arch"
#endif
# else
# error "Unsupported arch"
# endif
}
#if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
# if defined(GP_ARCH_amd64) || defined(GP_ARCH_x86)
TaggedUWord ia = regs.xip;
TaggedUWord sp = regs.xsp;
#elif defined(GP_ARCH_arm)
# elif defined(GP_ARCH_arm)
TaggedUWord ia = (*aFramesUsed == 0 ? regs.r15 : regs.r14);
TaggedUWord sp = regs.r13;
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
TaggedUWord ia = (*aFramesUsed == 0 ? regs.pc : regs.x30);
TaggedUWord sp = regs.sp;
#elif defined(GP_ARCH_mips64)
# elif defined(GP_ARCH_mips64)
TaggedUWord ia = regs.pc;
TaggedUWord sp = regs.sp;
#else
# error "Unsupported arch"
#endif
# else
# error "Unsupported arch"
# endif
if (*aFramesUsed >= aFramesAvail) {
break;
@ -1325,7 +1327,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
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
@ -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.
if (ruleset) {
@ -1408,7 +1410,7 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
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
// 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..
//
// 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
// 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;
#if defined(GP_ARCH_mips64)
# if defined(GP_ARCH_mips64)
static __attribute__((noinline)) unsigned long __getpc(void) {
unsigned long rtaddr;
__asm__ volatile("move %0, $31" : "=r"(rtaddr));
return rtaddr;
}
#endif
# endif
// This function is innermost in the test call sequence. It uses LUL
// 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.
UnwindRegs startRegs;
memset(&startRegs, 0, sizeof(startRegs));
#if defined(GP_ARCH_amd64)
# if defined(GP_ARCH_amd64)
volatile uintptr_t block[3];
MOZ_ASSERT(sizeof(block) == 24);
__asm__ __volatile__(
@ -1581,7 +1583,7 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.xbp = TaggedUWord(block[2]);
const uintptr_t REDZONE_SIZE = 128;
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];
MOZ_ASSERT(sizeof(block) == 12);
__asm__ __volatile__(
@ -1603,7 +1605,7 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.xbp = TaggedUWord(block[2]);
const uintptr_t REDZONE_SIZE = 0;
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];
MOZ_ASSERT(sizeof(block) == 24);
__asm__ __volatile__(
@ -1632,7 +1634,7 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.r7 = TaggedUWord(block[5]);
const uintptr_t REDZONE_SIZE = 0;
uintptr_t start = block[1] - REDZONE_SIZE;
#elif defined(GP_ARCH_arm64)
# elif defined(GP_ARCH_arm64)
volatile uintptr_t block[4];
MOZ_ASSERT(sizeof(block) == 32);
__asm__ __volatile__(
@ -1651,7 +1653,7 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.sp = TaggedUWord(block[3]);
const uintptr_t REDZONE_SIZE = 0;
uintptr_t start = block[1] - REDZONE_SIZE;
#elif defined(GP_ARCH_mips64)
# elif defined(GP_ARCH_mips64)
volatile uintptr_t block[3];
MOZ_ASSERT(sizeof(block) == 24);
__asm__ __volatile__(
@ -1666,9 +1668,9 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
startRegs.fp = TaggedUWord(block[2]);
const uintptr_t REDZONE_SIZE = 0;
uintptr_t start = block[1] - REDZONE_SIZE;
#else
# error "Unsupported platform"
#endif
# else
# error "Unsupported platform"
# endif
// Get hold of the innermost LUL_UNIT_TEST_STACK_SIZE bytes of the
// stack.
@ -1796,77 +1798,78 @@ static __attribute__((noinline)) bool GetAndCheckStackTrace(
// results on |aLUL|'s logging sink, and also returns a boolean
// indicating whether or not the results are acceptable (correct).
#define DECL_TEST_FN(NAME) \
bool NAME(LUL* aLUL, const char* strPorig, const char* strP);
# define DECL_TEST_FN(NAME) \
bool NAME(LUL* aLUL, const char* strPorig, const char* strP);
#define GEN_TEST_FN(NAME, FRAMESIZE) \
bool NAME(LUL* aLUL, const char* strPorig, const char* strP) { \
/* Create a frame of size (at least) FRAMESIZE, so that the */ \
/* 8 functions created by this macro offer some variation in frame */ \
/* sizes. This isn't as simple as it might seem, since a clever */ \
/* 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 */ \
/* in a different compilation unit, and hoping that clang does not */ \
/* notice that the call is a no-op. */ \
char space[FRAMESIZE]; \
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. */ \
/* Take a stack snapshot. */ \
return GetAndCheckStackTrace(aLUL, strPorig); \
} else { \
/* Recurse onwards. This is a bit subtle. The obvious */ \
/* thing to do here is call onwards directly, from within the */ \
/* arms of the case statement. That gives a problem in that */ \
/* there will be multiple return points inside each function when */ \
/* unwinding, so it will be difficult to check for consistency */ \
/* against the director string. Instead, we make an indirect */ \
/* call, so as to guarantee that there is only one call site */ \
/* within each function. This does assume that the compiler */ \
/* won't transform it back to the simple direct-call form. */ \
/* To discourage it from doing so, the call is bracketed with */ \
/* __asm__ __volatile__ sections so as to make it not-movable. */ \
bool (*nextFn)(LUL*, const char*, const char*) = NULL; \
switch (*strP) { \
case '1': \
nextFn = TestFn1; \
break; \
case '2': \
nextFn = TestFn2; \
break; \
case '3': \
nextFn = TestFn3; \
break; \
case '4': \
nextFn = TestFn4; \
break; \
case '5': \
nextFn = TestFn5; \
break; \
case '6': \
nextFn = TestFn6; \
break; \
case '7': \
nextFn = TestFn7; \
break; \
case '8': \
nextFn = TestFn8; \
break; \
default: \
nextFn = TestFn8; \
break; \
} \
/* "use" |space| immediately after the recursive call, */ \
/* so as to dissuade clang from deallocating the space while */ \
/* the call is active, or otherwise messing with the stack frame. */ \
__asm__ __volatile__("" ::: "cc", "memory"); \
bool passed = nextFn(aLUL, strPorig, strP + 1); \
Unused << write(1, space, 0); \
__asm__ __volatile__("" ::: "cc", "memory"); \
return passed; \
} \
}
# define GEN_TEST_FN(NAME, FRAMESIZE) \
bool NAME(LUL* aLUL, const char* strPorig, const char* strP) { \
/* Create a frame of size (at least) FRAMESIZE, so that the */ \
/* 8 functions created by this macro offer some variation in frame */ \
/* sizes. This isn't as simple as it might seem, since a clever */ \
/* 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 */ \
/* in a different compilation unit, and hoping that clang does not */ \
/* notice that the call is a no-op. */ \
char space[FRAMESIZE]; \
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. */ \
/* Take a stack snapshot. */ \
return GetAndCheckStackTrace(aLUL, strPorig); \
} else { \
/* Recurse onwards. This is a bit subtle. The obvious */ \
/* thing to do here is call onwards directly, from within the */ \
/* arms of the case statement. That gives a problem in that */ \
/* there will be multiple return points inside each function when */ \
/* unwinding, so it will be difficult to check for consistency */ \
/* against the director string. Instead, we make an indirect */ \
/* call, so as to guarantee that there is only one call site */ \
/* within each function. This does assume that the compiler */ \
/* won't transform it back to the simple direct-call form. */ \
/* To discourage it from doing so, the call is bracketed with */ \
/* __asm__ __volatile__ sections so as to make it not-movable. */ \
bool (*nextFn)(LUL*, const char*, const char*) = NULL; \
switch (*strP) { \
case '1': \
nextFn = TestFn1; \
break; \
case '2': \
nextFn = TestFn2; \
break; \
case '3': \
nextFn = TestFn3; \
break; \
case '4': \
nextFn = TestFn4; \
break; \
case '5': \
nextFn = TestFn5; \
break; \
case '6': \
nextFn = TestFn6; \
break; \
case '7': \
nextFn = TestFn7; \
break; \
case '8': \
nextFn = TestFn8; \
break; \
default: \
nextFn = TestFn8; \
break; \
} \
/* "use" |space| immediately after the recursive call, */ \
/* so as to dissuade clang from deallocating the space while */ \
/* the call is active, or otherwise messing with the stack frame. */ \
__asm__ __volatile__("" ::: "cc", "memory"); \
bool passed = nextFn(aLUL, strPorig, strP + 1); \
Unused << write(1, space, 0); \
__asm__ __volatile__("" ::: "cc", "memory"); \
return passed; \
} \
}
// The test functions are mutually recursive, so it is necessary to
// declare them before defining them.
@ -1950,3 +1953,5 @@ void RunLulUnitTests(/*OUT*/ int* aNTests, /*OUT*/ int* aNTestsPassed,
}
} // 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "BaseProfiler.h"
#include "platform.h"
#include "PlatformMacros.h"
#include "LulMain.h"
#include "BaseProfilerSharedLibraries.h"
#include "AutoObjectMapper.h"
#ifdef MOZ_BASE_PROFILER
# include <stdio.h>
# include <signal.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
// and LUL.
@ -24,7 +28,7 @@
void read_procmaps(lul::LUL* aLUL) {
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();
for (size_t i = 0; i < info.GetSize(); i++) {
@ -32,13 +36,13 @@ void read_procmaps(lul::LUL* aLUL) {
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.
AutoObjectMapperFaultyLib mapper(aLUL->mLog);
# else
# else
// We can use the standard POSIX-based mapper.
AutoObjectMapperPOSIX mapper(aLUL->mLog);
# endif
# endif
// Ask |mapper| to map the object. Then hand its mapped address
// to NotifyAfterMap().
@ -62,9 +66,9 @@ void read_procmaps(lul::LUL* aLUL) {
// unmaps the object.
}
#else
# error "Unknown platform"
#endif
# else
# error "Unknown platform"
# endif
}
// 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,
("[%d] %s", profiler_current_process_id(), str));
}
#endif // MOZ_BASE_PROFILER

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

@ -6,6 +6,12 @@
#ifndef 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/UniquePtr.h"

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

@ -16,8 +16,26 @@
#ifndef GeckoProfiler_h
#define GeckoProfiler_h
// everything in here is also safe to include unconditionally, and only defines
// empty macros if MOZ_BASE_PROFILER is unset
// Everything in here is also safe to include unconditionally, and only defines
// 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"
#ifndef MOZ_BASE_PROFILER

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

@ -7,6 +7,12 @@
#ifndef 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/Maybe.h"
#include "mozilla/RefPtr.h"
@ -16,7 +22,6 @@
#include "mozilla/net/TimingStruct.h"
#include "nsString.h"
#include "BaseProfiler.h"
#include "js/Utility.h"
#include "gfxASurface.h"

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

@ -7,8 +7,10 @@
#ifndef BASE_PROFILER_SHARED_LIBRARIES_H_
#define BASE_PROFILER_SHARED_LIBRARIES_H_
#include "BaseProfiler.h"
#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
#include "nsNativeCharsetUtils.h"

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

@ -7,6 +7,12 @@
#ifndef 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
// clang-format off

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

@ -7,6 +7,12 @@
#ifndef 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 <stdint.h>

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

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