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/compiler/instruction-selector.h" | 5 #include "src/compiler/instruction-selector.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/adapters.h" | 9 #include "src/base/adapters.h" |
10 #include "src/compiler/instruction-selector-impl.h" | 10 #include "src/compiler/instruction-selector-impl.h" |
(...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1882 call_instr->MarkAsCall(); | 1882 call_instr->MarkAsCall(); |
1883 } | 1883 } |
1884 | 1884 |
1885 | 1885 |
1886 void InstructionSelector::VisitTailCall(Node* node) { | 1886 void InstructionSelector::VisitTailCall(Node* node) { |
1887 OperandGenerator g(this); | 1887 OperandGenerator g(this); |
1888 CallDescriptor const* descriptor = CallDescriptorOf(node->op()); | 1888 CallDescriptor const* descriptor = CallDescriptorOf(node->op()); |
1889 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); | 1889 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); |
1890 | 1890 |
1891 CallDescriptor* caller = linkage()->GetIncomingDescriptor(); | 1891 CallDescriptor* caller = linkage()->GetIncomingDescriptor(); |
1892 if (caller->CanTailCall(node)) { | 1892 DCHECK(caller->CanTailCall(node)); |
1893 const CallDescriptor* callee = CallDescriptorOf(node->op()); | 1893 const CallDescriptor* callee = CallDescriptorOf(node->op()); |
1894 int stack_param_delta = callee->GetStackParameterDelta(caller); | 1894 int stack_param_delta = callee->GetStackParameterDelta(caller); |
1895 CallBuffer buffer(zone(), descriptor, nullptr); | 1895 CallBuffer buffer(zone(), descriptor, nullptr); |
1896 | 1896 |
1897 // Compute InstructionOperands for inputs and outputs. | 1897 // Compute InstructionOperands for inputs and outputs. |
1898 CallBufferFlags flags(kCallCodeImmediate | kCallTail); | 1898 CallBufferFlags flags(kCallCodeImmediate | kCallTail); |
1899 if (IsTailCallAddressImmediate()) { | 1899 if (IsTailCallAddressImmediate()) { |
1900 flags |= kCallAddressImmediate; | 1900 flags |= kCallAddressImmediate; |
1901 } | 1901 } |
1902 InitializeCallBuffer(node, &buffer, flags, stack_param_delta); | 1902 InitializeCallBuffer(node, &buffer, flags, stack_param_delta); |
1903 | 1903 |
1904 // Select the appropriate opcode based on the call type. | 1904 // Select the appropriate opcode based on the call type. |
1905 InstructionCode opcode; | 1905 InstructionCode opcode; |
1906 InstructionOperandVector temps(zone()); | 1906 InstructionOperandVector temps(zone()); |
1907 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { | 1907 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { |
1908 switch (descriptor->kind()) { | |
1909 case CallDescriptor::kCallCodeObject: | |
1910 opcode = kArchTailCallCodeObjectFromJSFunction; | |
1911 break; | |
1912 case CallDescriptor::kCallJSFunction: | |
1913 opcode = kArchTailCallJSFunctionFromJSFunction; | |
1914 break; | |
1915 default: | |
1916 UNREACHABLE(); | |
1917 return; | |
1918 } | |
1919 int temps_count = GetTempsCountForTailCallFromJSFunction(); | |
1920 for (int i = 0; i < temps_count; i++) { | |
1921 temps.push_back(g.TempRegister()); | |
1922 } | |
1923 } else { | |
1924 switch (descriptor->kind()) { | |
1925 case CallDescriptor::kCallCodeObject: | |
1926 opcode = kArchTailCallCodeObject; | |
1927 break; | |
1928 case CallDescriptor::kCallAddress: | |
1929 opcode = kArchTailCallAddress; | |
1930 break; | |
1931 default: | |
1932 UNREACHABLE(); | |
1933 return; | |
1934 } | |
1935 } | |
1936 opcode |= MiscField::encode(descriptor->flags()); | |
1937 | |
1938 Emit(kArchPrepareTailCall, g.NoOutput()); | |
1939 | |
1940 int first_unused_stack_slot = | |
1941 (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0) + | |
1942 stack_param_delta; | |
1943 buffer.instruction_args.push_back(g.TempImmediate(first_unused_stack_slot)); | |
1944 | |
1945 // Emit the tailcall instruction. | |
1946 Emit(opcode, 0, nullptr, buffer.instruction_args.size(), | |
1947 &buffer.instruction_args.front(), temps.size(), | |
1948 temps.empty() ? nullptr : &temps.front()); | |
1949 } else { | |
1950 FrameStateDescriptor* frame_state_descriptor = | |
1951 descriptor->NeedsFrameState() | |
1952 ? GetFrameStateDescriptor( | |
1953 node->InputAt(static_cast<int>(descriptor->InputCount()))) | |
1954 : nullptr; | |
1955 | |
1956 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | |
1957 | |
1958 // Compute InstructionOperands for inputs and outputs. | |
1959 CallBufferFlags flags = kCallCodeImmediate; | |
1960 if (IsTailCallAddressImmediate()) { | |
1961 flags |= kCallAddressImmediate; | |
1962 } | |
1963 InitializeCallBuffer(node, &buffer, flags); | |
1964 | |
1965 EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node); | |
1966 | |
1967 // Select the appropriate opcode based on the call type. | |
1968 InstructionCode opcode; | |
1969 switch (descriptor->kind()) { | 1908 switch (descriptor->kind()) { |
1970 case CallDescriptor::kCallCodeObject: | 1909 case CallDescriptor::kCallCodeObject: |
1971 opcode = kArchCallCodeObject; | 1910 opcode = kArchTailCallCodeObjectFromJSFunction; |
1972 break; | 1911 break; |
1973 case CallDescriptor::kCallJSFunction: | 1912 case CallDescriptor::kCallJSFunction: |
1974 opcode = kArchCallJSFunction; | 1913 opcode = kArchTailCallJSFunctionFromJSFunction; |
1975 break; | 1914 break; |
1976 default: | 1915 default: |
1977 UNREACHABLE(); | 1916 UNREACHABLE(); |
1978 return; | 1917 return; |
1979 } | 1918 } |
1980 opcode |= MiscField::encode(descriptor->flags()); | 1919 int temps_count = GetTempsCountForTailCallFromJSFunction(); |
| 1920 for (int i = 0; i < temps_count; i++) { |
| 1921 temps.push_back(g.TempRegister()); |
| 1922 } |
| 1923 } else { |
| 1924 switch (descriptor->kind()) { |
| 1925 case CallDescriptor::kCallCodeObject: |
| 1926 opcode = kArchTailCallCodeObject; |
| 1927 break; |
| 1928 case CallDescriptor::kCallAddress: |
| 1929 opcode = kArchTailCallAddress; |
| 1930 break; |
| 1931 default: |
| 1932 UNREACHABLE(); |
| 1933 return; |
| 1934 } |
| 1935 } |
| 1936 opcode |= MiscField::encode(descriptor->flags()); |
1981 | 1937 |
1982 // Emit the call instruction. | 1938 Emit(kArchPrepareTailCall, g.NoOutput()); |
1983 size_t output_count = buffer.outputs.size(); | 1939 |
1984 auto* outputs = &buffer.outputs.front(); | 1940 int first_unused_stack_slot = |
1985 Instruction* call_instr = | 1941 (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0) + |
1986 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | 1942 stack_param_delta; |
1987 &buffer.instruction_args.front()); | 1943 buffer.instruction_args.push_back(g.TempImmediate(first_unused_stack_slot)); |
1988 if (instruction_selection_failed()) return; | 1944 |
1989 call_instr->MarkAsCall(); | 1945 // Emit the tailcall instruction. |
1990 Emit(kArchRet, 0, nullptr, output_count, outputs); | 1946 Emit(opcode, 0, nullptr, buffer.instruction_args.size(), |
1991 } | 1947 &buffer.instruction_args.front(), temps.size(), |
| 1948 temps.empty() ? nullptr : &temps.front()); |
1992 } | 1949 } |
1993 | 1950 |
1994 | 1951 |
1995 void InstructionSelector::VisitGoto(BasicBlock* target) { | 1952 void InstructionSelector::VisitGoto(BasicBlock* target) { |
1996 // jump to the next block. | 1953 // jump to the next block. |
1997 OperandGenerator g(this); | 1954 OperandGenerator g(this); |
1998 Emit(kArchJmp, g.NoOutput(), g.Label(target)); | 1955 Emit(kArchJmp, g.NoOutput(), g.Label(target)); |
1999 } | 1956 } |
2000 | 1957 |
2001 | |
2002 void InstructionSelector::VisitReturn(Node* ret) { | 1958 void InstructionSelector::VisitReturn(Node* ret) { |
2003 OperandGenerator g(this); | 1959 OperandGenerator g(this); |
2004 if (linkage()->GetIncomingDescriptor()->ReturnCount() == 0) { | 1960 const int input_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0 |
2005 Emit(kArchRet, g.NoOutput()); | 1961 ? 1 |
2006 } else { | 1962 : ret->op()->ValueInputCount(); |
2007 const int ret_count = ret->op()->ValueInputCount(); | 1963 DCHECK_GE(input_count, 1); |
2008 auto value_locations = zone()->NewArray<InstructionOperand>(ret_count); | 1964 auto value_locations = zone()->NewArray<InstructionOperand>(input_count); |
2009 for (int i = 0; i < ret_count; ++i) { | 1965 Node* pop_count = ret->InputAt(0); |
2010 value_locations[i] = | 1966 value_locations[0] = pop_count->opcode() == IrOpcode::kInt32Constant |
2011 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i)); | 1967 ? g.UseImmediate(pop_count) |
2012 } | 1968 : g.UseRegister(pop_count); |
2013 Emit(kArchRet, 0, nullptr, ret_count, value_locations); | 1969 for (int i = 1; i < input_count; ++i) { |
| 1970 value_locations[i] = |
| 1971 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1)); |
2014 } | 1972 } |
| 1973 Emit(kArchRet, 0, nullptr, input_count, value_locations); |
2015 } | 1974 } |
2016 | 1975 |
2017 Instruction* InstructionSelector::EmitDeoptimize(InstructionCode opcode, | 1976 Instruction* InstructionSelector::EmitDeoptimize(InstructionCode opcode, |
2018 InstructionOperand output, | 1977 InstructionOperand output, |
2019 InstructionOperand a, | 1978 InstructionOperand a, |
2020 DeoptimizeReason reason, | 1979 DeoptimizeReason reason, |
2021 Node* frame_state) { | 1980 Node* frame_state) { |
2022 size_t output_count = output.IsInvalid() ? 0 : 1; | 1981 size_t output_count = output.IsInvalid() ? 0 : 1; |
2023 InstructionOperand inputs[] = {a}; | 1982 InstructionOperand inputs[] = {a}; |
2024 size_t input_count = arraysize(inputs); | 1983 size_t input_count = arraysize(inputs); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2144 return new (instruction_zone()) FrameStateDescriptor( | 2103 return new (instruction_zone()) FrameStateDescriptor( |
2145 instruction_zone(), state_info.type(), state_info.bailout_id(), | 2104 instruction_zone(), state_info.type(), state_info.bailout_id(), |
2146 state_info.state_combine(), parameters, locals, stack, | 2105 state_info.state_combine(), parameters, locals, stack, |
2147 state_info.shared_info(), outer_state); | 2106 state_info.shared_info(), outer_state); |
2148 } | 2107 } |
2149 | 2108 |
2150 | 2109 |
2151 } // namespace compiler | 2110 } // namespace compiler |
2152 } // namespace internal | 2111 } // namespace internal |
2153 } // namespace v8 | 2112 } // namespace v8 |
OLD | NEW |