Chromium Code Reviews| Index: src/interpreter/bytecode-array-builder.cc |
| diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc |
| index 7f5799e75345b246ab64dac32eaaf389866a633e..32c8da31dd26775fd1cf7cf0fd0bdec4de3fb5cc 100644 |
| --- a/src/interpreter/bytecode-array-builder.cc |
| +++ b/src/interpreter/bytecode-array-builder.cc |
| @@ -8,9 +8,10 @@ namespace v8 { |
| namespace internal { |
| namespace interpreter { |
| -BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate) |
| +BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) |
| : isolate_(isolate), |
| bytecode_generated_(false), |
| + constants_map_(isolate->heap(), zone), |
| parameter_count_(-1), |
| local_register_count_(-1), |
| temporary_register_count_(0), |
| @@ -48,10 +49,22 @@ Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { |
| int bytecode_size = static_cast<int>(bytecodes_.size()); |
| int register_count = local_register_count_ + temporary_register_count_; |
| int frame_size = register_count * kPointerSize; |
| + |
| Factory* factory = isolate_->factory(); |
| + Handle<FixedArray> constant_pool; |
| + if (constants_.size() == 0) { |
|
Michael Starzinger
2015/08/28 12:21:04
This special-casing is already part of Factory::Ne
rmcilroy
2015/08/28 14:42:05
Perfect! thanks, done.
|
| + constant_pool = factory->empty_fixed_array(); |
| + } else { |
| + int constants_count = static_cast<int>(constants_.size()); |
| + constant_pool = factory->NewFixedArray(constants_count, TENURED); |
| + for (int i = 0; i < constants_count; i++) { |
| + constant_pool->set(i, *constants_[i]); |
| + } |
| + } |
| + |
| Handle<BytecodeArray> output = |
| factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, |
| - parameter_count_, factory->empty_fixed_array()); |
| + parameter_count_, constant_pool); |
| bytecode_generated_ = true; |
| return output; |
| } |
| @@ -72,7 +85,17 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( |
| } else if (raw_smi >= -128 && raw_smi <= 127) { |
| Output(Bytecode::kLdaSmi8, static_cast<uint8_t>(raw_smi)); |
| } else { |
| - // TODO(oth): Put Smi in constant pool. |
| + LoadLiteral(Handle<Object>(smi, isolate_)); |
| + } |
| + return *this; |
| +} |
| + |
| + |
| +BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { |
| + size_t entry = GetConstantPoolEntry(object); |
| + if (entry <= 255) { |
| + Output(Bytecode::kLdaConstant, static_cast<uint8_t>(entry)); |
| + } else { |
| UNIMPLEMENTED(); |
| } |
| return *this; |
| @@ -129,6 +152,26 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { |
| } |
| +size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
| + // These constants shouldn't be added to the constant pool, the should use |
| + // specialzed bytecodes instead. |
| + DCHECK(!object.is_identical_to(isolate_->factory()->undefined_value())); |
| + DCHECK(!object.is_identical_to(isolate_->factory()->null_value())); |
| + DCHECK(!object.is_identical_to(isolate_->factory()->the_hole_value())); |
| + DCHECK(!object.is_identical_to(isolate_->factory()->true_value())); |
| + DCHECK(!object.is_identical_to(isolate_->factory()->false_value())); |
| + |
| + size_t* entry = constants_map_.Find(object); |
| + if (!entry) { |
| + entry = constants_map_.Get(object); |
| + *entry = constants_.size(); |
| + constants_.push_back(object); |
| + } |
| + DCHECK(constants_[*entry].is_identical_to(object)); |
| + return *entry; |
| +} |
| + |
| + |
| int BytecodeArrayBuilder::BorrowTemporaryRegister() { |
| DCHECK_GE(local_register_count_, 0); |
| int temporary_reg_index = temporary_register_next_++; |
| @@ -154,6 +197,8 @@ bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, |
| return false; |
| case OperandType::kImm8: |
| return true; |
| + case OperandType::kIdx: |
| + return operand_value < constants_.size(); |
| case OperandType::kReg: { |
| int reg_index = Register::FromOperand(operand_value).index(); |
| return (reg_index >= 0 && reg_index < temporary_register_next_) || |