BasicBlock.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/DeprecatedString.h>
  7. #include <LibJS/Bytecode/BasicBlock.h>
  8. #include <LibJS/Bytecode/Op.h>
  9. namespace JS::Bytecode {
  10. NonnullOwnPtr<BasicBlock> BasicBlock::create(DeprecatedString name, size_t size)
  11. {
  12. return adopt_own(*new BasicBlock(move(name), max(size, static_cast<size_t>(4 * KiB))));
  13. }
  14. BasicBlock::BasicBlock(DeprecatedString name, size_t size)
  15. : m_name(move(name))
  16. {
  17. // FIXME: This is not the smartest solution ever. Find something cleverer!
  18. // The main issue we're working around here is that we don't want pointers into the bytecode stream to become invalidated
  19. // during code generation due to dynamic buffer resizing. Otherwise we could just use a Vector.
  20. m_buffer_capacity = size;
  21. m_buffer = new u8[m_buffer_capacity];
  22. }
  23. BasicBlock::~BasicBlock()
  24. {
  25. Bytecode::InstructionStreamIterator it(instruction_stream());
  26. while (!it.at_end()) {
  27. auto& to_destroy = (*it);
  28. ++it;
  29. Instruction::destroy(const_cast<Instruction&>(to_destroy));
  30. }
  31. delete[] m_buffer;
  32. }
  33. void BasicBlock::seal()
  34. {
  35. // FIXME: mprotect the instruction stream as PROT_READ
  36. // This is currently not possible because instructions can have destructors (that clean up strings)
  37. // Instructions should instead be destructor-less and refer to strings in a string table on the Bytecode::Block.
  38. // It also doesn't work because instructions that have String members use RefPtr internally which must be in writable memory.
  39. }
  40. void BasicBlock::dump(Bytecode::Executable const& executable) const
  41. {
  42. Bytecode::InstructionStreamIterator it(instruction_stream());
  43. if (!m_name.is_empty())
  44. warnln("{}:", m_name);
  45. while (!it.at_end()) {
  46. warnln("[{:4x}] {}", it.offset(), (*it).to_deprecated_string(executable));
  47. ++it;
  48. }
  49. }
  50. void BasicBlock::grow(size_t additional_size)
  51. {
  52. m_buffer_size += additional_size;
  53. VERIFY(m_buffer_size <= m_buffer_capacity);
  54. }
  55. }