| 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 <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
| 8 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
| 9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
| (...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 if (descriptor->NeedsFrameState()) { | 1031 if (descriptor->NeedsFrameState()) { |
| 1032 frame_state_descriptor = GetFrameStateDescriptor( | 1032 frame_state_descriptor = GetFrameStateDescriptor( |
| 1033 node->InputAt(static_cast<int>(descriptor->InputCount()))); | 1033 node->InputAt(static_cast<int>(descriptor->InputCount()))); |
| 1034 } | 1034 } |
| 1035 | 1035 |
| 1036 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 1036 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
| 1037 | 1037 |
| 1038 // Compute InstructionOperands for inputs and outputs. | 1038 // Compute InstructionOperands for inputs and outputs. |
| 1039 InitializeCallBuffer(node, &buffer, true, true); | 1039 InitializeCallBuffer(node, &buffer, true, true); |
| 1040 | 1040 |
| 1041 // Push any stack arguments. | 1041 // Prepare for C function call. |
| 1042 for (Node* node : base::Reversed(buffer.pushed_nodes)) { | 1042 if (descriptor->IsCFunctionCall()) { |
| 1043 // TODO(titzer): handle pushing double parameters. | 1043 Emit(kArchPrepareCallCFunction | |
| 1044 InstructionOperand value = | 1044 MiscField::encode(static_cast<int>(descriptor->CParameterCount())), |
| 1045 g.CanBeImmediate(node) | 1045 0, nullptr, 0, nullptr); |
| 1046 ? g.UseImmediate(node) | 1046 |
| 1047 : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); | 1047 // Poke any stack arguments. |
| 1048 Emit(kX64Push, g.NoOutput(), value); | 1048 for (size_t n = 0; n < buffer.pushed_nodes.size(); ++n) { |
| 1049 if (Node* node = buffer.pushed_nodes[n]) { |
| 1050 int const slot = static_cast<int>(n); |
| 1051 InstructionOperand value = |
| 1052 g.CanBeImmediate(node) ? g.UseImmediate(node) : g.UseRegister(node); |
| 1053 Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value); |
| 1054 } |
| 1055 } |
| 1056 } else { |
| 1057 // Push any stack arguments. |
| 1058 for (Node* node : base::Reversed(buffer.pushed_nodes)) { |
| 1059 // TODO(titzer): handle pushing double parameters. |
| 1060 InstructionOperand value = |
| 1061 g.CanBeImmediate(node) |
| 1062 ? g.UseImmediate(node) |
| 1063 : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); |
| 1064 Emit(kX64Push, g.NoOutput(), value); |
| 1065 } |
| 1049 } | 1066 } |
| 1050 | 1067 |
| 1051 // Pass label of exception handler block. | 1068 // Pass label of exception handler block. |
| 1052 CallDescriptor::Flags flags = descriptor->flags(); | 1069 CallDescriptor::Flags flags = descriptor->flags(); |
| 1053 if (handler) { | 1070 if (handler) { |
| 1054 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); | 1071 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); |
| 1055 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); | 1072 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); |
| 1056 if (hint == IfExceptionHint::kLocallyCaught) { | 1073 if (hint == IfExceptionHint::kLocallyCaught) { |
| 1057 flags |= CallDescriptor::kHasLocalCatchHandler; | 1074 flags |= CallDescriptor::kHasLocalCatchHandler; |
| 1058 } | 1075 } |
| 1059 flags |= CallDescriptor::kHasExceptionHandler; | 1076 flags |= CallDescriptor::kHasExceptionHandler; |
| 1060 buffer.instruction_args.push_back(g.Label(handler)); | 1077 buffer.instruction_args.push_back(g.Label(handler)); |
| 1061 } | 1078 } |
| 1062 | 1079 |
| 1063 // Select the appropriate opcode based on the call type. | 1080 // Select the appropriate opcode based on the call type. |
| 1064 InstructionCode opcode; | 1081 InstructionCode opcode; |
| 1065 switch (descriptor->kind()) { | 1082 switch (descriptor->kind()) { |
| 1083 case CallDescriptor::kCallAddress: |
| 1084 opcode = |
| 1085 kArchCallCFunction | |
| 1086 MiscField::encode(static_cast<int>(descriptor->CParameterCount())); |
| 1087 break; |
| 1066 case CallDescriptor::kCallCodeObject: | 1088 case CallDescriptor::kCallCodeObject: |
| 1067 opcode = kArchCallCodeObject; | 1089 opcode = kArchCallCodeObject | MiscField::encode(flags); |
| 1068 break; | 1090 break; |
| 1069 case CallDescriptor::kCallJSFunction: | 1091 case CallDescriptor::kCallJSFunction: |
| 1070 opcode = kArchCallJSFunction; | 1092 opcode = kArchCallJSFunction | MiscField::encode(flags); |
| 1071 break; | 1093 break; |
| 1072 default: | 1094 default: |
| 1073 UNREACHABLE(); | 1095 UNREACHABLE(); |
| 1074 return; | 1096 return; |
| 1075 } | 1097 } |
| 1076 opcode |= MiscField::encode(flags); | |
| 1077 | 1098 |
| 1078 // Emit the call instruction. | 1099 // Emit the call instruction. |
| 1079 size_t const output_count = buffer.outputs.size(); | 1100 size_t const output_count = buffer.outputs.size(); |
| 1080 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | 1101 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; |
| 1081 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | 1102 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
| 1082 &buffer.instruction_args.front())->MarkAsCall(); | 1103 &buffer.instruction_args.front())->MarkAsCall(); |
| 1083 } | 1104 } |
| 1084 | 1105 |
| 1085 | 1106 |
| 1086 void InstructionSelector::VisitTailCall(Node* node) { | 1107 void InstructionSelector::VisitTailCall(Node* node) { |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1640 if (CpuFeatures::IsSupported(SSE4_1)) { | 1661 if (CpuFeatures::IsSupported(SSE4_1)) { |
| 1641 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1662 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
| 1642 MachineOperatorBuilder::kFloat64RoundTruncate; | 1663 MachineOperatorBuilder::kFloat64RoundTruncate; |
| 1643 } | 1664 } |
| 1644 return flags; | 1665 return flags; |
| 1645 } | 1666 } |
| 1646 | 1667 |
| 1647 } // namespace compiler | 1668 } // namespace compiler |
| 1648 } // namespace internal | 1669 } // namespace internal |
| 1649 } // namespace v8 | 1670 } // namespace v8 |
| OLD | NEW |