Chromium Code Reviews| Index: src/interpreter/bytecode-array-writer.cc |
| diff --git a/src/interpreter/bytecode-array-writer.cc b/src/interpreter/bytecode-array-writer.cc |
| index bf9bb0a6fcb36bb381fb99e2f9cce3d584d516d5..94c627cfe35be5cac4580fb426dad87293fed91b 100644 |
| --- a/src/interpreter/bytecode-array-writer.cc |
| +++ b/src/interpreter/bytecode-array-writer.cc |
| @@ -105,10 +105,60 @@ void BytecodeArrayWriter::UpdateSourcePositionTable( |
| } |
| } |
| +namespace { |
| + |
| +OperandScale GetOperandScale(const BytecodeNode* const node) { |
| + static const OperandTypeInfo kTypeInfo[] = { |
| +#define VALUE(Name, Info) Info, |
| + OPERAND_TYPE_LIST(VALUE) |
| +#undef VALUE |
| + }; |
| + |
| + OperandSize operand_size = OperandSize::kByte; |
| + const int operand_count = node->operand_count(); |
| + const OperandType* operand_types = |
| + Bytecodes::GetOperandTypes(node->bytecode()); |
|
rmcilroy
2016/06/07 10:32:46
Could we just add Bytecodes::GetOperandTypeInfos i
oth
2016/06/08 15:08:41
Done.
|
| + for (int i = 0; i < operand_count; ++i) { |
| + OperandType operand_type = operand_types[i]; |
| + OperandTypeInfo operand_type_info = |
| + kTypeInfo[static_cast<size_t>(operand_type)]; |
| + switch (operand_type_info) { |
| + case OperandTypeInfo::kNone: |
| + UNREACHABLE(); |
| + break; |
| + case OperandTypeInfo::kScalableSignedByte: { |
| + int32_t signed_operand = static_cast<int32_t>(node->operand(i)); |
| + operand_size = std::max( |
| + operand_size, Bytecodes::SizeForSignedOperand(signed_operand)); |
| + break; |
| + } |
| + case OperandTypeInfo::kScalableUnsignedByte: { |
| + uint32_t unsigned_operand = node->operand(i); |
| + operand_size = std::max( |
| + operand_size, Bytecodes::SizeForUnsignedOperand(unsigned_operand)); |
| + break; |
| + } |
| + case OperandTypeInfo::kFixedUnsignedByte: { |
| + DCHECK_EQ(Bytecodes::SizeForUnsignedOperand(node->operand(i)), |
| + OperandSize::kByte); |
| + break; |
| + } |
| + case OperandTypeInfo::kFixedUnsignedShort: { |
| + DCHECK_EQ(Bytecodes::SizeForUnsignedOperand(node->operand(i)), |
| + OperandSize::kShort); |
| + break; |
| + } |
| + } |
| + } |
| + return Bytecodes::OperandSizesToScale(operand_size); |
| +} |
| + |
| +} // namespace |
| + |
| void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) { |
| DCHECK_NE(node->bytecode(), Bytecode::kIllegal); |
| - OperandScale operand_scale = node->operand_scale(); |
| + OperandScale operand_scale = GetOperandScale(node); |
| if (operand_scale != OperandScale::kSingle) { |
| Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale); |
| bytecodes()->push_back(Bytecodes::ToByte(prefix)); |
| @@ -160,23 +210,6 @@ void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) { |
| } |
| } |
| -// TODO(rmcilroy): This is the same as SignedOperand in BytecodeArrayBuilder. |
| -// Once we move the scalable operand processing here remove the SignedOperand |
| -// in BytecodeArrayBuilder. |
| -static uint32_t SignedOperand(int value, OperandSize size) { |
| - switch (size) { |
| - case OperandSize::kByte: |
| - return static_cast<uint8_t>(value & 0xff); |
| - case OperandSize::kShort: |
| - return static_cast<uint16_t>(value & 0xffff); |
| - case OperandSize::kQuad: |
| - return static_cast<uint32_t>(value); |
| - case OperandSize::kNone: |
| - UNREACHABLE(); |
| - } |
| - return 0; |
| -} |
| - |
| // static |
| Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) { |
| switch (jump_bytecode) { |
| @@ -207,7 +240,7 @@ void BytecodeArrayWriter::PatchJumpWith8BitOperand(size_t jump_location, |
| Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes()->at(jump_location)); |
| DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); |
| size_t operand_location = jump_location + 1; |
| - DCHECK_EQ(bytecodes()->at(operand_location), 0); |
| + DCHECK_EQ(bytecodes()->at(operand_location), k8BitPlaceholder); |
| if (Bytecodes::SizeForSignedOperand(delta) == OperandSize::kByte) { |
| // The jump fits within the range of an Imm operand, so cancel |
| // the reservation and jump directly. |
| @@ -219,7 +252,9 @@ void BytecodeArrayWriter::PatchJumpWith8BitOperand(size_t jump_location, |
| // and update the jump instruction and operand. |
| size_t entry = constant_array_builder()->CommitReservedEntry( |
| OperandSize::kByte, handle(Smi::FromInt(delta), isolate())); |
| - DCHECK(Bytecodes::SizeForUnsignedOperand(entry) == OperandSize::kByte); |
| + DCHECK_LE(entry, kMaxUInt32); |
| + DCHECK_EQ(Bytecodes::SizeForUnsignedOperand(static_cast<uint32_t>(entry)), |
| + OperandSize::kByte); |
| jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); |
| bytecodes()->at(jump_location) = Bytecodes::ToByte(jump_bytecode); |
| bytecodes()->at(operand_location) = static_cast<uint8_t>(entry); |
| @@ -242,8 +277,8 @@ void BytecodeArrayWriter::PatchJumpWith16BitOperand(size_t jump_location, |
| OperandSize::kShort, handle(Smi::FromInt(delta), isolate())); |
| WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry)); |
| } |
| - DCHECK(bytecodes()->at(operand_location) == 0 && |
| - bytecodes()->at(operand_location + 1) == 0); |
| + DCHECK(bytecodes()->at(operand_location) == k8BitPlaceholder && |
| + bytecodes()->at(operand_location + 1) == k8BitPlaceholder); |
| bytecodes()->at(operand_location++) = operand_bytes[0]; |
| bytecodes()->at(operand_location) = operand_bytes[1]; |
| } |
| @@ -256,10 +291,10 @@ void BytecodeArrayWriter::PatchJumpWith32BitOperand(size_t jump_location, |
| uint8_t operand_bytes[4]; |
| WriteUnalignedUInt32(operand_bytes, static_cast<uint32_t>(delta)); |
| size_t operand_location = jump_location + 1; |
| - DCHECK(bytecodes()->at(operand_location) == 0 && |
| - bytecodes()->at(operand_location + 1) == 0 && |
| - bytecodes()->at(operand_location + 2) == 0 && |
| - bytecodes()->at(operand_location + 3) == 0); |
| + DCHECK(bytecodes()->at(operand_location) == k8BitPlaceholder && |
| + bytecodes()->at(operand_location + 1) == k8BitPlaceholder && |
| + bytecodes()->at(operand_location + 2) == k8BitPlaceholder && |
| + bytecodes()->at(operand_location + 3) == k8BitPlaceholder); |
| bytecodes()->at(operand_location++) = operand_bytes[0]; |
| bytecodes()->at(operand_location++) = operand_bytes[1]; |
| bytecodes()->at(operand_location++) = operand_bytes[2]; |
| @@ -316,8 +351,7 @@ void BytecodeArrayWriter::EmitJump(BytecodeNode* node, BytecodeLabel* label) { |
| DCHECK_LE(delta, 0); |
| delta -= 1; |
| } |
| - node->set_bytecode(node->bytecode(), SignedOperand(delta, operand_size), |
| - Bytecodes::OperandSizesToScale(operand_size)); |
| + node->set_bytecode(node->bytecode(), delta); |
| } else { |
| // The label has not yet been bound so this is a forward reference |
| // that will be patched when the label is bound. We create a |
| @@ -329,9 +363,20 @@ void BytecodeArrayWriter::EmitJump(BytecodeNode* node, BytecodeLabel* label) { |
| label->set_referrer(current_offset); |
| OperandSize reserved_operand_size = |
| constant_array_builder()->CreateReservedEntry(); |
| - OperandScale operand_scale = |
| - Bytecodes::OperandSizesToScale(reserved_operand_size); |
| - node->set_bytecode(node->bytecode(), 0, operand_scale); |
| + switch (reserved_operand_size) { |
| + case OperandSize::kNone: |
| + UNREACHABLE(); |
| + break; |
| + case OperandSize::kByte: |
| + node->set_bytecode(node->bytecode(), k8BitPlaceholder); |
| + break; |
| + case OperandSize::kShort: |
| + node->set_bytecode(node->bytecode(), k16BitPlaceholder); |
| + break; |
| + case OperandSize::kQuad: |
| + node->set_bytecode(node->bytecode(), k32BitPlaceholder); |
| + break; |
| + } |
| } |
| EmitBytecode(node); |
| } |