Chromium Code Reviews| Index: src/interpreter/register-translator.h |
| diff --git a/src/interpreter/register-translator.h b/src/interpreter/register-translator.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..46bed4672c0e552a074b169afa5d4f84225b26c2 |
| --- /dev/null |
| +++ b/src/interpreter/register-translator.h |
| @@ -0,0 +1,119 @@ |
| +// Copyright 2015 the V8 project authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef V8_INTERPRETER_REGISTER_TRANSLATOR_H_ |
| +#define V8_INTERPRETER_REGISTER_TRANSLATOR_H_ |
| + |
| +#include "src/interpreter/bytecodes.h" |
| + |
| +namespace v8 { |
| +namespace internal { |
| +namespace interpreter { |
| + |
| +class BytecodeArrayBuilder; |
| + |
| +// Interface for RegisterTranslator helper class that will emit |
| +// register move bytecodes at the translator's behest. |
| +class RegisterMover { |
| + public: |
| + virtual ~RegisterMover() {} |
| + |
| + // Move register |from| to register |to| with no translation. |
| + // returns false if either register operand is invalid. |
| + virtual bool MoveRegisterUntranslated(Register from, Register to) = 0; |
| +}; |
|
rmcilroy
2016/01/22 17:50:57
nit - just declare RegisterMover here and move the
|
| + |
| +// A class that enables bytecodes having only byte sized register operands |
| +// to access all registers in the two byte space. Most bytecode uses few |
| +// registers so space can be saved if most bytecodes with register operands |
| +// just take byte operands. |
| +// |
| +// To reach the wider register space, a translation window is reserved in |
| +// the byte addressable space specifically for copying registers into and |
| +// out of before a bytecode is emitted. The translation window occupies |
| +// the last register slots at the top of the byte addressable range. |
| +// |
| +// Because of the translation window any registers which naturally lie |
| +// at above the translation window have to have their register index |
| +// incremented by the window width before they are emitted. |
| +// |
| +// This class does not support moving ranges of registers to and fro |
|
rmcilroy
2016/01/22 17:50:57
/s/fro/from
|
| +// the translation window. It would be straightforward to add support |
| +// for constrained ranges, e.g. kRegPair8, kRegTriple8 operands, but |
| +// these would have two negative effects. The translation window would |
| +// need to be wider so would further limit the space for byte |
| +// operands. And every register in a range would need to be moved |
| +// consuming more space in the bytecode array. |
| +class RegisterTranslator final { |
| + public: |
| + explicit RegisterTranslator(RegisterMover* mover); |
| + |
| + // Translates one register returning a new register that should be |
| + // used to generate the register operand for a bytecode. |
| + Register Translate(Bytecode bytecode, Register reg); |
| + |
| + // Complete translations by copying registers back to their home |
| + // positions if necessary. |
| + void CompleteTranslations(); |
| + |
| + // Validate that all register operands with bytecode have been |
| + // translated with Translate(). |
| + bool RegisterOperandsValid(Bytecode bytecode, const uint32_t* const operands, |
| + int operand_count) const; |
| + |
| + // Returns true if |reg| is in the translation window. |
| + static bool InTranslationWindow(Register reg); |
| + |
| + // Returns the distance in registers between the translation window |
| + // start and |reg|. The result is negative when |reg| is above the |
| + // start of the translation window. |
| + static int DistanceToTranslationWindow(Register reg); |
| + |
| + // Returns true if |reg| can be represented as an 8-bit operand |
| + // after translation. |
| + static bool FitsInReg8Operand(Register reg); |
| + |
| + // Returns true if |reg| can be represented as an 16-bit operand |
| + // after translation. |
| + static bool FitsInReg16Operand(Register reg); |
| + |
| + // Returns the increment to the register count necessary if the |
| + // value indicates the translation window is required. |
| + static int RegisterCountAdjustment(int register_count, int parameter_count); |
| + |
| + private: |
| + static const int kTranslationWindowLength = 4; |
| + static const int kTranslationWindowLimit = kMaxInt8; |
| + static const int kTranslationWindowStart = |
| + kTranslationWindowLimit - kTranslationWindowLength + 1; |
| + |
| + Register MakeAddressable(Register translated_reg, |
| + OperandType translated_reg_type); |
| + void Move(Register from, Register to, OperandType to_operand_type); |
| + bool MoveIsValid(Register from, Register to) const; |
| + static Register Translate(Register reg); |
| + static OperandType GetRegisterOperandType(Bytecode bytecode, |
| + int register_operand); |
| + |
| + RegisterMover* mover() const { return mover_; } |
| + |
| + // Entity to perform register moves necessary to translate registers |
| + // and ensure reachability. |
| + RegisterMover* mover_; |
| + |
| + // State for restoring registers after bytecode. |
| + Register window_registers_[kTranslationWindowLength]; |
| + int window_registers_count_; |
| + |
| + // State for emitted register operands. |
| + Bytecode bytecode_; |
| + uint32_t register_operands_[kTranslationWindowLength]; |
| + int register_operands_count_ = 0; |
| +}; |
| + |
| +} // namespace interpreter |
| +} // namespace internal |
| +} // namespace v8 |
| + |
| +#endif // V8_INTERPRETER_REGISTER_TRANSLATOR_H_ |