code: func annotateAssembly(insts []plugin.Inst, samples graph.Nodes, base uint64) []assemblyInstruction {
  	// Add end marker to simplify printing loop.
  	insts = append(insts, plugin.Inst{
  		Addr: ^uint64(0),
  	})
  
  	// Ensure samples are sorted by address.
  	samples.Sort(graph.AddressOrder)
  
  	s := 0
  	asm := make([]assemblyInstruction, 0, len(insts))
  	for ix, in := range insts[:len(insts)-1] {
  		n := assemblyInstruction{
  			address:     in.Addr,
  			instruction: in.Text,
  			function:    in.Function,
  			line:        in.Line,
  		}
  		if in.File != "" {
  			n.file = filepath.Base(in.File)
  		}
  
  		// Sum all the samples until the next instruction (to account
  		// for samples attributed to the middle of an instruction).
  		for next := insts[ix+1].Addr; s < len(samples) && samples[s].Info.Address-base < next; s++ {
  			sample := samples[s]
  			n.flatDiv += sample.FlatDiv
  			n.flat += sample.Flat
  			n.cumDiv += sample.CumDiv
  			n.cum += sample.Cum
  			if f := sample.Info.File; f != "" && n.file == "" {
  				n.file = filepath.Base(f)
  			}
  			if ln := sample.Info.Lineno; ln != 0 && n.line == 0 {
  				n.line = ln
  			}
  			if f := sample.Info.Name; f != "" && n.function == "" {
  				n.function = f
  			}
  		}
  		asm = append(asm, n)
  	}
  
  	return asm
  }
docs: // annotateAssembly annotates a set of assembly instructions with a
  // set of samples. It returns a set of nodes to display. base is an
  // offset to adjust the sample addresses.