| 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..5a6169795b083231c61999c6ee297169c16845fc
|
| --- /dev/null
|
| +++ b/src/interpreter/register-translator.h
|
| @@ -0,0 +1,115 @@
|
| +// 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 RegisterMover;
|
| +
|
| +// 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 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, further limiting 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);
|
| +
|
| + // Translate and re-write register operands in bytecode to be
|
| + // emitted.
|
| + void TranslateRegisters(Bytecode bytecode, uint32_t* raw_operands,
|
| + int raw_operand_count);
|
| +
|
| + // Undo translations after bytecode has been emitted.
|
| + void UntranslateRegisters();
|
| +
|
| + // 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 = -kMinInt8;
|
| + static const int kTranslationWindowStart =
|
| + kTranslationWindowLimit - kTranslationWindowLength + 1;
|
| +
|
| + Register TranslateAndMove(Bytecode bytecode, int operand_index, Register reg);
|
| + Register MakeAddressable(Register reg, OperandType reg_type);
|
| + static Register Translate(Register reg);
|
| +
|
| + static bool NonRegisterOperandIsValid(Bytecode bytecode, int operand_index);
|
| + static bool OperandIsMoveable(Bytecode bytecode, int operand_index);
|
| +
|
| + RegisterMover* mover() const { return mover_; }
|
| +
|
| + // Entity to perform register moves necessary to translate registers
|
| + // and ensure reachability.
|
| + RegisterMover* mover_;
|
| +
|
| + // Flag to avoid re-entrancy when emitting move bytecodes for
|
| + // translation.
|
| + bool emitting_moves_;
|
| +
|
| + // State for restoring registers after bytecode.
|
| + Register window_registers_[kTranslationWindowLength];
|
| + int window_registers_count_;
|
| +};
|
| +
|
| +
|
| +// 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. Implementations
|
| + // of this method must be aware that register moves with bad
|
| + // register values are a security hole.
|
| + virtual void MoveRegisterUntranslated(Register from, Register to) = 0;
|
| +};
|
| +
|
| +} // namespace interpreter
|
| +} // namespace internal
|
| +} // namespace v8
|
| +
|
| +#endif // V8_INTERPRETER_REGISTER_TRANSLATOR_H_
|
|
|