Bug 1143802 - Forward jit level information to profiler frontend. r=shu

This commit is contained in:
Kannan Vijayan 2015-03-20 13:50:23 -04:00
Родитель b64dc1a002
Коммит 8299080b57
4 изменённых файлов: 62 добавлений и 10 удалений

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

@ -123,6 +123,9 @@ class JS_PUBLIC_API(ProfilingFrameIterator)
bool isJit() const;
};
extern JS_PUBLIC_API(ProfilingFrameIterator::FrameKind)
GetProfilingFrameKindFromNativeAddr(JSRuntime *runtime, void *pc, bool *hasOptInfo);
JS_FRIEND_API(bool)
IsProfilingEnabledForRuntime(JSRuntime *runtime);

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

@ -1502,3 +1502,26 @@ JitcodeIonTable::WriteIonTable(CompactBufferWriter &writer,
} // namespace jit
} // namespace js
JS_PUBLIC_API(JS::ProfilingFrameIterator::FrameKind)
JS::GetProfilingFrameKindFromNativeAddr(JSRuntime *rt, void *addr, bool *hasOptInfo)
{
MOZ_ASSERT(hasOptInfo);
*hasOptInfo = false;
JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable();
JitcodeGlobalEntry entry;
table->lookupInfallible(addr, &entry, rt);
MOZ_ASSERT(entry.isIon() || entry.isIonCache() || entry.isBaseline());
if (false && entry.hasTrackedOptimizations()) {
mozilla::Maybe<uint8_t> index = entry.trackedOptimizationIndexAtAddr(addr);
*hasOptInfo = index.isSome();
}
if (entry.isBaseline())
return JS::ProfilingFrameIterator::Frame_Baseline;
return JS::ProfilingFrameIterator::Frame_Ion;
}

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

@ -11,6 +11,7 @@
// JS
#include "jsapi.h"
#include "js/ProfilingFrameIterator.h"
#include "js/TrackedOptimizationInfo.h"
// JSON
@ -408,6 +409,16 @@ void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JS
if (rt) {
JSScript *optsScript;
jsbytecode *optsPC;
bool hasOptInfo = false;
JS::ProfilingFrameIterator::FrameKind frameKind =
JS::GetProfilingFrameKindFromNativeAddr(rt, pc, &hasOptInfo);
MOZ_ASSERT(frameKind == JS::ProfilingFrameIterator::Frame_Ion ||
frameKind == JS::ProfilingFrameIterator::Frame_Baseline);
const char *jitLevelString =
(frameKind == JS::ProfilingFrameIterator::Frame_Ion) ? "ion"
: "baseline";
b.NameValue("implementation", jitLevelString);
if (hasOptInfo) {
b.Name("opts");
b.BeginArray();
StreamOptimizationTypeInfoOp typeInfoOp(b);
@ -419,6 +430,7 @@ void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JS
b.NameValue("optsLine", JS_PCToLineNumber(optsScript, optsPC));
}
}
}
b.EndObject();
}
framePos = (framePos + incBy) % mEntrySize;

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

@ -590,7 +590,21 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
// Stringifying optimization information is delayed until streaming
// time. To re-lookup the entry in the JitcodeGlobalTable, we need to
// store the JIT code address ('J') in the circular buffer.
if (jsFrames[jsIndex].hasTrackedOptimizations) {
//
// Note that we cannot do this when we are sychronously sampling the
// current thread; that is, when called from profiler_get_backtrace. The
// captured backtrace is usually externally stored for an indeterminate
// amount of time, such as in nsRefreshDriver. Problematically, the
// stored backtrace may be alive across a GC during which the profiler
// itself is disabled. In that case, the JS engine is free to discard
// its JIT code. This means that if we inserted such 'J' entries into
// the buffer, nsRefreshDriver would now be holding on to a backtrace
// with stale JIT code return addresses.
MOZ_ASSERT_IF(jsFrames[jsIndex].hasTrackedOptimizations,
jsFrames[jsIndex].kind == JS::ProfilingFrameIterator::Frame_Ion);
if (!aSample->isSamplingCurrentThread &&
(jsFrames[jsIndex].kind == JS::ProfilingFrameIterator::Frame_Ion ||
jsFrames[jsIndex].kind == JS::ProfilingFrameIterator::Frame_Baseline)) {
aProfile.addTag(ProfileEntry('J', jsFrames[jsIndex].returnAddress));
}