mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1129780 - Report the youngest sampled frame's line number if it has optimization info. (r=djvj)
This commit is contained in:
parent
ae0d6a31fa
commit
522ad62eb8
@ -279,7 +279,8 @@ struct ForEachTrackedOptimizationAttemptOp
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr,
|
||||
ForEachTrackedOptimizationAttemptOp &op);
|
||||
ForEachTrackedOptimizationAttemptOp &op,
|
||||
JSScript **scriptOut, jsbytecode **pcOut);
|
||||
|
||||
struct ForEachTrackedOptimizationTypeInfoOp
|
||||
{
|
||||
|
@ -20,19 +20,28 @@
|
||||
namespace js {
|
||||
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
|
||||
JitcodeGlobalEntry::IonEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||
BytecodeLocationVector &results,
|
||||
uint32_t *depth) const
|
||||
{
|
||||
MOZ_ASSERT(containsPointer(ptr));
|
||||
uint32_t ptrOffset = reinterpret_cast<uint8_t *>(ptr) -
|
||||
reinterpret_cast<uint8_t *>(nativeStartAddr());
|
||||
|
||||
uint32_t regionIdx = regionTable()->findRegionEntry(ptrOffset);
|
||||
MOZ_ASSERT(regionIdx < regionTable()->numRegions());
|
||||
|
||||
JitcodeRegionEntry region = regionTable()->regionEntry(regionIdx);
|
||||
uint32_t ptrOffset;
|
||||
JitcodeRegionEntry region = RegionAtAddr(*this, ptr, &ptrOffset);
|
||||
*depth = region.scriptDepth();
|
||||
|
||||
JitcodeRegionEntry::ScriptPcIterator locationIter = region.scriptPcIterator();
|
||||
@ -61,15 +70,10 @@ JitcodeGlobalEntry::IonEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||
const char **results,
|
||||
uint32_t maxResults) const
|
||||
{
|
||||
MOZ_ASSERT(containsPointer(ptr));
|
||||
MOZ_ASSERT(maxResults >= 1);
|
||||
uint32_t ptrOffset = reinterpret_cast<uint8_t *>(ptr) -
|
||||
reinterpret_cast<uint8_t *>(nativeStartAddr());
|
||||
|
||||
uint32_t regionIdx = regionTable()->findRegionEntry(ptrOffset);
|
||||
MOZ_ASSERT(regionIdx < regionTable()->numRegions());
|
||||
|
||||
JitcodeRegionEntry region = regionTable()->regionEntry(regionIdx);
|
||||
uint32_t ptrOffset;
|
||||
JitcodeRegionEntry region = RegionAtAddr(*this, ptr, &ptrOffset);
|
||||
|
||||
JitcodeRegionEntry::ScriptPcIterator locationIter = region.scriptPcIterator();
|
||||
MOZ_ASSERT(locationIter.hasMore());
|
||||
@ -88,6 +92,23 @@ JitcodeGlobalEntry::IonEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||
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
|
||||
JitcodeGlobalEntry::IonEntry::destroy()
|
||||
{
|
||||
@ -155,6 +176,16 @@ JitcodeGlobalEntry::BaselineEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||
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
|
||||
JitcodeGlobalEntry::BaselineEntry::destroy()
|
||||
{
|
||||
@ -164,19 +195,25 @@ JitcodeGlobalEntry::BaselineEntry::destroy()
|
||||
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
|
||||
JitcodeGlobalEntry::IonCacheEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||
BytecodeLocationVector &results,
|
||||
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;
|
||||
jitrt->getJitcodeGlobalTable()->lookupInfallible(rejoinAddr(), &entry, rt);
|
||||
MOZ_ASSERT(entry.isIon());
|
||||
|
||||
RejoinEntry(rt, *this, ptr, &entry);
|
||||
return entry.callStackAtAddr(rt, rejoinAddr(), results, depth);
|
||||
}
|
||||
|
||||
@ -185,17 +222,21 @@ JitcodeGlobalEntry::IonCacheEntry::callStackAtAddr(JSRuntime *rt, void *ptr,
|
||||
const char **results,
|
||||
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;
|
||||
jitrt->getJitcodeGlobalTable()->lookupInfallible(rejoinAddr(), &entry, rt);
|
||||
MOZ_ASSERT(entry.isIon());
|
||||
|
||||
RejoinEntry(rt, *this, ptr, &entry);
|
||||
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) {
|
||||
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 maxResults) const;
|
||||
|
||||
void youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||
JSScript **script, jsbytecode **pc) const;
|
||||
|
||||
bool hasTrackedOptimizations() const {
|
||||
return !!optsRegionTable_;
|
||||
}
|
||||
@ -278,6 +281,9 @@ class JitcodeGlobalEntry
|
||||
|
||||
uint32_t callStackAtAddr(JSRuntime *rt, void *ptr, const char **results,
|
||||
uint32_t maxResults) const;
|
||||
|
||||
void youngestFrameLocationAtAddr(JSRuntime *rt, void *ptr,
|
||||
JSScript **script, jsbytecode **pc) const;
|
||||
};
|
||||
|
||||
struct IonCacheEntry : public BaseEntry
|
||||
@ -302,6 +308,9 @@ class JitcodeGlobalEntry
|
||||
|
||||
uint32_t callStackAtAddr(JSRuntime *rt, void *ptr, const char **results,
|
||||
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,
|
||||
@ -326,6 +335,13 @@ class JitcodeGlobalEntry
|
||||
{
|
||||
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
|
||||
@ -551,6 +567,23 @@ class JitcodeGlobalEntry
|
||||
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
|
||||
// at this location.
|
||||
uint32_t lookupInlineCallDepth(void *ptr);
|
||||
|
@ -1123,11 +1123,13 @@ IonBuilder::trackInlineSuccessUnchecked(InliningStatus status)
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr,
|
||||
ForEachTrackedOptimizationAttemptOp &op)
|
||||
ForEachTrackedOptimizationAttemptOp &op,
|
||||
JSScript **scriptOut, jsbytecode **pcOut)
|
||||
{
|
||||
JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable();
|
||||
JitcodeGlobalEntry entry;
|
||||
table->lookupInfallible(addr, &entry, rt);
|
||||
entry.youngestFrameLocationAtAddr(rt, addr, scriptOut, pcOut);
|
||||
Maybe<uint8_t> index = entry.trackedOptimizationIndexAtAddr(addr);
|
||||
entry.trackedOptimizationAttempts(index.value()).forEach(op);
|
||||
}
|
||||
@ -1143,7 +1145,7 @@ InterpretedFunctionFilenameAndLineNumber(JSFunction *fun, const char **filename,
|
||||
source = fun->lazyScript()->maybeForwardedScriptSource();
|
||||
*lineno = fun->lazyScript()->lineno();
|
||||
}
|
||||
*filename = source->introducerFilename();
|
||||
*filename = source->filename();
|
||||
}
|
||||
|
||||
static JSFunction *
|
||||
@ -1224,7 +1226,7 @@ class ForEachTypeInfoAdapter : public IonTrackedOptimizationsTypeInfo::ForEachOp
|
||||
if (tracked.hasAllocationSite()) {
|
||||
JSScript *script = tracked.script;
|
||||
op_.readType("alloc site", buf,
|
||||
script->maybeForwardedScriptSource()->introducerFilename(),
|
||||
script->maybeForwardedScriptSource()->filename(),
|
||||
PCToLineNumber(script, script->offsetToPC(tracked.offset)));
|
||||
return;
|
||||
}
|
||||
|
@ -400,13 +400,17 @@ void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JS
|
||||
// TODOshu: cannot stream tracked optimization info if
|
||||
// the JS engine has already shut down when streaming.
|
||||
if (rt) {
|
||||
JSScript *optsScript;
|
||||
jsbytecode *optsPC;
|
||||
b.Name("opts");
|
||||
b.BeginArray();
|
||||
StreamOptimizationTypeInfoOp typeInfoOp(b);
|
||||
JS::ForEachTrackedOptimizationTypeInfo(rt, pc, typeInfoOp);
|
||||
StreamOptimizationAttemptsOp attemptOp(b);
|
||||
JS::ForEachTrackedOptimizationAttempt(rt, pc, attemptOp);
|
||||
JS::ForEachTrackedOptimizationAttempt(rt, pc, attemptOp,
|
||||
&optsScript, &optsPC);
|
||||
b.EndArray();
|
||||
b.NameValue("optsLine", JS_PCToLineNumber(optsScript, optsPC));
|
||||
}
|
||||
}
|
||||
b.EndObject();
|
||||
|
Loading…
Reference in New Issue
Block a user