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

Side by Side Diff: test/unittests/interpreter/bytecode-array-builder-unittest.cc

Issue 1403943004: [Interpreter] Add support for local context loads and stores. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_contextchain
Patch Set: Add back outer_ &&] Created 5 years, 2 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
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/interpreter/bytecode-array-builder.h" 7 #include "src/interpreter/bytecode-array-builder.h"
8 #include "src/interpreter/bytecode-array-iterator.h" 8 #include "src/interpreter/bytecode-array-iterator.h"
9 #include "test/unittests/test-utils.h" 9 #include "test/unittests/test-utils.h"
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 namespace interpreter { 13 namespace interpreter {
14 14
15 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { 15 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone {
16 public: 16 public:
17 BytecodeArrayBuilderTest() {} 17 BytecodeArrayBuilderTest() {}
18 ~BytecodeArrayBuilderTest() override {} 18 ~BytecodeArrayBuilderTest() override {}
19 }; 19 };
20 20
21 21
22 TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { 22 TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
23 BytecodeArrayBuilder builder(isolate(), zone()); 23 BytecodeArrayBuilder builder(isolate(), zone());
24 24
25 builder.set_locals_count(1); 25 builder.set_locals_count(1);
26 builder.set_context_count(1);
26 builder.set_parameter_count(0); 27 builder.set_parameter_count(0);
27 CHECK_EQ(builder.locals_count(), 1); 28 CHECK_EQ(builder.locals_count(), 1);
29 CHECK_EQ(builder.context_count(), 1);
30 CHECK_EQ(builder.fixed_register_count(), 2);
28 31
29 // Emit constant loads. 32 // Emit constant loads.
30 builder.LoadLiteral(Smi::FromInt(0)) 33 builder.LoadLiteral(Smi::FromInt(0))
31 .LoadLiteral(Smi::FromInt(8)) 34 .LoadLiteral(Smi::FromInt(8))
32 .LoadLiteral(Smi::FromInt(10000000)) 35 .LoadLiteral(Smi::FromInt(10000000))
33 .LoadUndefined() 36 .LoadUndefined()
34 .LoadNull() 37 .LoadNull()
35 .LoadTheHole() 38 .LoadTheHole()
36 .LoadTrue() 39 .LoadTrue()
37 .LoadFalse(); 40 .LoadFalse();
38 41
39 // Emit accumulator transfers. 42 // Emit accumulator transfers.
40 Register reg(0); 43 Register reg(0);
41 builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg); 44 builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg);
42 45
43 // Emit global load / store operations. 46 // Emit global load / store operations.
44 builder.LoadGlobal(1); 47 builder.LoadGlobal(1);
45 builder.StoreGlobal(1, LanguageMode::SLOPPY); 48 builder.StoreGlobal(1, LanguageMode::SLOPPY);
46 49
47 // Emit context operations. 50 // Emit context operations.
48 builder.PushContext(reg); 51 builder.PushContext(reg);
49 builder.PopContext(reg); 52 builder.PopContext(reg);
50 builder.LoadContextSlot(reg, 1); 53 builder.LoadContextSlot(reg, 1);
54 builder.StoreContextSlot(reg, 1);
51 55
52 // Emit load / store property operations. 56 // Emit load / store property operations.
53 builder.LoadNamedProperty(reg, 0, LanguageMode::SLOPPY) 57 builder.LoadNamedProperty(reg, 0, LanguageMode::SLOPPY)
54 .LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY) 58 .LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY)
55 .StoreNamedProperty(reg, reg, 0, LanguageMode::SLOPPY) 59 .StoreNamedProperty(reg, reg, 0, LanguageMode::SLOPPY)
56 .StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY) 60 .StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY)
57 .LoadNamedProperty(reg, 0, LanguageMode::STRICT) 61 .LoadNamedProperty(reg, 0, LanguageMode::STRICT)
58 .LoadKeyedProperty(reg, 0, LanguageMode::STRICT) 62 .LoadKeyedProperty(reg, 0, LanguageMode::STRICT)
59 .StoreNamedProperty(reg, reg, 0, LanguageMode::STRICT) 63 .StoreNamedProperty(reg, reg, 0, LanguageMode::STRICT)
60 .StoreKeyedProperty(reg, reg, 0, LanguageMode::STRICT); 64 .StoreKeyedProperty(reg, reg, 0, LanguageMode::STRICT);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 // Longer jumps requiring Constant operand 127 // Longer jumps requiring Constant operand
124 builder.Jump(&start) 128 builder.Jump(&start)
125 .JumpIfTrue(&start) 129 .JumpIfTrue(&start)
126 .JumpIfFalse(&start) 130 .JumpIfFalse(&start)
127 .JumpIfToBooleanTrue(&start) 131 .JumpIfToBooleanTrue(&start)
128 .JumpIfToBooleanFalse(&start); 132 .JumpIfToBooleanFalse(&start);
129 builder.Return(); 133 builder.Return();
130 134
131 // Generate BytecodeArray. 135 // Generate BytecodeArray.
132 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); 136 Handle<BytecodeArray> the_array = builder.ToBytecodeArray();
133 CHECK_EQ(the_array->frame_size(), builder.locals_count() * kPointerSize); 137 CHECK_EQ(the_array->frame_size(),
138 builder.fixed_register_count() * kPointerSize);
134 139
135 // Build scorecard of bytecodes encountered in the BytecodeArray. 140 // Build scorecard of bytecodes encountered in the BytecodeArray.
136 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1); 141 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1);
137 Bytecode final_bytecode = Bytecode::kLdaZero; 142 Bytecode final_bytecode = Bytecode::kLdaZero;
138 int i = 0; 143 int i = 0;
139 while (i < the_array->length()) { 144 while (i < the_array->length()) {
140 uint8_t code = the_array->get(i); 145 uint8_t code = the_array->get(i);
141 scorecard[code] += 1; 146 scorecard[code] += 1;
142 final_bytecode = Bytecodes::FromByte(code); 147 final_bytecode = Bytecodes::FromByte(code);
143 i += Bytecodes::Size(Bytecodes::FromByte(code)); 148 i += Bytecodes::Size(Bytecodes::FromByte(code));
144 } 149 }
145 150
146 // Check return occurs at the end and only once in the BytecodeArray. 151 // Check return occurs at the end and only once in the BytecodeArray.
147 CHECK_EQ(final_bytecode, Bytecode::kReturn); 152 CHECK_EQ(final_bytecode, Bytecode::kReturn);
148 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1); 153 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1);
149 154
150 #define CHECK_BYTECODE_PRESENT(Name, ...) \ 155 #define CHECK_BYTECODE_PRESENT(Name, ...) \
151 /* Check Bytecode is marked in scorecard */ \ 156 /* Check Bytecode is marked in scorecard */ \
152 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); 157 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1);
153 BYTECODE_LIST(CHECK_BYTECODE_PRESENT) 158 BYTECODE_LIST(CHECK_BYTECODE_PRESENT)
154 #undef CHECK_BYTECODE_PRESENT 159 #undef CHECK_BYTECODE_PRESENT
155 } 160 }
156 161
157 162
158 TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) { 163 TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) {
159 for (int locals = 0; locals < 5; locals++) { 164 for (int locals = 0; locals < 5; locals++) {
160 for (int temps = 0; temps < 3; temps++) { 165 for (int contexts = 0; contexts < 4; contexts++) {
161 BytecodeArrayBuilder builder(isolate(), zone()); 166 for (int temps = 0; temps < 3; temps++) {
162 builder.set_parameter_count(0); 167 BytecodeArrayBuilder builder(isolate(), zone());
163 builder.set_locals_count(locals); 168 builder.set_parameter_count(0);
164 builder.Return(); 169 builder.set_locals_count(locals);
170 builder.set_context_count(contexts);
171 builder.Return();
165 172
166 TemporaryRegisterScope temporaries(&builder); 173 TemporaryRegisterScope temporaries(&builder);
167 for (int i = 0; i < temps; i++) { 174 for (int i = 0; i < temps; i++) {
168 temporaries.NewRegister(); 175 temporaries.NewRegister();
176 }
177
178 Handle<BytecodeArray> the_array = builder.ToBytecodeArray();
179 int total_registers = locals + contexts + temps;
180 CHECK_EQ(the_array->frame_size(), total_registers * kPointerSize);
169 } 181 }
170
171 Handle<BytecodeArray> the_array = builder.ToBytecodeArray();
172 int total_registers = locals + temps;
173 CHECK_EQ(the_array->frame_size(), total_registers * kPointerSize);
174 } 182 }
175 } 183 }
176 } 184 }
177 185
178 186
179 TEST_F(BytecodeArrayBuilderTest, TemporariesRecycled) { 187 TEST_F(BytecodeArrayBuilderTest, TemporariesRecycled) {
180 BytecodeArrayBuilder builder(isolate(), zone()); 188 BytecodeArrayBuilder builder(isolate(), zone());
181 builder.set_parameter_count(0); 189 builder.set_parameter_count(0);
182 builder.set_locals_count(0); 190 builder.set_locals_count(0);
191 builder.set_context_count(0);
183 builder.Return(); 192 builder.Return();
184 193
185 int first; 194 int first;
186 { 195 {
187 TemporaryRegisterScope temporaries(&builder); 196 TemporaryRegisterScope temporaries(&builder);
188 first = temporaries.NewRegister().index(); 197 first = temporaries.NewRegister().index();
189 temporaries.NewRegister(); 198 temporaries.NewRegister();
190 temporaries.NewRegister(); 199 temporaries.NewRegister();
191 temporaries.NewRegister(); 200 temporaries.NewRegister();
192 } 201 }
(...skipping 20 matching lines...) Expand all
213 222
214 int actual_index = Register::FromOperand(actual_operand).index(); 223 int actual_index = Register::FromOperand(actual_operand).index();
215 CHECK_EQ(actual_index, index); 224 CHECK_EQ(actual_index, index);
216 } 225 }
217 226
218 227
219 TEST_F(BytecodeArrayBuilderTest, Parameters) { 228 TEST_F(BytecodeArrayBuilderTest, Parameters) {
220 BytecodeArrayBuilder builder(isolate(), zone()); 229 BytecodeArrayBuilder builder(isolate(), zone());
221 builder.set_parameter_count(10); 230 builder.set_parameter_count(10);
222 builder.set_locals_count(0); 231 builder.set_locals_count(0);
232 builder.set_context_count(0);
223 233
224 Register param0(builder.Parameter(0)); 234 Register param0(builder.Parameter(0));
225 Register param9(builder.Parameter(9)); 235 Register param9(builder.Parameter(9));
226 CHECK_EQ(param9.index() - param0.index(), 9); 236 CHECK_EQ(param9.index() - param0.index(), 9);
227 } 237 }
228 238
229 239
230 TEST_F(BytecodeArrayBuilderTest, Constants) { 240 TEST_F(BytecodeArrayBuilderTest, Constants) {
231 BytecodeArrayBuilder builder(isolate(), zone()); 241 BytecodeArrayBuilder builder(isolate(), zone());
232 builder.set_parameter_count(0); 242 builder.set_parameter_count(0);
233 builder.set_locals_count(0); 243 builder.set_locals_count(0);
244 builder.set_context_count(0);
234 245
235 Factory* factory = isolate()->factory(); 246 Factory* factory = isolate()->factory();
236 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(3.14); 247 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(3.14);
237 Handle<HeapObject> heap_num_2 = factory->NewHeapNumber(5.2); 248 Handle<HeapObject> heap_num_2 = factory->NewHeapNumber(5.2);
238 Handle<Object> large_smi(Smi::FromInt(0x12345678), isolate()); 249 Handle<Object> large_smi(Smi::FromInt(0x12345678), isolate());
239 Handle<HeapObject> heap_num_2_copy(*heap_num_2); 250 Handle<HeapObject> heap_num_2_copy(*heap_num_2);
240 builder.LoadLiteral(heap_num_1) 251 builder.LoadLiteral(heap_num_1)
241 .LoadLiteral(heap_num_2) 252 .LoadLiteral(heap_num_2)
242 .LoadLiteral(large_smi) 253 .LoadLiteral(large_smi)
243 .LoadLiteral(heap_num_1) 254 .LoadLiteral(heap_num_1)
244 .LoadLiteral(heap_num_1) 255 .LoadLiteral(heap_num_1)
245 .LoadLiteral(heap_num_2_copy); 256 .LoadLiteral(heap_num_2_copy);
246 257
247 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 258 Handle<BytecodeArray> array = builder.ToBytecodeArray();
248 // Should only have one entry for each identical constant. 259 // Should only have one entry for each identical constant.
249 CHECK_EQ(array->constant_pool()->length(), 3); 260 CHECK_EQ(array->constant_pool()->length(), 3);
250 } 261 }
251 262
252 263
253 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { 264 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
254 static const int kFarJumpDistance = 256; 265 static const int kFarJumpDistance = 256;
255 266
256 BytecodeArrayBuilder builder(isolate(), zone()); 267 BytecodeArrayBuilder builder(isolate(), zone());
257 builder.set_parameter_count(0); 268 builder.set_parameter_count(0);
258 builder.set_locals_count(0); 269 builder.set_locals_count(0);
270 builder.set_context_count(0);
259 271
260 BytecodeLabel far0, far1, far2; 272 BytecodeLabel far0, far1, far2;
261 BytecodeLabel near0, near1, near2; 273 BytecodeLabel near0, near1, near2;
262 274
263 builder.Jump(&near0) 275 builder.Jump(&near0)
264 .JumpIfTrue(&near1) 276 .JumpIfTrue(&near1)
265 .JumpIfFalse(&near2) 277 .JumpIfFalse(&near2)
266 .Bind(&near0) 278 .Bind(&near0)
267 .Bind(&near1) 279 .Bind(&near1)
268 .Bind(&near2) 280 .Bind(&near2)
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), 329 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
318 Bytecodes::ToByte(Bytecode::kReturn)); 330 Bytecodes::ToByte(Bytecode::kReturn));
319 iterator.Advance(); 331 iterator.Advance();
320 } 332 }
321 333
322 334
323 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { 335 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
324 BytecodeArrayBuilder builder(isolate(), zone()); 336 BytecodeArrayBuilder builder(isolate(), zone());
325 builder.set_parameter_count(0); 337 builder.set_parameter_count(0);
326 builder.set_locals_count(0); 338 builder.set_locals_count(0);
339 builder.set_context_count(0);
327 340
328 BytecodeLabel label0, label1, label2; 341 BytecodeLabel label0, label1, label2;
329 builder.Bind(&label0) 342 builder.Bind(&label0)
330 .Jump(&label0) 343 .Jump(&label0)
331 .Bind(&label1) 344 .Bind(&label1)
332 .JumpIfTrue(&label1) 345 .JumpIfTrue(&label1)
333 .Bind(&label2) 346 .Bind(&label2)
334 .JumpIfFalse(&label2); 347 .JumpIfFalse(&label2);
335 for (int i = 0; i < 64; i++) { 348 for (int i = 0; i < 64; i++) {
336 builder.Jump(&label2); 349 builder.Jump(&label2);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 381 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
369 iterator.Advance(); 382 iterator.Advance();
370 CHECK(iterator.done()); 383 CHECK(iterator.done());
371 } 384 }
372 385
373 386
374 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { 387 TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
375 BytecodeArrayBuilder builder(isolate(), zone()); 388 BytecodeArrayBuilder builder(isolate(), zone());
376 builder.set_parameter_count(0); 389 builder.set_parameter_count(0);
377 builder.set_locals_count(0); 390 builder.set_locals_count(0);
391 builder.set_context_count(0);
378 392
379 // Labels can only have 1 forward reference, but 393 // Labels can only have 1 forward reference, but
380 // can be referred to mulitple times once bound. 394 // can be referred to mulitple times once bound.
381 BytecodeLabel label; 395 BytecodeLabel label;
382 396
383 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label).Return(); 397 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label).Return();
384 398
385 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 399 Handle<BytecodeArray> array = builder.ToBytecodeArray();
386 BytecodeArrayIterator iterator(array); 400 BytecodeArrayIterator iterator(array);
387 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 401 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
(...skipping 10 matching lines...) Expand all
398 CHECK(iterator.done()); 412 CHECK(iterator.done());
399 } 413 }
400 414
401 415
402 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) { 416 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) {
403 static const int kRepeats = 3; 417 static const int kRepeats = 3;
404 418
405 BytecodeArrayBuilder builder(isolate(), zone()); 419 BytecodeArrayBuilder builder(isolate(), zone());
406 builder.set_parameter_count(0); 420 builder.set_parameter_count(0);
407 builder.set_locals_count(0); 421 builder.set_locals_count(0);
422 builder.set_context_count(0);
408 423
409 for (int i = 0; i < kRepeats; i++) { 424 for (int i = 0; i < kRepeats; i++) {
410 BytecodeLabel label; 425 BytecodeLabel label;
411 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label); 426 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label);
412 } 427 }
413 428
414 builder.Return(); 429 builder.Return();
415 430
416 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 431 Handle<BytecodeArray> array = builder.ToBytecodeArray();
417 BytecodeArrayIterator iterator(array); 432 BytecodeArrayIterator iterator(array);
(...skipping 11 matching lines...) Expand all
429 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 444 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
430 iterator.Advance(); 445 iterator.Advance();
431 CHECK(iterator.done()); 446 CHECK(iterator.done());
432 } 447 }
433 448
434 449
435 TEST_F(BytecodeArrayBuilderTest, ToBoolean) { 450 TEST_F(BytecodeArrayBuilderTest, ToBoolean) {
436 BytecodeArrayBuilder builder(isolate(), zone()); 451 BytecodeArrayBuilder builder(isolate(), zone());
437 builder.set_parameter_count(0); 452 builder.set_parameter_count(0);
438 builder.set_locals_count(0); 453 builder.set_locals_count(0);
454 builder.set_context_count(0);
439 455
440 // Check ToBoolean emitted at start of block. 456 // Check ToBoolean emitted at start of block.
441 builder.EnterBlock().CastAccumulatorToBoolean(); 457 builder.EnterBlock().CastAccumulatorToBoolean();
442 458
443 // Check ToBoolean emitted preceding bytecode is non-boolean. 459 // Check ToBoolean emitted preceding bytecode is non-boolean.
444 builder.LoadNull().CastAccumulatorToBoolean(); 460 builder.LoadNull().CastAccumulatorToBoolean();
445 461
446 // Check ToBoolean omitted if preceding bytecode is boolean. 462 // Check ToBoolean omitted if preceding bytecode is boolean.
447 builder.LoadFalse().CastAccumulatorToBoolean(); 463 builder.LoadFalse().CastAccumulatorToBoolean();
448 464
(...skipping 26 matching lines...) Expand all
475 491
476 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 492 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
477 iterator.Advance(); 493 iterator.Advance();
478 CHECK(iterator.done()); 494 CHECK(iterator.done());
479 } 495 }
480 496
481 497
482 } // namespace interpreter 498 } // namespace interpreter
483 } // namespace internal 499 } // namespace internal
484 } // namespace v8 500 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698