Bug 1129780 - Report the youngest sampled frame's line number if it has optimization info. (r=djvj)

This commit is contained in:
Shu-yu Guo 2015-02-23 20:33:56 -08:00
Родитель 7c033d640a
Коммит df02b37be7
5 изменённых файлов: 115 добавлений и 34 удалений

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

@ -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();