@@ -26,7 +26,7 @@ use crate::Engine;
2626use crate :: hash_map:: HashMap ;
2727use crate :: hash_set:: HashSet ;
2828use crate :: prelude:: * ;
29- use std:: { any:: Any , borrow:: Cow , collections :: BTreeMap , mem, ops:: Range } ;
29+ use std:: { any:: Any , borrow:: Cow , mem, ops:: Range } ;
3030use wasmtime_environ:: {
3131 Abi , CompiledFunctionBody , CompiledFunctionsTable , CompiledFunctionsTableBuilder ,
3232 CompiledModuleInfo , Compiler , DefinedFuncIndex , FilePos , FinishedObject , FuncKey ,
@@ -655,11 +655,10 @@ the use case.
655655 // compiled.
656656 compile_required_builtins ( engine, types, & mut raw_outputs) ?;
657657
658- // Bucket the outputs by kind.
659- let mut outputs: BTreeMap < FuncKey , CompileOutput > = BTreeMap :: new ( ) ;
660- for output in raw_outputs {
661- outputs. insert ( output. key , output) ;
662- }
658+ // Sort the outputs by their `FuncKey` which enables deterministically
659+ // linking this output by function kind.
660+ let mut outputs = raw_outputs;
661+ outputs. sort_unstable_by_key ( |output| output. key ) ;
663662
664663 Ok ( UnlinkedCompileOutputs { outputs } )
665664 }
@@ -1045,8 +1044,8 @@ fn compile_required_builtins<'a>(
10451044
10461045#[ derive( Default ) ]
10471046struct UnlinkedCompileOutputs < ' a > {
1048- // A map from kind to `CompileOutput `.
1049- outputs : BTreeMap < FuncKey , CompileOutput < ' a > > ,
1047+ // The compile outputs, sorted by `FuncKey `.
1048+ outputs : Vec < CompileOutput < ' a > > ,
10501049}
10511050
10521051impl UnlinkedCompileOutputs < ' _ > {
@@ -1065,14 +1064,16 @@ impl UnlinkedCompileOutputs<'_> {
10651064 // trampolines, are not interspersed between hot Wasm functions, and (b)
10661065 // Wasm functions that are likely to call each other (i.e. are in the
10671066 // same module together) are grouped together.
1068- let mut compiled_funcs = vec ! [ ] ;
1067+ let num_funcs = self . outputs . len ( ) ;
1068+ let mut compiled_funcs = Vec :: with_capacity ( num_funcs) ;
10691069
1070- let mut indices = FunctionIndices :: default ( ) ;
1070+ let mut indices = FunctionIndices {
1071+ start_srclocs : HashMap :: with_capacity ( num_funcs) ,
1072+ indices : HashMap :: with_capacity ( num_funcs) ,
1073+ } ;
10711074 let mut needs_gc_heap = false ;
10721075
1073- // NB: Iteration over this `BTreeMap` ensures that we uphold
1074- // `compiled_func`'s sorted property.
1075- for output in self . outputs . into_values ( ) {
1076+ for output in self . outputs {
10761077 needs_gc_heap |= output. function . needs_gc_heap ;
10771078
10781079 let index = compiled_funcs. len ( ) ;
@@ -1114,7 +1115,7 @@ struct FunctionIndices {
11141115 start_srclocs : HashMap < FuncKey , FilePos > ,
11151116
11161117 // The index of each compiled function in `compiled_funcs`.
1117- indices : BTreeMap < FuncKey , usize > ,
1118+ indices : HashMap < FuncKey , usize > ,
11181119}
11191120
11201121impl FunctionIndices {
@@ -1162,14 +1163,13 @@ impl FunctionIndices {
11621163 }
11631164
11641165 let mut table_builder = CompiledFunctionsTableBuilder :: new ( ) ;
1165- for ( key, compiled_func_index) in & self . indices {
1166- let ( _, func_loc) = symbol_ids_and_locs[ * compiled_func_index] ;
1166+ for ( ( _, key, _) , ( _, func_loc) ) in compiled_funcs. iter ( ) . zip ( & symbol_ids_and_locs) {
11671167 let src_loc = self
11681168 . start_srclocs
11691169 . get ( key)
11701170 . copied ( )
11711171 . unwrap_or_else ( FilePos :: none) ;
1172- table_builder. push_func ( * key, func_loc, src_loc) ;
1172+ table_builder. push_func ( * key, * func_loc, src_loc) ;
11731173 }
11741174
11751175 let mut obj = wasmtime_environ:: ObjectBuilder :: new ( obj, tunables) ;
0 commit comments