@@ -34,10 +34,10 @@ use wasmparser::{FuncValidatorAllocations, FunctionBody};
34
34
use wasmtime_environ:: obj:: { ELF_WASMTIME_EXCEPTIONS , ELF_WASMTIME_FRAMES } ;
35
35
use wasmtime_environ:: {
36
36
Abi , AddressMapSection , BuiltinFunctionIndex , CacheStore , CompileError , CompiledFunctionBody ,
37
- DefinedFuncIndex , FlagValue , FrameInstPos , FrameStackShape , FrameTableBuilder , FuncKey ,
38
- FunctionBodyData , FunctionLoc , HostCall , InliningCompiler , ModuleTranslation ,
39
- ModuleTypesBuilder , PtrSize , StackMapSection , StaticModuleIndex , TrapEncodingBuilder ,
40
- TrapSentinel , TripleExt , Tunables , VMOffsets , WasmFuncType , WasmValType ,
37
+ DefinedFuncIndex , FlagValue , FrameInstPos , FrameStackShape , FrameStateSlotBuilder ,
38
+ FrameTableBuilder , FuncKey , FunctionBodyData , FunctionLoc , HostCall , InliningCompiler ,
39
+ ModuleTranslation , ModuleTypesBuilder , PtrSize , StackMapSection , StaticModuleIndex ,
40
+ TrapEncodingBuilder , TrapSentinel , TripleExt , Tunables , VMOffsets , WasmFuncType , WasmValType ,
41
41
} ;
42
42
use wasmtime_unwinder:: ExceptionTableBuilder ;
43
43
@@ -56,6 +56,7 @@ struct CompilerContext {
56
56
codegen_context : Context ,
57
57
incremental_cache_ctx : Option < IncrementalCacheContext > ,
58
58
validator_allocations : FuncValidatorAllocations ,
59
+ debug_slot_descriptor : Option < FrameStateSlotBuilder > ,
59
60
abi : Option < Abi > ,
60
61
}
61
62
@@ -66,6 +67,7 @@ impl Default for CompilerContext {
66
67
codegen_context : Context :: new ( ) ,
67
68
incremental_cache_ctx : None ,
68
69
validator_allocations : Default :: default ( ) ,
70
+ debug_slot_descriptor : None ,
69
71
abi : None ,
70
72
}
71
73
}
@@ -329,13 +331,19 @@ impl wasmtime_environ::Compiler for Compiler {
329
331
. map_err ( |e| CompileError :: Codegen ( e. to_string ( ) ) ) ?;
330
332
}
331
333
334
+ let needs_gc_heap = func_env. needs_gc_heap ( ) ;
335
+
336
+ if let Some ( ( _, slot_builder) ) = func_env. state_slot {
337
+ compiler. cx . debug_slot_descriptor = Some ( slot_builder) ;
338
+ }
339
+
332
340
let timing = cranelift_codegen:: timing:: take_current ( ) ;
333
341
log:: debug!( "`{symbol}` translated to CLIF in {:?}" , timing. total( ) ) ;
334
342
log:: trace!( "`{symbol}` timing info\n {timing}" ) ;
335
343
336
344
Ok ( CompiledFunctionBody {
337
345
code : box_dyn_any_compiler_context ( Some ( compiler. cx ) ) ,
338
- needs_gc_heap : func_env . needs_gc_heap ( ) ,
346
+ needs_gc_heap,
339
347
} )
340
348
}
341
349
@@ -561,12 +569,12 @@ impl wasmtime_environ::Compiler for Compiler {
561
569
fn append_code (
562
570
& self ,
563
571
obj : & mut Object < ' static > ,
564
- funcs : & [ ( String , Box < dyn Any + Send + Sync > ) ] ,
572
+ funcs : & [ ( String , FuncKey , Box < dyn Any + Send + Sync > ) ] ,
565
573
resolve_reloc : & dyn Fn ( usize , FuncKey ) -> usize ,
566
574
) -> Result < Vec < ( SymbolId , FunctionLoc ) > > {
567
575
log:: trace!(
568
576
"appending functions to object file: {:#?}" ,
569
- funcs. iter( ) . map( |( sym, _) | sym) . collect:: <Vec <_>>( )
577
+ funcs. iter( ) . map( |( sym, _, _ ) | sym) . collect:: <Vec <_>>( )
570
578
) ;
571
579
572
580
let mut builder =
@@ -580,8 +588,24 @@ impl wasmtime_environ::Compiler for Compiler {
580
588
let mut exception_tables = ExceptionTableBuilder :: default ( ) ;
581
589
let mut frame_tables = FrameTableBuilder :: default ( ) ;
582
590
591
+ let mut frame_descriptors = HashMap :: new ( ) ;
592
+ if self . tunables . debug_instrumentation {
593
+ for ( _, key, func) in funcs {
594
+ debug_assert ! ( !func. is:: <Option <CompilerContext >>( ) ) ;
595
+ debug_assert ! ( func. is:: <CompiledFunction >( ) ) ;
596
+ let func = func. downcast_ref :: < CompiledFunction > ( ) . unwrap ( ) ;
597
+ frame_descriptors. insert (
598
+ * key,
599
+ func. debug_slot_descriptor
600
+ . as_ref ( )
601
+ . map ( |builder| builder. serialize ( ) )
602
+ . unwrap_or_else ( || vec ! [ ] ) ,
603
+ ) ;
604
+ }
605
+ }
606
+
583
607
let mut ret = Vec :: with_capacity ( funcs. len ( ) ) ;
584
- for ( i, ( sym, func) ) in funcs. iter ( ) . enumerate ( ) {
608
+ for ( i, ( sym, _key , func) ) in funcs. iter ( ) . enumerate ( ) {
585
609
debug_assert ! ( !func. is:: <Option <CompilerContext >>( ) ) ;
586
610
debug_assert ! ( func. is:: <CompiledFunction >( ) ) ;
587
611
let func = func. downcast_ref :: < CompiledFunction > ( ) . unwrap ( ) ;
@@ -614,6 +638,7 @@ impl wasmtime_environ::Compiler for Compiler {
614
638
range. clone ( ) ,
615
639
func. buffer . debug_tags ( ) ,
616
640
frame_layout,
641
+ & frame_descriptors,
617
642
) ?;
618
643
}
619
644
builder. append_padding ( self . linkopts . padding_between_functions ) ;
@@ -1405,6 +1430,10 @@ impl FunctionCompiler<'_> {
1405
1430
}
1406
1431
}
1407
1432
1433
+ if let Some ( builder) = self . cx . debug_slot_descriptor . take ( ) {
1434
+ compiled_function. debug_slot_descriptor = Some ( builder) ;
1435
+ }
1436
+
1408
1437
if body_and_tunables
1409
1438
. map ( |( _, t) | t. generate_native_debuginfo )
1410
1439
. unwrap_or ( false )
@@ -1477,8 +1506,9 @@ fn clif_to_env_frame_tables<'a>(
1477
1506
range : Range < u64 > ,
1478
1507
tag_sites : impl Iterator < Item = MachBufferDebugTagList < ' a > > ,
1479
1508
frame_layout : & MachBufferFrameLayout ,
1509
+ frame_descriptors : & HashMap < FuncKey , Vec < u8 > > ,
1480
1510
) -> anyhow:: Result < ( ) > {
1481
- let mut frame_descriptors = HashMap :: new ( ) ;
1511
+ let mut frame_descriptor_indices = HashMap :: new ( ) ;
1482
1512
for tag_site in tag_sites {
1483
1513
// Split into frames; each has three debug tags.
1484
1514
let mut frames = vec ! [ ] ;
@@ -1492,11 +1522,18 @@ fn clif_to_env_frame_tables<'a>(
1492
1522
panic ! ( "Invalid tags" ) ;
1493
1523
} ;
1494
1524
1495
- let frame_descriptor = * frame_descriptors. entry ( slot) . or_insert_with ( || {
1525
+ let func_key = frame_layout. stackslots [ slot]
1526
+ . key
1527
+ . expect ( "Key must be present on stackslot used as state slot" )
1528
+ . bits ( ) ;
1529
+ let func_key = FuncKey :: from_raw_u64 ( func_key) ;
1530
+ let frame_descriptor = * frame_descriptor_indices. entry ( slot) . or_insert_with ( || {
1496
1531
let slot_to_fp_offset =
1497
1532
frame_layout. frame_to_fp_offset - frame_layout. stackslots [ slot] . offset ;
1498
- let descriptor = frame_layout. stackslots [ slot] . descriptor . clone ( ) ;
1499
- builder. add_frame_descriptor ( slot_to_fp_offset, descriptor)
1533
+ let descriptor = frame_descriptors
1534
+ . get ( & func_key)
1535
+ . expect ( "frame descriptor not present for FuncKey" ) ;
1536
+ builder. add_frame_descriptor ( slot_to_fp_offset, & descriptor)
1500
1537
} ) ;
1501
1538
1502
1539
frames. push ( (
0 commit comments