Merge f-t to m-c, a=merge

This commit is contained in:
Phil Ringnalda 2015-10-04 09:56:33 -07:00
commit ced4ccaf2d
3 changed files with 43 additions and 13 deletions

View File

@ -26,6 +26,7 @@ gDirectorySource = "data:application/json," + JSON.stringify({
function runTests() {
requestLongerTimeout(4);
let origEnhanced = NewTabUtils.allPages.enhanced;
let origCompareLinks = NewTabUtils.links.compareLinks;
registerCleanupFunction(() => {

View File

@ -23,10 +23,16 @@ function checkRecursion(n, limit) {
}
// Async stacks are limited even if we didn't ask for a limit. There is a
// default limit on frames attached on top of any synchronous frames. In this
// case the synchronous frame is the last call to `recur`.
// default limit on frames attached on top of any synchronous frames, and
// every time the limit is reached when capturing, half of the frames are
// truncated from the old end of the async stack.
if (limit == 0) {
limit = defaultAsyncStackLimit + 1;
// Always add one synchronous frame that is the last call to `recur`.
if (n + 1 < defaultAsyncStackLimit) {
limit = defaultAsyncStackLimit + 1;
} else {
limit = n + 2 - (defaultAsyncStackLimit / 2);
}
}
// The first `n` or `limit` frames should have `recur` as their `asyncParent`.
@ -68,6 +74,8 @@ function checkRecursion(n, limit) {
checkRecursion(0, 0);
checkRecursion(1, 0);
checkRecursion(2, 0);
checkRecursion(defaultAsyncStackLimit - 10, 0);
checkRecursion(defaultAsyncStackLimit, 0);
checkRecursion(defaultAsyncStackLimit + 10, 0);
// Limit of 1 frame.

View File

@ -206,7 +206,7 @@ class MOZ_STACK_CLASS SavedFrame::AutoLookupVector : public JS::CustomAutoRooter
lookups(cx)
{ }
typedef Vector<Lookup, 20> LookupVector;
typedef Vector<Lookup, ASYNC_STACK_MAX_FRAME_COUNT> LookupVector;
inline LookupVector* operator->() { return &lookups; }
inline HandleLookup operator[](size_t i) { return HandleLookup(lookups[i]); }
@ -1141,29 +1141,50 @@ SavedStacks::adoptAsyncStack(JSContext* cx, HandleSavedFrame asyncStack,
// stack frames, but async stacks are not limited by the available stack
// memory, so we need to set an arbitrary limit when collecting them. We
// still don't enforce an upper limit if the caller requested more frames.
if (maxFrameCount == 0)
maxFrameCount = ASYNC_STACK_MAX_FRAME_COUNT;
unsigned maxFrames = maxFrameCount > 0 ? maxFrameCount : ASYNC_STACK_MAX_FRAME_COUNT;
// Accumulate the vector of Lookup objects in |stackChain|.
SavedFrame::AutoLookupVector stackChain(cx);
SavedFrame* currentSavedFrame = asyncStack;
for (unsigned i = 0; i < maxFrameCount && currentSavedFrame; i++) {
SavedFrame* firstSavedFrameParent = nullptr;
for (unsigned i = 0; i < maxFrames && currentSavedFrame; i++) {
if (!stackChain->emplaceBack(*currentSavedFrame)) {
ReportOutOfMemory(cx);
return false;
}
// Attach the asyncCause to the youngest frame.
if (i == 0)
stackChain->back().asyncCause = asyncCauseAtom;
currentSavedFrame = currentSavedFrame->getParent();
// Attach the asyncCause to the youngest frame.
if (i == 0) {
stackChain->back().asyncCause = asyncCauseAtom;
firstSavedFrameParent = currentSavedFrame;
}
}
// This is the 1-based index of the oldest frame we care about.
size_t oldestFramePosition = stackChain->length();
RootedSavedFrame parentFrame(cx, nullptr);
if (currentSavedFrame == nullptr &&
asyncStack->compartment() == cx->compartment()) {
// If we consumed the full async stack, and the stack is in the same
// compartment as the one requested, we don't need to rebuild the full
// chain again using the lookup objects, we can just reference the
// existing chain and change the asyncCause on the younger frame.
oldestFramePosition = 1;
parentFrame = firstSavedFrameParent;
} else if (maxFrameCount == 0 &&
oldestFramePosition == ASYNC_STACK_MAX_FRAME_COUNT) {
// If we captured the maximum number of frames and the caller requested
// no specific limit, we only return half of them. This means that for
// the next iterations, it's likely we can use the optimization above.
oldestFramePosition = ASYNC_STACK_MAX_FRAME_COUNT / 2;
}
// Iterate through |stackChain| in reverse order and get or create the
// actual SavedFrame instances.
RootedSavedFrame parentFrame(cx, nullptr);
for (size_t i = stackChain->length(); i != 0; i--) {
for (size_t i = oldestFramePosition; i != 0; i--) {
SavedFrame::HandleLookup lookup = stackChain[i-1];
lookup->parent = parentFrame;
parentFrame.set(getOrCreateSavedFrame(cx, lookup));