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 DCHECK(caller->CanTailCall(node)); | 1892 if (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; |
1908 switch (descriptor->kind()) { | 1969 switch (descriptor->kind()) { |
1909 case CallDescriptor::kCallCodeObject: | 1970 case CallDescriptor::kCallCodeObject: |
1910 opcode = kArchTailCallCodeObjectFromJSFunction; | 1971 opcode = kArchCallCodeObject; |
1911 break; | 1972 break; |
1912 case CallDescriptor::kCallJSFunction: | 1973 case CallDescriptor::kCallJSFunction: |
1913 opcode = kArchTailCallJSFunctionFromJSFunction; | 1974 opcode = kArchCallJSFunction; |
1914 break; | 1975 break; |
1915 default: | 1976 default: |
1916 UNREACHABLE(); | 1977 UNREACHABLE(); |
1917 return; | 1978 return; |
1918 } | 1979 } |
1919 int temps_count = GetTempsCountForTailCallFromJSFunction(); | 1980 opcode |= MiscField::encode(descriptor->flags()); |
1920 for (int i = 0; i < temps_count; i++) { | 1981 |
1921 temps.push_back(g.TempRegister()); | 1982 // Emit the call instruction. |
1922 } | 1983 size_t output_count = buffer.outputs.size(); |
1923 } else { | 1984 auto* outputs = &buffer.outputs.front(); |
1924 switch (descriptor->kind()) { | 1985 Instruction* call_instr = |
1925 case CallDescriptor::kCallCodeObject: | 1986 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
1926 opcode = kArchTailCallCodeObject; | 1987 &buffer.instruction_args.front()); |
1927 break; | 1988 if (instruction_selection_failed()) return; |
1928 case CallDescriptor::kCallAddress: | 1989 call_instr->MarkAsCall(); |
1929 opcode = kArchTailCallAddress; | 1990 Emit(kArchRet, 0, nullptr, output_count, outputs); |
1930 break; | |
1931 default: | |
1932 UNREACHABLE(); | |
1933 return; | |
1934 } | |
1935 } | 1991 } |
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 } | 1992 } |
1950 | 1993 |
1951 | 1994 |
1952 void InstructionSelector::VisitGoto(BasicBlock* target) { | 1995 void InstructionSelector::VisitGoto(BasicBlock* target) { |
1953 // jump to the next block. | 1996 // jump to the next block. |
1954 OperandGenerator g(this); | 1997 OperandGenerator g(this); |
1955 Emit(kArchJmp, g.NoOutput(), g.Label(target)); | 1998 Emit(kArchJmp, g.NoOutput(), g.Label(target)); |
1956 } | 1999 } |
1957 | 2000 |
| 2001 |
1958 void InstructionSelector::VisitReturn(Node* ret) { | 2002 void InstructionSelector::VisitReturn(Node* ret) { |
1959 OperandGenerator g(this); | 2003 OperandGenerator g(this); |
1960 const int input_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0 | 2004 if (linkage()->GetIncomingDescriptor()->ReturnCount() == 0) { |
1961 ? 1 | 2005 Emit(kArchRet, g.NoOutput()); |
1962 : ret->op()->ValueInputCount(); | 2006 } else { |
1963 DCHECK_GE(input_count, 1); | 2007 const int ret_count = ret->op()->ValueInputCount(); |
1964 auto value_locations = zone()->NewArray<InstructionOperand>(input_count); | 2008 auto value_locations = zone()->NewArray<InstructionOperand>(ret_count); |
1965 Node* pop_count = ret->InputAt(0); | 2009 for (int i = 0; i < ret_count; ++i) { |
1966 value_locations[0] = pop_count->opcode() == IrOpcode::kInt32Constant | 2010 value_locations[i] = |
1967 ? g.UseImmediate(pop_count) | 2011 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i)); |
1968 : g.UseRegister(pop_count); | 2012 } |
1969 for (int i = 1; i < input_count; ++i) { | 2013 Emit(kArchRet, 0, nullptr, ret_count, value_locations); |
1970 value_locations[i] = | |
1971 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1)); | |
1972 } | 2014 } |
1973 Emit(kArchRet, 0, nullptr, input_count, value_locations); | |
1974 } | 2015 } |
1975 | 2016 |
1976 Instruction* InstructionSelector::EmitDeoptimize(InstructionCode opcode, | 2017 Instruction* InstructionSelector::EmitDeoptimize(InstructionCode opcode, |
1977 InstructionOperand output, | 2018 InstructionOperand output, |
1978 InstructionOperand a, | 2019 InstructionOperand a, |
1979 DeoptimizeReason reason, | 2020 DeoptimizeReason reason, |
1980 Node* frame_state) { | 2021 Node* frame_state) { |
1981 size_t output_count = output.IsInvalid() ? 0 : 1; | 2022 size_t output_count = output.IsInvalid() ? 0 : 1; |
1982 InstructionOperand inputs[] = {a}; | 2023 InstructionOperand inputs[] = {a}; |
1983 size_t input_count = arraysize(inputs); | 2024 size_t input_count = arraysize(inputs); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2103 return new (instruction_zone()) FrameStateDescriptor( | 2144 return new (instruction_zone()) FrameStateDescriptor( |
2104 instruction_zone(), state_info.type(), state_info.bailout_id(), | 2145 instruction_zone(), state_info.type(), state_info.bailout_id(), |
2105 state_info.state_combine(), parameters, locals, stack, | 2146 state_info.state_combine(), parameters, locals, stack, |
2106 state_info.shared_info(), outer_state); | 2147 state_info.shared_info(), outer_state); |
2107 } | 2148 } |
2108 | 2149 |
2109 | 2150 |
2110 } // namespace compiler | 2151 } // namespace compiler |
2111 } // namespace internal | 2152 } // namespace internal |
2112 } // namespace v8 | 2153 } // namespace v8 |
OLD | NEW |