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/control-builders.h" | 7 #include "src/compiler/control-builders.h" |
8 #include "src/compiler/generic-node-inl.h" | 8 #include "src/compiler/generic-node-inl.h" |
9 #include "src/compiler/graph-visualizer.h" | 9 #include "src/compiler/graph-visualizer.h" |
10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "test/cctest/compiler/codegen-tester.h" | 22 #include "test/cctest/compiler/codegen-tester.h" |
23 #include "test/cctest/compiler/graph-builder-tester.h" | 23 #include "test/cctest/compiler/graph-builder-tester.h" |
24 #include "test/cctest/compiler/value-helper.h" | 24 #include "test/cctest/compiler/value-helper.h" |
25 | 25 |
26 using namespace v8::internal; | 26 using namespace v8::internal; |
27 using namespace v8::internal::compiler; | 27 using namespace v8::internal::compiler; |
28 | 28 |
29 template <typename ReturnType> | 29 template <typename ReturnType> |
30 class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> { | 30 class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> { |
31 public: | 31 public: |
32 SimplifiedLoweringTester(MachineRepresentation p0 = kMachineLast, | 32 SimplifiedLoweringTester(MachineType p0 = kMachineLast, |
33 MachineRepresentation p1 = kMachineLast, | 33 MachineType p1 = kMachineLast, |
34 MachineRepresentation p2 = kMachineLast, | 34 MachineType p2 = kMachineLast, |
35 MachineRepresentation p3 = kMachineLast, | 35 MachineType p3 = kMachineLast, |
36 MachineRepresentation p4 = kMachineLast) | 36 MachineType p4 = kMachineLast) |
37 : GraphBuilderTester<ReturnType>(p0, p1, p2, p3, p4), | 37 : GraphBuilderTester<ReturnType>(p0, p1, p2, p3, p4), |
38 typer(this->zone()), | 38 typer(this->zone()), |
39 source_positions(this->graph()), | 39 source_positions(this->graph()), |
40 jsgraph(this->graph(), this->common(), &typer), | 40 jsgraph(this->graph(), this->common(), &typer), |
41 lowering(&jsgraph, &source_positions) {} | 41 lowering(&jsgraph, &source_positions) {} |
42 | 42 |
43 Typer typer; | 43 Typer typer; |
44 SourcePositionTable source_positions; | 44 SourcePositionTable source_positions; |
45 JSGraph jsgraph; | 45 JSGraph jsgraph; |
46 SimplifiedLowering lowering; | 46 SimplifiedLowering lowering; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 } | 82 } |
83 | 83 |
84 | 84 |
85 ElementAccess ForFixedArrayElement() { | 85 ElementAccess ForFixedArrayElement() { |
86 ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), | 86 ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), |
87 kMachineTagged}; | 87 kMachineTagged}; |
88 return access; | 88 return access; |
89 } | 89 } |
90 | 90 |
91 | 91 |
92 ElementAccess ForBackingStoreElement(MachineRepresentation rep) { | 92 ElementAccess ForBackingStoreElement(MachineType rep) { |
93 ElementAccess access = {kUntaggedBase, | 93 ElementAccess access = {kUntaggedBase, |
94 kNonHeapObjectHeaderSize - kHeapObjectTag, | 94 kNonHeapObjectHeaderSize - kHeapObjectTag, |
95 Type::Any(), rep}; | 95 Type::Any(), rep}; |
96 return access; | 96 return access; |
97 } | 97 } |
98 } | 98 } |
99 | 99 |
100 | 100 |
101 // Create a simple JSObject with a unique map. | 101 // Create a simple JSObject with a unique map. |
102 static Handle<JSObject> TestObject() { | 102 static Handle<JSObject> TestObject() { |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } | 356 } |
357 | 357 |
358 | 358 |
359 // A helper class for accessing fields and elements of various types, on both | 359 // A helper class for accessing fields and elements of various types, on both |
360 // tagged and untagged base pointers. Contains both tagged and untagged buffers | 360 // tagged and untagged base pointers. Contains both tagged and untagged buffers |
361 // for testing direct memory access from generated code. | 361 // for testing direct memory access from generated code. |
362 template <typename E> | 362 template <typename E> |
363 class AccessTester : public HandleAndZoneScope { | 363 class AccessTester : public HandleAndZoneScope { |
364 public: | 364 public: |
365 bool tagged; | 365 bool tagged; |
366 MachineRepresentation rep; | 366 MachineType rep; |
367 E* original_elements; | 367 E* original_elements; |
368 size_t num_elements; | 368 size_t num_elements; |
369 E* untagged_array; | 369 E* untagged_array; |
370 Handle<ByteArray> tagged_array; // TODO(titzer): use FixedArray for tagged. | 370 Handle<ByteArray> tagged_array; // TODO(titzer): use FixedArray for tagged. |
371 | 371 |
372 AccessTester(bool t, MachineRepresentation r, E* orig, size_t num) | 372 AccessTester(bool t, MachineType r, E* orig, size_t num) |
373 : tagged(t), | 373 : tagged(t), |
374 rep(r), | 374 rep(r), |
375 original_elements(orig), | 375 original_elements(orig), |
376 num_elements(num), | 376 num_elements(num), |
377 untagged_array(static_cast<E*>(malloc(ByteSize()))), | 377 untagged_array(static_cast<E*>(malloc(ByteSize()))), |
378 tagged_array(main_isolate()->factory()->NewByteArray( | 378 tagged_array(main_isolate()->factory()->NewByteArray( |
379 static_cast<int>(ByteSize()))) { | 379 static_cast<int>(ByteSize()))) { |
380 Reinitialize(); | 380 Reinitialize(); |
381 } | 381 } |
382 | 382 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 | 510 |
511 void BoundsCheck(int index) { | 511 void BoundsCheck(int index) { |
512 CHECK_GE(index, 0); | 512 CHECK_GE(index, 0); |
513 CHECK_LT(index, static_cast<int>(num_elements)); | 513 CHECK_LT(index, static_cast<int>(num_elements)); |
514 CHECK_EQ(static_cast<int>(ByteSize()), tagged_array->length()); | 514 CHECK_EQ(static_cast<int>(ByteSize()), tagged_array->length()); |
515 } | 515 } |
516 }; | 516 }; |
517 | 517 |
518 | 518 |
519 template <typename E> | 519 template <typename E> |
520 static void RunAccessTest(MachineRepresentation rep, E* original_elements, | 520 static void RunAccessTest(MachineType rep, E* original_elements, size_t num) { |
521 size_t num) { | |
522 int num_elements = static_cast<int>(num); | 521 int num_elements = static_cast<int>(num); |
523 | 522 |
524 for (int taggedness = 0; taggedness < 2; taggedness++) { | 523 for (int taggedness = 0; taggedness < 2; taggedness++) { |
525 AccessTester<E> a(taggedness == 1, rep, original_elements, num); | 524 AccessTester<E> a(taggedness == 1, rep, original_elements, num); |
526 for (int field = 0; field < 2; field++) { | 525 for (int field = 0; field < 2; field++) { |
527 for (int i = 0; i < num_elements - 1; i++) { | 526 for (int i = 0; i < num_elements - 1; i++) { |
528 a.Reinitialize(); | 527 a.Reinitialize(); |
529 if (field == 0) { | 528 if (field == 0) { |
530 a.RunCopyField(i, i + 1); // Test field read/write. | 529 a.RunCopyField(i, i + 1); // Test field read/write. |
531 } else { | 530 } else { |
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1151 Int32BinopMatcher mul(index.left().node()); | 1150 Int32BinopMatcher mul(index.left().node()); |
1152 CHECK_EQ(IrOpcode::kInt32Mul, mul.node()->opcode()); | 1151 CHECK_EQ(IrOpcode::kInt32Mul, mul.node()->opcode()); |
1153 CHECK(mul.right().Is(element_size)); | 1152 CHECK(mul.right().Is(element_size)); |
1154 return mul.left().node(); | 1153 return mul.left().node(); |
1155 } else { | 1154 } else { |
1156 return index.left().node(); | 1155 return index.left().node(); |
1157 } | 1156 } |
1158 } | 1157 } |
1159 | 1158 |
1160 | 1159 |
1161 static const MachineRepresentation machine_reps[] = { | 1160 static const MachineType machine_reps[] = {kMachineWord8, kMachineWord16, |
1162 kMachineWord8, kMachineWord16, kMachineWord32, | 1161 kMachineWord32, kMachineWord64, |
1163 kMachineWord64, kMachineFloat64, kMachineTagged}; | 1162 kMachineFloat64, kMachineTagged}; |
1164 | 1163 |
1165 | 1164 |
1166 // Representation types corresponding to those above. | 1165 // Representation types corresponding to those above. |
1167 static const RepType rep_types[] = {static_cast<RepType>(rWord32 | tUint32), | 1166 static const RepType rep_types[] = {static_cast<RepType>(rWord32 | tUint32), |
1168 static_cast<RepType>(rWord32 | tUint32), | 1167 static_cast<RepType>(rWord32 | tUint32), |
1169 static_cast<RepType>(rWord32 | tInt32), | 1168 static_cast<RepType>(rWord32 | tInt32), |
1170 static_cast<RepType>(rWord64), | 1169 static_cast<RepType>(rWord64), |
1171 static_cast<RepType>(rFloat64 | tNumber), | 1170 static_cast<RepType>(rFloat64 | tNumber), |
1172 static_cast<RepType>(rTagged | tAny)}; | 1171 static_cast<RepType>(rTagged | tAny)}; |
1173 | 1172 |
1174 | 1173 |
1175 TEST(LowerLoadField_to_load) { | 1174 TEST(LowerLoadField_to_load) { |
1176 TestingGraph t(Type::Any(), Type::Signed32()); | 1175 TestingGraph t(Type::Any(), Type::Signed32()); |
1177 | 1176 |
1178 for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { | 1177 for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { |
1179 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1178 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1180 Handle<Name>::null(), Type::Any(), machine_reps[i]}; | 1179 Handle<Name>::null(), Type::Any(), machine_reps[i]}; |
1181 | 1180 |
1182 Node* load = | 1181 Node* load = |
1183 t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start); | 1182 t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start); |
1184 Node* use = t.Use(load, rep_types[i]); | 1183 Node* use = t.Use(load, rep_types[i]); |
1185 t.Return(use); | 1184 t.Return(use); |
1186 t.Lower(); | 1185 t.Lower(); |
1187 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1186 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1188 CHECK_EQ(t.p0, load->InputAt(0)); | 1187 CHECK_EQ(t.p0, load->InputAt(0)); |
1189 CheckFieldAccessArithmetic(access, load); | 1188 CheckFieldAccessArithmetic(access, load); |
1190 | 1189 |
1191 MachineRepresentation rep = OpParameter<MachineRepresentation>(load); | 1190 MachineType rep = OpParameter<MachineType>(load); |
1192 CHECK_EQ(machine_reps[i], rep); | 1191 CHECK_EQ(machine_reps[i], rep); |
1193 } | 1192 } |
1194 } | 1193 } |
1195 | 1194 |
1196 | 1195 |
1197 TEST(LowerStoreField_to_store) { | 1196 TEST(LowerStoreField_to_store) { |
1198 TestingGraph t(Type::Any(), Type::Signed32()); | 1197 TestingGraph t(Type::Any(), Type::Signed32()); |
1199 | 1198 |
1200 for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { | 1199 for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { |
1201 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1200 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
(...skipping 27 matching lines...) Expand all Loading... |
1229 | 1228 |
1230 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, | 1229 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1231 t.p1, t.start); | 1230 t.p1, t.start); |
1232 Node* use = t.Use(load, rep_types[i]); | 1231 Node* use = t.Use(load, rep_types[i]); |
1233 t.Return(use); | 1232 t.Return(use); |
1234 t.Lower(); | 1233 t.Lower(); |
1235 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1234 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1236 CHECK_EQ(t.p0, load->InputAt(0)); | 1235 CHECK_EQ(t.p0, load->InputAt(0)); |
1237 CheckElementAccessArithmetic(access, load); | 1236 CheckElementAccessArithmetic(access, load); |
1238 | 1237 |
1239 MachineRepresentation rep = OpParameter<MachineRepresentation>(load); | 1238 MachineType rep = OpParameter<MachineType>(load); |
1240 CHECK_EQ(machine_reps[i], rep); | 1239 CHECK_EQ(machine_reps[i], rep); |
1241 } | 1240 } |
1242 } | 1241 } |
1243 | 1242 |
1244 | 1243 |
1245 TEST(LowerStoreElement_to_store) { | 1244 TEST(LowerStoreElement_to_store) { |
1246 TestingGraph t(Type::Any(), Type::Signed32()); | 1245 TestingGraph t(Type::Any(), Type::Signed32()); |
1247 | 1246 |
1248 for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { | 1247 for (size_t i = 0; i < ARRAY_SIZE(machine_reps); i++) { |
1249 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1248 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 | 1363 |
1365 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1364 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
1366 t.p1, t.start, t.start); | 1365 t.p1, t.start, t.start); |
1367 t.Effect(store); | 1366 t.Effect(store); |
1368 t.Lower(); | 1367 t.Lower(); |
1369 | 1368 |
1370 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1369 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1371 CHECK_EQ(t.p0, store->InputAt(0)); | 1370 CHECK_EQ(t.p0, store->InputAt(0)); |
1372 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); | 1371 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); |
1373 } | 1372 } |
OLD | NEW |