Bug 1146718 - Split the 'J' tag in the profiler into 'J' (JIT frames without opt info) and 'O' (with opt info). (r=djvj)

This commit is contained in:
Shu-yu Guo 2015-03-24 18:49:16 -07:00
parent 0afd5aa7d1
commit dfa17e9fc8
4 changed files with 33 additions and 28 deletions

View File

@ -109,7 +109,7 @@ class JS_PUBLIC_API(ProfilingFrameIterator)
void *returnAddress;
void *activation;
const char *label;
bool hasTrackedOptimizations;
bool mightHaveTrackedOptimizations;
};
uint32_t extractStack(Frame *frames, uint32_t offset, uint32_t end) const;

View File

@ -1862,7 +1862,7 @@ JS::ProfilingFrameIterator::extractStack(Frame *frames, uint32_t offset, uint32_
frames[offset].returnAddress = nullptr;
frames[offset].activation = activation_;
frames[offset].label = asmJSIter().label();
frames[offset].hasTrackedOptimizations = false;
frames[offset].mightHaveTrackedOptimizations = false;
return 1;
}
@ -1898,21 +1898,16 @@ JS::ProfilingFrameIterator::extractStack(Frame *frames, uint32_t offset, uint32_
frames[offset + i].returnAddress = returnAddr;
frames[offset + i].activation = activation_;
frames[offset + i].label = labels[i];
frames[offset + i].hasTrackedOptimizations = false;
frames[offset + i].mightHaveTrackedOptimizations = false;
}
// Extract the index into the side table of optimization information and
// store it on the youngest frame. All inlined frames will have the same
// optimization information by virtue of sharing the JitcodeGlobalEntry,
// but such information is only interpretable on the youngest frame.
// A particular return address might have tracked optimizations only if
// there are any optimizations at all.
//
// FIXMEshu: disabled until we can ensure the optimization info is live
// when we write out the JSON stream of the profile.
if (false && entry.hasTrackedOptimizations()) {
uint32_t dummy;
mozilla::Maybe<uint8_t> index = entry.trackedOptimizationIndexAtAddr(returnAddr, &dummy);
frames[offset].hasTrackedOptimizations = index.isSome();
}
// All inlined Ion frames will have the same optimization information by
// virtue of sharing the JitcodeGlobalEntry, but such information is only
// interpretable on the youngest frame.
frames[offset].mightHaveTrackedOptimizations = entry.hasTrackedOptimizations();
return depth;
}

View File

@ -343,7 +343,7 @@ void UniqueJITOptimizations::stream(JSStreamWriter& b, JSRuntime* rt)
}
void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JSRuntime* rt,
UniqueJITOptimizations &aUniqueOpts)
UniqueJITOptimizations& aUniqueOpts)
{
b.BeginArray();
@ -468,7 +468,8 @@ void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JS
}
readAheadPos = (framePos + incBy) % mEntrySize;
if (readAheadPos != mWritePos &&
mEntries[readAheadPos].mTagName == 'J') {
(mEntries[readAheadPos].mTagName == 'J' ||
mEntries[readAheadPos].mTagName == 'O')) {
void* pc = mEntries[readAheadPos].mTagPtr;
// TODOshu: cannot stream tracked optimization info if
@ -486,11 +487,16 @@ void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JS
// Sampled JIT optimizations are deduplicated by
// aUniqueOpts to save space. Stream an index that
// references into the optimizations array.
Maybe<unsigned> optsIndex = aUniqueOpts.getIndex(pc, rt);
if (optsIndex.isSome()) {
b.NameValue("optsIndex", optsIndex.value());
bool mightHaveTrackedOpts = mEntries[readAheadPos].mTagName == 'O';
if (mightHaveTrackedOpts) {
Maybe<unsigned> optsIndex = aUniqueOpts.getIndex(pc, rt);
if (optsIndex.isSome()) {
b.NameValue("optsIndex", optsIndex.value());
}
}
}
incBy++;
}
b.EndObject();
}

View File

@ -596,11 +596,16 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
// Check to see if JS jit stack frame is top-most
if (jsStackAddr > nativeStackAddr) {
MOZ_ASSERT(jsIndex >= 0);
addDynamicTag(aProfile, 'c', jsFrames[jsIndex].label);
const JS::ProfilingFrameIterator::Frame& jsFrame = jsFrames[jsIndex];
addDynamicTag(aProfile, 'c', jsFrame.label);
// 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.
// Stringifying optimization information and the JIT tier is delayed
// until streaming time. To re-lookup the entry in the
// JitcodeGlobalTable, we need to store the JIT code address in the
// circular buffer.
//
// Frames which may have optimization information are tagged by an 'O'
// entry. Otherwise they are tagged by a 'J' entry.
//
// Note that we cannot do this when we are sychronously sampling the
// current thread; that is, when called from profiler_get_backtrace. The
@ -611,12 +616,11 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
// 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));
(jsFrame.kind == JS::ProfilingFrameIterator::Frame_Ion ||
jsFrame.kind == JS::ProfilingFrameIterator::Frame_Baseline)) {
char entryTag = jsFrame.mightHaveTrackedOptimizations ? 'O' : 'J';
aProfile.addTag(ProfileEntry(entryTag, jsFrames[jsIndex].returnAddress));
}
jsIndex--;