@@ -568,20 +568,35 @@ const BenchmarkState = Object.freeze({
568568
569569
570570class Scripts {
571- constructor ( ) {
571+ constructor ( preloads ) {
572572 this . scripts = [ ] ;
573+
574+ let preloadsCode = "" ;
575+ let resourcesCode = "" ;
576+ for ( let { name, resource, blobURLOrPath } of preloads ) {
577+ console . assert ( name ?. length > 0 , "Invalid preload name." ) ;
578+ console . assert ( resource ?. length > 0 , "Invalid preload resource." ) ;
579+ console . assert ( blobURLOrPath ?. length > 0 , "Invalid preload data." ) ;
580+ preloadsCode += `${ JSON . stringify ( name ) } : "${ blobURLOrPath } ",\n` ;
581+ resourcesCode += `${ JSON . stringify ( resource ) } : "${ blobURLOrPath } ",\n` ;
582+ }
573583 // Expose a globalThis.JetStream object to the workload. We use
574584 // a proxy to prevent prototype access and throw on unknown properties.
575585 this . add ( `
576586 const throwOnAccess = (name) => new Proxy({}, {
577587 get(target, property, receiver) {
578588 throw new Error(name + "." + property + " is not defined.");
579589 }
580- });
590+ });
581591 globalThis.JetStream = {
582592 __proto__: throwOnAccess("JetStream"),
583593 preload: {
584594 __proto__: throwOnAccess("JetStream.preload"),
595+ ${ preloadsCode }
596+ },
597+ resources: {
598+ __proto__: throwOnAccess("JetStream.preload"),
599+ ${ resourcesCode }
585600 },
586601 };
587602 ` ) ;
@@ -639,8 +654,8 @@ class Scripts {
639654}
640655
641656class ShellScripts extends Scripts {
642- constructor ( ) {
643- super ( ) ;
657+ constructor ( preloads ) {
658+ super ( preloads ) ;
644659 this . prefetchedResources = Object . create ( null ) ; ;
645660 }
646661
@@ -706,8 +721,8 @@ class ShellScripts extends Scripts {
706721}
707722
708723class BrowserScripts extends Scripts {
709- constructor ( ) {
710- super ( ) ;
724+ constructor ( preloads ) {
725+ super ( preloads ) ;
711726 this . add ( "window.onerror = top.currentReject;" ) ;
712727 }
713728
@@ -746,7 +761,7 @@ class Benchmark {
746761 this . isAsync = ! ! plan . isAsync ;
747762 this . allowUtf16 = ! ! plan . allowUtf16 ;
748763 this . scripts = null ;
749- this . preloads = null ;
764+ this . preloads = [ ] ;
750765 this . shellPrefetchedResources = null ;
751766 this . results = [ ] ;
752767 this . _state = BenchmarkState . READY ;
@@ -850,8 +865,9 @@ class Benchmark {
850865
851866 get prerunCode ( ) { return null ; }
852867
868+
853869 get preIterationCode ( ) {
854- let code = `benchmark.prepareForNextIteration?.();` ;
870+ let code = this . prepareForNextIterationCode ;
855871 if ( this . plan . deterministicRandom )
856872 code += `Math.random.__resetSeed();` ;
857873
@@ -861,6 +877,10 @@ class Benchmark {
861877 return code ;
862878 }
863879
880+ get prepareForNextIterationCode ( ) {
881+ return "benchmark.prepareForNextIteration?.();"
882+ }
883+
864884 get postIterationCode ( ) {
865885 let code = "" ;
866886
@@ -901,7 +921,7 @@ class Benchmark {
901921 if ( this . isDone )
902922 throw new Error ( `Cannot run Benchmark ${ this . name } twice` ) ;
903923 this . _state = BenchmarkState . PREPARE ;
904- const scripts = isInBrowser ? new BrowserScripts ( ) : new ShellScripts ( ) ;
924+ const scripts = isInBrowser ? new BrowserScripts ( this . preloads ) : new ShellScripts ( this . preloads ) ;
905925
906926 if ( ! ! this . plan . deterministicRandom )
907927 scripts . addDeterministicRandom ( )
@@ -911,15 +931,6 @@ class Benchmark {
911931 if ( this . shellPrefetchedResources ) {
912932 scripts . addPrefetchedResources ( this . shellPrefetchedResources ) ;
913933 }
914- if ( this . plan . preload ) {
915- let preloadCode = "" ;
916- for ( let [ variableName , blobURLOrPath ] of this . preloads ) {
917- console . assert ( variableName ?. length > 0 , "Invalid preload name." ) ;
918- console . assert ( blobURLOrPath ?. length > 0 , "Invalid preload data." ) ;
919- preloadCode += `JetStream.preload[${ JSON . stringify ( variableName ) } ] = "${ blobURLOrPath } ";\n` ;
920- }
921- scripts . add ( preloadCode ) ;
922- }
923934
924935 const prerunCode = this . prerunCode ;
925936 if ( prerunCode )
@@ -1070,12 +1081,11 @@ class Benchmark {
10701081 } ) ) ;
10711082
10721083 if ( this . plan . preload ) {
1073- this . preloads = [ ] ;
10741084 for ( const [ name , resource ] of Object . entries ( this . plan . preload ) ) {
10751085 promises . push ( this . loadBlob ( "preload" , name , resource ) . then ( ( blobData ) => {
10761086 if ( ! globalThis . allIsGood )
10771087 return ;
1078- this . preloads . push ( [ blobData . prop , blobData . blobURL ] ) ;
1088+ this . preloads . push ( { name : blobData . prop , resource : blobData . resource , blobURLOrPath : blobData . blobURL } ) ;
10791089 this . updateCounter ( ) ;
10801090 } ) . catch ( ( error ) => {
10811091 // We'll try again later in retryPrefetchResourceForBrowser(). Don't throw an error.
@@ -1102,7 +1112,7 @@ class Benchmark {
11021112 if ( type == "preload" ) {
11031113 if ( this . failedPreloads && this . failedPreloads [ blobData . prop ] ) {
11041114 this . failedPreloads [ blobData . prop ] = false ;
1105- this . preloads . push ( [ blobData . prop , blobData . blobURL ] ) ;
1115+ this . preloads . push ( { name : blobData . prop , resource : blobData . resource , blobURLOrPath : blobData . blobURL } ) ;
11061116 counter . failedPreloadResources -- ;
11071117 }
11081118 }
@@ -1115,7 +1125,7 @@ class Benchmark {
11151125 if ( ! globalThis . allIsGood )
11161126 return ;
11171127 if ( blobData . type == "preload" )
1118- this . preloads . push ( [ blobData . prop , blobData . blobURL ] ) ;
1128+ this . preloads . push ( { name : blobData . prop , resource : blobData . resource , blobURLOrPath : blobData . blobURL } ) ;
11191129 this . updateCounter ( ) ;
11201130 } ) ;
11211131
@@ -1153,8 +1163,7 @@ class Benchmark {
11531163 console . assert ( this . scripts === null , "This initialization should be called only once." ) ;
11541164 this . scripts = this . plan . files . map ( file => shellFileLoader . load ( file ) ) ;
11551165
1156- console . assert ( this . preloads === null , "This initialization should be called only once." ) ;
1157- this . preloads = [ ] ;
1166+ console . assert ( this . preloads . length === 0 , "This initialization should be called only once." ) ;
11581167 this . shellPrefetchedResources = Object . create ( null ) ;
11591168 if ( ! this . plan . preload ) {
11601169 return ;
@@ -1173,7 +1182,7 @@ class Benchmark {
11731182 this . shellPrefetchedResources [ resource ] = bytes ;
11741183 }
11751184
1176- this . preloads . push ( [ name , resource ] ) ;
1185+ this . preloads . push ( { name, resource, blobURLOrPath : resource } ) ;
11771186 }
11781187 }
11791188
@@ -1527,6 +1536,10 @@ class AsyncBenchmark extends DefaultBenchmark {
15271536 return str ;
15281537 }
15291538
1539+ get prepareForNextIterationCode ( ) {
1540+ return "await benchmark.prepareForNextIteration?.();"
1541+ }
1542+
15301543 get runnerCode ( ) {
15311544 return `
15321545 async function doRun() {
@@ -2515,8 +2528,8 @@ let BENCHMARKS = [
25152528 inputFontItalic : "./Kotlin-compose/build/jetbrainsmono_italic.ttf" ,
25162529 inputFontRegular : "./Kotlin-compose/build/jetbrainsmono_regular.ttf"
25172530 } ,
2518- iterations : 15 ,
2519- worstCaseCount : 2 ,
2531+ iterations : 5 ,
2532+ worstCaseCount : 1 ,
25202533 tags : [ "default" , "Wasm" ] ,
25212534 } ) ,
25222535 new AsyncBenchmark ( {
0 commit comments