@@ -1257,29 +1257,18 @@ export function focusSubtree(
12571257 const prefixDepth = callNodePath . length ;
12581258 const stackMatches = new Int32Array ( stackTable . length ) ;
12591259 const funcMatchesImplementation = FUNC_MATCHES [ implementation ] ;
1260- const oldStackToNewStack : Map <
1261- IndexIntoStackTable | null ,
1262- IndexIntoStackTable | null
1263- > = new Map ( ) ;
1264- // A root stack's prefix will be null. Maintain that relationship from old to new
1265- // stacks by mapping from null to null.
1266- oldStackToNewStack . set ( null , null ) ;
1267- const newFrameCol = [ ] ;
1268- const newPrefixCol = [ ] ;
1269- const newCategoryCol = [ ] ;
1270- const newSubcategoryCol = [ ] ;
1271- let newLength = 0 ;
1260+ const oldStackToNewStack = new Int32Array ( stackTable . length ) . fill ( - 1 ) ;
1261+ const newPrefixCol : Array < IndexIntoStackTable | null > = [ ] ;
1262+ const keepStack = makeBitSet ( stackTable . length ) ;
12721263 for ( let stackIndex = 0 ; stackIndex < stackTable . length ; stackIndex ++ ) {
12731264 const prefix = stackTable . prefix [ stackIndex ] ;
12741265 const prefixMatchesUpTo = prefix !== null ? stackMatches [ prefix ] : 0 ;
12751266 let stackMatchesUpTo = - 1 ;
12761267 if ( prefixMatchesUpTo !== - 1 ) {
1277- const frame = stackTable . frame [ stackIndex ] ;
1278- const category = stackTable . category [ stackIndex ] ;
1279- const subcategory = stackTable . subcategory [ stackIndex ] ;
12801268 if ( prefixMatchesUpTo === prefixDepth ) {
12811269 stackMatchesUpTo = prefixDepth ;
12821270 } else {
1271+ const frame = stackTable . frame [ stackIndex ] ;
12831272 const funcIndex = frameTable . func [ frame ] ;
12841273 if ( funcIndex === callNodePath [ prefixMatchesUpTo ] ) {
12851274 stackMatchesUpTo = prefixMatchesUpTo + 1 ;
@@ -1288,41 +1277,25 @@ export function focusSubtree(
12881277 }
12891278 }
12901279 if ( stackMatchesUpTo === prefixDepth ) {
1291- const newStackIndex = newLength ++ ;
1292- const newStackPrefix = oldStackToNewStack . get ( prefix ) ;
1293- newPrefixCol [ newStackIndex ] = newStackPrefix ?? null ;
1294- newFrameCol [ newStackIndex ] = frame ;
1295- newCategoryCol [ newStackIndex ] = category ;
1296- newSubcategoryCol [ newStackIndex ] = subcategory ;
1297- oldStackToNewStack . set ( stackIndex , newStackIndex ) ;
1280+ const prefixNewStack =
1281+ prefix === null ? - 1 : oldStackToNewStack [ prefix ] ;
1282+ oldStackToNewStack [ stackIndex ] = newPrefixCol . length ;
1283+ newPrefixCol . push ( prefixNewStack === - 1 ? null : prefixNewStack ) ;
1284+ setBit ( keepStack , stackIndex ) ;
12981285 }
12991286 }
13001287 stackMatches [ stackIndex ] = stackMatchesUpTo ;
13011288 }
13021289
1303- const newStackTable = {
1304- frame : newFrameCol ,
1305- prefix : newPrefixCol ,
1306- category : new Uint8Array ( newCategoryCol ) ,
1307- subcategory :
1308- stackTable . subcategory instanceof Uint8Array
1309- ? new Uint8Array ( newSubcategoryCol )
1310- : new Uint16Array ( newSubcategoryCol ) ,
1311- length : newLength ,
1312- } ;
1313-
1314- return updateThreadStacks ( thread , newStackTable , ( oldStack ) => {
1315- if ( oldStack === null || stackMatches [ oldStack ] !== prefixDepth ) {
1316- return null ;
1317- }
1318- const newStack = oldStackToNewStack . get ( oldStack ) ;
1319- if ( newStack === undefined ) {
1320- throw new Error (
1321- 'Converting from the old stack to a new stack cannot be undefined'
1322- ) ;
1323- }
1324- return newStack ;
1325- } ) ;
1290+ const newStackTable = createStackTableBySkippingDiscarded (
1291+ stackTable ,
1292+ newPrefixCol ,
1293+ keepStack
1294+ ) ;
1295+ return applyTransformOutputToThread (
1296+ { newStackTable, effectOnThreadData : { oldStackToNewStack } } ,
1297+ thread
1298+ ) ;
13261299 } ) ;
13271300}
13281301
@@ -1386,53 +1359,32 @@ export function focusFunction(
13861359) : Thread {
13871360 return timeCode ( 'focusFunction' , ( ) => {
13881361 const { stackTable, frameTable } = thread ;
1389- // A map oldStack -> newStack+1, implemented as a Uint32Array for performance.
1390- // If newStack+1 is zero it means "null", i.e. this stack was filtered out.
1391- // Typed arrays are initialized to zero, which we interpret as null.
1392- const oldStackToNewStackPlusOne = new Uint32Array ( stackTable . length ) ;
1393-
1394- const newFrameCol = [ ] ;
1395- const newPrefixCol = [ ] ;
1396- const newCategoryCol = [ ] ;
1397- const newSubcategoryCol = [ ] ;
1398- let newLength = 0 ;
1362+ const oldStackToNewStack = new Int32Array ( stackTable . length ) . fill ( - 1 ) ;
1363+ const newPrefixCol : Array < IndexIntoStackTable | null > = [ ] ;
1364+ const keepStack = makeBitSet ( stackTable . length ) ;
13991365
14001366 for ( let stackIndex = 0 ; stackIndex < stackTable . length ; stackIndex ++ ) {
14011367 const prefix = stackTable . prefix [ stackIndex ] ;
14021368 const frameIndex = stackTable . frame [ stackIndex ] ;
14031369 const funcIndex = frameTable . func [ frameIndex ] ;
14041370
1405- const newPrefixPlusOne =
1406- prefix === null ? 0 : oldStackToNewStackPlusOne [ prefix ] ;
1407- const newPrefix = newPrefixPlusOne === 0 ? null : newPrefixPlusOne - 1 ;
1408- if ( newPrefix !== null || funcIndex === funcIndexToFocus ) {
1409- const newStackIndex = newLength ++ ;
1410- newPrefixCol [ newStackIndex ] = newPrefix ;
1411- newFrameCol [ newStackIndex ] = frameIndex ;
1412- newCategoryCol [ newStackIndex ] = stackTable . category [ stackIndex ] ;
1413- newSubcategoryCol [ newStackIndex ] = stackTable . subcategory [ stackIndex ] ;
1414- oldStackToNewStackPlusOne [ stackIndex ] = newStackIndex + 1 ;
1371+ const prefixNewStack = prefix === null ? - 1 : oldStackToNewStack [ prefix ] ;
1372+ if ( prefixNewStack !== - 1 || funcIndex === funcIndexToFocus ) {
1373+ oldStackToNewStack [ stackIndex ] = newPrefixCol . length ;
1374+ newPrefixCol . push ( prefixNewStack === - 1 ? null : prefixNewStack ) ;
1375+ setBit ( keepStack , stackIndex ) ;
14151376 }
14161377 }
14171378
1418- const newStackTable = {
1419- frame : newFrameCol ,
1420- prefix : newPrefixCol ,
1421- category : new Uint8Array ( newCategoryCol ) ,
1422- subcategory :
1423- stackTable . subcategory instanceof Uint8Array
1424- ? new Uint8Array ( newSubcategoryCol )
1425- : new Uint16Array ( newSubcategoryCol ) ,
1426- length : newLength ,
1427- } ;
1428-
1429- return updateThreadStacks ( thread , newStackTable , ( oldStack ) => {
1430- if ( oldStack === null ) {
1431- return null ;
1432- }
1433- const newStackPlusOne = oldStackToNewStackPlusOne [ oldStack ] ;
1434- return newStackPlusOne === 0 ? null : newStackPlusOne - 1 ;
1435- } ) ;
1379+ const newStackTable = createStackTableBySkippingDiscarded (
1380+ stackTable ,
1381+ newPrefixCol ,
1382+ keepStack
1383+ ) ;
1384+ return applyTransformOutputToThread (
1385+ { newStackTable, effectOnThreadData : { oldStackToNewStack } } ,
1386+ thread
1387+ ) ;
14361388 } ) ;
14371389}
14381390
@@ -1498,56 +1450,34 @@ export function focusSelf(
14981450export function focusCategory ( thread : Thread , category : IndexIntoCategoryList ) {
14991451 return timeCode ( 'focusCategory' , ( ) => {
15001452 const { stackTable } = thread ;
1501- const oldStackToNewStack : Map <
1502- IndexIntoStackTable | null ,
1503- IndexIntoStackTable | null
1504- > = new Map ( ) ;
1505- oldStackToNewStack . set ( null , null ) ;
1506-
1507- const newFrameCol = [ ] ;
1508- const newPrefixCol = [ ] ;
1509- const newCategoryCol = [ ] ;
1510- const newSubcategoryCol = [ ] ;
1511- let newLength = 0 ;
1453+ const oldStackToNewStack = new Int32Array ( stackTable . length ) . fill ( - 1 ) ;
1454+ const newPrefixCol : Array < IndexIntoStackTable | null > = [ ] ;
1455+ const keepStack = makeBitSet ( stackTable . length ) ;
15121456
15131457 // fill the new stack table with the kept frames
15141458 for ( let stackIndex = 0 ; stackIndex < stackTable . length ; stackIndex ++ ) {
15151459 const prefix = stackTable . prefix [ stackIndex ] ;
1516- const newPrefix = oldStackToNewStack . get ( prefix ) ;
1517- if ( newPrefix === undefined ) {
1518- throw new Error ( 'The prefix should not map to an undefined value' ) ;
1519- }
1460+ const prefixNewStack = prefix === null ? - 1 : oldStackToNewStack [ prefix ] ;
15201461
15211462 if ( stackTable . category [ stackIndex ] !== category ) {
1522- oldStackToNewStack . set ( stackIndex , newPrefix ) ;
1463+ oldStackToNewStack [ stackIndex ] = prefixNewStack ;
15231464 continue ;
15241465 }
15251466
1526- const newStackIndex = newLength ++ ;
1527- newPrefixCol [ newStackIndex ] = newPrefix ;
1528- newFrameCol [ newStackIndex ] = stackTable . frame [ stackIndex ] ;
1529- newCategoryCol [ newStackIndex ] = stackTable . category [ stackIndex ] ;
1530- newSubcategoryCol [ newStackIndex ] = stackTable . subcategory [ stackIndex ] ;
1531- oldStackToNewStack . set ( stackIndex , newStackIndex ) ;
1467+ oldStackToNewStack [ stackIndex ] = newPrefixCol . length ;
1468+ newPrefixCol . push ( prefixNewStack === - 1 ? null : prefixNewStack ) ;
1469+ setBit ( keepStack , stackIndex ) ;
15321470 }
15331471
1534- const newStackTable = {
1535- frame : newFrameCol ,
1536- prefix : newPrefixCol ,
1537- category : new Uint8Array ( newCategoryCol ) ,
1538- subcategory :
1539- stackTable . subcategory instanceof Uint8Array
1540- ? new Uint8Array ( newSubcategoryCol )
1541- : new Uint16Array ( newSubcategoryCol ) ,
1542- length : newLength ,
1543- } ;
1544-
1545- const updated = updateThreadStacks (
1546- thread ,
1547- newStackTable ,
1548- getMapStackUpdater ( oldStackToNewStack )
1472+ const newStackTable = createStackTableBySkippingDiscarded (
1473+ stackTable ,
1474+ newPrefixCol ,
1475+ keepStack
1476+ ) ;
1477+ return applyTransformOutputToThread (
1478+ { newStackTable, effectOnThreadData : { oldStackToNewStack } } ,
1479+ thread
15491480 ) ;
1550- return updated ;
15511481 } ) ;
15521482}
15531483
0 commit comments