| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef V8_INTERPRETER_REGISTER_TRANSLATOR_H_ | |
| 6 #define V8_INTERPRETER_REGISTER_TRANSLATOR_H_ | |
| 7 | |
| 8 #include "src/interpreter/bytecodes.h" | |
| 9 | |
| 10 namespace v8 { | |
| 11 namespace internal { | |
| 12 namespace interpreter { | |
| 13 | |
| 14 class RegisterMover; | |
| 15 | |
| 16 // A class that enables bytecodes having only byte sized register operands | |
| 17 // to access all registers in the two byte space. Most bytecode uses few | |
| 18 // registers so space can be saved if most bytecodes with register operands | |
| 19 // just take byte operands. | |
| 20 // | |
| 21 // To reach the wider register space, a translation window is reserved in | |
| 22 // the byte addressable space specifically for copying registers into and | |
| 23 // out of before a bytecode is emitted. The translation window occupies | |
| 24 // the last register slots at the top of the byte addressable range. | |
| 25 // | |
| 26 // Because of the translation window any registers which naturally lie | |
| 27 // at above the translation window have to have their register index | |
| 28 // incremented by the window width before they are emitted. | |
| 29 // | |
| 30 // This class does not support moving ranges of registers to and from | |
| 31 // the translation window. It would be straightforward to add support | |
| 32 // for constrained ranges, e.g. kRegPair8, kRegTriple8 operands, but | |
| 33 // these would have two negative effects. The translation window would | |
| 34 // need to be wider, further limiting the space for byte operands. And | |
| 35 // every register in a range would need to be moved consuming more | |
| 36 // space in the bytecode array. | |
| 37 class RegisterTranslator final { | |
| 38 public: | |
| 39 explicit RegisterTranslator(RegisterMover* mover); | |
| 40 | |
| 41 // Translate and re-write the register operands that are inputs | |
| 42 // to |bytecode| when it is about to be emitted. | |
| 43 void TranslateInputRegisters(Bytecode bytecode, uint32_t* raw_operands, | |
| 44 int raw_operand_count); | |
| 45 | |
| 46 // Translate and re-write the register operands that are outputs | |
| 47 // from |bytecode| when it has just been output. | |
| 48 void TranslateOutputRegisters(); | |
| 49 | |
| 50 // Returns true if |reg| is in the translation window. | |
| 51 static bool InTranslationWindow(Register reg); | |
| 52 | |
| 53 // Return register value as if it had been translated. | |
| 54 static Register UntranslateRegister(Register reg); | |
| 55 | |
| 56 // Returns the distance in registers between the translation window | |
| 57 // start and |reg|. The result is negative when |reg| is above the | |
| 58 // start of the translation window. | |
| 59 static int DistanceToTranslationWindow(Register reg); | |
| 60 | |
| 61 // Returns true if |reg| can be represented as an 8-bit operand | |
| 62 // after translation. | |
| 63 static bool FitsInReg8Operand(Register reg); | |
| 64 | |
| 65 // Returns true if |reg| can be represented as an 16-bit operand | |
| 66 // after translation. | |
| 67 static bool FitsInReg16Operand(Register reg); | |
| 68 | |
| 69 // Returns the increment to the register count necessary if the | |
| 70 // value indicates the translation window is required. | |
| 71 static int RegisterCountAdjustment(int register_count, int parameter_count); | |
| 72 | |
| 73 private: | |
| 74 static const int kTranslationWindowLength = 4; | |
| 75 static const int kTranslationWindowLimit = -kMinInt8; | |
| 76 static const int kTranslationWindowStart = | |
| 77 kTranslationWindowLimit - kTranslationWindowLength + 1; | |
| 78 | |
| 79 Register TranslateAndMove(Bytecode bytecode, int operand_index, Register reg); | |
| 80 static bool RegisterIsMovableToWindow(Bytecode bytecode, int operand_index); | |
| 81 | |
| 82 static Register Translate(Register reg); | |
| 83 | |
| 84 RegisterMover* mover() const { return mover_; } | |
| 85 | |
| 86 // Entity to perform register moves necessary to translate registers | |
| 87 // and ensure reachability. | |
| 88 RegisterMover* mover_; | |
| 89 | |
| 90 // Flag to avoid re-entrancy when emitting move bytecodes for | |
| 91 // translation. | |
| 92 bool emitting_moves_; | |
| 93 | |
| 94 // Number of window registers in use. | |
| 95 int window_registers_count_; | |
| 96 | |
| 97 // State for restoring register moves emitted by TranslateOutputRegisters. | |
| 98 std::pair<Register, Register> output_moves_[kTranslationWindowLength]; | |
| 99 int output_moves_count_; | |
| 100 }; | |
| 101 | |
| 102 // Interface for RegisterTranslator helper class that will emit | |
| 103 // register move bytecodes at the translator's behest. | |
| 104 class RegisterMover { | |
| 105 public: | |
| 106 virtual ~RegisterMover() {} | |
| 107 | |
| 108 // Move register |from| to register |to| with no translation. | |
| 109 // returns false if either register operand is invalid. Implementations | |
| 110 // of this method must be aware that register moves with bad | |
| 111 // register values are a security hole. | |
| 112 virtual void MoveRegisterUntranslated(Register from, Register to) = 0; | |
| 113 }; | |
| 114 | |
| 115 } // namespace interpreter | |
| 116 } // namespace internal | |
| 117 } // namespace v8 | |
| 118 | |
| 119 #endif // V8_INTERPRETER_REGISTER_TRANSLATOR_H_ | |
| OLD | NEW |