From a37bee919a24c5e16092f6f2b2b1a12eb93b48e2 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Mon, 14 Mar 2022 14:48:42 +0000 Subject: [PATCH] LibJS: Use ranges instead of specifying all registers for NewArray Listing all the registers will lead to the inability to allocate enough space in one basic block (as there can be an arbitrary number of registers used), instead switch to specifying the range of registers used and save a lot of space in the process. --- .../Libraries/LibJS/Bytecode/ASTCodegen.cpp | 61 +++++++++++++------ Userland/Libraries/LibJS/Bytecode/Op.cpp | 2 +- Userland/Libraries/LibJS/Bytecode/Op.h | 10 +-- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index e770e7773b..5c8be88eb0 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -845,24 +845,33 @@ Bytecode::CodeGenerationErrorOr ObjectExpression::generate_bytecode(Byteco Bytecode::CodeGenerationErrorOr ArrayExpression::generate_bytecode(Bytecode::Generator& generator) const { Vector element_regs; + for (auto& element : m_elements) { + if (element && is(*element)) { + return Bytecode::CodeGenerationError { + this, + "Unimplemented element kind: SpreadExpression"sv, + }; + } + element_regs.append(generator.allocate_register()); + } + size_t i = 0; for (auto& element : m_elements) { if (element) { TRY(element->generate_bytecode(generator)); - if (is(*element)) { - return Bytecode::CodeGenerationError { - this, - "Unimplemented element kind: SpreadExpression"sv, - }; - } + if (is(*element)) + VERIFY_NOT_REACHED(); } else { generator.emit(Value {}); } - auto element_reg = generator.allocate_register(); + auto& element_reg = element_regs[i++]; generator.emit(element_reg); - element_regs.append(element_reg); } - generator.emit_with_extra_register_slots(element_regs.size(), element_regs); + if (element_regs.is_empty()) { + generator.emit(); + } else { + generator.emit_with_extra_register_slots(2u, AK::Array { element_regs.first(), element_regs.last() }); + } return {}; } @@ -1394,14 +1403,24 @@ Bytecode::CodeGenerationErrorOr TaggedTemplateLiteral::generate_bytecode(B for (size_t i = 0; i < expressions.size(); ++i) { if (i % 2 != 0) continue; - - TRY(expressions[i].generate_bytecode(generator)); - auto string_reg = generator.allocate_register(); - generator.emit(string_reg); - string_regs.append(string_reg); + string_regs.append(generator.allocate_register()); } - generator.emit_with_extra_register_slots(string_regs.size(), string_regs); + size_t reg_index = 0; + for (size_t i = 0; i < expressions.size(); ++i) { + if (i % 2 != 0) + continue; + + TRY(expressions[i].generate_bytecode(generator)); + auto string_reg = string_regs[reg_index++]; + generator.emit(string_reg); + } + + if (string_regs.is_empty()) { + generator.emit(); + } else { + generator.emit_with_extra_register_slots(2u, AK::Array { string_regs.first(), string_regs.last() }); + } auto strings_reg = generator.allocate_register(); generator.emit(strings_reg); @@ -1418,14 +1437,22 @@ Bytecode::CodeGenerationErrorOr TaggedTemplateLiteral::generate_bytecode(B } Vector raw_string_regs; + for ([[maybe_unused]] auto& raw_string : m_template_literal->raw_strings()) + string_regs.append(generator.allocate_register()); + + reg_index = 0; for (auto& raw_string : m_template_literal->raw_strings()) { TRY(raw_string.generate_bytecode(generator)); - auto raw_string_reg = generator.allocate_register(); + auto raw_string_reg = string_regs[reg_index++]; generator.emit(raw_string_reg); raw_string_regs.append(raw_string_reg); } - generator.emit_with_extra_register_slots(raw_string_regs.size(), raw_string_regs); + if (raw_string_regs.is_empty()) { + generator.emit(); + } else { + generator.emit_with_extra_register_slots(2u, AK::Array { raw_string_regs.first(), raw_string_regs.last() }); + } auto raw_strings_reg = generator.allocate_register(); generator.emit(raw_strings_reg); diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 795ae98e0e..942725271b 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -129,7 +129,7 @@ ThrowCompletionOr NewArray::execute_impl(Bytecode::Interpreter& interprete { auto* array = MUST(Array::create(interpreter.global_object(), 0)); for (size_t i = 0; i < m_element_count; i++) { - auto& value = interpreter.reg(m_elements[i]); + auto& value = interpreter.reg(Register(m_elements[0].index() + i)); array->indexed_properties().put(i, value, default_attributes); } interpreter.accumulator() = array; diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index b286e925e0..ced232b32e 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -232,12 +232,12 @@ public: { } - explicit NewArray(Vector const& elements) + explicit NewArray(AK::Array const& elements_range) : Instruction(Type::NewArray) - , m_element_count(elements.size()) + , m_element_count(elements_range[1].index() - elements_range[0].index() + 1) { - for (size_t i = 0; i < m_element_count; ++i) - m_elements[i] = elements[i]; + m_elements[0] = elements_range[0]; + m_elements[1] = elements_range[1]; } ThrowCompletionOr execute_impl(Bytecode::Interpreter&) const; @@ -246,7 +246,7 @@ public: size_t length_impl() const { - return sizeof(*this) + sizeof(Register) * m_element_count; + return sizeof(*this) + sizeof(Register) * (m_element_count == 0 ? 0 : 2); } private: