OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 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/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compiler/code-assembler.h" | 6 #include "src/compiler/code-assembler.h" |
7 #include "src/isolate.h" | 7 #include "src/isolate.h" |
8 #include "test/cctest/compiler/code-assembler-tester.h" | 8 #include "test/cctest/compiler/code-assembler-tester.h" |
9 #include "test/cctest/compiler/function-tester.h" | 9 #include "test/cctest/compiler/function-tester.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 namespace compiler { | 13 namespace compiler { |
14 | 14 |
| 15 typedef CodeAssemblerTesterImpl<CodeAssembler> CodeAssemblerTester; |
| 16 |
15 namespace { | 17 namespace { |
16 | 18 |
17 Node* SmiTag(CodeAssembler& m, Node* value) { | 19 Node* SmiTag(CodeAssemblerTester& m, Node* value) { |
18 int32_t constant_value; | 20 int32_t constant_value; |
19 if (m.ToInt32Constant(value, constant_value) && | 21 if (m.ToInt32Constant(value, constant_value) && |
20 Smi::IsValid(constant_value)) { | 22 Smi::IsValid(constant_value)) { |
21 return m.SmiConstant(Smi::FromInt(constant_value)); | 23 return m.SmiConstant(Smi::FromInt(constant_value)); |
22 } | 24 } |
23 return m.WordShl(value, m.IntPtrConstant(kSmiShiftSize + kSmiTagSize)); | 25 return m.WordShl(value, m.IntPtrConstant(kSmiShiftSize + kSmiTagSize)); |
24 } | 26 } |
25 | 27 |
26 Node* UndefinedConstant(CodeAssembler& m) { | 28 Node* UndefinedConstant(CodeAssemblerTester& m) { |
27 return m.LoadRoot(Heap::kUndefinedValueRootIndex); | 29 return m.LoadRoot(Heap::kUndefinedValueRootIndex); |
28 } | 30 } |
29 | 31 |
30 Node* LoadObjectField(CodeAssembler& m, Node* object, int offset, | 32 Node* LoadObjectField(CodeAssemblerTester& m, Node* object, int offset, |
31 MachineType rep = MachineType::AnyTagged()) { | 33 MachineType rep = MachineType::AnyTagged()) { |
32 return m.Load(rep, object, m.IntPtrConstant(offset - kHeapObjectTag)); | 34 return m.Load(rep, object, m.IntPtrConstant(offset - kHeapObjectTag)); |
33 } | 35 } |
34 | 36 |
35 } // namespace | 37 } // namespace |
36 | 38 |
37 TEST(SimpleSmiReturn) { | 39 TEST(SimpleSmiReturn) { |
38 Isolate* isolate(CcTest::InitIsolateOnce()); | 40 Isolate* isolate(CcTest::InitIsolateOnce()); |
39 CodeAssemblerTester data(isolate); | 41 VoidDescriptor descriptor(isolate); |
40 CodeAssembler m(data.state()); | 42 CodeAssemblerTester m(isolate, descriptor); |
41 m.Return(SmiTag(m, m.Int32Constant(37))); | 43 m.Return(SmiTag(m, m.Int32Constant(37))); |
42 Handle<Code> code = data.GenerateCode(); | 44 Handle<Code> code = m.GenerateCode(); |
43 FunctionTester ft(code); | 45 FunctionTester ft(descriptor, code); |
44 MaybeHandle<Object> result = ft.Call(); | 46 MaybeHandle<Object> result = ft.Call(); |
45 CHECK_EQ(37, Handle<Smi>::cast(result.ToHandleChecked())->value()); | 47 CHECK_EQ(37, Handle<Smi>::cast(result.ToHandleChecked())->value()); |
46 } | 48 } |
47 | 49 |
48 TEST(SimpleIntPtrReturn) { | 50 TEST(SimpleIntPtrReturn) { |
49 Isolate* isolate(CcTest::InitIsolateOnce()); | 51 Isolate* isolate(CcTest::InitIsolateOnce()); |
50 CodeAssemblerTester data(isolate); | 52 VoidDescriptor descriptor(isolate); |
51 CodeAssembler m(data.state()); | 53 CodeAssemblerTester m(isolate, descriptor); |
52 int test; | 54 int test; |
53 m.Return(m.IntPtrConstant(reinterpret_cast<intptr_t>(&test))); | 55 m.Return(m.IntPtrConstant(reinterpret_cast<intptr_t>(&test))); |
54 Handle<Code> code = data.GenerateCode(); | 56 Handle<Code> code = m.GenerateCode(); |
55 FunctionTester ft(code); | 57 FunctionTester ft(descriptor, code); |
56 MaybeHandle<Object> result = ft.Call(); | 58 MaybeHandle<Object> result = ft.Call(); |
57 CHECK_EQ(reinterpret_cast<intptr_t>(&test), | 59 CHECK_EQ(reinterpret_cast<intptr_t>(&test), |
58 reinterpret_cast<intptr_t>(*result.ToHandleChecked())); | 60 reinterpret_cast<intptr_t>(*result.ToHandleChecked())); |
59 } | 61 } |
60 | 62 |
61 TEST(SimpleDoubleReturn) { | 63 TEST(SimpleDoubleReturn) { |
62 Isolate* isolate(CcTest::InitIsolateOnce()); | 64 Isolate* isolate(CcTest::InitIsolateOnce()); |
63 CodeAssemblerTester data(isolate); | 65 VoidDescriptor descriptor(isolate); |
64 CodeAssembler m(data.state()); | 66 CodeAssemblerTester m(isolate, descriptor); |
65 m.Return(m.NumberConstant(0.5)); | 67 m.Return(m.NumberConstant(0.5)); |
66 Handle<Code> code = data.GenerateCode(); | 68 Handle<Code> code = m.GenerateCode(); |
67 FunctionTester ft(code); | 69 FunctionTester ft(descriptor, code); |
68 MaybeHandle<Object> result = ft.Call(); | 70 MaybeHandle<Object> result = ft.Call(); |
69 CHECK_EQ(0.5, Handle<HeapNumber>::cast(result.ToHandleChecked())->value()); | 71 CHECK_EQ(0.5, Handle<HeapNumber>::cast(result.ToHandleChecked())->value()); |
70 } | 72 } |
71 | 73 |
72 TEST(SimpleCallRuntime1Arg) { | 74 TEST(SimpleCallRuntime1Arg) { |
73 Isolate* isolate(CcTest::InitIsolateOnce()); | 75 Isolate* isolate(CcTest::InitIsolateOnce()); |
74 CodeAssemblerTester data(isolate); | 76 VoidDescriptor descriptor(isolate); |
75 CodeAssembler m(data.state()); | 77 CodeAssemblerTester m(isolate, descriptor); |
76 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); | 78 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); |
77 Node* b = SmiTag(m, m.Int32Constant(0)); | 79 Node* b = SmiTag(m, m.Int32Constant(0)); |
78 m.Return(m.CallRuntime(Runtime::kNumberToSmi, context, b)); | 80 m.Return(m.CallRuntime(Runtime::kNumberToSmi, context, b)); |
79 Handle<Code> code = data.GenerateCode(); | 81 Handle<Code> code = m.GenerateCode(); |
80 FunctionTester ft(code); | 82 FunctionTester ft(descriptor, code); |
81 MaybeHandle<Object> result = ft.Call(); | 83 MaybeHandle<Object> result = ft.Call(); |
82 CHECK_EQ(0, Handle<Smi>::cast(result.ToHandleChecked())->value()); | 84 CHECK_EQ(0, Handle<Smi>::cast(result.ToHandleChecked())->value()); |
83 } | 85 } |
84 | 86 |
85 TEST(SimpleTailCallRuntime1Arg) { | 87 TEST(SimpleTailCallRuntime1Arg) { |
86 Isolate* isolate(CcTest::InitIsolateOnce()); | 88 Isolate* isolate(CcTest::InitIsolateOnce()); |
87 CodeAssemblerTester data(isolate); | 89 VoidDescriptor descriptor(isolate); |
88 CodeAssembler m(data.state()); | 90 CodeAssemblerTester m(isolate, descriptor); |
89 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); | 91 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); |
90 Node* b = SmiTag(m, m.Int32Constant(0)); | 92 Node* b = SmiTag(m, m.Int32Constant(0)); |
91 m.TailCallRuntime(Runtime::kNumberToSmi, context, b); | 93 m.TailCallRuntime(Runtime::kNumberToSmi, context, b); |
92 Handle<Code> code = data.GenerateCode(); | 94 Handle<Code> code = m.GenerateCode(); |
93 FunctionTester ft(code); | 95 FunctionTester ft(descriptor, code); |
94 MaybeHandle<Object> result = ft.Call(); | 96 MaybeHandle<Object> result = ft.Call(); |
95 CHECK_EQ(0, Handle<Smi>::cast(result.ToHandleChecked())->value()); | 97 CHECK_EQ(0, Handle<Smi>::cast(result.ToHandleChecked())->value()); |
96 } | 98 } |
97 | 99 |
98 TEST(SimpleCallRuntime2Arg) { | 100 TEST(SimpleCallRuntime2Arg) { |
99 Isolate* isolate(CcTest::InitIsolateOnce()); | 101 Isolate* isolate(CcTest::InitIsolateOnce()); |
100 CodeAssemblerTester data(isolate); | 102 VoidDescriptor descriptor(isolate); |
101 CodeAssembler m(data.state()); | 103 CodeAssemblerTester m(isolate, descriptor); |
102 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); | 104 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); |
103 Node* a = SmiTag(m, m.Int32Constant(2)); | 105 Node* a = SmiTag(m, m.Int32Constant(2)); |
104 Node* b = SmiTag(m, m.Int32Constant(4)); | 106 Node* b = SmiTag(m, m.Int32Constant(4)); |
105 m.Return(m.CallRuntime(Runtime::kAdd, context, a, b)); | 107 m.Return(m.CallRuntime(Runtime::kAdd, context, a, b)); |
106 Handle<Code> code = data.GenerateCode(); | 108 Handle<Code> code = m.GenerateCode(); |
107 FunctionTester ft(code); | 109 FunctionTester ft(descriptor, code); |
108 MaybeHandle<Object> result = ft.Call(); | 110 MaybeHandle<Object> result = ft.Call(); |
109 CHECK_EQ(6, Handle<Smi>::cast(result.ToHandleChecked())->value()); | 111 CHECK_EQ(6, Handle<Smi>::cast(result.ToHandleChecked())->value()); |
110 } | 112 } |
111 | 113 |
112 TEST(SimpleTailCallRuntime2Arg) { | 114 TEST(SimpleTailCallRuntime2Arg) { |
113 Isolate* isolate(CcTest::InitIsolateOnce()); | 115 Isolate* isolate(CcTest::InitIsolateOnce()); |
114 CodeAssemblerTester data(isolate); | 116 VoidDescriptor descriptor(isolate); |
115 CodeAssembler m(data.state()); | 117 CodeAssemblerTester m(isolate, descriptor); |
116 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); | 118 Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); |
117 Node* a = SmiTag(m, m.Int32Constant(2)); | 119 Node* a = SmiTag(m, m.Int32Constant(2)); |
118 Node* b = SmiTag(m, m.Int32Constant(4)); | 120 Node* b = SmiTag(m, m.Int32Constant(4)); |
119 m.TailCallRuntime(Runtime::kAdd, context, a, b); | 121 m.TailCallRuntime(Runtime::kAdd, context, a, b); |
120 Handle<Code> code = data.GenerateCode(); | 122 Handle<Code> code = m.GenerateCode(); |
121 FunctionTester ft(code); | 123 FunctionTester ft(descriptor, code); |
122 MaybeHandle<Object> result = ft.Call(); | 124 MaybeHandle<Object> result = ft.Call(); |
123 CHECK_EQ(6, Handle<Smi>::cast(result.ToHandleChecked())->value()); | 125 CHECK_EQ(6, Handle<Smi>::cast(result.ToHandleChecked())->value()); |
124 } | 126 } |
125 | 127 |
126 namespace { | 128 namespace { |
127 | 129 |
128 Handle<JSFunction> CreateSumAllArgumentsFunction(FunctionTester& ft) { | 130 Handle<JSFunction> CreateSumAllArgumentsFunction(FunctionTester& ft) { |
129 const char* source = | 131 const char* source = |
130 "(function() {\n" | 132 "(function() {\n" |
131 " var sum = 0 + this;\n" | 133 " var sum = 0 + this;\n" |
132 " for (var i = 0; i < arguments.length; i++) {\n" | 134 " for (var i = 0; i < arguments.length; i++) {\n" |
133 " sum += arguments[i];\n" | 135 " sum += arguments[i];\n" |
134 " }\n" | 136 " }\n" |
135 " return sum;\n" | 137 " return sum;\n" |
136 "})"; | 138 "})"; |
137 return ft.NewFunction(source); | 139 return ft.NewFunction(source); |
138 } | 140 } |
139 | 141 |
140 } // namespace | 142 } // namespace |
141 | 143 |
142 TEST(SimpleCallJSFunction0Arg) { | 144 TEST(SimpleCallJSFunction0Arg) { |
143 Isolate* isolate(CcTest::InitIsolateOnce()); | 145 Isolate* isolate(CcTest::InitIsolateOnce()); |
144 const int kNumParams = 1; | 146 const int kNumParams = 1; |
145 CodeAssemblerTester data(isolate, kNumParams); | 147 CodeAssemblerTester m(isolate, kNumParams); |
146 CodeAssembler m(data.state()); | |
147 { | 148 { |
148 Node* function = m.Parameter(0); | 149 Node* function = m.Parameter(0); |
149 Node* context = m.Parameter(kNumParams + 2); | 150 Node* context = m.Parameter(kNumParams + 2); |
150 | 151 |
151 Node* receiver = SmiTag(m, m.Int32Constant(42)); | 152 Node* receiver = SmiTag(m, m.Int32Constant(42)); |
152 | 153 |
153 Callable callable = CodeFactory::Call(isolate); | 154 Callable callable = CodeFactory::Call(isolate); |
154 Node* result = m.CallJS(callable, context, function, receiver); | 155 Node* result = m.CallJS(callable, context, function, receiver); |
155 m.Return(result); | 156 m.Return(result); |
156 } | 157 } |
157 Handle<Code> code = data.GenerateCode(); | 158 Handle<Code> code = m.GenerateCode(); |
158 FunctionTester ft(code, kNumParams); | 159 FunctionTester ft(code, kNumParams); |
159 | 160 |
160 Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); | 161 Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); |
161 MaybeHandle<Object> result = ft.Call(sum); | 162 MaybeHandle<Object> result = ft.Call(sum); |
162 CHECK_EQ(Smi::FromInt(42), *result.ToHandleChecked()); | 163 CHECK_EQ(Smi::FromInt(42), *result.ToHandleChecked()); |
163 } | 164 } |
164 | 165 |
165 TEST(SimpleCallJSFunction1Arg) { | 166 TEST(SimpleCallJSFunction1Arg) { |
166 Isolate* isolate(CcTest::InitIsolateOnce()); | 167 Isolate* isolate(CcTest::InitIsolateOnce()); |
167 const int kNumParams = 2; | 168 const int kNumParams = 2; |
168 CodeAssemblerTester data(isolate, kNumParams); | 169 CodeAssemblerTester m(isolate, kNumParams); |
169 CodeAssembler m(data.state()); | |
170 { | 170 { |
171 Node* function = m.Parameter(0); | 171 Node* function = m.Parameter(0); |
172 Node* context = m.Parameter(1); | 172 Node* context = m.Parameter(1); |
173 | 173 |
174 Node* receiver = SmiTag(m, m.Int32Constant(42)); | 174 Node* receiver = SmiTag(m, m.Int32Constant(42)); |
175 Node* a = SmiTag(m, m.Int32Constant(13)); | 175 Node* a = SmiTag(m, m.Int32Constant(13)); |
176 | 176 |
177 Callable callable = CodeFactory::Call(isolate); | 177 Callable callable = CodeFactory::Call(isolate); |
178 Node* result = m.CallJS(callable, context, function, receiver, a); | 178 Node* result = m.CallJS(callable, context, function, receiver, a); |
179 m.Return(result); | 179 m.Return(result); |
180 } | 180 } |
181 Handle<Code> code = data.GenerateCode(); | 181 Handle<Code> code = m.GenerateCode(); |
182 FunctionTester ft(code, kNumParams); | 182 FunctionTester ft(code, kNumParams); |
183 | 183 |
184 Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); | 184 Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); |
185 MaybeHandle<Object> result = ft.Call(sum); | 185 MaybeHandle<Object> result = ft.Call(sum); |
186 CHECK_EQ(Smi::FromInt(55), *result.ToHandleChecked()); | 186 CHECK_EQ(Smi::FromInt(55), *result.ToHandleChecked()); |
187 } | 187 } |
188 | 188 |
189 TEST(SimpleCallJSFunction2Arg) { | 189 TEST(SimpleCallJSFunction2Arg) { |
190 Isolate* isolate(CcTest::InitIsolateOnce()); | 190 Isolate* isolate(CcTest::InitIsolateOnce()); |
191 const int kNumParams = 2; | 191 const int kNumParams = 2; |
192 CodeAssemblerTester data(isolate, kNumParams); | 192 CodeAssemblerTester m(isolate, kNumParams); |
193 CodeAssembler m(data.state()); | |
194 { | 193 { |
195 Node* function = m.Parameter(0); | 194 Node* function = m.Parameter(0); |
196 Node* context = m.Parameter(1); | 195 Node* context = m.Parameter(1); |
197 | 196 |
198 Node* receiver = SmiTag(m, m.Int32Constant(42)); | 197 Node* receiver = SmiTag(m, m.Int32Constant(42)); |
199 Node* a = SmiTag(m, m.Int32Constant(13)); | 198 Node* a = SmiTag(m, m.Int32Constant(13)); |
200 Node* b = SmiTag(m, m.Int32Constant(153)); | 199 Node* b = SmiTag(m, m.Int32Constant(153)); |
201 | 200 |
202 Callable callable = CodeFactory::Call(isolate); | 201 Callable callable = CodeFactory::Call(isolate); |
203 Node* result = m.CallJS(callable, context, function, receiver, a, b); | 202 Node* result = m.CallJS(callable, context, function, receiver, a, b); |
204 m.Return(result); | 203 m.Return(result); |
205 } | 204 } |
206 Handle<Code> code = data.GenerateCode(); | 205 Handle<Code> code = m.GenerateCode(); |
207 FunctionTester ft(code, kNumParams); | 206 FunctionTester ft(code, kNumParams); |
208 | 207 |
209 Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); | 208 Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); |
210 MaybeHandle<Object> result = ft.Call(sum); | 209 MaybeHandle<Object> result = ft.Call(sum); |
211 CHECK_EQ(Smi::FromInt(208), *result.ToHandleChecked()); | 210 CHECK_EQ(Smi::FromInt(208), *result.ToHandleChecked()); |
212 } | 211 } |
213 | 212 |
214 TEST(VariableMerge1) { | 213 TEST(VariableMerge1) { |
215 Isolate* isolate(CcTest::InitIsolateOnce()); | 214 Isolate* isolate(CcTest::InitIsolateOnce()); |
216 CodeAssemblerTester data(isolate); | 215 VoidDescriptor descriptor(isolate); |
217 CodeAssembler m(data.state()); | 216 CodeAssemblerTester m(isolate, descriptor); |
218 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); | 217 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); |
219 CodeStubAssembler::Label l1(&m), l2(&m), merge(&m); | 218 CodeStubAssembler::Label l1(&m), l2(&m), merge(&m); |
220 Node* temp = m.Int32Constant(0); | 219 Node* temp = m.Int32Constant(0); |
221 var1.Bind(temp); | 220 var1.Bind(temp); |
222 m.Branch(m.Int32Constant(1), &l1, &l2); | 221 m.Branch(m.Int32Constant(1), &l1, &l2); |
223 m.Bind(&l1); | 222 m.Bind(&l1); |
224 CHECK_EQ(var1.value(), temp); | 223 CHECK_EQ(var1.value(), temp); |
225 m.Goto(&merge); | 224 m.Goto(&merge); |
226 m.Bind(&l2); | 225 m.Bind(&l2); |
227 CHECK_EQ(var1.value(), temp); | 226 CHECK_EQ(var1.value(), temp); |
228 m.Goto(&merge); | 227 m.Goto(&merge); |
229 m.Bind(&merge); | 228 m.Bind(&merge); |
230 CHECK_EQ(var1.value(), temp); | 229 CHECK_EQ(var1.value(), temp); |
231 } | 230 } |
232 | 231 |
233 TEST(VariableMerge2) { | 232 TEST(VariableMerge2) { |
234 Isolate* isolate(CcTest::InitIsolateOnce()); | 233 Isolate* isolate(CcTest::InitIsolateOnce()); |
235 CodeAssemblerTester data(isolate); | 234 VoidDescriptor descriptor(isolate); |
236 CodeAssembler m(data.state()); | 235 CodeAssemblerTester m(isolate, descriptor); |
237 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); | 236 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); |
238 CodeStubAssembler::Label l1(&m), l2(&m), merge(&m); | 237 CodeStubAssembler::Label l1(&m), l2(&m), merge(&m); |
239 Node* temp = m.Int32Constant(0); | 238 Node* temp = m.Int32Constant(0); |
240 var1.Bind(temp); | 239 var1.Bind(temp); |
241 m.Branch(m.Int32Constant(1), &l1, &l2); | 240 m.Branch(m.Int32Constant(1), &l1, &l2); |
242 m.Bind(&l1); | 241 m.Bind(&l1); |
243 CHECK_EQ(var1.value(), temp); | 242 CHECK_EQ(var1.value(), temp); |
244 m.Goto(&merge); | 243 m.Goto(&merge); |
245 m.Bind(&l2); | 244 m.Bind(&l2); |
246 Node* temp2 = m.Int32Constant(2); | 245 Node* temp2 = m.Int32Constant(2); |
247 var1.Bind(temp2); | 246 var1.Bind(temp2); |
248 CHECK_EQ(var1.value(), temp2); | 247 CHECK_EQ(var1.value(), temp2); |
249 m.Goto(&merge); | 248 m.Goto(&merge); |
250 m.Bind(&merge); | 249 m.Bind(&merge); |
251 CHECK_NE(var1.value(), temp); | 250 CHECK_NE(var1.value(), temp); |
252 } | 251 } |
253 | 252 |
254 TEST(VariableMerge3) { | 253 TEST(VariableMerge3) { |
255 Isolate* isolate(CcTest::InitIsolateOnce()); | 254 Isolate* isolate(CcTest::InitIsolateOnce()); |
256 CodeAssemblerTester data(isolate); | 255 VoidDescriptor descriptor(isolate); |
257 CodeAssembler m(data.state()); | 256 CodeAssemblerTester m(isolate, descriptor); |
258 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); | 257 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); |
259 CodeStubAssembler::Variable var2(&m, MachineRepresentation::kTagged); | 258 CodeStubAssembler::Variable var2(&m, MachineRepresentation::kTagged); |
260 CodeStubAssembler::Label l1(&m), l2(&m), merge(&m); | 259 CodeStubAssembler::Label l1(&m), l2(&m), merge(&m); |
261 Node* temp = m.Int32Constant(0); | 260 Node* temp = m.Int32Constant(0); |
262 var1.Bind(temp); | 261 var1.Bind(temp); |
263 var2.Bind(temp); | 262 var2.Bind(temp); |
264 m.Branch(m.Int32Constant(1), &l1, &l2); | 263 m.Branch(m.Int32Constant(1), &l1, &l2); |
265 m.Bind(&l1); | 264 m.Bind(&l1); |
266 CHECK_EQ(var1.value(), temp); | 265 CHECK_EQ(var1.value(), temp); |
267 m.Goto(&merge); | 266 m.Goto(&merge); |
268 m.Bind(&l2); | 267 m.Bind(&l2); |
269 Node* temp2 = m.Int32Constant(2); | 268 Node* temp2 = m.Int32Constant(2); |
270 var1.Bind(temp2); | 269 var1.Bind(temp2); |
271 CHECK_EQ(var1.value(), temp2); | 270 CHECK_EQ(var1.value(), temp2); |
272 m.Goto(&merge); | 271 m.Goto(&merge); |
273 m.Bind(&merge); | 272 m.Bind(&merge); |
274 CHECK_NE(var1.value(), temp); | 273 CHECK_NE(var1.value(), temp); |
275 CHECK_NE(var1.value(), temp2); | 274 CHECK_NE(var1.value(), temp2); |
276 CHECK_EQ(var2.value(), temp); | 275 CHECK_EQ(var2.value(), temp); |
277 } | 276 } |
278 | 277 |
279 TEST(VariableMergeBindFirst) { | 278 TEST(VariableMergeBindFirst) { |
280 Isolate* isolate(CcTest::InitIsolateOnce()); | 279 Isolate* isolate(CcTest::InitIsolateOnce()); |
281 CodeAssemblerTester data(isolate); | 280 VoidDescriptor descriptor(isolate); |
282 CodeAssembler m(data.state()); | 281 CodeAssemblerTester m(isolate, descriptor); |
283 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); | 282 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); |
284 CodeStubAssembler::Label l1(&m), l2(&m), merge(&m, &var1), end(&m); | 283 CodeStubAssembler::Label l1(&m), l2(&m), merge(&m, &var1), end(&m); |
285 Node* temp = m.Int32Constant(0); | 284 Node* temp = m.Int32Constant(0); |
286 var1.Bind(temp); | 285 var1.Bind(temp); |
287 m.Branch(m.Int32Constant(1), &l1, &l2); | 286 m.Branch(m.Int32Constant(1), &l1, &l2); |
288 m.Bind(&l1); | 287 m.Bind(&l1); |
289 CHECK_EQ(var1.value(), temp); | 288 CHECK_EQ(var1.value(), temp); |
290 m.Goto(&merge); | 289 m.Goto(&merge); |
291 m.Bind(&merge); | 290 m.Bind(&merge); |
292 CHECK(var1.value() != temp); | 291 CHECK(var1.value() != temp); |
293 CHECK(var1.value() != nullptr); | 292 CHECK(var1.value() != nullptr); |
294 m.Goto(&end); | 293 m.Goto(&end); |
295 m.Bind(&l2); | 294 m.Bind(&l2); |
296 Node* temp2 = m.Int32Constant(2); | 295 Node* temp2 = m.Int32Constant(2); |
297 var1.Bind(temp2); | 296 var1.Bind(temp2); |
298 CHECK_EQ(var1.value(), temp2); | 297 CHECK_EQ(var1.value(), temp2); |
299 m.Goto(&merge); | 298 m.Goto(&merge); |
300 m.Bind(&end); | 299 m.Bind(&end); |
301 CHECK(var1.value() != temp); | 300 CHECK(var1.value() != temp); |
302 CHECK(var1.value() != nullptr); | 301 CHECK(var1.value() != nullptr); |
303 } | 302 } |
304 | 303 |
305 TEST(VariableMergeSwitch) { | 304 TEST(VariableMergeSwitch) { |
306 Isolate* isolate(CcTest::InitIsolateOnce()); | 305 Isolate* isolate(CcTest::InitIsolateOnce()); |
307 CodeAssemblerTester data(isolate); | 306 VoidDescriptor descriptor(isolate); |
308 CodeAssembler m(data.state()); | 307 CodeAssemblerTester m(isolate, descriptor); |
309 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); | 308 CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged); |
310 CodeStubAssembler::Label l1(&m), l2(&m), default_label(&m); | 309 CodeStubAssembler::Label l1(&m), l2(&m), default_label(&m); |
311 CodeStubAssembler::Label* labels[] = {&l1, &l2}; | 310 CodeStubAssembler::Label* labels[] = {&l1, &l2}; |
312 int32_t values[] = {1, 2}; | 311 int32_t values[] = {1, 2}; |
313 Node* temp = m.Int32Constant(0); | 312 Node* temp = m.Int32Constant(0); |
314 var1.Bind(temp); | 313 var1.Bind(temp); |
315 m.Switch(m.Int32Constant(2), &default_label, values, labels, 2); | 314 m.Switch(m.Int32Constant(2), &default_label, values, labels, 2); |
316 m.Bind(&l1); | 315 m.Bind(&l1); |
317 DCHECK_EQ(temp, var1.value()); | 316 DCHECK_EQ(temp, var1.value()); |
318 m.Return(temp); | 317 m.Return(temp); |
319 m.Bind(&l2); | 318 m.Bind(&l2); |
320 DCHECK_EQ(temp, var1.value()); | 319 DCHECK_EQ(temp, var1.value()); |
321 m.Return(temp); | 320 m.Return(temp); |
322 m.Bind(&default_label); | 321 m.Bind(&default_label); |
323 DCHECK_EQ(temp, var1.value()); | 322 DCHECK_EQ(temp, var1.value()); |
324 m.Return(temp); | 323 m.Return(temp); |
325 } | 324 } |
326 | 325 |
327 TEST(SplitEdgeBranchMerge) { | 326 TEST(SplitEdgeBranchMerge) { |
328 Isolate* isolate(CcTest::InitIsolateOnce()); | 327 Isolate* isolate(CcTest::InitIsolateOnce()); |
329 CodeAssemblerTester data(isolate); | 328 VoidDescriptor descriptor(isolate); |
330 CodeAssembler m(data.state()); | 329 CodeAssemblerTester m(isolate, descriptor); |
331 CodeStubAssembler::Label l1(&m), merge(&m); | 330 CodeStubAssembler::Label l1(&m), merge(&m); |
332 m.Branch(m.Int32Constant(1), &l1, &merge); | 331 m.Branch(m.Int32Constant(1), &l1, &merge); |
333 m.Bind(&l1); | 332 m.Bind(&l1); |
334 m.Goto(&merge); | 333 m.Goto(&merge); |
335 m.Bind(&merge); | 334 m.Bind(&merge); |
336 USE(data.GenerateCode()); | 335 USE(m.GenerateCode()); |
337 } | 336 } |
338 | 337 |
339 TEST(SplitEdgeSwitchMerge) { | 338 TEST(SplitEdgeSwitchMerge) { |
340 Isolate* isolate(CcTest::InitIsolateOnce()); | 339 Isolate* isolate(CcTest::InitIsolateOnce()); |
341 CodeAssemblerTester data(isolate); | 340 VoidDescriptor descriptor(isolate); |
342 CodeAssembler m(data.state()); | 341 CodeAssemblerTester m(isolate, descriptor); |
343 CodeStubAssembler::Label l1(&m), l2(&m), l3(&m), default_label(&m); | 342 CodeStubAssembler::Label l1(&m), l2(&m), l3(&m), default_label(&m); |
344 CodeStubAssembler::Label* labels[] = {&l1, &l2}; | 343 CodeStubAssembler::Label* labels[] = {&l1, &l2}; |
345 int32_t values[] = {1, 2}; | 344 int32_t values[] = {1, 2}; |
346 m.Branch(m.Int32Constant(1), &l3, &l1); | 345 m.Branch(m.Int32Constant(1), &l3, &l1); |
347 m.Bind(&l3); | 346 m.Bind(&l3); |
348 m.Switch(m.Int32Constant(2), &default_label, values, labels, 2); | 347 m.Switch(m.Int32Constant(2), &default_label, values, labels, 2); |
349 m.Bind(&l1); | 348 m.Bind(&l1); |
350 m.Goto(&l2); | 349 m.Goto(&l2); |
351 m.Bind(&l2); | 350 m.Bind(&l2); |
352 m.Goto(&default_label); | 351 m.Goto(&default_label); |
353 m.Bind(&default_label); | 352 m.Bind(&default_label); |
354 USE(data.GenerateCode()); | 353 USE(m.GenerateCode()); |
355 } | 354 } |
356 | 355 |
357 TEST(TestToConstant) { | 356 TEST(TestToConstant) { |
358 Isolate* isolate(CcTest::InitIsolateOnce()); | 357 Isolate* isolate(CcTest::InitIsolateOnce()); |
359 CodeAssemblerTester data(isolate); | 358 VoidDescriptor descriptor(isolate); |
360 CodeAssembler m(data.state()); | 359 CodeAssemblerTester m(isolate, descriptor); |
361 int32_t value32; | 360 int32_t value32; |
362 int64_t value64; | 361 int64_t value64; |
363 Node* a = m.Int32Constant(5); | 362 Node* a = m.Int32Constant(5); |
364 CHECK(m.ToInt32Constant(a, value32)); | 363 CHECK(m.ToInt32Constant(a, value32)); |
365 CHECK(m.ToInt64Constant(a, value64)); | 364 CHECK(m.ToInt64Constant(a, value64)); |
366 | 365 |
367 a = m.Int64Constant(static_cast<int64_t>(1) << 32); | 366 a = m.Int64Constant(static_cast<int64_t>(1) << 32); |
368 CHECK(!m.ToInt32Constant(a, value32)); | 367 CHECK(!m.ToInt32Constant(a, value32)); |
369 CHECK(m.ToInt64Constant(a, value64)); | 368 CHECK(m.ToInt64Constant(a, value64)); |
370 | 369 |
371 a = m.Int64Constant(13); | 370 a = m.Int64Constant(13); |
372 CHECK(m.ToInt32Constant(a, value32)); | 371 CHECK(m.ToInt32Constant(a, value32)); |
373 CHECK(m.ToInt64Constant(a, value64)); | 372 CHECK(m.ToInt64Constant(a, value64)); |
374 | 373 |
375 a = UndefinedConstant(m); | 374 a = UndefinedConstant(m); |
376 CHECK(!m.ToInt32Constant(a, value32)); | 375 CHECK(!m.ToInt32Constant(a, value32)); |
377 CHECK(!m.ToInt64Constant(a, value64)); | 376 CHECK(!m.ToInt64Constant(a, value64)); |
378 | 377 |
379 a = UndefinedConstant(m); | 378 a = UndefinedConstant(m); |
380 CHECK(!m.ToInt32Constant(a, value32)); | 379 CHECK(!m.ToInt32Constant(a, value32)); |
381 CHECK(!m.ToInt64Constant(a, value64)); | 380 CHECK(!m.ToInt64Constant(a, value64)); |
382 } | 381 } |
383 | 382 |
384 TEST(DeferredCodePhiHints) { | 383 TEST(DeferredCodePhiHints) { |
385 typedef compiler::Node Node; | 384 typedef compiler::Node Node; |
386 typedef CodeStubAssembler::Label Label; | 385 typedef CodeStubAssembler::Label Label; |
387 typedef CodeStubAssembler::Variable Variable; | 386 typedef CodeStubAssembler::Variable Variable; |
388 Isolate* isolate(CcTest::InitIsolateOnce()); | 387 Isolate* isolate(CcTest::InitIsolateOnce()); |
389 CodeAssemblerTester data(isolate); | 388 VoidDescriptor descriptor(isolate); |
390 CodeAssembler m(data.state()); | 389 CodeAssemblerTester m(isolate, descriptor); |
391 Label block1(&m, Label::kDeferred); | 390 Label block1(&m, Label::kDeferred); |
392 m.Goto(&block1); | 391 m.Goto(&block1); |
393 m.Bind(&block1); | 392 m.Bind(&block1); |
394 { | 393 { |
395 Variable var_object(&m, MachineRepresentation::kTagged); | 394 Variable var_object(&m, MachineRepresentation::kTagged); |
396 Label loop(&m, &var_object); | 395 Label loop(&m, &var_object); |
397 var_object.Bind(m.IntPtrConstant(0)); | 396 var_object.Bind(m.IntPtrConstant(0)); |
398 m.Goto(&loop); | 397 m.Goto(&loop); |
399 m.Bind(&loop); | 398 m.Bind(&loop); |
400 { | 399 { |
401 Node* map = LoadObjectField(m, var_object.value(), JSObject::kMapOffset); | 400 Node* map = LoadObjectField(m, var_object.value(), JSObject::kMapOffset); |
402 var_object.Bind(map); | 401 var_object.Bind(map); |
403 m.Goto(&loop); | 402 m.Goto(&loop); |
404 } | 403 } |
405 } | 404 } |
406 CHECK(!data.GenerateCode().is_null()); | 405 CHECK(!m.GenerateCode().is_null()); |
407 } | 406 } |
408 | 407 |
409 TEST(TestOutOfScopeVariable) { | 408 TEST(TestOutOfScopeVariable) { |
410 typedef CodeStubAssembler::Label Label; | 409 typedef CodeStubAssembler::Label Label; |
411 typedef CodeStubAssembler::Variable Variable; | 410 typedef CodeStubAssembler::Variable Variable; |
412 Isolate* isolate(CcTest::InitIsolateOnce()); | 411 Isolate* isolate(CcTest::InitIsolateOnce()); |
413 CodeAssemblerTester data(isolate); | 412 VoidDescriptor descriptor(isolate); |
414 CodeAssembler m(data.state()); | 413 CodeAssemblerTester m(isolate, descriptor); |
415 Label block1(&m); | 414 Label block1(&m); |
416 Label block2(&m); | 415 Label block2(&m); |
417 Label block3(&m); | 416 Label block3(&m); |
418 Label block4(&m); | 417 Label block4(&m); |
419 m.Branch(m.WordEqual(m.Parameter(0), m.IntPtrConstant(0)), &block1, &block4); | 418 m.Branch(m.WordEqual(m.Parameter(0), m.IntPtrConstant(0)), &block1, &block4); |
420 m.Bind(&block4); | 419 m.Bind(&block4); |
421 { | 420 { |
422 Variable var_object(&m, MachineRepresentation::kTagged); | 421 Variable var_object(&m, MachineRepresentation::kTagged); |
423 m.Branch(m.WordEqual(m.Parameter(0), m.IntPtrConstant(0)), &block2, | 422 m.Branch(m.WordEqual(m.Parameter(0), m.IntPtrConstant(0)), &block2, |
424 &block3); | 423 &block3); |
425 | 424 |
426 m.Bind(&block2); | 425 m.Bind(&block2); |
427 var_object.Bind(m.IntPtrConstant(55)); | 426 var_object.Bind(m.IntPtrConstant(55)); |
428 m.Goto(&block1); | 427 m.Goto(&block1); |
429 | 428 |
430 m.Bind(&block3); | 429 m.Bind(&block3); |
431 var_object.Bind(m.IntPtrConstant(66)); | 430 var_object.Bind(m.IntPtrConstant(66)); |
432 m.Goto(&block1); | 431 m.Goto(&block1); |
433 } | 432 } |
434 m.Bind(&block1); | 433 m.Bind(&block1); |
435 CHECK(!data.GenerateCode().is_null()); | 434 CHECK(!m.GenerateCode().is_null()); |
436 } | 435 } |
437 | 436 |
438 } // namespace compiler | 437 } // namespace compiler |
439 } // namespace internal | 438 } // namespace internal |
440 } // namespace v8 | 439 } // namespace v8 |
OLD | NEW |