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..783924d34c92d09d68bc9430b240c7ff08990518 |
--- /dev/null |
+++ b/src/interpreter/register-translator.h |
@@ -0,0 +1,120 @@ |
+// 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 the register operands that are inputs |
+ // to |bytecode| when it is about to be emitted. |
+ void TranslateInputRegisters(Bytecode bytecode, uint32_t* raw_operands, |
+ int raw_operand_count); |
+ |
+ // Translate and re-write the register operands that are outputs |
+ // from |bytecode| when it has just been output. |
+ void TranslateOutputRegisters(); |
+ |
+ // Returns true if |reg| is in the translation window. |
+ static bool InTranslationWindow(Register reg); |
+ |
+ // Return register value as if it had been translated. |
+ static Register UntranslateRegister(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); |
+ |
+ 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; |
+ |
+ // Returns true if the register operand can be moved into the |
+ // translation window. |
+ virtual bool RegisterOperandIsMovable(Bytecode bytecode, |
+ int operand_index) = 0; |
+}; |
+ |
+} // namespace interpreter |
+} // namespace internal |
+} // namespace v8 |
+ |
+#endif // V8_INTERPRETER_REGISTER_TRANSLATOR_H_ |