| Index: src/interpreter/bytecode-array-builder.cc
|
| diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc
|
| index 4a1602a1d6ea6c3749cc74b30111c53a4cd1e730..4403c8e14178f08db52e7cd8fe1b12039155559a 100644
|
| --- a/src/interpreter/bytecode-array-builder.cc
|
| +++ b/src/interpreter/bytecode-array-builder.cc
|
| @@ -64,7 +64,9 @@ class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED {
|
| DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper);
|
| };
|
|
|
| -BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
|
| +BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone,
|
| + int parameter_count,
|
| + int context_count, int locals_count)
|
| : isolate_(isolate),
|
| zone_(zone),
|
| bytecodes_(zone),
|
| @@ -75,32 +77,17 @@ BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
|
| last_bytecode_start_(~0),
|
| exit_seen_in_block_(false),
|
| unbound_jumps_(0),
|
| - parameter_count_(-1),
|
| - local_register_count_(-1),
|
| - context_register_count_(-1),
|
| - temporary_register_count_(0),
|
| - free_temporaries_(zone),
|
| - register_translator_(this) {}
|
| -
|
| -BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); }
|
| -
|
| -
|
| -void BytecodeArrayBuilder::set_locals_count(int number_of_locals) {
|
| - local_register_count_ = number_of_locals;
|
| - DCHECK_LE(context_register_count_, 0);
|
| -}
|
| -
|
| -
|
| -void BytecodeArrayBuilder::set_parameter_count(int number_of_parameters) {
|
| - parameter_count_ = number_of_parameters;
|
| -}
|
| -
|
| -
|
| -void BytecodeArrayBuilder::set_context_count(int number_of_contexts) {
|
| - context_register_count_ = number_of_contexts;
|
| + parameter_count_(parameter_count),
|
| + local_register_count_(locals_count),
|
| + context_register_count_(context_count),
|
| + temporary_allocator_(zone, fixed_register_count()),
|
| + register_translator_(this) {
|
| + DCHECK_GE(parameter_count_, 0);
|
| + DCHECK_GE(context_register_count_, 0);
|
| DCHECK_GE(local_register_count_, 0);
|
| }
|
|
|
| +BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); }
|
|
|
| Register BytecodeArrayBuilder::first_context_register() const {
|
| DCHECK_GT(context_register_count_, 0);
|
| @@ -114,18 +101,6 @@ Register BytecodeArrayBuilder::last_context_register() const {
|
| }
|
|
|
|
|
| -Register BytecodeArrayBuilder::first_temporary_register() const {
|
| - DCHECK_GT(temporary_register_count_, 0);
|
| - return Register(fixed_register_count());
|
| -}
|
| -
|
| -
|
| -Register BytecodeArrayBuilder::last_temporary_register() const {
|
| - DCHECK_GT(temporary_register_count_, 0);
|
| - return Register(fixed_register_count() + temporary_register_count_ - 1);
|
| -}
|
| -
|
| -
|
| Register BytecodeArrayBuilder::Parameter(int parameter_index) const {
|
| DCHECK_GE(parameter_index, 0);
|
| return Register::FromParameterIndex(parameter_index, parameter_count());
|
| @@ -137,12 +112,6 @@ bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const {
|
| }
|
|
|
|
|
| -bool BytecodeArrayBuilder::RegisterIsTemporary(Register reg) const {
|
| - return temporary_register_count_ > 0 && first_temporary_register() <= reg &&
|
| - reg <= last_temporary_register();
|
| -}
|
| -
|
| -
|
| Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
|
| DCHECK_EQ(bytecode_generated_, false);
|
| EnsureReturn();
|
| @@ -1208,148 +1177,10 @@ size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
|
| return constant_array_builder()->Insert(object);
|
| }
|
|
|
| -void BytecodeArrayBuilder::ForgeTemporaryRegister() {
|
| - temporary_register_count_++;
|
| -}
|
| -
|
| -int BytecodeArrayBuilder::BorrowTemporaryRegister() {
|
| - if (free_temporaries_.empty()) {
|
| - ForgeTemporaryRegister();
|
| - return last_temporary_register().index();
|
| - } else {
|
| - auto pos = free_temporaries_.begin();
|
| - int retval = *pos;
|
| - free_temporaries_.erase(pos);
|
| - return retval;
|
| - }
|
| -}
|
| -
|
| -
|
| -int BytecodeArrayBuilder::BorrowTemporaryRegisterNotInRange(int start_index,
|
| - int end_index) {
|
| - auto index = free_temporaries_.lower_bound(start_index);
|
| - if (index == free_temporaries_.begin()) {
|
| - // If start_index is the first free register, check for a register
|
| - // greater than end_index.
|
| - index = free_temporaries_.upper_bound(end_index);
|
| - if (index == free_temporaries_.end()) {
|
| - ForgeTemporaryRegister();
|
| - return last_temporary_register().index();
|
| - }
|
| - } else {
|
| - // If there is a free register < start_index
|
| - index--;
|
| - }
|
| -
|
| - int retval = *index;
|
| - free_temporaries_.erase(index);
|
| - return retval;
|
| -}
|
| -
|
| -
|
| -void BytecodeArrayBuilder::BorrowConsecutiveTemporaryRegister(int reg_index) {
|
| - DCHECK(free_temporaries_.find(reg_index) != free_temporaries_.end());
|
| - free_temporaries_.erase(reg_index);
|
| -}
|
| -
|
| -
|
| -void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) {
|
| - DCHECK(free_temporaries_.find(reg_index) == free_temporaries_.end());
|
| - free_temporaries_.insert(reg_index);
|
| -}
|
| -
|
| -
|
| -int BytecodeArrayBuilder::PrepareForConsecutiveTemporaryRegisters(
|
| - size_t count) {
|
| - if (count == 0) {
|
| - return -1;
|
| - }
|
| -
|
| - // TODO(oth): replace use of set<> here for free_temporaries with a
|
| - // more efficient structure. And/or partition into two searches -
|
| - // one before the translation window and one after.
|
| -
|
| - // A run will require at least |count| free temporaries.
|
| - while (free_temporaries_.size() < count) {
|
| - ForgeTemporaryRegister();
|
| - free_temporaries_.insert(last_temporary_register().index());
|
| - }
|
| -
|
| - // Search within existing temporaries for a run.
|
| - auto start = free_temporaries_.begin();
|
| - size_t run_length = 0;
|
| - for (auto run_end = start; run_end != free_temporaries_.end(); run_end++) {
|
| - int expected = *start + static_cast<int>(run_length);
|
| - if (*run_end != expected) {
|
| - start = run_end;
|
| - run_length = 0;
|
| - }
|
| - Register reg_start(*start);
|
| - Register reg_expected(expected);
|
| - if (RegisterTranslator::DistanceToTranslationWindow(reg_start) > 0 &&
|
| - RegisterTranslator::DistanceToTranslationWindow(reg_expected) <= 0) {
|
| - // Run straddles the lower edge of the translation window. Registers
|
| - // after the start of this boundary are displaced by the register
|
| - // translator to provide a hole for translation. Runs either side
|
| - // of the boundary are fine.
|
| - start = run_end;
|
| - run_length = 0;
|
| - }
|
| - if (++run_length == count) {
|
| - return *start;
|
| - }
|
| - }
|
| -
|
| - // Continue run if possible across existing last temporary.
|
| - if (temporary_register_count_ > 0 &&
|
| - (start == free_temporaries_.end() ||
|
| - *start + static_cast<int>(run_length) !=
|
| - last_temporary_register().index() + 1)) {
|
| - run_length = 0;
|
| - }
|
| -
|
| - // Pad temporaries if extended run would cross translation boundary.
|
| - Register reg_first(*start);
|
| - Register reg_last(*start + static_cast<int>(count) - 1);
|
| - DCHECK_GT(RegisterTranslator::DistanceToTranslationWindow(reg_first),
|
| - RegisterTranslator::DistanceToTranslationWindow(reg_last));
|
| - while (RegisterTranslator::DistanceToTranslationWindow(reg_first) > 0 &&
|
| - RegisterTranslator::DistanceToTranslationWindow(reg_last) <= 0) {
|
| - ForgeTemporaryRegister();
|
| - free_temporaries_.insert(last_temporary_register().index());
|
| - start = --free_temporaries_.end();
|
| - reg_first = Register(*start);
|
| - reg_last = Register(*start + static_cast<int>(count) - 1);
|
| - run_length = 0;
|
| - }
|
| -
|
| - // Ensure enough registers for run.
|
| - while (run_length++ < count) {
|
| - ForgeTemporaryRegister();
|
| - free_temporaries_.insert(last_temporary_register().index());
|
| - }
|
| -
|
| - int run_start =
|
| - last_temporary_register().index() - static_cast<int>(count) + 1;
|
| - DCHECK(RegisterTranslator::DistanceToTranslationWindow(Register(run_start)) <=
|
| - 0 ||
|
| - RegisterTranslator::DistanceToTranslationWindow(
|
| - Register(run_start + static_cast<int>(count) - 1)) > 0);
|
| - return run_start;
|
| -}
|
| -
|
| -
|
| bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
|
| - if (temporary_register_count_ > 0) {
|
| - DCHECK(reg.index() >= first_temporary_register().index() &&
|
| - reg.index() <= last_temporary_register().index());
|
| - return free_temporaries_.find(reg.index()) == free_temporaries_.end();
|
| - } else {
|
| - return false;
|
| - }
|
| + return temporary_register_allocator()->RegisterIsLive(reg);
|
| }
|
|
|
| -
|
| bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index,
|
| uint32_t operand_value) const {
|
| OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
|
|
|