Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Side by Side Diff: test/unittests/interpreter/register-translator-unittest.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Re-generate golden files. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 #include <stack>
6
7 #include "src/v8.h"
8
9 #include "src/interpreter/register-translator.h"
10 #include "src/isolate.h"
11 #include "test/unittests/test-utils.h"
12
13 namespace v8 {
14 namespace internal {
15 namespace interpreter {
16
17 class RegisterTranslatorTest : public TestWithIsolateAndZone,
18 private RegisterMover {
19 public:
20 RegisterTranslatorTest() : translator_(this), move_count_(0) {
21 window_start_ =
22 RegisterTranslator::DistanceToTranslationWindow(Register(0));
23 window_width_ =
24 Register::MaxRegisterIndexForByteOperand() - window_start_ + 1;
25 }
26
27 ~RegisterTranslatorTest() override {}
28
29 bool PopMoveAndMatch(Register from, Register to) {
30 if (!moves_.empty()) {
31 CHECK(from.is_valid() && to.is_valid());
32 const std::pair<Register, Register> top = moves_.top();
33 moves_.pop();
34 return top.first == from && top.second == to;
35 } else {
36 return false;
37 }
38 }
39
40 int move_count() const { return move_count_; }
41 RegisterTranslator* translator() { return &translator_; }
42
43 int window_start() const { return window_start_; }
44 int window_width() const { return window_width_; }
45 int window_limit() const { return window_start_ + window_width_; }
46
47 protected:
48 static const char* const kBadOperandRegex;
49
50 private:
51 void MoveRegisterUntranslated(Register from, Register to) override {
52 moves_.push(std::make_pair(from, to));
53 move_count_++;
54 }
55
56 RegisterTranslator translator_;
57 std::stack<std::pair<Register, Register>> moves_;
58 int move_count_;
59 int window_start_;
60 int window_width_;
61 };
62
63 const char* const RegisterTranslatorTest::kBadOperandRegex =
64 ".*OperandType::kReg8 \\|\\| .*OperandType::kRegOut8\\) && "
65 "RegisterIsMovableToWindow.*";
66
67 TEST_F(RegisterTranslatorTest, TestFrameSizeAdjustmentsForTranslationWindow) {
68 EXPECT_EQ(0, RegisterTranslator::RegisterCountAdjustment(0, 0));
69 EXPECT_EQ(0, RegisterTranslator::RegisterCountAdjustment(10, 10));
70 EXPECT_EQ(window_width(),
71 RegisterTranslator::RegisterCountAdjustment(173, 0));
72 EXPECT_EQ(window_width(),
73 RegisterTranslator::RegisterCountAdjustment(173, 137));
74 EXPECT_EQ(window_width(),
75 RegisterTranslator::RegisterCountAdjustment(173, 137));
76 // TODO(oth): Add a kMaxParameters8 that derives this info from the frame.
77 int param_limit = FLAG_enable_embedded_constant_pool ? 119 : 120;
78 EXPECT_EQ(0, RegisterTranslator::RegisterCountAdjustment(0, param_limit));
79 EXPECT_EQ(window_limit(),
80 RegisterTranslator::RegisterCountAdjustment(0, 128));
81 EXPECT_EQ(window_limit(),
82 RegisterTranslator::RegisterCountAdjustment(0, 129));
83 EXPECT_EQ(window_limit() - 32,
84 RegisterTranslator::RegisterCountAdjustment(32, 129));
85 }
86
87 TEST_F(RegisterTranslatorTest, TestInTranslationWindow) {
88 EXPECT_GE(window_start(), 0);
89 EXPECT_FALSE(
90 RegisterTranslator::InTranslationWindow(Register(window_start() - 1)));
91 EXPECT_TRUE(RegisterTranslator::InTranslationWindow(
92 Register(Register::MaxRegisterIndexForByteOperand())));
93 EXPECT_FALSE(RegisterTranslator::InTranslationWindow(
94 Register(Register::MaxRegisterIndexForByteOperand() + 1)));
95 for (int index = window_start(); index < window_limit(); index += 1) {
96 EXPECT_TRUE(RegisterTranslator::InTranslationWindow(Register(index)));
97 }
98 }
99
100 TEST_F(RegisterTranslatorTest, FitsInReg8Operand) {
101 EXPECT_GT(window_start(), 0);
102 EXPECT_TRUE(RegisterTranslator::FitsInReg8Operand(
103 Register::FromParameterIndex(0, 3)));
104 EXPECT_TRUE(RegisterTranslator::FitsInReg8Operand(
105 Register::FromParameterIndex(2, 3)));
106 EXPECT_TRUE(RegisterTranslator::FitsInReg8Operand(Register(0)));
107 EXPECT_TRUE(
108 RegisterTranslator::FitsInReg8Operand(Register(window_start() - 1)));
109 EXPECT_FALSE(RegisterTranslator::FitsInReg8Operand(Register(kMaxInt8)));
110 EXPECT_FALSE(RegisterTranslator::FitsInReg8Operand(Register(kMaxInt8 + 1)));
111 for (int index = window_start(); index < window_limit(); index += 1) {
112 EXPECT_FALSE(RegisterTranslator::FitsInReg8Operand(Register(index)));
113 }
114 }
115
116 TEST_F(RegisterTranslatorTest, FitsInReg16Operand) {
117 EXPECT_GT(window_start(), 0);
118 EXPECT_TRUE(RegisterTranslator::FitsInReg16Operand(
119 Register::FromParameterIndex(0, 3)));
120 EXPECT_TRUE(RegisterTranslator::FitsInReg16Operand(
121 Register::FromParameterIndex(2, 3)));
122 EXPECT_TRUE(RegisterTranslator::FitsInReg16Operand(
123 Register::FromParameterIndex(0, 999)));
124 EXPECT_TRUE(RegisterTranslator::FitsInReg16Operand(
125 Register::FromParameterIndex(0, Register::MaxParameterIndex() + 1)));
126 EXPECT_TRUE(RegisterTranslator::FitsInReg16Operand(Register(0)));
127 EXPECT_TRUE(
128 RegisterTranslator::FitsInReg16Operand(Register(window_start() - 1)));
129 EXPECT_TRUE(RegisterTranslator::FitsInReg16Operand(Register(kMaxInt8 + 1)));
130 EXPECT_TRUE(RegisterTranslator::FitsInReg16Operand(Register(kMaxInt8 + 2)));
131 for (int index = 0; index <= kMaxInt16 - window_width(); index += 1) {
132 EXPECT_TRUE(RegisterTranslator::FitsInReg16Operand(Register(index)));
133 }
134 for (int index = Register::MaxRegisterIndex() - window_width() + 1;
135 index < Register::MaxRegisterIndex() + 2; index += 1) {
136 EXPECT_FALSE(RegisterTranslator::FitsInReg16Operand(Register(index)));
137 }
138 }
139
140 TEST_F(RegisterTranslatorTest, NoTranslationRequired) {
141 Register window_reg(window_start());
142 Register local_reg(57);
143 uint32_t operands[] = {local_reg.ToRawOperand()};
144 translator()->TranslateInputRegisters(Bytecode::kLdar, operands, 1);
145 translator()->TranslateOutputRegisters();
146 EXPECT_EQ(0, move_count());
147
148 Register param_reg = Register::FromParameterIndex(129, 130);
149 operands[0] = param_reg.ToRawOperand();
150 translator()->TranslateInputRegisters(Bytecode::kAdd, operands, 1);
151 translator()->TranslateOutputRegisters();
152 EXPECT_EQ(0, move_count());
153 }
154
155 TEST_F(RegisterTranslatorTest, TranslationRequired) {
156 Register window_reg(window_start());
157 Register local_reg(137);
158 Register local_reg_translated(local_reg.index() + window_width());
159
160 uint32_t operands[] = {local_reg.ToRawOperand()};
161 translator()->TranslateInputRegisters(Bytecode::kLdar, operands, 1);
162 EXPECT_EQ(1, move_count());
163 EXPECT_TRUE(PopMoveAndMatch(local_reg_translated, window_reg));
164 translator()->TranslateOutputRegisters();
165 EXPECT_EQ(1, move_count());
166 EXPECT_FALSE(PopMoveAndMatch(window_reg, local_reg_translated));
167
168 operands[0] = local_reg.ToRawOperand();
169 translator()->TranslateInputRegisters(Bytecode::kStar, operands, 1);
170 EXPECT_EQ(1, move_count());
171 EXPECT_FALSE(PopMoveAndMatch(local_reg_translated, window_reg));
172 translator()->TranslateOutputRegisters();
173 EXPECT_EQ(2, move_count());
174 EXPECT_TRUE(PopMoveAndMatch(window_reg, local_reg_translated));
175
176 Register param_reg = Register::FromParameterIndex(0, 130);
177 operands[0] = {param_reg.ToRawOperand()};
178 translator()->TranslateInputRegisters(Bytecode::kLdar, operands, 1);
179 EXPECT_EQ(3, move_count());
180 EXPECT_TRUE(PopMoveAndMatch(param_reg, window_reg));
181 translator()->TranslateOutputRegisters();
182 EXPECT_EQ(3, move_count());
183 EXPECT_FALSE(PopMoveAndMatch(window_reg, param_reg));
184
185 operands[0] = {param_reg.ToRawOperand()};
186 translator()->TranslateInputRegisters(Bytecode::kStar, operands, 1);
187 EXPECT_EQ(3, move_count());
188 EXPECT_FALSE(PopMoveAndMatch(local_reg_translated, window_reg));
189 translator()->TranslateOutputRegisters();
190 EXPECT_EQ(4, move_count());
191 EXPECT_TRUE(PopMoveAndMatch(window_reg, param_reg));
192 }
193
194 TEST_F(RegisterTranslatorTest, RangeTranslation) {
195 Register window0(window_start());
196 Register window1(window_start() + 1);
197 Register window2(window_start() + 2);
198 uint32_t operands[3];
199
200 // Bytecode::kNew with valid range operand.
201 Register constructor0(0);
202 Register args0(1);
203 operands[0] = constructor0.ToRawOperand();
204 operands[1] = args0.ToRawOperand();
205 operands[2] = 1;
206 translator()->TranslateInputRegisters(Bytecode::kNew, operands, 3);
207 translator()->TranslateOutputRegisters();
208 EXPECT_EQ(0, move_count());
209
210 // Bytecode::kNewWide with valid range operand.
211 Register constructor1(128);
212 Register constructor1_translated(constructor1.index() + window_width());
213 Register args1(129);
214 Register args1_translated(args1.index() + window_width());
215 operands[0] = constructor1.ToRawOperand();
216 operands[1] = args1.ToRawOperand();
217 operands[2] = 3;
218 translator()->TranslateInputRegisters(Bytecode::kNewWide, operands, 3);
219 translator()->TranslateOutputRegisters();
220 EXPECT_EQ(0, move_count());
221 }
222
223 TEST_F(RegisterTranslatorTest, BadRange0) {
224 // Bytecode::kNew with invalid range operand (kMaybeReg8).
225 Register constructor1(128);
226 Register args1(129);
227 uint32_t operands[] = {constructor1.ToRawOperand(), args1.ToRawOperand(), 3};
228 ASSERT_DEATH_IF_SUPPORTED(
229 translator()->TranslateInputRegisters(Bytecode::kNew, operands, 3),
230 kBadOperandRegex);
231 }
232
233 TEST_F(RegisterTranslatorTest, BadRange1) {
234 // Bytecode::kForInPrepare with invalid range operand (kRegTriple8)
235 Register for_in_state(160);
236 Register for_in_state_translated(for_in_state.index() + window_width());
237 uint32_t operands[] = {for_in_state.ToRawOperand()};
238 ASSERT_DEATH_IF_SUPPORTED(translator()->TranslateInputRegisters(
239 Bytecode::kForInPrepare, operands, 1),
240 kBadOperandRegex);
241 }
242
243 TEST_F(RegisterTranslatorTest, BadRange2) {
244 // Bytecode::kForInNext with invalid range operand (kRegPair8)
245 Register receiver(192);
246 Register receiver_translated(receiver.index() + window_width());
247 Register index(193);
248 Register index_translated(index.index() + window_width());
249 Register cache_info_pair(194);
250 Register cache_info_pair_translated(cache_info_pair.index() + window_width());
251 uint32_t operands[] = {receiver.ToRawOperand(), index.ToRawOperand(),
252 cache_info_pair.ToRawOperand(), 1};
253 ASSERT_DEATH_IF_SUPPORTED(
254 translator()->TranslateInputRegisters(Bytecode::kForInNext, operands, 4),
255 kBadOperandRegex);
256 }
257
258 } // namespace interpreter
259 } // namespace internal
260 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/interpreter/interpreter-assembler-unittest.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698