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()) { | 1908 switch (descriptor->kind()) { |
1909 case CallDescriptor::kCallCodeObject: | 1909 case CallDescriptor::kCallCodeObject: |
1910 opcode = kArchTailCallCodeObjectFromJSFunction; | 1910 opcode = kArchTailCallCodeObjectFromJSFunction; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1942 | 1942 |
1943 int first_unused_stack_slot = | 1943 int first_unused_stack_slot = |
1944 (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0) + | 1944 (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0) + |
1945 stack_param_delta; | 1945 stack_param_delta; |
1946 buffer.instruction_args.push_back(g.TempImmediate(first_unused_stack_slot)); | 1946 buffer.instruction_args.push_back(g.TempImmediate(first_unused_stack_slot)); |
1947 | 1947 |
1948 // Emit the tailcall instruction. | 1948 // Emit the tailcall instruction. |
1949 Emit(opcode, 0, nullptr, buffer.instruction_args.size(), | 1949 Emit(opcode, 0, nullptr, buffer.instruction_args.size(), |
1950 &buffer.instruction_args.front(), temps.size(), | 1950 &buffer.instruction_args.front(), temps.size(), |
1951 temps.empty() ? nullptr : &temps.front()); | 1951 temps.empty() ? nullptr : &temps.front()); |
1952 } else { | |
danno
2016/10/25 06:43:32
Given that return instructions now need to know ho
| |
1953 FrameStateDescriptor* frame_state_descriptor = | |
1954 descriptor->NeedsFrameState() | |
1955 ? GetFrameStateDescriptor( | |
1956 node->InputAt(static_cast<int>(descriptor->InputCount()))) | |
1957 : nullptr; | |
1958 | |
1959 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | |
1960 | |
1961 // Compute InstructionOperands for inputs and outputs. | |
1962 CallBufferFlags flags = kCallCodeImmediate; | |
1963 if (IsTailCallAddressImmediate()) { | |
1964 flags |= kCallAddressImmediate; | |
1965 } | |
1966 InitializeCallBuffer(node, &buffer, flags); | |
1967 | |
1968 EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node); | |
1969 | |
1970 // Select the appropriate opcode based on the call type. | |
1971 InstructionCode opcode; | |
1972 switch (descriptor->kind()) { | |
1973 case CallDescriptor::kCallCodeObject: | |
1974 opcode = kArchCallCodeObject; | |
1975 break; | |
1976 case CallDescriptor::kCallJSFunction: | |
1977 opcode = kArchCallJSFunction; | |
1978 break; | |
1979 default: | |
1980 UNREACHABLE(); | |
1981 return; | |
1982 } | |
1983 opcode |= MiscField::encode(descriptor->flags()); | |
1984 | |
1985 // Emit the call instruction. | |
1986 size_t output_count = buffer.outputs.size(); | |
1987 auto* outputs = &buffer.outputs.front(); | |
1988 Instruction* call_instr = | |
1989 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | |
1990 &buffer.instruction_args.front()); | |
1991 if (instruction_selection_failed()) return; | |
1992 call_instr->MarkAsCall(); | |
1993 Emit(kArchRet, 0, nullptr, output_count, outputs); | |
1994 } | |
1995 } | 1952 } |
1996 | 1953 |
1997 | 1954 |
1998 void InstructionSelector::VisitGoto(BasicBlock* target) { | 1955 void InstructionSelector::VisitGoto(BasicBlock* target) { |
1999 // jump to the next block. | 1956 // jump to the next block. |
2000 OperandGenerator g(this); | 1957 OperandGenerator g(this); |
2001 Emit(kArchJmp, g.NoOutput(), g.Label(target)); | 1958 Emit(kArchJmp, g.NoOutput(), g.Label(target)); |
2002 } | 1959 } |
2003 | 1960 |
2004 | |
2005 void InstructionSelector::VisitReturn(Node* ret) { | 1961 void InstructionSelector::VisitReturn(Node* ret) { |
2006 OperandGenerator g(this); | 1962 OperandGenerator g(this); |
2007 if (linkage()->GetIncomingDescriptor()->ReturnCount() == 0) { | 1963 const int ret_count = linkage()->GetIncomingDescriptor()->ReturnCount() == 0 |
2008 Emit(kArchRet, g.NoOutput()); | 1964 ? 1 |
2009 } else { | 1965 : ret->op()->ValueInputCount(); |
2010 const int ret_count = ret->op()->ValueInputCount(); | 1966 DCHECK_GE(ret_count, 1); |
2011 auto value_locations = zone()->NewArray<InstructionOperand>(ret_count); | 1967 auto value_locations = zone()->NewArray<InstructionOperand>(ret_count); |
2012 for (int i = 0; i < ret_count; ++i) { | 1968 Node* pop_count = ret->InputAt(0); |
2013 value_locations[i] = | 1969 value_locations[0] = pop_count->opcode() == IrOpcode::kInt32Constant |
2014 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i)); | 1970 ? g.UseImmediate(pop_count) |
2015 } | 1971 : g.UseRegister(pop_count); |
2016 Emit(kArchRet, 0, nullptr, ret_count, value_locations); | 1972 for (int i = 1; i < ret_count; ++i) { |
1973 value_locations[i] = | |
1974 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i - 1)); | |
2017 } | 1975 } |
1976 Emit(kArchRet, 0, nullptr, ret_count, value_locations); | |
2018 } | 1977 } |
2019 | 1978 |
2020 Instruction* InstructionSelector::EmitDeoptimize( | 1979 Instruction* InstructionSelector::EmitDeoptimize( |
2021 InstructionCode opcode, InstructionOperand output, InstructionOperand a, | 1980 InstructionCode opcode, InstructionOperand output, InstructionOperand a, |
2022 InstructionOperand b, DeoptimizeReason reason, Node* frame_state) { | 1981 InstructionOperand b, DeoptimizeReason reason, Node* frame_state) { |
2023 size_t output_count = output.IsInvalid() ? 0 : 1; | 1982 size_t output_count = output.IsInvalid() ? 0 : 1; |
2024 InstructionOperand inputs[] = {a, b}; | 1983 InstructionOperand inputs[] = {a, b}; |
2025 size_t input_count = arraysize(inputs); | 1984 size_t input_count = arraysize(inputs); |
2026 return EmitDeoptimize(opcode, output_count, &output, input_count, inputs, | 1985 return EmitDeoptimize(opcode, output_count, &output, input_count, inputs, |
2027 reason, frame_state); | 1986 reason, frame_state); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2135 return new (instruction_zone()) FrameStateDescriptor( | 2094 return new (instruction_zone()) FrameStateDescriptor( |
2136 instruction_zone(), state_info.type(), state_info.bailout_id(), | 2095 instruction_zone(), state_info.type(), state_info.bailout_id(), |
2137 state_info.state_combine(), parameters, locals, stack, | 2096 state_info.state_combine(), parameters, locals, stack, |
2138 state_info.shared_info(), outer_state); | 2097 state_info.shared_info(), outer_state); |
2139 } | 2098 } |
2140 | 2099 |
2141 | 2100 |
2142 } // namespace compiler | 2101 } // namespace compiler |
2143 } // namespace internal | 2102 } // namespace internal |
2144 } // namespace v8 | 2103 } // namespace v8 |
OLD | NEW |