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

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

Issue 1343363002: [Interpreter] Basic flow control. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase to fix patch failure with git cl try. Created 5 years, 3 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 "test/unittests/test-utils.h" 9 #include "test/unittests/test-utils.h"
9 10
10 namespace v8 { 11 namespace v8 {
11 namespace internal { 12 namespace internal {
12 namespace interpreter { 13 namespace interpreter {
13 14
14 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { 15 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone {
15 public: 16 public:
16 BytecodeArrayBuilderTest() {} 17 BytecodeArrayBuilderTest() {}
17 ~BytecodeArrayBuilderTest() override {} 18 ~BytecodeArrayBuilderTest() override {}
(...skipping 23 matching lines...) Expand all
41 42
42 // Emit load / store property operations. 43 // Emit load / store property operations.
43 builder.LoadNamedProperty(reg, 0, LanguageMode::SLOPPY) 44 builder.LoadNamedProperty(reg, 0, LanguageMode::SLOPPY)
44 .LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY) 45 .LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY)
45 .StoreNamedProperty(reg, reg, 0, LanguageMode::SLOPPY) 46 .StoreNamedProperty(reg, reg, 0, LanguageMode::SLOPPY)
46 .StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY); 47 .StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY);
47 48
48 // Call operations. 49 // Call operations.
49 builder.Call(reg, reg, 0); 50 builder.Call(reg, reg, 0);
50 51
51 // Emit binary operators invocations. 52 // Emit binary operator invocations.
52 builder.BinaryOperation(Token::Value::ADD, reg) 53 builder.BinaryOperation(Token::Value::ADD, reg)
53 .BinaryOperation(Token::Value::SUB, reg) 54 .BinaryOperation(Token::Value::SUB, reg)
54 .BinaryOperation(Token::Value::MUL, reg) 55 .BinaryOperation(Token::Value::MUL, reg)
55 .BinaryOperation(Token::Value::DIV, reg) 56 .BinaryOperation(Token::Value::DIV, reg)
56 .BinaryOperation(Token::Value::MOD, reg); 57 .BinaryOperation(Token::Value::MOD, reg);
57 58
59 // Emit test operator invocations.
60 builder.CompareOperation(Token::Value::EQ, reg, LanguageMode::SLOPPY)
61 .CompareOperation(Token::Value::NE, reg, LanguageMode::SLOPPY)
62 .CompareOperation(Token::Value::EQ_STRICT, reg, LanguageMode::SLOPPY)
63 .CompareOperation(Token::Value::NE_STRICT, reg, LanguageMode::SLOPPY)
64 .CompareOperation(Token::Value::LT, reg, LanguageMode::SLOPPY)
65 .CompareOperation(Token::Value::GT, reg, LanguageMode::SLOPPY)
66 .CompareOperation(Token::Value::LTE, reg, LanguageMode::SLOPPY)
67 .CompareOperation(Token::Value::GTE, reg, LanguageMode::SLOPPY)
68 .CompareOperation(Token::Value::INSTANCEOF, reg, LanguageMode::SLOPPY)
69 .CompareOperation(Token::Value::IN, reg, LanguageMode::SLOPPY);
70
71 // Emit cast operator invocations.
72 builder.LoadNull().CastAccumulatorToBoolean();
73
58 // Emit control flow. Return must be the last instruction. 74 // Emit control flow. Return must be the last instruction.
75 BytecodeLabel start;
76 builder.Bind(&start);
77 // Short jumps with Imm8 operands
78 builder.Jump(&start).JumpIfTrue(&start).JumpIfFalse(&start);
79 // Insert dummy ops to force longer jumps
80 for (int i = 0; i < 128; i++) {
81 builder.LoadTrue();
82 }
83 // Longer jumps requiring Constant operand
84 builder.Jump(&start).JumpIfTrue(&start).JumpIfFalse(&start);
59 builder.Return(); 85 builder.Return();
60 86
61 // Generate BytecodeArray. 87 // Generate BytecodeArray.
62 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); 88 Handle<BytecodeArray> the_array = builder.ToBytecodeArray();
63 CHECK_EQ(the_array->frame_size(), builder.locals_count() * kPointerSize); 89 CHECK_EQ(the_array->frame_size(), builder.locals_count() * kPointerSize);
64 90
65 // Build scorecard of bytecodes encountered in the BytecodeArray. 91 // Build scorecard of bytecodes encountered in the BytecodeArray.
66 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1); 92 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1);
67 Bytecode final_bytecode = Bytecode::kLdaZero; 93 Bytecode final_bytecode = Bytecode::kLdaZero;
68 for (int i = 0; i < the_array->length(); i++) { 94 for (int i = 0; i < the_array->length(); i++) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 .LoadLiteral(large_smi) 199 .LoadLiteral(large_smi)
174 .LoadLiteral(heap_num_1) 200 .LoadLiteral(heap_num_1)
175 .LoadLiteral(heap_num_1) 201 .LoadLiteral(heap_num_1)
176 .LoadLiteral(heap_num_2_copy); 202 .LoadLiteral(heap_num_2_copy);
177 203
178 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 204 Handle<BytecodeArray> array = builder.ToBytecodeArray();
179 // Should only have one entry for each identical constant. 205 // Should only have one entry for each identical constant.
180 CHECK_EQ(array->constant_pool()->length(), 3); 206 CHECK_EQ(array->constant_pool()->length(), 3);
181 } 207 }
182 208
209
210 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
211 static const int kFarJumpDistance = 256;
212
213 BytecodeArrayBuilder builder(isolate(), zone());
214 builder.set_parameter_count(0);
215 builder.set_locals_count(0);
216
217 BytecodeLabel far0, far1, far2;
218 BytecodeLabel near0, near1, near2;
219
220 builder.Jump(&near0)
221 .JumpIfTrue(&near1)
222 .JumpIfFalse(&near2)
223 .Bind(&near0)
224 .Bind(&near1)
225 .Bind(&near2)
226 .Jump(&far0)
227 .JumpIfTrue(&far1)
228 .JumpIfFalse(&far2);
229 for (int i = 0; i < kFarJumpDistance - 6; i++) {
230 builder.LoadUndefined();
231 }
232 builder.Bind(&far0).Bind(&far1).Bind(&far2);
233 builder.Return();
234
235 Handle<BytecodeArray> array = builder.ToBytecodeArray();
236 DCHECK_EQ(array->length(), 12 + kFarJumpDistance - 6 + 1);
237
238 BytecodeArrayIterator iterator(array);
239 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
240 CHECK_EQ(iterator.GetSmi8Operand(0), 6);
241 iterator.Advance();
242
243 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
244 CHECK_EQ(iterator.GetSmi8Operand(0), 4);
245 iterator.Advance();
246
247 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
248 CHECK_EQ(iterator.GetSmi8Operand(0), 2);
249 iterator.Advance();
250
251 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
252 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
253 Smi::FromInt(kFarJumpDistance));
254 CHECK_EQ(
255 array->get(iterator.current_offset() +
256 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
257 Bytecodes::ToByte(Bytecode::kReturn));
258 iterator.Advance();
259
260 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
261 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
262 Smi::FromInt(kFarJumpDistance - 2));
263 CHECK_EQ(
264 array->get(iterator.current_offset() +
265 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
266 Bytecodes::ToByte(Bytecode::kReturn));
267 iterator.Advance();
268
269 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
270 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
271 Smi::FromInt(kFarJumpDistance - 4));
272 CHECK_EQ(
273 array->get(iterator.current_offset() +
274 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
275 Bytecodes::ToByte(Bytecode::kReturn));
276 iterator.Advance();
277 }
278
279
280 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
281 BytecodeArrayBuilder builder(isolate(), zone());
282 builder.set_parameter_count(0);
283 builder.set_locals_count(0);
284
285 BytecodeLabel label0, label1, label2;
286 builder.Bind(&label0)
287 .Jump(&label0)
288 .Bind(&label1)
289 .JumpIfTrue(&label1)
290 .Bind(&label2)
291 .JumpIfFalse(&label2);
292 for (int i = 0; i < 64; i++) {
293 builder.Jump(&label2);
294 }
295 builder.JumpIfFalse(&label2);
296 builder.JumpIfTrue(&label1);
297 builder.Jump(&label0);
298 builder.Return();
299
300 Handle<BytecodeArray> array = builder.ToBytecodeArray();
301 BytecodeArrayIterator iterator(array);
302 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
303 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
304 iterator.Advance();
305 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
306 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
307 iterator.Advance();
308 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
309 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
310 iterator.Advance();
311 for (int i = 0; i < 64; i++) {
312 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
313 CHECK_EQ(iterator.GetSmi8Operand(0), -i * 2 - 2);
314 iterator.Advance();
315 }
316 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
317 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -130);
318 iterator.Advance();
319 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
320 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -134);
321 iterator.Advance();
322 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
323 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -138);
324 iterator.Advance();
325 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
326 iterator.Advance();
327 CHECK(iterator.done());
328 }
329
330
331 TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
332 BytecodeArrayBuilder builder(isolate(), zone());
333 builder.set_parameter_count(0);
334 builder.set_locals_count(0);
335
336 // Labels can only have 1 forward reference, but
337 // can be referred to mulitple times once bound.
338 BytecodeLabel label;
339
340 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label).Return();
341
342 Handle<BytecodeArray> array = builder.ToBytecodeArray();
343 BytecodeArrayIterator iterator(array);
344 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
345 CHECK_EQ(iterator.GetSmi8Operand(0), 2);
346 iterator.Advance();
347 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
348 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
349 iterator.Advance();
350 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
351 CHECK_EQ(iterator.GetSmi8Operand(0), -2);
352 iterator.Advance();
353 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
354 iterator.Advance();
355 CHECK(iterator.done());
356 }
357
358
359 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) {
360 static const int kRepeats = 3;
361
362 BytecodeArrayBuilder builder(isolate(), zone());
363 builder.set_parameter_count(0);
364 builder.set_locals_count(0);
365
366 for (int i = 0; i < kRepeats; i++) {
367 BytecodeLabel label;
368 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label);
369 }
370
371 builder.Return();
372
373 Handle<BytecodeArray> array = builder.ToBytecodeArray();
374 BytecodeArrayIterator iterator(array);
375 for (int i = 0; i < kRepeats; i++) {
376 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
377 CHECK_EQ(iterator.GetSmi8Operand(0), 2);
378 iterator.Advance();
379 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
380 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
381 iterator.Advance();
382 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
383 CHECK_EQ(iterator.GetSmi8Operand(0), -2);
384 iterator.Advance();
385 }
386 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
387 iterator.Advance();
388 CHECK(iterator.done());
389 }
390
391
183 } // namespace interpreter 392 } // namespace interpreter
184 } // namespace internal 393 } // namespace internal
185 } // namespace v8 394 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698