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

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 x64 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
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()) { 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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698