Chromium Code Reviews| 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 BytecodeArrayBuilder; | |
| 15 | |
| 16 // Interface for RegisterTranslator helper class that will emit | |
| 17 // register move bytecodes at the translator's behest. | |
| 18 class RegisterMover { | |
| 19 public: | |
| 20 virtual ~RegisterMover() {} | |
| 21 | |
| 22 // Move register |from| to register |to| with no translation. | |
| 23 // returns false if either register operand is invalid. | |
| 24 virtual bool MoveRegisterUntranslated(Register from, Register to) = 0; | |
| 25 }; | |
|
rmcilroy
2016/01/22 17:50:57
nit - just declare RegisterMover here and move the
| |
| 26 | |
| 27 // A class that enables bytecodes having only byte sized register operands | |
| 28 // to access all registers in the two byte space. Most bytecode uses few | |
| 29 // registers so space can be saved if most bytecodes with register operands | |
| 30 // just take byte operands. | |
| 31 // | |
| 32 // To reach the wider register space, a translation window is reserved in | |
| 33 // the byte addressable space specifically for copying registers into and | |
| 34 // out of before a bytecode is emitted. The translation window occupies | |
| 35 // the last register slots at the top of the byte addressable range. | |
| 36 // | |
| 37 // Because of the translation window any registers which naturally lie | |
| 38 // at above the translation window have to have their register index | |
| 39 // incremented by the window width before they are emitted. | |
| 40 // | |
| 41 // This class does not support moving ranges of registers to and fro | |
|
rmcilroy
2016/01/22 17:50:57
/s/fro/from
| |
| 42 // the translation window. It would be straightforward to add support | |
| 43 // for constrained ranges, e.g. kRegPair8, kRegTriple8 operands, but | |
| 44 // these would have two negative effects. The translation window would | |
| 45 // need to be wider so would further limit the space for byte | |
| 46 // operands. And every register in a range would need to be moved | |
| 47 // consuming more space in the bytecode array. | |
| 48 class RegisterTranslator final { | |
| 49 public: | |
| 50 explicit RegisterTranslator(RegisterMover* mover); | |
| 51 | |
| 52 // Translates one register returning a new register that should be | |
| 53 // used to generate the register operand for a bytecode. | |
| 54 Register Translate(Bytecode bytecode, Register reg); | |
| 55 | |
| 56 // Complete translations by copying registers back to their home | |
| 57 // positions if necessary. | |
| 58 void CompleteTranslations(); | |
| 59 | |
| 60 // Validate that all register operands with bytecode have been | |
| 61 // translated with Translate(). | |
| 62 bool RegisterOperandsValid(Bytecode bytecode, const uint32_t* const operands, | |
| 63 int operand_count) const; | |
| 64 | |
| 65 // Returns true if |reg| is in the translation window. | |
| 66 static bool InTranslationWindow(Register reg); | |
| 67 | |
| 68 // Returns the distance in registers between the translation window | |
| 69 // start and |reg|. The result is negative when |reg| is above the | |
| 70 // start of the translation window. | |
| 71 static int DistanceToTranslationWindow(Register reg); | |
| 72 | |
| 73 // Returns true if |reg| can be represented as an 8-bit operand | |
| 74 // after translation. | |
| 75 static bool FitsInReg8Operand(Register reg); | |
| 76 | |
| 77 // Returns true if |reg| can be represented as an 16-bit operand | |
| 78 // after translation. | |
| 79 static bool FitsInReg16Operand(Register reg); | |
| 80 | |
| 81 // Returns the increment to the register count necessary if the | |
| 82 // value indicates the translation window is required. | |
| 83 static int RegisterCountAdjustment(int register_count, int parameter_count); | |
| 84 | |
| 85 private: | |
| 86 static const int kTranslationWindowLength = 4; | |
| 87 static const int kTranslationWindowLimit = kMaxInt8; | |
| 88 static const int kTranslationWindowStart = | |
| 89 kTranslationWindowLimit - kTranslationWindowLength + 1; | |
| 90 | |
| 91 Register MakeAddressable(Register translated_reg, | |
| 92 OperandType translated_reg_type); | |
| 93 void Move(Register from, Register to, OperandType to_operand_type); | |
| 94 bool MoveIsValid(Register from, Register to) const; | |
| 95 static Register Translate(Register reg); | |
| 96 static OperandType GetRegisterOperandType(Bytecode bytecode, | |
| 97 int register_operand); | |
| 98 | |
| 99 RegisterMover* mover() const { return mover_; } | |
| 100 | |
| 101 // Entity to perform register moves necessary to translate registers | |
| 102 // and ensure reachability. | |
| 103 RegisterMover* mover_; | |
| 104 | |
| 105 // State for restoring registers after bytecode. | |
| 106 Register window_registers_[kTranslationWindowLength]; | |
| 107 int window_registers_count_; | |
| 108 | |
| 109 // State for emitted register operands. | |
| 110 Bytecode bytecode_; | |
| 111 uint32_t register_operands_[kTranslationWindowLength]; | |
| 112 int register_operands_count_ = 0; | |
| 113 }; | |
| 114 | |
| 115 } // namespace interpreter | |
| 116 } // namespace internal | |
| 117 } // namespace v8 | |
| 118 | |
| 119 #endif // V8_INTERPRETER_REGISTER_TRANSLATOR_H_ | |
| OLD | NEW |