зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1129780 - Report the youngest sampled frame's line number if it has optimization info. (r=djvj)
This commit is contained in:
Родитель
7c033d640a
Коммит
df02b37be7
|
@ -279,7 +279,8 @@ struct ForEachTrackedOptimizationAttemptOp
|
||||||
|
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr,
|
ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr,
|
||||||
ForEachTrackedOptimizationAttemptOp &op);
|
ForEachTrackedOptimizationAttemptOp &op,
|
||||||
|
JSScript **scriptOut, jsbytecode **pcOut);
|
||||||
|
|
||||||
struct ForEachTrackedOptimizationTypeInfoOp
|
struct ForEachTrackedOptimizationTypeInfoOp
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,19 +20,28 @@
|
||||||
namespace js {
|
namespace js {
|
||||||
namespace jit {
|
namespace jit {
|
||||||
|
|
||||||
|
|
||||||
|
static inline JitcodeRegionEntry
|
||||||
|
RegionAtAddr(const JitcodeGlobalEntry::IonEntry &entry, void *ptr,
|
||||||
|
uint32_t *ptrOffset)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(entry.containsPointer(ptr));
|
||||||
|
*ptrOffset = reinterpret_cast<uint8_t *>(ptr) -
|
||||||
|
reinterpret_cast<uint8_t *>(entry.nativeStartAddr());
|
||||||
|
|
||||||
|
uint32_t regionIdx = entry.regionTable()->findRegionEntry(*ptrOffset);
|
||||||
|
MOZ_ASSERT(regionIdx < entry.regionTable()->numRegions());
|
||||||
|
|
||||||
|
return entry.regionTable()->regionEntry(regionIdx);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
JitcodeGlobalEntry::IonEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
JitcodeGlobalEntry::IonEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||||
BytecodeLocationVector &results,
|
BytecodeLocationVector &results,
|
||||||
uint32_t *depth) const
|
uint32_t *depth) const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(containsPointer(ptr));
|
uint32_t ptrOffset;
|
||||||
uint32_t ptrOffset = reinterpret_cast<uint8_t *>(ptr) -
|
JitcodeRegionEntry region = RegionAtAddr(*this, ptr, &ptrOffset);
|
||||||
reinterpret_cast<uint8_t *>(nativeStartAddr());
|
|
||||||
|
|
||||||
uint32_t regionIdx = regionTable()->findRegionEntry(ptrOffset);
|
|
||||||
MOZ_ASSERT(regionIdx < regionTable()->numRegions());
|
|
||||||
|
|
||||||
JitcodeRegionEntry region = regionTable()->regionEntry(regionIdx);
|
|
||||||
*depth = region.scriptDepth();
|
*depth = region.scriptDepth();
|
||||||
|
|
||||||
JitcodeRegionEntry::ScriptPcIterator locationIter = region.scriptPcIterator();
|
JitcodeRegionEntry::ScriptPcIterator locationIter = region.scriptPcIterator();
|
||||||
|
@ -61,15 +70,10 @@ JitcodeGlobalEntry::IonEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||||
const char **results,
|
const char **results,
|
||||||
uint32_t maxResults) const
|
uint32_t maxResults) const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(containsPointer(ptr));
|
|
||||||
MOZ_ASSERT(maxResults >= 1);
|
MOZ_ASSERT(maxResults >= 1);
|
||||||
uint32_t ptrOffset = reinterpret_cast<uint8_t *>(ptr) -
|
|
||||||
reinterpret_cast<uint8_t *>(nativeStartAddr());
|
|
||||||
|
|
||||||
uint32_t regionIdx = regionTable()->findRegionEntry(ptrOffset);
|
uint32_t ptrOffset;
|
||||||
MOZ_ASSERT(regionIdx < regionTable()->numRegions());
|
JitcodeRegionEntry region = RegionAtAddr(*this, ptr, &ptrOffset);
|
||||||
|
|
||||||
JitcodeRegionEntry region = regionTable()->regionEntry(regionIdx);
|
|
||||||
|
|
||||||
JitcodeRegionEntry::ScriptPcIterator locationIter = region.scriptPcIterator();
|
JitcodeRegionEntry::ScriptPcIterator locationIter = region.scriptPcIterator();
|
||||||
MOZ_ASSERT(locationIter.hasMore());
|
MOZ_ASSERT(locationIter.hasMore());
|
||||||
|
@ -88,6 +92,23 @@ JitcodeGlobalEntry::IonEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JitcodeGlobalEntry::IonEntry::youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||||
|
JSScript **script, jsbytecode **pc) const
|
||||||
|
{
|
||||||
|
uint32_t ptrOffset;
|
||||||
|
JitcodeRegionEntry region = RegionAtAddr(*this, ptr, &ptrOffset);
|
||||||
|
|
||||||
|
JitcodeRegionEntry::ScriptPcIterator locationIter = region.scriptPcIterator();
|
||||||
|
MOZ_ASSERT(locationIter.hasMore());
|
||||||
|
uint32_t scriptIdx, pcOffset;
|
||||||
|
locationIter.readNext(&scriptIdx, &pcOffset);
|
||||||
|
pcOffset = region.findPcOffset(ptrOffset, pcOffset);
|
||||||
|
|
||||||
|
*script = getScript(scriptIdx);
|
||||||
|
*pc = (*script)->offsetToPC(pcOffset);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JitcodeGlobalEntry::IonEntry::destroy()
|
JitcodeGlobalEntry::IonEntry::destroy()
|
||||||
{
|
{
|
||||||
|
@ -155,6 +176,16 @@ JitcodeGlobalEntry::BaselineEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JitcodeGlobalEntry::BaselineEntry::youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||||
|
JSScript **script,
|
||||||
|
jsbytecode **pc) const
|
||||||
|
{
|
||||||
|
uint8_t *addr = reinterpret_cast<uint8_t*>(ptr);
|
||||||
|
*script = script_;
|
||||||
|
*pc = script_->baselineScript()->approximatePcForNativeAddress(script_, addr);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JitcodeGlobalEntry::BaselineEntry::destroy()
|
JitcodeGlobalEntry::BaselineEntry::destroy()
|
||||||
{
|
{
|
||||||
|
@ -164,19 +195,25 @@ JitcodeGlobalEntry::BaselineEntry::destroy()
|
||||||
str_ = nullptr;
|
str_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RejoinEntry(JSRuntime *rt, const JitcodeGlobalEntry::IonCacheEntry &cache,
|
||||||
|
void *ptr, JitcodeGlobalEntry *entry)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(cache.containsPointer(ptr));
|
||||||
|
|
||||||
|
// There must exist an entry for the rejoin addr if this entry exists.
|
||||||
|
JitRuntime *jitrt = rt->jitRuntime();
|
||||||
|
jitrt->getJitcodeGlobalTable()->lookupInfallible(cache.rejoinAddr(), entry, rt);
|
||||||
|
MOZ_ASSERT(entry->isIon());
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
JitcodeGlobalEntry::IonCacheEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
JitcodeGlobalEntry::IonCacheEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||||
BytecodeLocationVector &results,
|
BytecodeLocationVector &results,
|
||||||
uint32_t *depth) const
|
uint32_t *depth) const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(containsPointer(ptr));
|
|
||||||
|
|
||||||
// There must exist an entry for the rejoin addr if this entry exists.
|
|
||||||
JitRuntime *jitrt = rt->jitRuntime();
|
|
||||||
JitcodeGlobalEntry entry;
|
JitcodeGlobalEntry entry;
|
||||||
jitrt->getJitcodeGlobalTable()->lookupInfallible(rejoinAddr(), &entry, rt);
|
RejoinEntry(rt, *this, ptr, &entry);
|
||||||
MOZ_ASSERT(entry.isIon());
|
|
||||||
|
|
||||||
return entry.callStackAtAddr(rt, rejoinAddr(), results, depth);
|
return entry.callStackAtAddr(rt, rejoinAddr(), results, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,17 +222,21 @@ JitcodeGlobalEntry::IonCacheEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||||
const char **results,
|
const char **results,
|
||||||
uint32_t maxResults) const
|
uint32_t maxResults) const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(containsPointer(ptr));
|
|
||||||
|
|
||||||
// There must exist an entry for the rejoin addr if this entry exists.
|
|
||||||
JitRuntime *jitrt = rt->jitRuntime();
|
|
||||||
JitcodeGlobalEntry entry;
|
JitcodeGlobalEntry entry;
|
||||||
jitrt->getJitcodeGlobalTable()->lookupInfallible(rejoinAddr(), &entry, rt);
|
RejoinEntry(rt, *this, ptr, &entry);
|
||||||
MOZ_ASSERT(entry.isIon());
|
|
||||||
|
|
||||||
return entry.callStackAtAddr(rt, rejoinAddr(), results, maxResults);
|
return entry.callStackAtAddr(rt, rejoinAddr(), results, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JitcodeGlobalEntry::IonCacheEntry::youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||||
|
JSScript **script,
|
||||||
|
jsbytecode **pc) const
|
||||||
|
{
|
||||||
|
JitcodeGlobalEntry entry;
|
||||||
|
RejoinEntry(rt, *this, ptr, &entry);
|
||||||
|
return entry.youngestFrameLocationAtAddr(rt, ptr, script, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ComparePointers(const void *a, const void *b) {
|
static int ComparePointers(const void *a, const void *b) {
|
||||||
const uint8_t *a_ptr = reinterpret_cast<const uint8_t *>(a);
|
const uint8_t *a_ptr = reinterpret_cast<const uint8_t *>(a);
|
||||||
|
|
|
@ -210,6 +210,9 @@ class JitcodeGlobalEntry
|
||||||
uint32_t callStackAtAddr(JSRuntime *rt, void *ptr, const char **results,
|
uint32_t callStackAtAddr(JSRuntime *rt, void *ptr, const char **results,
|
||||||
uint32_t maxResults) const;
|
uint32_t maxResults) const;
|
||||||
|
|
||||||
|
void youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||||
|
JSScript **script, jsbytecode **pc) const;
|
||||||
|
|
||||||
bool hasTrackedOptimizations() const {
|
bool hasTrackedOptimizations() const {
|
||||||
return !!optsRegionTable_;
|
return !!optsRegionTable_;
|
||||||
}
|
}
|
||||||
|
@ -278,6 +281,9 @@ class JitcodeGlobalEntry
|
||||||
|
|
||||||
uint32_t callStackAtAddr(JSRuntime *rt, void *ptr, const char **results,
|
uint32_t callStackAtAddr(JSRuntime *rt, void *ptr, const char **results,
|
||||||
uint32_t maxResults) const;
|
uint32_t maxResults) const;
|
||||||
|
|
||||||
|
void youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||||
|
JSScript **script, jsbytecode **pc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IonCacheEntry : public BaseEntry
|
struct IonCacheEntry : public BaseEntry
|
||||||
|
@ -302,6 +308,9 @@ class JitcodeGlobalEntry
|
||||||
|
|
||||||
uint32_t callStackAtAddr(JSRuntime *rt, void *ptr, const char **results,
|
uint32_t callStackAtAddr(JSRuntime *rt, void *ptr, const char **results,
|
||||||
uint32_t maxResults) const;
|
uint32_t maxResults) const;
|
||||||
|
|
||||||
|
void youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||||
|
JSScript **script, jsbytecode **pc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Dummy entries are created for jitcode generated when profiling is not turned on,
|
// Dummy entries are created for jitcode generated when profiling is not turned on,
|
||||||
|
@ -326,6 +335,13 @@ class JitcodeGlobalEntry
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||||
|
JSScript **script, jsbytecode **pc) const
|
||||||
|
{
|
||||||
|
*script = nullptr;
|
||||||
|
*pc = nullptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// QueryEntry is never stored in the table, just used for queries
|
// QueryEntry is never stored in the table, just used for queries
|
||||||
|
@ -551,6 +567,23 @@ class JitcodeGlobalEntry
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||||
|
JSScript **script, jsbytecode **pc) const
|
||||||
|
{
|
||||||
|
switch (kind()) {
|
||||||
|
case Ion:
|
||||||
|
return ionEntry().youngestFrameLocationAtAddr(rt, ptr, script, pc);
|
||||||
|
case Baseline:
|
||||||
|
return baselineEntry().youngestFrameLocationAtAddr(rt, ptr, script, pc);
|
||||||
|
case IonCache:
|
||||||
|
return ionCacheEntry().youngestFrameLocationAtAddr(rt, ptr, script, pc);
|
||||||
|
case Dummy:
|
||||||
|
return dummyEntry().youngestFrameLocationAtAddr(rt, ptr, script, pc);
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("Invalid JitcodeGlobalEntry kind.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Figure out the number of the (JSScript *, jsbytecode *) pairs that are active
|
// Figure out the number of the (JSScript *, jsbytecode *) pairs that are active
|
||||||
// at this location.
|
// at this location.
|
||||||
uint32_t lookupInlineCallDepth(void *ptr);
|
uint32_t lookupInlineCallDepth(void *ptr);
|
||||||
|
|
|
@ -1123,11 +1123,13 @@ IonBuilder::trackInlineSuccessUnchecked(InliningStatus status)
|
||||||
|
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
JS::ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr,
|
JS::ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr,
|
||||||
ForEachTrackedOptimizationAttemptOp &op)
|
ForEachTrackedOptimizationAttemptOp &op,
|
||||||
|
JSScript **scriptOut, jsbytecode **pcOut)
|
||||||
{
|
{
|
||||||
JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable();
|
JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable();
|
||||||
JitcodeGlobalEntry entry;
|
JitcodeGlobalEntry entry;
|
||||||
table->lookupInfallible(addr, &entry, rt);
|
table->lookupInfallible(addr, &entry, rt);
|
||||||
|
entry.youngestFrameLocationAtAddr(rt, addr, scriptOut, pcOut);
|
||||||
Maybe<uint8_t> index = entry.trackedOptimizationIndexAtAddr(addr);
|
Maybe<uint8_t> index = entry.trackedOptimizationIndexAtAddr(addr);
|
||||||
entry.trackedOptimizationAttempts(index.value()).forEach(op);
|
entry.trackedOptimizationAttempts(index.value()).forEach(op);
|
||||||
}
|
}
|
||||||
|
@ -1143,7 +1145,7 @@ InterpretedFunctionFilenameAndLineNumber(JSFunction *fun, const char **filename,
|
||||||
source = fun->lazyScript()->maybeForwardedScriptSource();
|
source = fun->lazyScript()->maybeForwardedScriptSource();
|
||||||
*lineno = fun->lazyScript()->lineno();
|
*lineno = fun->lazyScript()->lineno();
|
||||||
}
|
}
|
||||||
*filename = source->introducerFilename();
|
*filename = source->filename();
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSFunction *
|
static JSFunction *
|
||||||
|
@ -1224,7 +1226,7 @@ class ForEachTypeInfoAdapter : public IonTrackedOptimizationsTypeInfo::ForEachOp
|
||||||
if (tracked.hasAllocationSite()) {
|
if (tracked.hasAllocationSite()) {
|
||||||
JSScript *script = tracked.script;
|
JSScript *script = tracked.script;
|
||||||
op_.readType("alloc site", buf,
|
op_.readType("alloc site", buf,
|
||||||
script->maybeForwardedScriptSource()->introducerFilename(),
|
script->maybeForwardedScriptSource()->filename(),
|
||||||
PCToLineNumber(script, script->offsetToPC(tracked.offset)));
|
PCToLineNumber(script, script->offsetToPC(tracked.offset)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -400,13 +400,17 @@ void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JS
|
||||||
// TODOshu: cannot stream tracked optimization info if
|
// TODOshu: cannot stream tracked optimization info if
|
||||||
// the JS engine has already shut down when streaming.
|
// the JS engine has already shut down when streaming.
|
||||||
if (rt) {
|
if (rt) {
|
||||||
|
JSScript *optsScript;
|
||||||
|
jsbytecode *optsPC;
|
||||||
b.Name("opts");
|
b.Name("opts");
|
||||||
b.BeginArray();
|
b.BeginArray();
|
||||||
StreamOptimizationTypeInfoOp typeInfoOp(b);
|
StreamOptimizationTypeInfoOp typeInfoOp(b);
|
||||||
JS::ForEachTrackedOptimizationTypeInfo(rt, pc, typeInfoOp);
|
JS::ForEachTrackedOptimizationTypeInfo(rt, pc, typeInfoOp);
|
||||||
StreamOptimizationAttemptsOp attemptOp(b);
|
StreamOptimizationAttemptsOp attemptOp(b);
|
||||||
JS::ForEachTrackedOptimizationAttempt(rt, pc, attemptOp);
|
JS::ForEachTrackedOptimizationAttempt(rt, pc, attemptOp,
|
||||||
|
&optsScript, &optsPC);
|
||||||
b.EndArray();
|
b.EndArray();
|
||||||
|
b.NameValue("optsLine", JS_PCToLineNumber(optsScript, optsPC));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.EndObject();
|
b.EndObject();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче