Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(477)

Side by Side Diff: src/compiler/instruction-selector.cc

Issue 2446543002: [turbofan] Support variable size argument popping in TF-generated functions (Closed)
Patch Set: Fix tests and arm64 Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/ia32/code-generator-ia32.cc ('k') | src/compiler/js-inlining.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/ia32/code-generator-ia32.cc ('k') | src/compiler/js-inlining.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698