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..989fb2d17749c9c54fbabdd4e24696ee3a09db4d 100644 |
--- a/src/interpreter/bytecode-array-builder.cc |
+++ b/src/interpreter/bytecode-array-builder.cc |
@@ -8,9 +8,12 @@ namespace v8 { |
namespace internal { |
namespace interpreter { |
-BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate) |
+BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) |
: isolate_(isolate), |
+ bytecodes_(zone), |
bytecode_generated_(false), |
+ constants_map_(isolate->heap(), zone), |
+ constants_(zone), |
parameter_count_(-1), |
local_register_count_(-1), |
temporary_register_count_(0), |
@@ -48,10 +51,18 @@ 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(); |
+ int constants_count = static_cast<int>(constants_.size()); |
+ Handle<FixedArray> 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 +83,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 +150,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 +195,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_) || |