| 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 "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
| 6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
| 7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
| 8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 if (descriptor->NeedsFrameState()) { | 807 if (descriptor->NeedsFrameState()) { |
| 808 frame_state_descriptor = | 808 frame_state_descriptor = |
| 809 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); | 809 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); |
| 810 } | 810 } |
| 811 | 811 |
| 812 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 812 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
| 813 | 813 |
| 814 // Compute InstructionOperands for inputs and outputs. | 814 // Compute InstructionOperands for inputs and outputs. |
| 815 InitializeCallBuffer(node, &buffer, true, true); | 815 InitializeCallBuffer(node, &buffer, true, true); |
| 816 | 816 |
| 817 // Push any stack arguments. | 817 // Prepare for C function call. |
| 818 for (Node* node : base::Reversed(buffer.pushed_nodes)) { | 818 if (descriptor->IsCFunctionCall()) { |
| 819 // TODO(titzer): handle pushing double parameters. | 819 InstructionOperand temps[] = {g.TempRegister()}; |
| 820 InstructionOperand value = | 820 size_t const temp_count = arraysize(temps); |
| 821 g.CanBeImmediate(node) | 821 Emit(kArchPrepareCallCFunction | |
| 822 ? g.UseImmediate(node) | 822 MiscField::encode(static_cast<int>(descriptor->CParameterCount())), |
| 823 : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); | 823 0, nullptr, 0, nullptr, temp_count, temps); |
| 824 Emit(kX87Push, g.NoOutput(), value); | 824 |
| 825 // Poke any stack arguments. |
| 826 for (size_t n = 0; n < buffer.pushed_nodes.size(); ++n) { |
| 827 if (Node* node = buffer.pushed_nodes[n]) { |
| 828 int const slot = static_cast<int>(n); |
| 829 InstructionOperand value = |
| 830 g.CanBeImmediate(node) ? g.UseImmediate(node) : g.UseRegister(node); |
| 831 Emit(kX87Poke | MiscField::encode(slot), g.NoOutput(), value); |
| 832 } |
| 833 } |
| 834 } else { |
| 835 // Push any stack arguments. |
| 836 for (Node* node : base::Reversed(buffer.pushed_nodes)) { |
| 837 // TODO(titzer): handle pushing double parameters. |
| 838 InstructionOperand value = |
| 839 g.CanBeImmediate(node) |
| 840 ? g.UseImmediate(node) |
| 841 : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); |
| 842 Emit(kX87Push, g.NoOutput(), value); |
| 843 } |
| 825 } | 844 } |
| 826 | 845 |
| 827 // Pass label of exception handler block. | 846 // Pass label of exception handler block. |
| 828 CallDescriptor::Flags flags = descriptor->flags(); | 847 CallDescriptor::Flags flags = descriptor->flags(); |
| 829 if (handler) { | 848 if (handler) { |
| 830 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); | 849 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); |
| 831 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); | 850 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); |
| 832 if (hint == IfExceptionHint::kLocallyCaught) { | 851 if (hint == IfExceptionHint::kLocallyCaught) { |
| 833 flags |= CallDescriptor::kHasLocalCatchHandler; | 852 flags |= CallDescriptor::kHasLocalCatchHandler; |
| 834 } | 853 } |
| 835 flags |= CallDescriptor::kHasExceptionHandler; | 854 flags |= CallDescriptor::kHasExceptionHandler; |
| 836 buffer.instruction_args.push_back(g.Label(handler)); | 855 buffer.instruction_args.push_back(g.Label(handler)); |
| 837 } | 856 } |
| 838 | 857 |
| 839 // Select the appropriate opcode based on the call type. | 858 // Select the appropriate opcode based on the call type. |
| 840 InstructionCode opcode; | 859 InstructionCode opcode; |
| 841 switch (descriptor->kind()) { | 860 switch (descriptor->kind()) { |
| 842 case CallDescriptor::kCallCodeObject: { | 861 case CallDescriptor::kCallAddress: |
| 843 opcode = kArchCallCodeObject; | 862 opcode = |
| 863 kArchCallCFunction | |
| 864 MiscField::encode(static_cast<int>(descriptor->CParameterCount())); |
| 844 break; | 865 break; |
| 845 } | 866 case CallDescriptor::kCallCodeObject: |
| 867 opcode = kArchCallCodeObject | MiscField::encode(flags); |
| 868 break; |
| 846 case CallDescriptor::kCallJSFunction: | 869 case CallDescriptor::kCallJSFunction: |
| 847 opcode = kArchCallJSFunction; | 870 opcode = kArchCallJSFunction | MiscField::encode(flags); |
| 848 break; | 871 break; |
| 849 default: | 872 default: |
| 850 UNREACHABLE(); | 873 UNREACHABLE(); |
| 851 return; | 874 return; |
| 852 } | 875 } |
| 853 opcode |= MiscField::encode(flags); | |
| 854 | 876 |
| 855 // Emit the call instruction. | 877 // Emit the call instruction. |
| 856 size_t const output_count = buffer.outputs.size(); | 878 size_t const output_count = buffer.outputs.size(); |
| 857 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | 879 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; |
| 858 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | 880 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
| 859 &buffer.instruction_args.front())->MarkAsCall(); | 881 &buffer.instruction_args.front())->MarkAsCall(); |
| 860 } | 882 } |
| 861 | 883 |
| 862 | 884 |
| 863 void InstructionSelector::VisitTailCall(Node* node) { | 885 void InstructionSelector::VisitTailCall(Node* node) { |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 MachineOperatorBuilder::kFloat32Min | | 1332 MachineOperatorBuilder::kFloat32Min | |
| 1311 MachineOperatorBuilder::kFloat64Max | | 1333 MachineOperatorBuilder::kFloat64Max | |
| 1312 MachineOperatorBuilder::kFloat64Min | | 1334 MachineOperatorBuilder::kFloat64Min | |
| 1313 MachineOperatorBuilder::kWord32ShiftIsSafe; | 1335 MachineOperatorBuilder::kWord32ShiftIsSafe; |
| 1314 return flags; | 1336 return flags; |
| 1315 } | 1337 } |
| 1316 | 1338 |
| 1317 } // namespace compiler | 1339 } // namespace compiler |
| 1318 } // namespace internal | 1340 } // namespace internal |
| 1319 } // namespace v8 | 1341 } // namespace v8 |
| OLD | NEW |