@@ -54,7 +54,6 @@ import type {
54
54
IndexIntoStackTable ,
55
55
IndexIntoResourceTable ,
56
56
IndexIntoNativeSymbolTable ,
57
- IndexIntoDeduplicatedCallNodeTable ,
58
57
DeduplicatedCallNodeInfo ,
59
58
ThreadIndex ,
60
59
Category ,
@@ -1219,58 +1218,127 @@ export function getTimingsForCallNodeIndex(
1219
1218
return { forPath : pathTimings , rootTime } ;
1220
1219
}
1221
1220
1221
+ function _hash32 ( val : number ) : number {
1222
+ const rotated1 = val << 5 ;
1223
+ const rotated2 = val >> 27 ;
1224
+ const rotated = rotated1 | rotated2 ;
1225
+ const xored = rotated ^ val ;
1226
+ return ( xored * 0x9e_37_79_b9 ) | 0 ;
1227
+ }
1228
+
1222
1229
export function computeDeduplicatedCallNodeInfo (
1223
1230
callNodeInfo : CallNodeInfo
1224
1231
) : DeduplicatedCallNodeInfo {
1225
1232
const callNodeTable = callNodeInfo . getNonInvertedCallNodeTable ( ) ;
1226
1233
1227
- let len = 0 ;
1228
- const prefixCol : IndexIntoDeduplicatedCallNodeTable [ ] = [ ] ;
1229
- const funcCol : IndexIntoFuncTable [ ] = [ ] ;
1230
-
1231
1234
const callNodeCount = callNodeTable . length ;
1235
+ const funcCol = callNodeTable . func ;
1236
+ const prefixCol = callNodeTable . prefix ;
1237
+ const newPrefixCol = new Int32Array ( callNodeCount ) ;
1238
+ const bloomBitsCol1 = new Int32Array ( callNodeCount ) ;
1239
+ const bloomBitsCol2 = new Int32Array ( callNodeCount ) ;
1240
+ const bloomBitsCol3 = new Int32Array ( callNodeCount ) ;
1241
+ const bloomBitsCol4 = new Int32Array ( callNodeCount ) ;
1242
+
1232
1243
const callNodeIndexToDeduplicatedCallNodeIndex = new Uint32Array (
1233
1244
callNodeCount
1234
1245
) ;
1235
1246
1247
+ const funcBloomBits = new Int32Array ( 4 ) ;
1236
1248
for ( let callNodeIndex = 0 ; callNodeIndex < callNodeCount ; callNodeIndex ++ ) {
1237
- const originalPrefix = callNodeTable . prefix [ callNodeIndex ] ;
1238
- const func = callNodeTable . func [ callNodeIndex ] ;
1239
- let prefix = - 1 ;
1240
- if ( originalPrefix !== - 1 ) {
1241
- prefix = callNodeIndexToDeduplicatedCallNodeIndex [ originalPrefix ] ;
1242
-
1243
- // Check if `func` is present in the prefix's call path.
1244
- let prefixHasFunc = false ;
1245
- for (
1246
- let dedupAnc = prefix ;
1247
- dedupAnc !== - 1 ;
1248
- dedupAnc = prefixCol [ dedupAnc ]
1249
- ) {
1250
- if ( funcCol [ dedupAnc ] === func ) {
1251
- prefixHasFunc = true ;
1252
- break ;
1249
+ const prefix = prefixCol [ callNodeIndex ] ;
1250
+ const func = funcCol [ callNodeIndex ] ;
1251
+
1252
+ const funcHash = _hash32 ( func ) ;
1253
+ const funcHashBitIndex1 = funcHash % 32 ;
1254
+ const funcHashBitIndex2 = ( funcHash >> 5 ) % 32 ;
1255
+ // const funcHashBitIndex3 = (funcHash >> 10) % 32;
1256
+ const funcHashBit1 = 1 << funcHashBitIndex1 ;
1257
+ const funcHashBit2 = 1 << funcHashBitIndex2 ;
1258
+ // const funcHashBit3 = 1 << funcHashBitIndex3;
1259
+ const funcBitDistributor1 = ( funcHash >> 15 ) & 0b11 ;
1260
+ const funcBitDistributor2 = ( funcHash >> 17 ) & 0b11 ;
1261
+ // const funcBitDistributor3 = (funcHash >> 19) & 0b11;
1262
+
1263
+ funcBloomBits [ 0 ] = 0 ;
1264
+ funcBloomBits [ 1 ] = 0 ;
1265
+ funcBloomBits [ 2 ] = 0 ;
1266
+ funcBloomBits [ 3 ] = 0 ;
1267
+ funcBloomBits [ funcBitDistributor1 ] |= funcHashBit1 ;
1268
+ funcBloomBits [ funcBitDistributor2 ] |= funcHashBit2 ;
1269
+ // funcBloomBits[funcBitDistributor3] |= funcHashBit3;
1270
+
1271
+ const funcBloomBits1 = funcBloomBits [ 0 ] ;
1272
+ const funcBloomBits2 = funcBloomBits [ 1 ] ;
1273
+ const funcBloomBits3 = funcBloomBits [ 2 ] ;
1274
+ const funcBloomBits4 = funcBloomBits [ 3 ] ;
1275
+
1276
+ let prefixBloomBits1 = 0 ;
1277
+ let prefixBloomBits2 = 0 ;
1278
+ let prefixBloomBits3 = 0 ;
1279
+ let prefixBloomBits4 = 0 ;
1280
+ let newPrefix = - 1 ;
1281
+ if ( prefix !== - 1 ) {
1282
+ newPrefix = callNodeIndexToDeduplicatedCallNodeIndex [ prefix ] ;
1283
+ prefixBloomBits1 = bloomBitsCol1 [ newPrefix ] ;
1284
+ prefixBloomBits2 = bloomBitsCol2 [ newPrefix ] ;
1285
+ prefixBloomBits3 = bloomBitsCol3 [ newPrefix ] ;
1286
+ prefixBloomBits4 = bloomBitsCol4 [ newPrefix ] ;
1287
+
1288
+ // Check if `func` is present in the newPrefix's call path.
1289
+ let funcIsAlreadyPresentInPrefix = false ;
1290
+
1291
+ const hashMatched =
1292
+ ( prefixBloomBits1 & funcBloomBits1 ) === funcBloomBits1 &&
1293
+ ( prefixBloomBits2 & funcBloomBits2 ) === funcBloomBits2 &&
1294
+ ( prefixBloomBits3 & funcBloomBits3 ) === funcBloomBits3 &&
1295
+ ( prefixBloomBits4 & funcBloomBits4 ) === funcBloomBits4 ;
1296
+ if ( hashMatched ) {
1297
+ let dedupIndex = newPrefix ;
1298
+ for ( let j = 0 ; ; j ++ ) {
1299
+ if ( funcCol [ dedupIndex ] === func ) {
1300
+ funcIsAlreadyPresentInPrefix = true ;
1301
+ break ;
1302
+ }
1303
+ dedupIndex = newPrefixCol [ dedupIndex ] ;
1304
+ if (
1305
+ dedupIndex === - 1 ||
1306
+ ( j % 2 === 0 &&
1307
+ ( ( bloomBitsCol1 [ dedupIndex ] & funcBloomBits1 ) !==
1308
+ funcBloomBits1 ||
1309
+ ( bloomBitsCol2 [ dedupIndex ] & funcBloomBits2 ) !==
1310
+ funcBloomBits2 ||
1311
+ ( bloomBitsCol3 [ dedupIndex ] & funcBloomBits3 ) !==
1312
+ funcBloomBits3 ||
1313
+ ( bloomBitsCol4 [ dedupIndex ] & funcBloomBits4 ) !==
1314
+ funcBloomBits4 ) )
1315
+ ) {
1316
+ break ;
1317
+ }
1253
1318
}
1254
1319
}
1255
-
1256
- if ( prefixHasFunc ) {
1320
+ if ( funcIsAlreadyPresentInPrefix ) {
1257
1321
// Drop this node.
1258
- callNodeIndexToDeduplicatedCallNodeIndex [ callNodeIndex ] = prefix ;
1322
+ callNodeIndexToDeduplicatedCallNodeIndex [ callNodeIndex ] = newPrefix ;
1259
1323
continue ;
1260
1324
}
1261
1325
}
1262
1326
1263
1327
// Create a node in the deduplicated call node table.
1264
- const newIndex = len ++ ;
1265
- prefixCol [ newIndex ] = prefix ;
1266
- funcCol [ newIndex ] = func ;
1267
- callNodeIndexToDeduplicatedCallNodeIndex [ callNodeIndex ] = newIndex ;
1328
+ newPrefixCol [ callNodeIndex ] = newPrefix ;
1329
+ bloomBitsCol1 [ callNodeIndex ] = prefixBloomBits1 | funcBloomBits1 ;
1330
+ bloomBitsCol2 [ callNodeIndex ] = prefixBloomBits2 | funcBloomBits2 ;
1331
+ bloomBitsCol3 [ callNodeIndex ] = prefixBloomBits3 | funcBloomBits3 ;
1332
+ bloomBitsCol4 [ callNodeIndex ] = prefixBloomBits4 | funcBloomBits4 ;
1333
+ callNodeIndexToDeduplicatedCallNodeIndex [ callNodeIndex ] = callNodeIndex ;
1268
1334
}
1269
1335
1336
+ // console.log({bloomBitsCol1: bloomBitsCol1.slice(0, 1000).map((num) => num.toString(2)) });
1337
+
1270
1338
const deduplicatedCallNodeTable = {
1271
- length : len ,
1272
- prefix : new Int32Array ( prefixCol ) ,
1273
- func : new Uint32Array ( funcCol ) ,
1339
+ length : callNodeCount ,
1340
+ prefix : newPrefixCol ,
1341
+ func : funcCol ,
1274
1342
} ;
1275
1343
1276
1344
return {
0 commit comments