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 |