mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 14:42:44 +00:00 
			
		
		
		
	Profiler: Display source location information in the disassembly view
With this, we can now have some amount of source-level profiling information :^)
This commit is contained in:
		
							parent
							
								
									c4437e19bd
								
							
						
					
					
						commit
						5d3b452897
					
				
					 2 changed files with 31 additions and 1 deletions
				
			
		|  | @ -7,6 +7,7 @@ | |||
| #include "DisassemblyModel.h" | ||||
| #include "Profile.h" | ||||
| #include <AK/MappedFile.h> | ||||
| #include <LibDebug/DebugInfo.h> | ||||
| #include <LibELF/Image.h> | ||||
| #include <LibGUI/Painter.h> | ||||
| #include <LibSymbolication/Symbolication.h> | ||||
|  | @ -75,6 +76,7 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node) | |||
|     X86::ELFSymbolProvider symbol_provider(*elf); | ||||
|     X86::SimpleInstructionStream stream((const u8*)view.characters_without_null_termination(), view.length()); | ||||
|     X86::Disassembler disassembler(stream); | ||||
|     Debug::DebugInfo debug_info { *elf, {}, base_address }; | ||||
| 
 | ||||
|     size_t offset_into_symbol = 0; | ||||
|     for (;;) { | ||||
|  | @ -89,7 +91,7 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node) | |||
|         u32 samples_at_this_instruction = m_node.events_per_address().get(address_in_profiled_program).value_or(0); | ||||
|         float percent = ((float)samples_at_this_instruction / (float)m_node.event_count()) * 100.0f; | ||||
| 
 | ||||
|         m_instructions.append({ insn.value(), disassembly, instruction_bytes, address_in_profiled_program, samples_at_this_instruction, percent }); | ||||
|         m_instructions.append({ insn.value(), disassembly, instruction_bytes, address_in_profiled_program, samples_at_this_instruction, percent, debug_info.get_source_position_with_inlines(address_in_profiled_program - base_address) }); | ||||
| 
 | ||||
|         offset_into_symbol += insn.value().length(); | ||||
|     } | ||||
|  | @ -115,6 +117,8 @@ String DisassemblyModel::column_name(int column) const | |||
|         return "Insn Bytes"; | ||||
|     case Column::Disassembly: | ||||
|         return "Disassembly"; | ||||
|     case Column::SourceLocation: | ||||
|         return "Source Location"; | ||||
|     default: | ||||
|         VERIFY_NOT_REACHED(); | ||||
|         return {}; | ||||
|  | @ -164,8 +168,10 @@ GUI::Variant DisassemblyModel::data(const GUI::ModelIndex& index, GUI::ModelRole | |||
|                 return ((float)insn.event_count / (float)m_node.event_count()) * 100.0f; | ||||
|             return insn.event_count; | ||||
|         } | ||||
| 
 | ||||
|         if (index.column() == Column::Address) | ||||
|             return String::formatted("{:p}", insn.address); | ||||
| 
 | ||||
|         if (index.column() == Column::InstructionBytes) { | ||||
|             StringBuilder builder; | ||||
|             for (auto ch : insn.bytes) { | ||||
|  | @ -173,8 +179,29 @@ GUI::Variant DisassemblyModel::data(const GUI::ModelIndex& index, GUI::ModelRole | |||
|             } | ||||
|             return builder.to_string(); | ||||
|         } | ||||
| 
 | ||||
|         if (index.column() == Column::Disassembly) | ||||
|             return insn.disassembly; | ||||
| 
 | ||||
|         if (index.column() == Column::SourceLocation) { | ||||
|             StringBuilder builder; | ||||
|             auto first = true; | ||||
|             for (auto& entry : insn.source_position_with_inlines.inline_chain) { | ||||
|                 if (first) | ||||
|                     first = false; | ||||
|                 else | ||||
|                     builder.append(" => "); | ||||
|                 builder.appendff("{}:{}", entry.file_path, entry.line_number); | ||||
|             } | ||||
|             if (insn.source_position_with_inlines.source_position.has_value()) { | ||||
|                 if (!first) | ||||
|                     builder.append(" => "); | ||||
|                 auto& entry = insn.source_position_with_inlines.source_position.value(); | ||||
|                 builder.appendff("{}:{}", entry.file_path, entry.line_number); | ||||
|             } | ||||
|             return builder.build(); | ||||
|         } | ||||
| 
 | ||||
|         return {}; | ||||
|     } | ||||
|     return {}; | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <LibDebug/DebugInfo.h> | ||||
| #include <LibGUI/Model.h> | ||||
| #include <LibX86/Instruction.h> | ||||
| 
 | ||||
|  | @ -21,6 +22,7 @@ struct InstructionData { | |||
|     FlatPtr address { 0 }; | ||||
|     u32 event_count { 0 }; | ||||
|     float percent { 0 }; | ||||
|     Debug::DebugInfo::SourcePositionWithInlines source_position_with_inlines; | ||||
| }; | ||||
| 
 | ||||
| class DisassemblyModel final : public GUI::Model { | ||||
|  | @ -35,6 +37,7 @@ public: | |||
|         SampleCount, | ||||
|         InstructionBytes, | ||||
|         Disassembly, | ||||
|         SourceLocation, | ||||
|         __Count | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ali Mohammad Pur
						Ali Mohammad Pur