mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 14:42:44 +00:00 
			
		
		
		
	LibJS/JIT: Dump disassembly of generated code using LibX86
This avoids the need for redirecting stdout to a file and using ndisasm, which can lead to problems if other things are printed.
This commit is contained in:
		
							parent
							
								
									1d68c64b98
								
							
						
					
					
						commit
						ec8330b647
					
				
					 4 changed files with 48 additions and 1 deletions
				
			
		|  | @ -268,3 +268,6 @@ set(SOURCES | |||
| 
 | ||||
| serenity_lib(LibJS js) | ||||
| target_link_libraries(LibJS PRIVATE LibCore LibCrypto LibFileSystem LibRegex LibSyntax LibLocale LibUnicode LibJIT) | ||||
| if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") | ||||
|     target_link_libraries(LibJS PRIVATE LibX86) | ||||
| endif() | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ | |||
| #    define LOG_JIT_SUCCESS 1 | ||||
| #    define LOG_JIT_FAILURE 1 | ||||
| #    define DUMP_JIT_MACHINE_CODE_TO_STDOUT 0 | ||||
| #    define DUMP_JIT_DISASSEMBLY 0 | ||||
| 
 | ||||
| #    define TRY_OR_SET_EXCEPTION(expression)                                                                                        \ | ||||
|         ({                                                                                                                          \ | ||||
|  | @ -1154,7 +1155,10 @@ OwnPtr<NativeExecutable> Compiler::compile(Bytecode::Executable& bytecode_execut | |||
|         dbgln("\033[32;1mJIT compilation succeeded!\033[0m {}", bytecode_executable.name); | ||||
|     } | ||||
| 
 | ||||
|     return make<NativeExecutable>(executable_memory, compiler.m_output.size()); | ||||
|     auto executable = make<NativeExecutable>(executable_memory, compiler.m_output.size()); | ||||
|     if constexpr (DUMP_JIT_DISASSEMBLY) | ||||
|         executable->dump_disassembly(); | ||||
|     return executable; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ | |||
| #include <LibJS/Bytecode/Interpreter.h> | ||||
| #include <LibJS/JIT/NativeExecutable.h> | ||||
| #include <LibJS/Runtime/VM.h> | ||||
| #include <LibX86/Disassembler.h> | ||||
| #include <sys/mman.h> | ||||
| 
 | ||||
| namespace JS::JIT { | ||||
|  | @ -30,4 +31,42 @@ void NativeExecutable::run(VM& vm) const | |||
|         vm.running_execution_context().local_variables.data()); | ||||
| } | ||||
| 
 | ||||
| void NativeExecutable::dump_disassembly() const | ||||
| { | ||||
| #if ARCH(X86_64) | ||||
|     auto const* code_bytes = static_cast<u8 const*>(m_code); | ||||
|     auto stream = X86::SimpleInstructionStream { code_bytes, m_size }; | ||||
|     auto disassembler = X86::Disassembler(stream); | ||||
| 
 | ||||
|     while (true) { | ||||
|         auto offset = stream.offset(); | ||||
|         auto virtual_offset = bit_cast<size_t>(m_code) + offset; | ||||
|         auto insn = disassembler.next(); | ||||
|         if (!insn.has_value()) | ||||
|             break; | ||||
| 
 | ||||
|         StringBuilder builder; | ||||
|         builder.appendff("{:p}  ", virtual_offset); | ||||
|         auto length = insn.value().length(); | ||||
|         for (size_t i = 0; i < 7; i++) { | ||||
|             if (i < length) | ||||
|                 builder.appendff("{:02x} ", code_bytes[offset + i]); | ||||
|             else | ||||
|                 builder.append("   "sv); | ||||
|         } | ||||
|         builder.append(" "sv); | ||||
|         builder.append(insn.value().to_deprecated_string(virtual_offset, nullptr)); | ||||
|         dbgln("{}", builder.string_view()); | ||||
| 
 | ||||
|         for (size_t bytes_printed = 7; bytes_printed < length; bytes_printed += 7) { | ||||
|             builder.clear(); | ||||
|             builder.appendff("{:p} ", virtual_offset + bytes_printed); | ||||
|             for (size_t i = bytes_printed; i < bytes_printed + 7 && i < length; i++) | ||||
|                 builder.appendff(" {:02x}", code_bytes[offset + i]); | ||||
|             dbgln("{}", builder.string_view()); | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ public: | |||
|     ~NativeExecutable(); | ||||
| 
 | ||||
|     void run(VM&) const; | ||||
|     void dump_disassembly() const; | ||||
| 
 | ||||
| private: | ||||
|     void* m_code { nullptr }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Simon Wanner
						Simon Wanner