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