| 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 |