NativeExecutable.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/Bytecode/Interpreter.h>
  7. #include <LibJS/JIT/NativeExecutable.h>
  8. #include <LibJS/Runtime/VM.h>
  9. #include <LibX86/Disassembler.h>
  10. #include <sys/mman.h>
  11. namespace JS::JIT {
  12. NativeExecutable::NativeExecutable(void* code, size_t size, Vector<BytecodeMapping> mapping)
  13. : m_code(code)
  14. , m_size(size)
  15. , m_mapping(move(mapping))
  16. {
  17. }
  18. NativeExecutable::~NativeExecutable()
  19. {
  20. munmap(m_code, m_size);
  21. }
  22. void NativeExecutable::run(VM& vm) const
  23. {
  24. typedef void (*JITCode)(VM&, Value* registers, Value* locals);
  25. ((JITCode)m_code)(vm,
  26. vm.bytecode_interpreter().registers().data(),
  27. vm.running_execution_context().local_variables.data());
  28. }
  29. void NativeExecutable::dump_disassembly() const
  30. {
  31. #if ARCH(X86_64)
  32. auto const* code_bytes = static_cast<u8 const*>(m_code);
  33. auto stream = X86::SimpleInstructionStream { code_bytes, m_size };
  34. auto disassembler = X86::Disassembler(stream);
  35. while (true) {
  36. auto offset = stream.offset();
  37. auto virtual_offset = bit_cast<size_t>(m_code) + offset;
  38. auto insn = disassembler.next();
  39. if (!insn.has_value())
  40. break;
  41. StringBuilder builder;
  42. builder.appendff("{:p} ", virtual_offset);
  43. auto length = insn.value().length();
  44. for (size_t i = 0; i < 7; i++) {
  45. if (i < length)
  46. builder.appendff("{:02x} ", code_bytes[offset + i]);
  47. else
  48. builder.append(" "sv);
  49. }
  50. builder.append(" "sv);
  51. builder.append(insn.value().to_deprecated_string(virtual_offset, nullptr));
  52. dbgln("{}", builder.string_view());
  53. for (size_t bytes_printed = 7; bytes_printed < length; bytes_printed += 7) {
  54. builder.clear();
  55. builder.appendff("{:p} ", virtual_offset + bytes_printed);
  56. for (size_t i = bytes_printed; i < bytes_printed + 7 && i < length; i++)
  57. builder.appendff(" {:02x}", code_bytes[offset + i]);
  58. dbgln("{}", builder.string_view());
  59. }
  60. }
  61. #endif
  62. }
  63. }