OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/compilation-info.h" | 7 #include "src/compilation-info.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 int deopt_state_id = | 642 int deopt_state_id = |
643 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); | 643 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); |
644 Deoptimizer::BailoutType bailout_type = | 644 Deoptimizer::BailoutType bailout_type = |
645 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); | 645 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); |
646 CodeGenResult result = AssembleDeoptimizerCall( | 646 CodeGenResult result = AssembleDeoptimizerCall( |
647 deopt_state_id, bailout_type, current_source_position_); | 647 deopt_state_id, bailout_type, current_source_position_); |
648 if (result != kSuccess) return result; | 648 if (result != kSuccess) return result; |
649 break; | 649 break; |
650 } | 650 } |
651 case kArchRet: | 651 case kArchRet: |
652 AssembleReturn(instr->InputAt(0)); | 652 AssembleReturn(); |
653 break; | 653 break; |
654 case kArchStackPointer: | 654 case kArchStackPointer: |
655 __ mov(i.OutputRegister(), esp); | 655 __ mov(i.OutputRegister(), esp); |
656 break; | 656 break; |
657 case kArchFramePointer: | 657 case kArchFramePointer: |
658 __ mov(i.OutputRegister(), ebp); | 658 __ mov(i.OutputRegister(), ebp); |
659 break; | 659 break; |
660 case kArchParentFramePointer: | 660 case kArchParentFramePointer: |
661 if (frame_access_state()->has_frame()) { | 661 if (frame_access_state()->has_frame()) { |
662 __ mov(i.OutputRegister(), Operand(ebp, 0)); | 662 __ mov(i.OutputRegister(), Operand(ebp, 0)); |
(...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1974 DCHECK(!info()->is_osr()); | 1974 DCHECK(!info()->is_osr()); |
1975 int pushed = 0; | 1975 int pushed = 0; |
1976 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { | 1976 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { |
1977 if (!((1 << i) & saves)) continue; | 1977 if (!((1 << i) & saves)) continue; |
1978 __ push(Register::from_code(i)); | 1978 __ push(Register::from_code(i)); |
1979 ++pushed; | 1979 ++pushed; |
1980 } | 1980 } |
1981 } | 1981 } |
1982 } | 1982 } |
1983 | 1983 |
1984 void CodeGenerator::AssembleReturn(InstructionOperand* pop) { | 1984 |
| 1985 void CodeGenerator::AssembleReturn() { |
1985 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1986 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1986 | 1987 |
1987 const RegList saves = descriptor->CalleeSavedRegisters(); | 1988 const RegList saves = descriptor->CalleeSavedRegisters(); |
1988 // Restore registers. | 1989 // Restore registers. |
1989 if (saves != 0) { | 1990 if (saves != 0) { |
1990 for (int i = 0; i < Register::kNumRegisters; i++) { | 1991 for (int i = 0; i < Register::kNumRegisters; i++) { |
1991 if (!((1 << i) & saves)) continue; | 1992 if (!((1 << i) & saves)) continue; |
1992 __ pop(Register::from_code(i)); | 1993 __ pop(Register::from_code(i)); |
1993 } | 1994 } |
1994 } | 1995 } |
1995 | 1996 |
1996 // Might need ecx for scratch if pop_size is too big or if there is a variable | |
1997 // pop count. | |
1998 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); | |
1999 size_t pop_size = descriptor->StackParameterCount() * kPointerSize; | |
2000 IA32OperandConverter g(this, nullptr); | |
2001 if (descriptor->IsCFunctionCall()) { | 1997 if (descriptor->IsCFunctionCall()) { |
2002 AssembleDeconstructFrame(); | 1998 AssembleDeconstructFrame(); |
2003 } else if (frame_access_state()->has_frame()) { | 1999 } else if (frame_access_state()->has_frame()) { |
2004 // Canonicalize JSFunction return sites for now if they always have the same | 2000 // Canonicalize JSFunction return sites for now. |
2005 // number of return args. | 2001 if (return_label_.is_bound()) { |
2006 if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) { | 2002 __ jmp(&return_label_); |
2007 if (return_label_.is_bound()) { | 2003 return; |
2008 __ jmp(&return_label_); | |
2009 return; | |
2010 } else { | |
2011 __ bind(&return_label_); | |
2012 AssembleDeconstructFrame(); | |
2013 } | |
2014 } else { | 2004 } else { |
| 2005 __ bind(&return_label_); |
2015 AssembleDeconstructFrame(); | 2006 AssembleDeconstructFrame(); |
2016 } | 2007 } |
2017 } | 2008 } |
2018 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & edx.bit()); | 2009 size_t pop_size = descriptor->StackParameterCount() * kPointerSize; |
| 2010 // Might need ecx for scratch if pop_size is too big. |
2019 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); | 2011 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); |
2020 if (pop->IsImmediate()) { | 2012 __ Ret(static_cast<int>(pop_size), ecx); |
2021 DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type()); | |
2022 pop_size += g.ToConstant(pop).ToInt32() * kPointerSize; | |
2023 __ Ret(static_cast<int>(pop_size), ecx); | |
2024 } else { | |
2025 Register pop_reg = g.ToRegister(pop); | |
2026 Register scratch_reg = pop_reg.is(ecx) ? edx : ecx; | |
2027 __ pop(scratch_reg); | |
2028 __ lea(esp, Operand(esp, pop_reg, times_4, static_cast<int>(pop_size))); | |
2029 __ jmp(scratch_reg); | |
2030 } | |
2031 } | 2013 } |
2032 | 2014 |
2033 | 2015 |
2034 void CodeGenerator::AssembleMove(InstructionOperand* source, | 2016 void CodeGenerator::AssembleMove(InstructionOperand* source, |
2035 InstructionOperand* destination) { | 2017 InstructionOperand* destination) { |
2036 IA32OperandConverter g(this, nullptr); | 2018 IA32OperandConverter g(this, nullptr); |
2037 // Dispatch on the source and destination operand kinds. Not all | 2019 // Dispatch on the source and destination operand kinds. Not all |
2038 // combinations are possible. | 2020 // combinations are possible. |
2039 if (source->IsRegister()) { | 2021 if (source->IsRegister()) { |
2040 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 2022 DCHECK(destination->IsRegister() || destination->IsStackSlot()); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2273 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2255 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2274 __ Nop(padding_size); | 2256 __ Nop(padding_size); |
2275 } | 2257 } |
2276 } | 2258 } |
2277 | 2259 |
2278 #undef __ | 2260 #undef __ |
2279 | 2261 |
2280 } // namespace compiler | 2262 } // namespace compiler |
2281 } // namespace internal | 2263 } // namespace internal |
2282 } // namespace v8 | 2264 } // namespace v8 |
OLD | NEW |