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 |