@@ -229,19 +229,28 @@ impl StackMapSink {
229229fn get_function_address_map < ' data > (
230230 context : & Context ,
231231 data : & FunctionBodyData < ' data > ,
232- body_len : usize ,
232+ body_len : u32 ,
233233 isa : & dyn isa:: TargetIsa ,
234234) -> FunctionAddressMap {
235+ // Generate artificial srcloc for function start/end to identify boundary
236+ // within module.
237+ let data = data. body . get_binary_reader ( ) ;
238+ let offset = data. original_position ( ) ;
239+ let len = data. bytes_remaining ( ) ;
240+ assert ! ( ( offset + len) <= u32 :: max_value( ) as usize ) ;
241+ let start_srcloc = ir:: SourceLoc :: new ( offset as u32 ) ;
242+ let end_srcloc = ir:: SourceLoc :: new ( ( offset + len) as u32 ) ;
243+
235244 let instructions = if let Some ( ref mcr) = & context. mach_compile_result {
236245 // New-style backend: we have a `MachCompileResult` that will give us `MachSrcLoc` mapping
237246 // tuples.
238- collect_address_maps ( mcr . buffer . get_srclocs_sorted ( ) . into_iter ( ) . map (
239- | & MachSrcLoc { start , end , loc } | InstructionAddressMap {
240- srcloc : loc ,
241- code_offset : start as usize ,
242- code_len : ( end - start ) as usize ,
243- } ,
244- ) )
247+ collect_address_maps (
248+ body_len ,
249+ mcr . buffer
250+ . get_srclocs_sorted ( )
251+ . into_iter ( )
252+ . map ( | & MachSrcLoc { start , end , loc } | ( loc , start , ( end - start ) ) ) ,
253+ )
245254 } else {
246255 // Old-style backend: we need to traverse the instruction/encoding info in the function.
247256 let func = & context. func ;
@@ -250,28 +259,16 @@ fn get_function_address_map<'data>(
250259
251260 let encinfo = isa. encoding_info ( ) ;
252261 collect_address_maps (
262+ body_len,
253263 blocks
254264 . into_iter ( )
255265 . flat_map ( |block| func. inst_offsets ( block, & encinfo) )
256- . map ( |( offset, inst, size) | InstructionAddressMap {
257- srcloc : func. srclocs [ inst] ,
258- code_offset : offset as usize ,
259- code_len : size as usize ,
260- } ) ,
266+ . map ( |( offset, inst, size) | ( func. srclocs [ inst] , offset, size) ) ,
261267 )
262268 } ;
263269
264- // Generate artificial srcloc for function start/end to identify boundary
265- // within module. Similar to FuncTranslator::cur_srcloc(): it will wrap around
266- // if byte code is larger than 4 GB.
267- let data = data. body . get_binary_reader ( ) ;
268- let offset = data. original_position ( ) ;
269- let len = data. bytes_remaining ( ) ;
270- let start_srcloc = ir:: SourceLoc :: new ( offset as u32 ) ;
271- let end_srcloc = ir:: SourceLoc :: new ( ( offset + len) as u32 ) ;
272-
273270 FunctionAddressMap {
274- instructions,
271+ instructions : instructions . into ( ) ,
275272 start_srcloc,
276273 end_srcloc,
277274 body_offset : 0 ,
@@ -283,23 +280,54 @@ fn get_function_address_map<'data>(
283280// into a `FunctionAddressMap`. This will automatically coalesce adjacent
284281// instructions which map to the same original source position.
285282fn collect_address_maps (
286- iter : impl IntoIterator < Item = InstructionAddressMap > ,
283+ code_size : u32 ,
284+ iter : impl IntoIterator < Item = ( ir:: SourceLoc , u32 , u32 ) > ,
287285) -> Vec < InstructionAddressMap > {
288286 let mut iter = iter. into_iter ( ) ;
289- let mut cur = match iter. next ( ) {
287+ let ( mut cur_loc , mut cur_offset , mut cur_len ) = match iter. next ( ) {
290288 Some ( i) => i,
291289 None => return Vec :: new ( ) ,
292290 } ;
293291 let mut ret = Vec :: new ( ) ;
294- for item in iter {
295- if cur. code_offset + cur. code_len == item. code_offset && item. srcloc == cur. srcloc {
296- cur. code_len += item. code_len ;
297- } else {
298- ret. push ( cur) ;
299- cur = item;
292+ for ( loc, offset, len) in iter {
293+ // If this instruction is adjacent to the previous and has the same
294+ // source location then we can "coalesce" it with the current
295+ // instruction.
296+ if cur_offset + cur_len == offset && loc == cur_loc {
297+ cur_len += len;
298+ continue ;
300299 }
300+
301+ // Push an entry for the previous source item.
302+ ret. push ( InstructionAddressMap {
303+ srcloc : cur_loc,
304+ code_offset : cur_offset,
305+ } ) ;
306+ // And push a "dummy" entry if necessary to cover the span of ranges,
307+ // if any, between the previous source offset and this one.
308+ if cur_offset + cur_len != offset {
309+ ret. push ( InstructionAddressMap {
310+ srcloc : ir:: SourceLoc :: default ( ) ,
311+ code_offset : cur_offset + cur_len,
312+ } ) ;
313+ }
314+ // Update our current location to get extended later or pushed on at
315+ // the end.
316+ cur_loc = loc;
317+ cur_offset = offset;
318+ cur_len = len;
301319 }
302- ret. push ( cur) ;
320+ ret. push ( InstructionAddressMap {
321+ srcloc : cur_loc,
322+ code_offset : cur_offset,
323+ } ) ;
324+ if cur_offset + cur_len != code_size {
325+ ret. push ( InstructionAddressMap {
326+ srcloc : ir:: SourceLoc :: default ( ) ,
327+ code_offset : cur_offset + cur_len,
328+ } ) ;
329+ }
330+
303331 return ret;
304332}
305333
@@ -406,7 +434,8 @@ impl Compiler for Cranelift {
406434 CompileError :: Codegen ( pretty_error ( & context. func , Some ( isa) , error) )
407435 } ) ?;
408436
409- let address_transform = get_function_address_map ( & context, & input, code_buf. len ( ) , isa) ;
437+ let address_transform =
438+ get_function_address_map ( & context, & input, code_buf. len ( ) as u32 , isa) ;
410439
411440 let ranges = if tunables. debug_info {
412441 let ranges = context. build_value_labels_ranges ( isa) . map_err ( |error| {
0 commit comments