| 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/assembler.h" | 5 #include "src/assembler.h" |
| 6 #include "src/codegen.h" | 6 #include "src/codegen.h" |
| 7 #include "src/compiler/linkage.h" | 7 #include "src/compiler/linkage.h" |
| 8 #include "src/compiler/raw-machine-assembler.h" | 8 #include "src/compiler/raw-machine-assembler.h" |
| 9 #include "src/machine-type.h" | 9 #include "src/machine-type.h" |
| 10 #include "src/register-configuration.h" | 10 #include "src/register-configuration.h" |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 { | 451 { |
| 452 // constant mode. | 452 // constant mode. |
| 453 Handle<Code> wrapper = Handle<Code>::null(); | 453 Handle<Code> wrapper = Handle<Code>::null(); |
| 454 { | 454 { |
| 455 // Wrap the above code with a callable function that passes constants. | 455 // Wrap the above code with a callable function that passes constants. |
| 456 Zone zone(isolate->allocator(), ZONE_NAME); | 456 Zone zone(isolate->allocator(), ZONE_NAME); |
| 457 Graph graph(&zone); | 457 Graph graph(&zone); |
| 458 CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); | 458 CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); |
| 459 RawMachineAssembler raw(isolate, &graph, cdesc); | 459 RawMachineAssembler raw(isolate, &graph, cdesc); |
| 460 Node* target = raw.HeapConstant(inner); | 460 Node* target = raw.HeapConstant(inner); |
| 461 Node** args = zone.NewArray<Node*>(num_params); | 461 Node** inputs = zone.NewArray<Node*>(num_params + 1); |
| 462 int input_count = 0; |
| 463 inputs[input_count++] = target; |
| 462 for (int i = 0; i < num_params; i++) { | 464 for (int i = 0; i < num_params; i++) { |
| 463 args[i] = io.MakeConstant(raw, io.input[i]); | 465 inputs[input_count++] = io.MakeConstant(raw, io.input[i]); |
| 464 } | 466 } |
| 465 | 467 |
| 466 Node* call = raw.CallN(desc, target, args); | 468 Node* call = raw.CallN(desc, input_count, inputs); |
| 467 Node* store = io.StoreOutput(raw, call); | 469 Node* store = io.StoreOutput(raw, call); |
| 468 USE(store); | 470 USE(store); |
| 469 raw.Return(raw.Int32Constant(seed)); | 471 raw.Return(raw.Int32Constant(seed)); |
| 470 wrapper = | 472 wrapper = |
| 471 CompileGraph("Compute-wrapper-const", cdesc, &graph, raw.Export()); | 473 CompileGraph("Compute-wrapper-const", cdesc, &graph, raw.Export()); |
| 472 } | 474 } |
| 473 | 475 |
| 474 CodeRunner<int32_t> runnable(isolate, wrapper, &csig); | 476 CodeRunner<int32_t> runnable(isolate, wrapper, &csig); |
| 475 | 477 |
| 476 // Run the code, checking it against the reference. | 478 // Run the code, checking it against the reference. |
| 477 CType expected = compute(desc, io.input); | 479 CType expected = compute(desc, io.input); |
| 478 int32_t check_seed = runnable.Call(); | 480 int32_t check_seed = runnable.Call(); |
| 479 CHECK_EQ(seed, check_seed); | 481 CHECK_EQ(seed, check_seed); |
| 480 CHECK_EQ(expected, io.output); | 482 CHECK_EQ(expected, io.output); |
| 481 } | 483 } |
| 482 | 484 |
| 483 { | 485 { |
| 484 // buffer mode. | 486 // buffer mode. |
| 485 Handle<Code> wrapper = Handle<Code>::null(); | 487 Handle<Code> wrapper = Handle<Code>::null(); |
| 486 { | 488 { |
| 487 // Wrap the above code with a callable function that loads from {input}. | 489 // Wrap the above code with a callable function that loads from {input}. |
| 488 Zone zone(isolate->allocator(), ZONE_NAME); | 490 Zone zone(isolate->allocator(), ZONE_NAME); |
| 489 Graph graph(&zone); | 491 Graph graph(&zone); |
| 490 CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); | 492 CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); |
| 491 RawMachineAssembler raw(isolate, &graph, cdesc); | 493 RawMachineAssembler raw(isolate, &graph, cdesc); |
| 492 Node* base = raw.PointerConstant(io.input); | 494 Node* base = raw.PointerConstant(io.input); |
| 493 Node* target = raw.HeapConstant(inner); | 495 Node* target = raw.HeapConstant(inner); |
| 494 Node** args = zone.NewArray<Node*>(kMaxParamCount); | 496 Node** inputs = zone.NewArray<Node*>(kMaxParamCount + 1); |
| 497 int input_count = 0; |
| 498 inputs[input_count++] = target; |
| 495 for (int i = 0; i < num_params; i++) { | 499 for (int i = 0; i < num_params; i++) { |
| 496 args[i] = io.LoadInput(raw, base, i); | 500 inputs[input_count++] = io.LoadInput(raw, base, i); |
| 497 } | 501 } |
| 498 | 502 |
| 499 Node* call = raw.CallN(desc, target, args); | 503 Node* call = raw.CallN(desc, input_count, inputs); |
| 500 Node* store = io.StoreOutput(raw, call); | 504 Node* store = io.StoreOutput(raw, call); |
| 501 USE(store); | 505 USE(store); |
| 502 raw.Return(raw.Int32Constant(seed)); | 506 raw.Return(raw.Int32Constant(seed)); |
| 503 wrapper = CompileGraph("Compute-wrapper", cdesc, &graph, raw.Export()); | 507 wrapper = CompileGraph("Compute-wrapper", cdesc, &graph, raw.Export()); |
| 504 } | 508 } |
| 505 | 509 |
| 506 CodeRunner<int32_t> runnable(isolate, wrapper, &csig); | 510 CodeRunner<int32_t> runnable(isolate, wrapper, &csig); |
| 507 | 511 |
| 508 // Run the code, checking it against the reference. | 512 // Run the code, checking it against the reference. |
| 509 for (int i = 0; i < 5; i++) { | 513 for (int i = 0; i < 5; i++) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 CSignature0<int32_t> csig; | 585 CSignature0<int32_t> csig; |
| 582 Handle<Code> wrapper = Handle<Code>::null(); | 586 Handle<Code> wrapper = Handle<Code>::null(); |
| 583 { | 587 { |
| 584 // Loads parameters from the input buffer and calls the above code. | 588 // Loads parameters from the input buffer and calls the above code. |
| 585 Zone zone(isolate->allocator(), ZONE_NAME); | 589 Zone zone(isolate->allocator(), ZONE_NAME); |
| 586 Graph graph(&zone); | 590 Graph graph(&zone); |
| 587 CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); | 591 CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); |
| 588 RawMachineAssembler raw(isolate, &graph, cdesc); | 592 RawMachineAssembler raw(isolate, &graph, cdesc); |
| 589 Node* base = raw.PointerConstant(input); | 593 Node* base = raw.PointerConstant(input); |
| 590 Node* target = raw.HeapConstant(inner); | 594 Node* target = raw.HeapConstant(inner); |
| 591 Node** args = zone.NewArray<Node*>(kNumParams); | 595 Node** inputs = zone.NewArray<Node*>(kNumParams + 1); |
| 596 int input_count = 0; |
| 597 inputs[input_count++] = target; |
| 592 for (int i = 0; i < kNumParams; i++) { | 598 for (int i = 0; i < kNumParams; i++) { |
| 593 Node* offset = raw.Int32Constant(i * sizeof(int32_t)); | 599 Node* offset = raw.Int32Constant(i * sizeof(int32_t)); |
| 594 args[i] = raw.Load(MachineType::Int32(), base, offset); | 600 inputs[input_count++] = raw.Load(MachineType::Int32(), base, offset); |
| 595 } | 601 } |
| 596 | 602 |
| 597 Node* call = raw.CallN(desc, target, args); | 603 Node* call = raw.CallN(desc, input_count, inputs); |
| 598 raw.Return(call); | 604 raw.Return(call); |
| 599 wrapper = | 605 wrapper = |
| 600 CompileGraph("CopyTwentyInt32-wrapper", cdesc, &graph, raw.Export()); | 606 CompileGraph("CopyTwentyInt32-wrapper", cdesc, &graph, raw.Export()); |
| 601 } | 607 } |
| 602 | 608 |
| 603 CodeRunner<int32_t> runnable(isolate, wrapper, &csig); | 609 CodeRunner<int32_t> runnable(isolate, wrapper, &csig); |
| 604 | 610 |
| 605 // Run the code, checking it correctly implements the memcpy. | 611 // Run the code, checking it correctly implements the memcpy. |
| 606 for (int i = 0; i < 5; i++) { | 612 for (int i = 0; i < 5; i++) { |
| 607 uint32_t base = 1111111111u * i; | 613 uint32_t base = 1111111111u * i; |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 RawMachineAssembler raw(isolate, &graph, desc); | 969 RawMachineAssembler raw(isolate, &graph, desc); |
| 964 raw.Return(raw.Parameter(which)); | 970 raw.Return(raw.Parameter(which)); |
| 965 inner = CompileGraph("Select-indirection", desc, &graph, raw.Export()); | 971 inner = CompileGraph("Select-indirection", desc, &graph, raw.Export()); |
| 966 CHECK(!inner.is_null()); | 972 CHECK(!inner.is_null()); |
| 967 CHECK(inner->IsCode()); | 973 CHECK(inner->IsCode()); |
| 968 } | 974 } |
| 969 | 975 |
| 970 { | 976 { |
| 971 // Build a call to the function that does the select. | 977 // Build a call to the function that does the select. |
| 972 Node* target = raw.HeapConstant(inner); | 978 Node* target = raw.HeapConstant(inner); |
| 973 Node** args = raw.zone()->NewArray<Node*>(num_params); | 979 Node** inputs = raw.zone()->NewArray<Node*>(num_params + 1); |
| 980 int input_count = 0; |
| 981 inputs[input_count++] = target; |
| 974 for (int i = 0; i < num_params; i++) { | 982 for (int i = 0; i < num_params; i++) { |
| 975 args[i] = raw.Parameter(i); | 983 inputs[input_count++] = raw.Parameter(i); |
| 976 } | 984 } |
| 977 | 985 |
| 978 Node* call = raw.CallN(desc, target, args); | 986 Node* call = raw.CallN(desc, input_count, inputs); |
| 979 raw.Return(call); | 987 raw.Return(call); |
| 980 } | 988 } |
| 981 } | 989 } |
| 982 | 990 |
| 983 | 991 |
| 984 TEST(Float64StackParamsToStackParams) { | 992 TEST(Float64StackParamsToStackParams) { |
| 985 int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)}; | 993 int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)}; |
| 986 Allocator params(nullptr, 0, nullptr, 0); | 994 Allocator params(nullptr, 0, nullptr, 0); |
| 987 Allocator rets(nullptr, 0, rarray, 1); | 995 Allocator rets(nullptr, 0, rarray, 1); |
| 988 | 996 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 V8_ALIGNED(8) char output[kDoubleSize]; | 1076 V8_ALIGNED(8) char output[kDoubleSize]; |
| 1069 int expected_size = 0; | 1077 int expected_size = 0; |
| 1070 CSignature0<int32_t> csig; | 1078 CSignature0<int32_t> csig; |
| 1071 { | 1079 { |
| 1072 // Wrap the select code with a callable function that passes constants. | 1080 // Wrap the select code with a callable function that passes constants. |
| 1073 Zone zone(&allocator, ZONE_NAME); | 1081 Zone zone(&allocator, ZONE_NAME); |
| 1074 Graph graph(&zone); | 1082 Graph graph(&zone); |
| 1075 CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); | 1083 CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); |
| 1076 RawMachineAssembler raw(isolate, &graph, cdesc); | 1084 RawMachineAssembler raw(isolate, &graph, cdesc); |
| 1077 Node* target = raw.HeapConstant(select); | 1085 Node* target = raw.HeapConstant(select); |
| 1078 Node** args = zone.NewArray<Node*>(num_params); | 1086 Node** inputs = zone.NewArray<Node*>(num_params + 1); |
| 1087 int input_count = 0; |
| 1088 inputs[input_count++] = target; |
| 1079 int64_t constant = 0x0102030405060708; | 1089 int64_t constant = 0x0102030405060708; |
| 1080 for (int i = 0; i < num_params; i++) { | 1090 for (int i = 0; i < num_params; i++) { |
| 1081 MachineType param_type = sig->GetParam(i); | 1091 MachineType param_type = sig->GetParam(i); |
| 1082 Node* konst = nullptr; | 1092 Node* konst = nullptr; |
| 1083 if (param_type == MachineType::Int32()) { | 1093 if (param_type == MachineType::Int32()) { |
| 1084 int32_t value[] = {static_cast<int32_t>(constant)}; | 1094 int32_t value[] = {static_cast<int32_t>(constant)}; |
| 1085 konst = raw.Int32Constant(value[0]); | 1095 konst = raw.Int32Constant(value[0]); |
| 1086 if (i == which) memcpy(bytes, value, expected_size = 4); | 1096 if (i == which) memcpy(bytes, value, expected_size = 4); |
| 1087 } | 1097 } |
| 1088 if (param_type == MachineType::Int64()) { | 1098 if (param_type == MachineType::Int64()) { |
| 1089 int64_t value[] = {static_cast<int64_t>(constant)}; | 1099 int64_t value[] = {static_cast<int64_t>(constant)}; |
| 1090 konst = raw.Int64Constant(value[0]); | 1100 konst = raw.Int64Constant(value[0]); |
| 1091 if (i == which) memcpy(bytes, value, expected_size = 8); | 1101 if (i == which) memcpy(bytes, value, expected_size = 8); |
| 1092 } | 1102 } |
| 1093 if (param_type == MachineType::Float32()) { | 1103 if (param_type == MachineType::Float32()) { |
| 1094 float32 value[] = {static_cast<float32>(constant)}; | 1104 float32 value[] = {static_cast<float32>(constant)}; |
| 1095 konst = raw.Float32Constant(value[0]); | 1105 konst = raw.Float32Constant(value[0]); |
| 1096 if (i == which) memcpy(bytes, value, expected_size = 4); | 1106 if (i == which) memcpy(bytes, value, expected_size = 4); |
| 1097 } | 1107 } |
| 1098 if (param_type == MachineType::Float64()) { | 1108 if (param_type == MachineType::Float64()) { |
| 1099 float64 value[] = {static_cast<float64>(constant)}; | 1109 float64 value[] = {static_cast<float64>(constant)}; |
| 1100 konst = raw.Float64Constant(value[0]); | 1110 konst = raw.Float64Constant(value[0]); |
| 1101 if (i == which) memcpy(bytes, value, expected_size = 8); | 1111 if (i == which) memcpy(bytes, value, expected_size = 8); |
| 1102 } | 1112 } |
| 1103 CHECK_NOT_NULL(konst); | 1113 CHECK_NOT_NULL(konst); |
| 1104 | 1114 |
| 1105 args[i] = konst; | 1115 inputs[input_count++] = konst; |
| 1106 constant += 0x1010101010101010; | 1116 constant += 0x1010101010101010; |
| 1107 } | 1117 } |
| 1108 | 1118 |
| 1109 Node* call = raw.CallN(desc, target, args); | 1119 Node* call = raw.CallN(desc, input_count, inputs); |
| 1110 Node* store = | 1120 Node* store = |
| 1111 raw.StoreToPointer(output, sig->GetReturn().representation(), call); | 1121 raw.StoreToPointer(output, sig->GetReturn().representation(), call); |
| 1112 USE(store); | 1122 USE(store); |
| 1113 expected_ret = static_cast<int32_t>(constant); | 1123 expected_ret = static_cast<int32_t>(constant); |
| 1114 raw.Return(raw.Int32Constant(expected_ret)); | 1124 raw.Return(raw.Int32Constant(expected_ret)); |
| 1115 wrapper = CompileGraph("Select-mixed-wrapper-const", cdesc, &graph, | 1125 wrapper = CompileGraph("Select-mixed-wrapper-const", cdesc, &graph, |
| 1116 raw.Export()); | 1126 raw.Export()); |
| 1117 } | 1127 } |
| 1118 | 1128 |
| 1119 CodeRunner<int32_t> runnable(isolate, wrapper, &csig); | 1129 CodeRunner<int32_t> runnable(isolate, wrapper, &csig); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 | 1181 |
| 1172 g.Store(slot_type.representation(), g.Parameter(11), g.Parameter(10), | 1182 g.Store(slot_type.representation(), g.Parameter(11), g.Parameter(10), |
| 1173 WriteBarrierKind::kNoWriteBarrier); | 1183 WriteBarrierKind::kNoWriteBarrier); |
| 1174 g.Return(g.Parameter(9)); | 1184 g.Return(g.Parameter(9)); |
| 1175 inner = CompileGraph("Compute", desc, &graph, g.Export()); | 1185 inner = CompileGraph("Compute", desc, &graph, g.Export()); |
| 1176 | 1186 |
| 1177 // Create function f with a stack slot which calls the inner function g. | 1187 // Create function f with a stack slot which calls the inner function g. |
| 1178 BufferedRawMachineAssemblerTester<T> f(slot_type); | 1188 BufferedRawMachineAssemblerTester<T> f(slot_type); |
| 1179 Node* target = f.HeapConstant(inner); | 1189 Node* target = f.HeapConstant(inner); |
| 1180 Node* stack_slot = f.StackSlot(slot_type.representation()); | 1190 Node* stack_slot = f.StackSlot(slot_type.representation()); |
| 1181 Node* args[12]; | 1191 Node* nodes[14]; |
| 1192 int input_count = 0; |
| 1193 nodes[input_count++] = target; |
| 1182 for (int i = 0; i < 10; i++) { | 1194 for (int i = 0; i < 10; i++) { |
| 1183 args[i] = f.Int32Constant(i); | 1195 nodes[input_count++] = f.Int32Constant(i); |
| 1184 } | 1196 } |
| 1185 args[10] = f.Parameter(0); | 1197 nodes[input_count++] = f.Parameter(0); |
| 1186 args[11] = stack_slot; | 1198 nodes[input_count++] = stack_slot; |
| 1187 | 1199 |
| 1188 f.CallN(desc, target, args); | 1200 f.CallN(desc, input_count, nodes); |
| 1189 f.Return(f.Load(slot_type, stack_slot, f.IntPtrConstant(0))); | 1201 f.Return(f.Load(slot_type, stack_slot, f.IntPtrConstant(0))); |
| 1190 | 1202 |
| 1191 CHECK_EQ(expected, f.Call(expected)); | 1203 CHECK_EQ(expected, f.Call(expected)); |
| 1192 } | 1204 } |
| 1193 | 1205 |
| 1194 TEST(RunStackSlotInt32) { | 1206 TEST(RunStackSlotInt32) { |
| 1195 int32_t magic = 0x12345678; | 1207 int32_t magic = 0x12345678; |
| 1196 TestStackSlot(MachineType::Int32(), magic); | 1208 TestStackSlot(MachineType::Int32(), magic); |
| 1197 } | 1209 } |
| 1198 | 1210 |
| 1199 #if !V8_TARGET_ARCH_32_BIT | 1211 #if !V8_TARGET_ARCH_32_BIT |
| 1200 TEST(RunStackSlotInt64) { | 1212 TEST(RunStackSlotInt64) { |
| 1201 int64_t magic = 0x123456789abcdef0; | 1213 int64_t magic = 0x123456789abcdef0; |
| 1202 TestStackSlot(MachineType::Int64(), magic); | 1214 TestStackSlot(MachineType::Int64(), magic); |
| 1203 } | 1215 } |
| 1204 #endif | 1216 #endif |
| 1205 | 1217 |
| 1206 TEST(RunStackSlotFloat32) { | 1218 TEST(RunStackSlotFloat32) { |
| 1207 float magic = 1234.125f; | 1219 float magic = 1234.125f; |
| 1208 TestStackSlot(MachineType::Float32(), magic); | 1220 TestStackSlot(MachineType::Float32(), magic); |
| 1209 } | 1221 } |
| 1210 | 1222 |
| 1211 TEST(RunStackSlotFloat64) { | 1223 TEST(RunStackSlotFloat64) { |
| 1212 double magic = 3456.375; | 1224 double magic = 3456.375; |
| 1213 TestStackSlot(MachineType::Float64(), magic); | 1225 TestStackSlot(MachineType::Float64(), magic); |
| 1214 } | 1226 } |
| 1215 } // namespace compiler | 1227 } // namespace compiler |
| 1216 } // namespace internal | 1228 } // namespace internal |
| 1217 } // namespace v8 | 1229 } // namespace v8 |
| OLD | NEW |