OLD | NEW |
| (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 "src/v8.h" | |
6 | |
7 #include "src/interpreter/bytecode-array-builder.h" | |
8 #include "test/cctest/cctest.h" | |
9 | |
10 using namespace v8::internal; | |
11 using namespace v8::internal::interpreter; | |
12 | |
13 TEST(AllBytecodesGenerated) { | |
14 InitializedHandleScope handle_scope; | |
15 BytecodeArrayBuilder builder(handle_scope.main_isolate()); | |
16 | |
17 builder.set_locals_count(1); | |
18 CHECK_EQ(builder.locals_count(), 1); | |
19 | |
20 // Emit constant loads. | |
21 builder.LoadLiteral(Smi::FromInt(0)) | |
22 .LoadLiteral(Smi::FromInt(8)) | |
23 .LoadUndefined() | |
24 .LoadNull() | |
25 .LoadTheHole() | |
26 .LoadTrue() | |
27 .LoadFalse(); | |
28 | |
29 // Emit accumulator transfers. | |
30 builder.LoadAccumulatorWithRegister(0).StoreAccumulatorInRegister(0); | |
31 | |
32 // Emit binary operators invocations. | |
33 builder.BinaryOperation(Token::Value::ADD, 0) | |
34 .BinaryOperation(Token::Value::SUB, 0) | |
35 .BinaryOperation(Token::Value::MUL, 0) | |
36 .BinaryOperation(Token::Value::DIV, 0); | |
37 | |
38 // Emit control flow. Return must be the last instruction. | |
39 builder.Return(); | |
40 | |
41 // Generate BytecodeArray. | |
42 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); | |
43 CHECK_EQ(the_array->frame_size(), builder.locals_count() * kPointerSize); | |
44 | |
45 // Build scorecard of bytecodes encountered in the BytecodeArray. | |
46 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1); | |
47 Bytecode final_bytecode = Bytecode::kLdaZero; | |
48 for (int i = 0; i < the_array->length(); i++) { | |
49 uint8_t code = the_array->get(i); | |
50 scorecard[code] += 1; | |
51 int operands = Bytecodes::NumberOfOperands(Bytecodes::FromByte(code)); | |
52 CHECK_LE(operands, Bytecodes::MaximumNumberOfOperands()); | |
53 final_bytecode = Bytecodes::FromByte(code); | |
54 i += operands; | |
55 } | |
56 | |
57 // Check return occurs at the end and only once in the BytecodeArray. | |
58 CHECK_EQ(final_bytecode, Bytecode::kReturn); | |
59 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1); | |
60 | |
61 #define CHECK_BYTECODE_PRESENT(Name, ...) \ | |
62 /* Check Bytecode is marked in scorecard */ \ | |
63 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); | |
64 BYTECODE_LIST(CHECK_BYTECODE_PRESENT) | |
65 #undef CHECK_BYTECODE_PRESENT | |
66 } | |
67 | |
68 | |
69 TEST(FrameSizesLookGood) { | |
70 for (int locals = 0; locals < 5; locals++) { | |
71 for (int temps = 0; temps < 3; temps++) { | |
72 InitializedHandleScope handle_scope; | |
73 BytecodeArrayBuilder builder(handle_scope.main_isolate()); | |
74 builder.set_locals_count(locals); | |
75 builder.Return(); | |
76 | |
77 TemporaryRegisterScope temporaries(&builder); | |
78 for (int i = 0; i < temps; i++) { | |
79 temporaries.NewRegister(); | |
80 } | |
81 | |
82 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); | |
83 int total_registers = locals + temps; | |
84 CHECK_EQ(the_array->frame_size(), total_registers * kPointerSize); | |
85 } | |
86 } | |
87 } | |
88 | |
89 | |
90 TEST(TemporariesRecycled) { | |
91 InitializedHandleScope handle_scope; | |
92 BytecodeArrayBuilder builder(handle_scope.main_isolate()); | |
93 builder.set_locals_count(0); | |
94 builder.Return(); | |
95 | |
96 int first; | |
97 { | |
98 TemporaryRegisterScope temporaries(&builder); | |
99 first = temporaries.NewRegister(); | |
100 temporaries.NewRegister(); | |
101 temporaries.NewRegister(); | |
102 temporaries.NewRegister(); | |
103 } | |
104 | |
105 int second; | |
106 { | |
107 TemporaryRegisterScope temporaries(&builder); | |
108 second = temporaries.NewRegister(); | |
109 } | |
110 | |
111 CHECK_EQ(first, second); | |
112 } | |
OLD | NEW |