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 |