зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1542830: Part 7 - Support MFBT Vector in ProcessedStack and add Swap operation to CombinedStacks; r=janerik
Untrusted modules 2.0 uses MFBT `Vector`, so this patch adds the ability for `ProcessedStack` to receive those as input. Depends on D43160 Differential Revision: https://phabricator.services.mozilla.com/D43161 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a66f824994
Коммит
7eea579d88
|
@ -104,6 +104,19 @@ void CombinedStacks::RemoveStack(unsigned aIndex) {
|
|||
}
|
||||
}
|
||||
|
||||
void CombinedStacks::Swap(CombinedStacks& aOther) {
|
||||
mModules.swap(aOther.mModules);
|
||||
mStacks.swap(aOther.mStacks);
|
||||
|
||||
size_t nextIndex = aOther.mNextIndex;
|
||||
aOther.mNextIndex = mNextIndex;
|
||||
mNextIndex = nextIndex;
|
||||
|
||||
size_t maxStacksCount = aOther.mMaxStacksCount;
|
||||
aOther.mMaxStacksCount = mMaxStacksCount;
|
||||
mMaxStacksCount = maxStacksCount;
|
||||
}
|
||||
|
||||
#if defined(MOZ_GECKO_PROFILER)
|
||||
void CombinedStacks::Clear() {
|
||||
mNextIndex = 0;
|
||||
|
|
|
@ -25,6 +25,11 @@ class CombinedStacks {
|
|||
explicit CombinedStacks();
|
||||
explicit CombinedStacks(size_t aMaxStacksCount);
|
||||
|
||||
CombinedStacks(CombinedStacks&&) = default;
|
||||
CombinedStacks& operator=(CombinedStacks&&) = default;
|
||||
|
||||
void Swap(CombinedStacks& aOther);
|
||||
|
||||
typedef std::vector<Telemetry::ProcessedStack::Frame> Stack;
|
||||
const Telemetry::ProcessedStack::Module& GetModule(unsigned aIndex) const;
|
||||
size_t GetModuleCount() const;
|
||||
|
|
|
@ -76,25 +76,19 @@ BatchProcessedStackGenerator::BatchProcessedStackGenerator()
|
|||
#endif
|
||||
}
|
||||
|
||||
ProcessedStack BatchProcessedStackGenerator::GetStackAndModules(
|
||||
const std::vector<uintptr_t>& aPCs) {
|
||||
std::vector<StackFrame> rawStack;
|
||||
auto stackEnd = aPCs.begin() + std::min(aPCs.size(), kMaxChromeStackDepth);
|
||||
for (auto i = aPCs.begin(); i != stackEnd; ++i) {
|
||||
uintptr_t aPC = *i;
|
||||
StackFrame Frame = {aPC, static_cast<uint16_t>(rawStack.size()),
|
||||
std::numeric_limits<uint16_t>::max()};
|
||||
rawStack.push_back(Frame);
|
||||
}
|
||||
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
SharedLibraryInfo rawModules(mSortedRawModules);
|
||||
#ifndef MOZ_GECKO_PROFILER
|
||||
static ProcessedStack GetStackAndModulesInternal(
|
||||
std::vector<StackFrame>& aRawStack) {
|
||||
#else
|
||||
static ProcessedStack GetStackAndModulesInternal(
|
||||
std::vector<StackFrame>& aRawStack, SharedLibraryInfo& aSortedRawModules) {
|
||||
SharedLibraryInfo rawModules(aSortedRawModules);
|
||||
// Remove all modules not referenced by a PC on the stack
|
||||
std::sort(rawStack.begin(), rawStack.end(), CompareByPC);
|
||||
std::sort(aRawStack.begin(), aRawStack.end(), CompareByPC);
|
||||
|
||||
size_t moduleIndex = 0;
|
||||
size_t stackIndex = 0;
|
||||
size_t stackSize = rawStack.size();
|
||||
size_t stackSize = aRawStack.size();
|
||||
|
||||
while (moduleIndex < rawModules.GetSize()) {
|
||||
const SharedLibrary& module = rawModules.GetEntry(moduleIndex);
|
||||
|
@ -104,20 +98,20 @@ ProcessedStack BatchProcessedStackGenerator::GetStackAndModules(
|
|||
|
||||
bool moduleReferenced = false;
|
||||
for (; stackIndex < stackSize; ++stackIndex) {
|
||||
uintptr_t pc = rawStack[stackIndex].mPC;
|
||||
uintptr_t pc = aRawStack[stackIndex].mPC;
|
||||
if (pc >= moduleEnd) break;
|
||||
|
||||
if (pc >= moduleStart) {
|
||||
// If the current PC is within the current module, mark
|
||||
// module as used
|
||||
moduleReferenced = true;
|
||||
rawStack[stackIndex].mPC -= moduleStart;
|
||||
rawStack[stackIndex].mModIndex = moduleIndex;
|
||||
aRawStack[stackIndex].mPC -= moduleStart;
|
||||
aRawStack[stackIndex].mModIndex = moduleIndex;
|
||||
} else {
|
||||
// PC does not belong to any module. It is probably from
|
||||
// the JIT. Use a fixed mPC so that we don't get different
|
||||
// stacks on different runs.
|
||||
rawStack[stackIndex].mPC = std::numeric_limits<uintptr_t>::max();
|
||||
aRawStack[stackIndex].mPC = std::numeric_limits<uintptr_t>::max();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,15 +125,15 @@ ProcessedStack BatchProcessedStackGenerator::GetStackAndModules(
|
|||
|
||||
for (; stackIndex < stackSize; ++stackIndex) {
|
||||
// These PCs are past the last module.
|
||||
rawStack[stackIndex].mPC = std::numeric_limits<uintptr_t>::max();
|
||||
aRawStack[stackIndex].mPC = std::numeric_limits<uintptr_t>::max();
|
||||
}
|
||||
|
||||
std::sort(rawStack.begin(), rawStack.end(), CompareByIndex);
|
||||
std::sort(aRawStack.begin(), aRawStack.end(), CompareByIndex);
|
||||
#endif
|
||||
|
||||
// Copy the information to the return value.
|
||||
ProcessedStack Ret;
|
||||
for (auto& rawFrame : rawStack) {
|
||||
for (auto& rawFrame : aRawStack) {
|
||||
mozilla::Telemetry::ProcessedStack::Frame frame = {rawFrame.mPC,
|
||||
rawFrame.mModIndex};
|
||||
Ret.AddFrame(frame);
|
||||
|
@ -157,5 +151,40 @@ ProcessedStack BatchProcessedStackGenerator::GetStackAndModules(
|
|||
return Ret;
|
||||
}
|
||||
|
||||
ProcessedStack BatchProcessedStackGenerator::GetStackAndModules(
|
||||
const std::vector<uintptr_t>& aPCs) {
|
||||
std::vector<StackFrame> rawStack;
|
||||
auto stackEnd = aPCs.begin() + std::min(aPCs.size(), kMaxChromeStackDepth);
|
||||
for (auto i = aPCs.begin(); i != stackEnd; ++i) {
|
||||
uintptr_t aPC = *i;
|
||||
StackFrame Frame = {aPC, static_cast<uint16_t>(rawStack.size()),
|
||||
std::numeric_limits<uint16_t>::max()};
|
||||
rawStack.push_back(Frame);
|
||||
}
|
||||
|
||||
#if defined(MOZ_GECKO_PROFILER)
|
||||
return GetStackAndModulesInternal(rawStack, mSortedRawModules);
|
||||
#else
|
||||
return GetStackAndModulesInternal(rawStack);
|
||||
#endif
|
||||
}
|
||||
|
||||
ProcessedStack BatchProcessedStackGenerator::GetStackAndModules(
|
||||
const uintptr_t* aBegin, const uintptr_t* aEnd) {
|
||||
std::vector<StackFrame> rawStack;
|
||||
for (auto i = aBegin; i != aEnd; ++i) {
|
||||
uintptr_t aPC = *i;
|
||||
StackFrame Frame = {aPC, static_cast<uint16_t>(rawStack.size()),
|
||||
std::numeric_limits<uint16_t>::max()};
|
||||
rawStack.push_back(Frame);
|
||||
}
|
||||
|
||||
#if defined(MOZ_GECKO_PROFILER)
|
||||
return GetStackAndModulesInternal(rawStack, mSortedRawModules);
|
||||
#else
|
||||
return GetStackAndModulesInternal(rawStack);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Telemetry
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "mozilla/Vector.h"
|
||||
#include "nsString.h"
|
||||
#if defined(MOZ_GECKO_PROFILER)
|
||||
# include "shared-libraries.h"
|
||||
|
@ -64,7 +66,16 @@ class BatchProcessedStackGenerator {
|
|||
BatchProcessedStackGenerator();
|
||||
ProcessedStack GetStackAndModules(const std::vector<uintptr_t>& aPCs);
|
||||
|
||||
template <typename AllocatorPolicy>
|
||||
ProcessedStack GetStackAndModules(
|
||||
const Vector<void*, 0, AllocatorPolicy>& aPCs) {
|
||||
return GetStackAndModules(reinterpret_cast<const uintptr_t*>(aPCs.begin()),
|
||||
reinterpret_cast<const uintptr_t*>(aPCs.end()));
|
||||
}
|
||||
|
||||
private:
|
||||
ProcessedStack GetStackAndModules(const uintptr_t* aBegin,
|
||||
const uintptr_t* aEnd);
|
||||
#if defined(MOZ_GECKO_PROFILER)
|
||||
SharedLibraryInfo mSortedRawModules;
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче