зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1499507 - Don't collect line numbers for profiling stack frames. r=njn
They were not displayed in the UI, and the instructions to initialize the line field of a stack frame increased code size unnecessarily. This change reduces the binary size on Linux x64 by around 100KB. Here's a diff of the impact on the code generated for Attr_Binding::get_specified in the Mac build: @@ -20,17 +20,16 @@ movq 0x8(%rbx), %rax movq %r12, %rcx shlq $0x5, %rcx leaq aGetAttrspecifi, %rdx ; "get Attr.specified" movq %rdx, (%rax,%rcx) movq $0x0, 0x8(%rax,%rcx) leaq -40(%rbp), %rdx movq %rdx, 0x10(%rax,%rcx) - movl $0x106, 0x18(%rax,%rcx) movl $0x1c, 0x1c(%rax,%rcx) leal 0x1(%r12), %eax movl %eax, 0x10(%rbx) movq %r15, %rdi call __ZNK7mozilla3dom4Attr9SpecifiedEv ; mozilla::dom::Attr::Specified() const movzxl %al, %eax movabsq $0xfff9000000000000, %rcx Depends on D9193 Differential Revision: https://phabricator.services.mozilla.com/D9195 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
abb7ce1a0a
Коммит
ab700f9fc0
|
@ -125,7 +125,7 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
|
|||
:
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
mAutoProfilerLabel("nsJSUtils::ExecutionContext", /* dynamicStr */ nullptr,
|
||||
__LINE__, js::ProfilingStackFrame::Category::JS),
|
||||
js::ProfilingStackFrame::Category::JS),
|
||||
#endif
|
||||
mCx(aCx)
|
||||
, mRealm(aCx, aGlobal)
|
||||
|
|
|
@ -645,7 +645,7 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
|||
// ran.
|
||||
, mCallerOverride(cx())
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
, mAutoProfilerLabel("AutoEntryScript", aReason, __LINE__,
|
||||
, mAutoProfilerLabel("AutoEntryScript", aReason,
|
||||
js::ProfilingStackFrame::Category::JS)
|
||||
#endif
|
||||
{
|
||||
|
|
|
@ -145,9 +145,12 @@ class ProfilingStackFrame
|
|||
mozilla::Atomic<void*, mozilla::ReleaseAcquire,
|
||||
mozilla::recordreplay::Behavior::DontPreserve> spOrScript;
|
||||
|
||||
// Line number for non-JS stack frames, the bytecode offset otherwise.
|
||||
// The bytecode offset for JS stack frames.
|
||||
// Must not be used on non-JS frames; it'll contain either the default 0,
|
||||
// or a leftover value from a previous JS stack frame that was using this
|
||||
// ProfilingStackFrame object.
|
||||
mozilla::Atomic<int32_t, mozilla::ReleaseAcquire,
|
||||
mozilla::recordreplay::Behavior::DontPreserve> lineOrPcOffset;
|
||||
mozilla::recordreplay::Behavior::DontPreserve> pcOffsetIfJS_;
|
||||
|
||||
// Bits 0...1 hold the Kind. Bits 2...31 hold the category.
|
||||
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire,
|
||||
|
@ -163,8 +166,8 @@ class ProfilingStackFrame
|
|||
dynamicString_ = other.dynamicString();
|
||||
void* spScript = other.spOrScript;
|
||||
spOrScript = spScript;
|
||||
int32_t offset = other.lineOrPcOffset;
|
||||
lineOrPcOffset = offset;
|
||||
int32_t offsetIfJS = other.pcOffsetIfJS_;
|
||||
pcOffsetIfJS_ = offsetIfJS;
|
||||
uint32_t kindAndCategory = other.kindAndCategory_;
|
||||
kindAndCategory_ = kindAndCategory;
|
||||
return *this;
|
||||
|
@ -233,12 +236,12 @@ class ProfilingStackFrame
|
|||
const char* dynamicString() const { return dynamicString_; }
|
||||
|
||||
void initLabelFrame(const char* aLabel, const char* aDynamicString, void* sp,
|
||||
uint32_t aLine, Category aCategory)
|
||||
Category aCategory)
|
||||
{
|
||||
label_ = aLabel;
|
||||
dynamicString_ = aDynamicString;
|
||||
spOrScript = sp;
|
||||
lineOrPcOffset = static_cast<int32_t>(aLine);
|
||||
// pcOffsetIfJS_ is not set and must not be used on label frames.
|
||||
kindAndCategory_ = uint32_t(Kind::LABEL) | (uint32_t(aCategory) << uint32_t(Kind::KIND_BITCOUNT));
|
||||
MOZ_ASSERT(isLabelFrame());
|
||||
}
|
||||
|
@ -248,7 +251,7 @@ class ProfilingStackFrame
|
|||
label_ = "";
|
||||
dynamicString_ = nullptr;
|
||||
spOrScript = sp;
|
||||
lineOrPcOffset = 0;
|
||||
// pcOffsetIfJS_ is not set and must not be used on sp marker frames.
|
||||
kindAndCategory_ = uint32_t(Kind::SP_MARKER) | (uint32_t(Category::OTHER) << uint32_t(Kind::KIND_BITCOUNT));
|
||||
MOZ_ASSERT(isSpMarkerFrame());
|
||||
}
|
||||
|
@ -259,7 +262,7 @@ class ProfilingStackFrame
|
|||
label_ = aLabel;
|
||||
dynamicString_ = aDynamicString;
|
||||
spOrScript = aScript;
|
||||
lineOrPcOffset = pcToOffset(aScript, aPc);
|
||||
pcOffsetIfJS_ = pcToOffset(aScript, aPc);
|
||||
kindAndCategory_ = uint32_t(Kind::JS_NORMAL) | (uint32_t(Category::JS) << uint32_t(Kind::KIND_BITCOUNT));
|
||||
MOZ_ASSERT(isJsFrame());
|
||||
}
|
||||
|
@ -283,11 +286,6 @@ class ProfilingStackFrame
|
|||
|
||||
JS_PUBLIC_API(JSScript*) script() const;
|
||||
|
||||
uint32_t line() const {
|
||||
MOZ_ASSERT(!isJsFrame());
|
||||
return static_cast<uint32_t>(lineOrPcOffset);
|
||||
}
|
||||
|
||||
// Note that the pointer returned might be invalid.
|
||||
JSScript* rawScript() const {
|
||||
MOZ_ASSERT(isJsFrame());
|
||||
|
@ -363,13 +361,13 @@ class ProfilingStack final
|
|||
~ProfilingStack();
|
||||
|
||||
void pushLabelFrame(const char* label, const char* dynamicString, void* sp,
|
||||
uint32_t line, js::ProfilingStackFrame::Category category) {
|
||||
js::ProfilingStackFrame::Category category) {
|
||||
uint32_t oldStackPointer = stackPointer;
|
||||
|
||||
if (MOZ_UNLIKELY(oldStackPointer >= capacity)) {
|
||||
ensureCapacitySlow();
|
||||
}
|
||||
frames[oldStackPointer].initLabelFrame(label, dynamicString, sp, line, category);
|
||||
frames[oldStackPointer].initLabelFrame(label, dynamicString, sp, category);
|
||||
|
||||
// This must happen at the end! The compiler will not reorder this
|
||||
// update because stackPointer is Atomic<..., ReleaseAcquire>, so any
|
||||
|
|
|
@ -98,7 +98,6 @@ AutoGeckoProfilerEntry::AutoGeckoProfilerEntry(JSContext* cx, const char* label,
|
|||
profiler_->profilingStack_->pushLabelFrame(label,
|
||||
/* dynamicString = */ nullptr,
|
||||
/* sp = */ this,
|
||||
/* line = */ 0,
|
||||
category);
|
||||
}
|
||||
|
||||
|
|
|
@ -256,7 +256,7 @@ GeckoProfilerThread::exit(JSScript* script, JSFunction* maybeFun)
|
|||
if (frame.isJsFrame()) {
|
||||
fprintf(stderr, " [%d] JS %s\n", i, frame.dynamicString());
|
||||
} else {
|
||||
fprintf(stderr, " [%d] C line %d %s\n", i, frame.line(), frame.dynamicString());
|
||||
fprintf(stderr, " [%d] Label %s\n", i, frame.dynamicString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -449,12 +449,12 @@ JS_FRIEND_API(jsbytecode*)
|
|||
ProfilingStackFrame::pc() const
|
||||
{
|
||||
MOZ_ASSERT(isJsFrame());
|
||||
if (lineOrPcOffset == NullPCOffset) {
|
||||
if (pcOffsetIfJS_ == NullPCOffset) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSScript* script = this->script();
|
||||
return script ? script->offsetToPC(lineOrPcOffset) : nullptr;
|
||||
return script ? script->offsetToPC(pcOffsetIfJS_) : nullptr;
|
||||
}
|
||||
|
||||
/* static */ int32_t
|
||||
|
@ -468,7 +468,7 @@ ProfilingStackFrame::setPC(jsbytecode* pc)
|
|||
MOZ_ASSERT(isJsFrame());
|
||||
JSScript* script = this->script();
|
||||
MOZ_ASSERT(script); // This should not be called while profiling is suppressed.
|
||||
lineOrPcOffset = pcToOffset(script, pc);
|
||||
pcOffsetIfJS_ = pcToOffset(script, pc);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
|
|
|
@ -56,7 +56,7 @@ GlobalHelperThreadState* gHelperThreadState = nullptr;
|
|||
#define PROFILER_RAII_EXPAND(id, line) PROFILER_RAII_PASTE(id, line)
|
||||
#define PROFILER_RAII PROFILER_RAII_EXPAND(raiiObject, __LINE__)
|
||||
#define AUTO_PROFILER_LABEL(label, category) \
|
||||
HelperThread::AutoProfilerLabel PROFILER_RAII(this, label, __LINE__, \
|
||||
HelperThread::AutoProfilerLabel PROFILER_RAII(this, label, \
|
||||
js::ProfilingStackFrame::Category::category)
|
||||
|
||||
bool
|
||||
|
@ -2583,12 +2583,11 @@ const HelperThread::TaskSpec HelperThread::taskSpecs[] = {
|
|||
|
||||
HelperThread::AutoProfilerLabel::AutoProfilerLabel(HelperThread* helperThread,
|
||||
const char* label,
|
||||
uint32_t line,
|
||||
ProfilingStackFrame::Category category)
|
||||
: profilingStack(helperThread->profilingStack)
|
||||
{
|
||||
if (profilingStack) {
|
||||
profilingStack->pushLabelFrame(label, nullptr, this, line, category);
|
||||
profilingStack->pushLabelFrame(label, nullptr, this, category);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -421,7 +421,6 @@ struct HelperThread
|
|||
struct AutoProfilerLabel
|
||||
{
|
||||
AutoProfilerLabel(HelperThread* helperThread, const char* label,
|
||||
uint32_t line,
|
||||
ProfilingStackFrame::Category category);
|
||||
~AutoProfilerLabel();
|
||||
|
||||
|
|
|
@ -669,8 +669,7 @@ continue_loading:
|
|||
// A few DLLs such as xul.dll and nss3.dll get loaded before mozglue's
|
||||
// AutoProfilerLabel is initialized, and this is a no-op in those cases. But
|
||||
// the vast majority of DLLs do get labelled here.
|
||||
AutoProfilerLabel label("WindowsDllBlocklist::patched_LdrLoadDll", dllName,
|
||||
__LINE__);
|
||||
AutoProfilerLabel label("WindowsDllBlocklist::patched_LdrLoadDll", dllName);
|
||||
|
||||
#ifdef _M_AMD64
|
||||
// Prevent the stack walker from suspending this thread when LdrLoadDll
|
||||
|
|
|
@ -20,13 +20,12 @@ RegisterProfilerLabelEnterExit(ProfilerLabelEnter aEnter,
|
|||
}
|
||||
|
||||
AutoProfilerLabel::AutoProfilerLabel(const char* aLabel,
|
||||
const char* aDynamicString,
|
||||
uint32_t aLine
|
||||
const char* aDynamicString
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
mProfilingStack = sEnter ? sEnter(aLabel, aDynamicString, this, aLine) : nullptr;
|
||||
mProfilingStack = sEnter ? sEnter(aLabel, aDynamicString, this) : nullptr;
|
||||
}
|
||||
|
||||
AutoProfilerLabel::~AutoProfilerLabel()
|
||||
|
|
|
@ -29,8 +29,7 @@ class ProfilingStack;
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
typedef ProfilingStack* (*ProfilerLabelEnter)(const char*, const char*, void*,
|
||||
uint32_t);
|
||||
typedef ProfilingStack* (*ProfilerLabelEnter)(const char*, const char*, void*);
|
||||
typedef void (*ProfilerLabelExit)(ProfilingStack*);
|
||||
|
||||
// Register callbacks that do the entry/exit work involving sProfilingStack.
|
||||
|
@ -44,8 +43,7 @@ MFBT_API void RegisterProfilerLabelEnterExit(ProfilerLabelEnter aEnter,
|
|||
class MOZ_RAII AutoProfilerLabel
|
||||
{
|
||||
public:
|
||||
AutoProfilerLabel(const char* aLabel, const char* aDynamicString,
|
||||
uint32_t aLine
|
||||
AutoProfilerLabel(const char* aLabel, const char* aDynamicString
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
~AutoProfilerLabel();
|
||||
|
||||
|
|
|
@ -198,7 +198,6 @@ ProfileBufferCollector::CollectProfilingStackFrame(const js::ProfilingStackFrame
|
|||
}
|
||||
} else {
|
||||
MOZ_ASSERT(aFrame.isLabelFrame());
|
||||
line = Some(aFrame.line());
|
||||
}
|
||||
|
||||
if (dynamicString) {
|
||||
|
|
|
@ -2493,12 +2493,11 @@ locked_profiler_start(PSLockRef aLock, uint32_t aCapacity, double aInterval,
|
|||
|
||||
// This basically duplicates AutoProfilerLabel's constructor.
|
||||
ProfilingStack*
|
||||
MozGlueLabelEnter(const char* aLabel, const char* aDynamicString, void* aSp,
|
||||
uint32_t aLine)
|
||||
MozGlueLabelEnter(const char* aLabel, const char* aDynamicString, void* aSp)
|
||||
{
|
||||
ProfilingStack* profilingStack = AutoProfilerLabel::sProfilingStack.get();
|
||||
if (profilingStack) {
|
||||
profilingStack->pushLabelFrame(aLabel, aDynamicString, aSp, aLine,
|
||||
profilingStack->pushLabelFrame(aLabel, aDynamicString, aSp,
|
||||
js::ProfilingStackFrame::Category::OTHER);
|
||||
}
|
||||
return profilingStack;
|
||||
|
|
|
@ -473,7 +473,7 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
|||
// Use AUTO_PROFILER_LABEL_DYNAMIC_* if you want to add additional / dynamic
|
||||
// information to the label stack frame.
|
||||
#define AUTO_PROFILER_LABEL(label, category) \
|
||||
mozilla::AutoProfilerLabel PROFILER_RAII(label, nullptr, __LINE__, \
|
||||
mozilla::AutoProfilerLabel PROFILER_RAII(label, nullptr, \
|
||||
js::ProfilingStackFrame::Category::category)
|
||||
|
||||
// Similar to AUTO_PROFILER_LABEL, but with an additional string. The inserted
|
||||
|
@ -497,7 +497,7 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
|||
// the profile buffer than AUTO_PROFILER_LABEL_DYNAMIC_* frames.
|
||||
#define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, category, cStr) \
|
||||
mozilla::AutoProfilerLabel \
|
||||
PROFILER_RAII(label, cStr, __LINE__, js::ProfilingStackFrame::Category::category)
|
||||
PROFILER_RAII(label, cStr, js::ProfilingStackFrame::Category::category)
|
||||
|
||||
// Similar to AUTO_PROFILER_LABEL_DYNAMIC_CSTR, but takes an nsACString.
|
||||
//
|
||||
|
@ -511,7 +511,7 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
|||
mozilla::Maybe<AutoProfilerLabel> raiiObjectNsCString; \
|
||||
if (profiler_is_active()) { \
|
||||
autoCStr.emplace(nsCStr); \
|
||||
raiiObjectNsCString.emplace(label, autoCStr->get(), __LINE__, \
|
||||
raiiObjectNsCString.emplace(label, autoCStr->get(), \
|
||||
js::ProfilingStackFrame::Category::category); \
|
||||
}
|
||||
|
||||
|
@ -528,7 +528,7 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
|||
mozilla::Maybe<AutoProfilerLabel> raiiObjectLossyNsString; \
|
||||
if (profiler_is_active()) { \
|
||||
asciiStr.emplace(nsStr); \
|
||||
raiiObjectLossyNsString.emplace(label, asciiStr->get(), __LINE__, \
|
||||
raiiObjectLossyNsString.emplace(label, asciiStr->get(), \
|
||||
js::ProfilingStackFrame::Category::category); \
|
||||
}
|
||||
|
||||
|
@ -539,7 +539,7 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
|||
// ProfilingStack from the JS context, and avoids almost all overhead in the case
|
||||
// where the profiler is disabled.
|
||||
#define AUTO_PROFILER_LABEL_FAST(label, category, ctx) \
|
||||
mozilla::AutoProfilerLabel PROFILER_RAII(ctx, label, nullptr, __LINE__, \
|
||||
mozilla::AutoProfilerLabel PROFILER_RAII(ctx, label, nullptr, \
|
||||
js::ProfilingStackFrame::Category::category)
|
||||
|
||||
// Insert a marker in the profile timeline. This is useful to delimit something
|
||||
|
@ -719,37 +719,36 @@ class MOZ_RAII AutoProfilerLabel
|
|||
public:
|
||||
// This is the AUTO_PROFILER_LABEL and AUTO_PROFILER_LABEL_DYNAMIC variant.
|
||||
AutoProfilerLabel(const char* aLabel, const char* aDynamicString,
|
||||
uint32_t aLine, js::ProfilingStackFrame::Category aCategory
|
||||
js::ProfilingStackFrame::Category aCategory
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
// Get the ProfilingStack from TLS.
|
||||
Push(sProfilingStack.get(), aLabel, aDynamicString, aLine, aCategory);
|
||||
Push(sProfilingStack.get(), aLabel, aDynamicString, aCategory);
|
||||
}
|
||||
|
||||
// This is the AUTO_PROFILER_LABEL_FAST variant. It retrieves the ProfilingStack
|
||||
// from the JSContext and does nothing if the profiler is inactive.
|
||||
AutoProfilerLabel(JSContext* aJSContext,
|
||||
const char* aLabel, const char* aDynamicString,
|
||||
uint32_t aLine, js::ProfilingStackFrame::Category aCategory
|
||||
js::ProfilingStackFrame::Category aCategory
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
Push(js::GetContextProfilingStackIfEnabled(aJSContext),
|
||||
aLabel, aDynamicString, aLine, aCategory);
|
||||
aLabel, aDynamicString, aCategory);
|
||||
}
|
||||
|
||||
void Push(ProfilingStack* aProfilingStack,
|
||||
const char* aLabel, const char* aDynamicString,
|
||||
uint32_t aLine, js::ProfilingStackFrame::Category aCategory)
|
||||
js::ProfilingStackFrame::Category aCategory)
|
||||
{
|
||||
// This function runs both on and off the main thread.
|
||||
|
||||
mProfilingStack = aProfilingStack;
|
||||
if (mProfilingStack) {
|
||||
mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this, aLine,
|
||||
aCategory);
|
||||
mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this, aCategory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -748,9 +748,9 @@ TEST(GeckoProfiler, ProfilingStack)
|
|||
ASSERT_TRUE(profiler_get_backtrace());
|
||||
}
|
||||
|
||||
AutoProfilerLabel label1("A", nullptr, 888,
|
||||
AutoProfilerLabel label1("A", nullptr,
|
||||
js::ProfilingStackFrame::Category::DOM);
|
||||
AutoProfilerLabel label2("A", dynamic.get(), 888,
|
||||
AutoProfilerLabel label2("A", dynamic.get(),
|
||||
js::ProfilingStackFrame::Category::NETWORK);
|
||||
ASSERT_TRUE(profiler_get_backtrace());
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче