OLD | NEW |
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 <limits> | 5 #include <limits> |
6 | 6 |
| 7 #include "src/compiler/access-builder.h" |
7 #include "src/compiler/control-builders.h" | 8 #include "src/compiler/control-builders.h" |
8 #include "src/compiler/generic-node-inl.h" | 9 #include "src/compiler/generic-node-inl.h" |
9 #include "src/compiler/graph-visualizer.h" | 10 #include "src/compiler/graph-visualizer.h" |
10 #include "src/compiler/node-properties-inl.h" | 11 #include "src/compiler/node-properties-inl.h" |
11 #include "src/compiler/pipeline.h" | 12 #include "src/compiler/pipeline.h" |
12 #include "src/compiler/representation-change.h" | 13 #include "src/compiler/representation-change.h" |
13 #include "src/compiler/simplified-lowering.h" | 14 #include "src/compiler/simplified-lowering.h" |
14 #include "src/compiler/simplified-node-factory.h" | 15 #include "src/compiler/simplified-node-factory.h" |
15 #include "src/compiler/typer.h" | 16 #include "src/compiler/typer.h" |
16 #include "src/compiler/verifier.h" | 17 #include "src/compiler/verifier.h" |
(...skipping 29 matching lines...) Expand all Loading... |
46 void LowerAllNodes() { | 47 void LowerAllNodes() { |
47 this->End(); | 48 this->End(); |
48 lowering.LowerAllNodes(); | 49 lowering.LowerAllNodes(); |
49 } | 50 } |
50 | 51 |
51 Factory* factory() { return this->isolate()->factory(); } | 52 Factory* factory() { return this->isolate()->factory(); } |
52 Heap* heap() { return this->isolate()->heap(); } | 53 Heap* heap() { return this->isolate()->heap(); } |
53 }; | 54 }; |
54 | 55 |
55 | 56 |
56 // TODO(dcarney): find a home for these functions. | |
57 namespace { | |
58 | |
59 FieldAccess ForJSObjectMap() { | |
60 FieldAccess access = {kTaggedBase, JSObject::kMapOffset, Handle<Name>(), | |
61 Type::Any(), kMachAnyTagged}; | |
62 return access; | |
63 } | |
64 | |
65 | |
66 FieldAccess ForJSObjectProperties() { | |
67 FieldAccess access = {kTaggedBase, JSObject::kPropertiesOffset, | |
68 Handle<Name>(), Type::Any(), kMachAnyTagged}; | |
69 return access; | |
70 } | |
71 | |
72 | |
73 FieldAccess ForArrayBufferBackingStore() { | |
74 FieldAccess access = { | |
75 kTaggedBase, JSArrayBuffer::kBackingStoreOffset, Handle<Name>(), | |
76 Type::UntaggedPtr(), kMachPtr, | |
77 }; | |
78 return access; | |
79 } | |
80 | |
81 | |
82 ElementAccess ForFixedArrayElement() { | |
83 ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), | |
84 kMachAnyTagged}; | |
85 return access; | |
86 } | |
87 | |
88 | |
89 ElementAccess ForBackingStoreElement(MachineType rep) { | |
90 ElementAccess access = {kUntaggedBase, | |
91 kNonHeapObjectHeaderSize - kHeapObjectTag, | |
92 Type::Any(), rep}; | |
93 return access; | |
94 } | |
95 } | |
96 | |
97 | |
98 #ifndef V8_TARGET_ARCH_ARM64 | 57 #ifndef V8_TARGET_ARCH_ARM64 |
99 // TODO(titzer): these result in a stub call that doesn't work on ARM64. | 58 // TODO(titzer): these result in a stub call that doesn't work on ARM64. |
100 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc. | 59 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc. |
101 // TODO(titzer): test tagged representation for input to NumberToInt32. | 60 // TODO(titzer): test tagged representation for input to NumberToInt32. |
102 TEST(RunNumberToInt32_float64) { | 61 TEST(RunNumberToInt32_float64) { |
103 // TODO(titzer): explicit load/stores here are only because of representations | 62 // TODO(titzer): explicit load/stores here are only because of representations |
104 double input; | 63 double input; |
105 int32_t result; | 64 int32_t result; |
106 SimplifiedLoweringTester<Object*> t; | 65 SimplifiedLoweringTester<Object*> t; |
107 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), | 66 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 static Handle<JSObject> TestObject() { | 118 static Handle<JSObject> TestObject() { |
160 static int index = 0; | 119 static int index = 0; |
161 char buffer[50]; | 120 char buffer[50]; |
162 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); | 121 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); |
163 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); | 122 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); |
164 } | 123 } |
165 | 124 |
166 | 125 |
167 TEST(RunLoadMap) { | 126 TEST(RunLoadMap) { |
168 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 127 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
169 FieldAccess access = ForJSObjectMap(); | 128 FieldAccess access = AccessBuilder::ForMap(); |
170 Node* load = t.LoadField(access, t.Parameter(0)); | 129 Node* load = t.LoadField(access, t.Parameter(0)); |
171 t.Return(load); | 130 t.Return(load); |
172 | 131 |
173 t.LowerAllNodes(); | 132 t.LowerAllNodes(); |
174 t.GenerateCode(); | 133 t.GenerateCode(); |
175 | 134 |
176 if (Pipeline::SupportedTarget()) { | 135 if (Pipeline::SupportedTarget()) { |
177 Handle<JSObject> src = TestObject(); | 136 Handle<JSObject> src = TestObject(); |
178 Handle<Map> src_map(src->map()); | 137 Handle<Map> src_map(src->map()); |
179 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call | 138 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
180 CHECK_EQ(*src_map, result); | 139 CHECK_EQ(*src_map, result); |
181 } | 140 } |
182 } | 141 } |
183 | 142 |
184 | 143 |
185 TEST(RunStoreMap) { | 144 TEST(RunStoreMap) { |
186 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); | 145 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); |
187 FieldAccess access = ForJSObjectMap(); | 146 FieldAccess access = AccessBuilder::ForMap(); |
188 t.StoreField(access, t.Parameter(1), t.Parameter(0)); | 147 t.StoreField(access, t.Parameter(1), t.Parameter(0)); |
189 t.Return(t.jsgraph.TrueConstant()); | 148 t.Return(t.jsgraph.TrueConstant()); |
190 | 149 |
191 t.LowerAllNodes(); | 150 t.LowerAllNodes(); |
192 t.GenerateCode(); | 151 t.GenerateCode(); |
193 | 152 |
194 if (Pipeline::SupportedTarget()) { | 153 if (Pipeline::SupportedTarget()) { |
195 Handle<JSObject> src = TestObject(); | 154 Handle<JSObject> src = TestObject(); |
196 Handle<Map> src_map(src->map()); | 155 Handle<Map> src_map(src->map()); |
197 Handle<JSObject> dst = TestObject(); | 156 Handle<JSObject> dst = TestObject(); |
198 CHECK(src->map() != dst->map()); | 157 CHECK(src->map() != dst->map()); |
199 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call | 158 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call |
200 CHECK(*src_map == dst->map()); | 159 CHECK(*src_map == dst->map()); |
201 } | 160 } |
202 } | 161 } |
203 | 162 |
204 | 163 |
205 TEST(RunLoadProperties) { | 164 TEST(RunLoadProperties) { |
206 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 165 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
207 FieldAccess access = ForJSObjectProperties(); | 166 FieldAccess access = AccessBuilder::ForJSObjectProperties(); |
208 Node* load = t.LoadField(access, t.Parameter(0)); | 167 Node* load = t.LoadField(access, t.Parameter(0)); |
209 t.Return(load); | 168 t.Return(load); |
210 | 169 |
211 t.LowerAllNodes(); | 170 t.LowerAllNodes(); |
212 t.GenerateCode(); | 171 t.GenerateCode(); |
213 | 172 |
214 if (Pipeline::SupportedTarget()) { | 173 if (Pipeline::SupportedTarget()) { |
215 Handle<JSObject> src = TestObject(); | 174 Handle<JSObject> src = TestObject(); |
216 Handle<FixedArray> src_props(src->properties()); | 175 Handle<FixedArray> src_props(src->properties()); |
217 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call | 176 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
218 CHECK_EQ(*src_props, result); | 177 CHECK_EQ(*src_props, result); |
219 } | 178 } |
220 } | 179 } |
221 | 180 |
222 | 181 |
223 TEST(RunLoadStoreMap) { | 182 TEST(RunLoadStoreMap) { |
224 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); | 183 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); |
225 FieldAccess access = ForJSObjectMap(); | 184 FieldAccess access = AccessBuilder::ForMap(); |
226 Node* load = t.LoadField(access, t.Parameter(0)); | 185 Node* load = t.LoadField(access, t.Parameter(0)); |
227 t.StoreField(access, t.Parameter(1), load); | 186 t.StoreField(access, t.Parameter(1), load); |
228 t.Return(load); | 187 t.Return(load); |
229 | 188 |
230 t.LowerAllNodes(); | 189 t.LowerAllNodes(); |
231 t.GenerateCode(); | 190 t.GenerateCode(); |
232 | 191 |
233 if (Pipeline::SupportedTarget()) { | 192 if (Pipeline::SupportedTarget()) { |
234 Handle<JSObject> src = TestObject(); | 193 Handle<JSObject> src = TestObject(); |
235 Handle<Map> src_map(src->map()); | 194 Handle<Map> src_map(src->map()); |
236 Handle<JSObject> dst = TestObject(); | 195 Handle<JSObject> dst = TestObject(); |
237 CHECK(src->map() != dst->map()); | 196 CHECK(src->map() != dst->map()); |
238 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call | 197 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call |
239 CHECK(result->IsMap()); | 198 CHECK(result->IsMap()); |
240 CHECK_EQ(*src_map, result); | 199 CHECK_EQ(*src_map, result); |
241 CHECK(*src_map == dst->map()); | 200 CHECK(*src_map == dst->map()); |
242 } | 201 } |
243 } | 202 } |
244 | 203 |
245 | 204 |
246 TEST(RunLoadStoreFixedArrayIndex) { | 205 TEST(RunLoadStoreFixedArrayIndex) { |
247 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 206 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
248 ElementAccess access = ForFixedArrayElement(); | 207 ElementAccess access = AccessBuilder::ForFixedArrayElement(); |
249 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); | 208 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); |
250 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); | 209 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); |
251 t.Return(load); | 210 t.Return(load); |
252 | 211 |
253 t.LowerAllNodes(); | 212 t.LowerAllNodes(); |
254 t.GenerateCode(); | 213 t.GenerateCode(); |
255 | 214 |
256 if (Pipeline::SupportedTarget()) { | 215 if (Pipeline::SupportedTarget()) { |
257 Handle<FixedArray> array = t.factory()->NewFixedArray(2); | 216 Handle<FixedArray> array = t.factory()->NewFixedArray(2); |
258 Handle<JSObject> src = TestObject(); | 217 Handle<JSObject> src = TestObject(); |
259 Handle<JSObject> dst = TestObject(); | 218 Handle<JSObject> dst = TestObject(); |
260 array->set(0, *src); | 219 array->set(0, *src); |
261 array->set(1, *dst); | 220 array->set(1, *dst); |
262 Object* result = t.Call(*array); | 221 Object* result = t.Call(*array); |
263 CHECK_EQ(*src, result); | 222 CHECK_EQ(*src, result); |
264 CHECK_EQ(*src, array->get(0)); | 223 CHECK_EQ(*src, array->get(0)); |
265 CHECK_EQ(*src, array->get(1)); | 224 CHECK_EQ(*src, array->get(1)); |
266 } | 225 } |
267 } | 226 } |
268 | 227 |
269 | 228 |
270 TEST(RunLoadStoreArrayBuffer) { | 229 TEST(RunLoadStoreArrayBuffer) { |
271 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 230 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
272 const int index = 12; | 231 const int index = 12; |
273 ElementAccess buffer_access = ForBackingStoreElement(kMachInt8); | 232 ElementAccess buffer_access = |
274 Node* backing_store = | 233 AccessBuilder::ForBackingStoreElement(kMachInt8); |
275 t.LoadField(ForArrayBufferBackingStore(), t.Parameter(0)); | 234 Node* backing_store = t.LoadField( |
| 235 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); |
276 Node* load = | 236 Node* load = |
277 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); | 237 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); |
278 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), | 238 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), |
279 load); | 239 load); |
280 t.Return(t.jsgraph.TrueConstant()); | 240 t.Return(t.jsgraph.TrueConstant()); |
281 | 241 |
282 t.LowerAllNodes(); | 242 t.LowerAllNodes(); |
283 t.GenerateCode(); | 243 t.GenerateCode(); |
284 | 244 |
285 if (Pipeline::SupportedTarget()) { | 245 if (Pipeline::SupportedTarget()) { |
(...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1448 | 1408 |
1449 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1409 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
1450 t.p1, t.start, t.start); | 1410 t.p1, t.start, t.start); |
1451 t.Effect(store); | 1411 t.Effect(store); |
1452 t.Lower(); | 1412 t.Lower(); |
1453 | 1413 |
1454 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1414 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1455 CHECK_EQ(t.p0, store->InputAt(0)); | 1415 CHECK_EQ(t.p0, store->InputAt(0)); |
1456 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); | 1416 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); |
1457 } | 1417 } |
OLD | NEW |