mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-09 08:48:07 +00:00
Merge f-t to m-c, a=merge
This commit is contained in:
commit
ced4ccaf2d
@ -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(() => {
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user