Skip to content

Commit d8aa94b

Browse files
authored
Only capture stacks for up to 10 frames for Owner Stacks (#34864)
1 parent 03ba0c7 commit d8aa94b

File tree

1 file changed

+57
-16
lines changed

1 file changed

+57
-16
lines changed

packages/react/src/jsx/ReactJSXElement.js

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ function getOwner() {
5757
return null;
5858
}
5959

60+
// v8 (Chromium, Node.js) defaults to 10
61+
// SpiderMonkey (Firefox) does not support Error.stackTraceLimit
62+
// JSC (Safari) defaults to 100
63+
// The lower the limit, the more likely we'll not reach react_stack_bottom_frame
64+
// The higher the limit, the slower Error() is when not inspecting with a debugger.
65+
// When inspecting with a debugger, Error.stackTraceLimit has no impact on Error() performance (in v8).
66+
const ownerStackTraceLimit = 10;
67+
6068
/** @noinline */
6169
function UnknownOwner() {
6270
/** @noinline */
@@ -352,15 +360,24 @@ export function jsxProdSignatureRunningInDevWithDynamicChildren(
352360
const trackActualOwner =
353361
__DEV__ &&
354362
ReactSharedInternals.recentlyCreatedOwnerStacks++ < ownerStackLimit;
363+
let debugStackDEV = false;
364+
if (__DEV__) {
365+
if (trackActualOwner) {
366+
const previousStackTraceLimit = Error.stackTraceLimit;
367+
Error.stackTraceLimit = ownerStackTraceLimit;
368+
debugStackDEV = Error('react-stack-top-frame');
369+
Error.stackTraceLimit = previousStackTraceLimit;
370+
} else {
371+
debugStackDEV = unknownOwnerDebugStack;
372+
}
373+
}
374+
355375
return jsxDEVImpl(
356376
type,
357377
config,
358378
maybeKey,
359379
isStaticChildren,
360-
__DEV__ &&
361-
(trackActualOwner
362-
? Error('react-stack-top-frame')
363-
: unknownOwnerDebugStack),
380+
debugStackDEV,
364381
__DEV__ &&
365382
(trackActualOwner
366383
? createTask(getTaskName(type))
@@ -379,15 +396,23 @@ export function jsxProdSignatureRunningInDevWithStaticChildren(
379396
const trackActualOwner =
380397
__DEV__ &&
381398
ReactSharedInternals.recentlyCreatedOwnerStacks++ < ownerStackLimit;
399+
let debugStackDEV = false;
400+
if (__DEV__) {
401+
if (trackActualOwner) {
402+
const previousStackTraceLimit = Error.stackTraceLimit;
403+
Error.stackTraceLimit = ownerStackTraceLimit;
404+
debugStackDEV = Error('react-stack-top-frame');
405+
Error.stackTraceLimit = previousStackTraceLimit;
406+
} else {
407+
debugStackDEV = unknownOwnerDebugStack;
408+
}
409+
}
382410
return jsxDEVImpl(
383411
type,
384412
config,
385413
maybeKey,
386414
isStaticChildren,
387-
__DEV__ &&
388-
(trackActualOwner
389-
? Error('react-stack-top-frame')
390-
: unknownOwnerDebugStack),
415+
debugStackDEV,
391416
__DEV__ &&
392417
(trackActualOwner
393418
? createTask(getTaskName(type))
@@ -408,15 +433,23 @@ export function jsxDEV(type, config, maybeKey, isStaticChildren) {
408433
const trackActualOwner =
409434
__DEV__ &&
410435
ReactSharedInternals.recentlyCreatedOwnerStacks++ < ownerStackLimit;
436+
let debugStackDEV = false;
437+
if (__DEV__) {
438+
if (trackActualOwner) {
439+
const previousStackTraceLimit = Error.stackTraceLimit;
440+
Error.stackTraceLimit = ownerStackTraceLimit;
441+
debugStackDEV = Error('react-stack-top-frame');
442+
Error.stackTraceLimit = previousStackTraceLimit;
443+
} else {
444+
debugStackDEV = unknownOwnerDebugStack;
445+
}
446+
}
411447
return jsxDEVImpl(
412448
type,
413449
config,
414450
maybeKey,
415451
isStaticChildren,
416-
__DEV__ &&
417-
(trackActualOwner
418-
? Error('react-stack-top-frame')
419-
: unknownOwnerDebugStack),
452+
debugStackDEV,
420453
__DEV__ &&
421454
(trackActualOwner
422455
? createTask(getTaskName(type))
@@ -667,15 +700,23 @@ export function createElement(type, config, children) {
667700
const trackActualOwner =
668701
__DEV__ &&
669702
ReactSharedInternals.recentlyCreatedOwnerStacks++ < ownerStackLimit;
703+
let debugStackDEV = false;
704+
if (__DEV__) {
705+
if (trackActualOwner) {
706+
const previousStackTraceLimit = Error.stackTraceLimit;
707+
Error.stackTraceLimit = ownerStackTraceLimit;
708+
debugStackDEV = Error('react-stack-top-frame');
709+
Error.stackTraceLimit = previousStackTraceLimit;
710+
} else {
711+
debugStackDEV = unknownOwnerDebugStack;
712+
}
713+
}
670714
return ReactElement(
671715
type,
672716
key,
673717
props,
674718
getOwner(),
675-
__DEV__ &&
676-
(trackActualOwner
677-
? Error('react-stack-top-frame')
678-
: unknownOwnerDebugStack),
719+
debugStackDEV,
679720
__DEV__ &&
680721
(trackActualOwner
681722
? createTask(getTaskName(type))

0 commit comments

Comments
 (0)