| 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 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 int deopt_state_id = | 645 int deopt_state_id = |
| 646 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); | 646 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); |
| 647 Deoptimizer::BailoutType bailout_type = | 647 Deoptimizer::BailoutType bailout_type = |
| 648 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); | 648 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); |
| 649 CodeGenResult result = AssembleDeoptimizerCall( | 649 CodeGenResult result = AssembleDeoptimizerCall( |
| 650 deopt_state_id, bailout_type, current_source_position_); | 650 deopt_state_id, bailout_type, current_source_position_); |
| 651 if (result != kSuccess) return result; | 651 if (result != kSuccess) return result; |
| 652 break; | 652 break; |
| 653 } | 653 } |
| 654 case kArchRet: | 654 case kArchRet: |
| 655 AssembleReturn(); | 655 AssembleReturn(instr->InputAt(0)); |
| 656 break; | 656 break; |
| 657 case kArchStackPointer: | 657 case kArchStackPointer: |
| 658 __ mov(i.OutputRegister(), esp); | 658 __ mov(i.OutputRegister(), esp); |
| 659 break; | 659 break; |
| 660 case kArchFramePointer: | 660 case kArchFramePointer: |
| 661 __ mov(i.OutputRegister(), ebp); | 661 __ mov(i.OutputRegister(), ebp); |
| 662 break; | 662 break; |
| 663 case kArchParentFramePointer: | 663 case kArchParentFramePointer: |
| 664 if (frame_access_state()->has_frame()) { | 664 if (frame_access_state()->has_frame()) { |
| 665 __ mov(i.OutputRegister(), Operand(ebp, 0)); | 665 __ mov(i.OutputRegister(), Operand(ebp, 0)); |
| (...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1977 DCHECK(!info()->is_osr()); | 1977 DCHECK(!info()->is_osr()); |
| 1978 int pushed = 0; | 1978 int pushed = 0; |
| 1979 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { | 1979 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { |
| 1980 if (!((1 << i) & saves)) continue; | 1980 if (!((1 << i) & saves)) continue; |
| 1981 __ push(Register::from_code(i)); | 1981 __ push(Register::from_code(i)); |
| 1982 ++pushed; | 1982 ++pushed; |
| 1983 } | 1983 } |
| 1984 } | 1984 } |
| 1985 } | 1985 } |
| 1986 | 1986 |
| 1987 | 1987 void CodeGenerator::AssembleReturn(InstructionOperand* pop) { |
| 1988 void CodeGenerator::AssembleReturn() { | |
| 1989 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1988 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1990 | 1989 |
| 1991 const RegList saves = descriptor->CalleeSavedRegisters(); | 1990 const RegList saves = descriptor->CalleeSavedRegisters(); |
| 1992 // Restore registers. | 1991 // Restore registers. |
| 1993 if (saves != 0) { | 1992 if (saves != 0) { |
| 1994 for (int i = 0; i < Register::kNumRegisters; i++) { | 1993 for (int i = 0; i < Register::kNumRegisters; i++) { |
| 1995 if (!((1 << i) & saves)) continue; | 1994 if (!((1 << i) & saves)) continue; |
| 1996 __ pop(Register::from_code(i)); | 1995 __ pop(Register::from_code(i)); |
| 1997 } | 1996 } |
| 1998 } | 1997 } |
| 1999 | 1998 |
| 2000 if (descriptor->IsCFunctionCall()) { | 1999 if (descriptor->IsCFunctionCall()) { |
| 2001 AssembleDeconstructFrame(); | 2000 AssembleDeconstructFrame(); |
| 2002 } else if (frame_access_state()->has_frame()) { | 2001 } else if (frame_access_state()->has_frame()) { |
| 2003 // Canonicalize JSFunction return sites for now. | 2002 // Canonicalize JSFunction return sites for now. |
| 2004 if (return_label_.is_bound()) { | 2003 if (return_label_.is_bound()) { |
| 2005 __ jmp(&return_label_); | 2004 __ jmp(&return_label_); |
| 2006 return; | 2005 return; |
| 2007 } else { | 2006 } else { |
| 2008 __ bind(&return_label_); | 2007 __ bind(&return_label_); |
| 2009 AssembleDeconstructFrame(); | 2008 AssembleDeconstructFrame(); |
| 2010 } | 2009 } |
| 2011 } | 2010 } |
| 2011 // Might need ecx for scratch if pop_size is too big or if there is a variable |
| 2012 // pop count. |
| 2013 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); |
| 2012 size_t pop_size = descriptor->StackParameterCount() * kPointerSize; | 2014 size_t pop_size = descriptor->StackParameterCount() * kPointerSize; |
| 2013 // Might need ecx for scratch if pop_size is too big. | 2015 IA32OperandConverter g(this, nullptr); |
| 2014 DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); | 2016 if (pop->IsImmediate()) { |
| 2015 __ Ret(static_cast<int>(pop_size), ecx); | 2017 DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type()); |
| 2018 pop_size += g.ToConstant(pop).ToInt32() * kPointerSize; |
| 2019 __ Ret(static_cast<int>(pop_size), ecx); |
| 2020 } else { |
| 2021 Register reg = g.ToRegister(pop); |
| 2022 __ pop(ecx); |
| 2023 __ lea(esp, Operand(esp, reg, times_4, pop_size)); |
| 2024 __ jmp(ecx); |
| 2025 } |
| 2016 } | 2026 } |
| 2017 | 2027 |
| 2018 | 2028 |
| 2019 void CodeGenerator::AssembleMove(InstructionOperand* source, | 2029 void CodeGenerator::AssembleMove(InstructionOperand* source, |
| 2020 InstructionOperand* destination) { | 2030 InstructionOperand* destination) { |
| 2021 IA32OperandConverter g(this, nullptr); | 2031 IA32OperandConverter g(this, nullptr); |
| 2022 // Dispatch on the source and destination operand kinds. Not all | 2032 // Dispatch on the source and destination operand kinds. Not all |
| 2023 // combinations are possible. | 2033 // combinations are possible. |
| 2024 if (source->IsRegister()) { | 2034 if (source->IsRegister()) { |
| 2025 DCHECK(destination->IsRegister() || destination->IsStackSlot()); | 2035 DCHECK(destination->IsRegister() || destination->IsStackSlot()); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2258 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2268 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
| 2259 __ Nop(padding_size); | 2269 __ Nop(padding_size); |
| 2260 } | 2270 } |
| 2261 } | 2271 } |
| 2262 | 2272 |
| 2263 #undef __ | 2273 #undef __ |
| 2264 | 2274 |
| 2265 } // namespace compiler | 2275 } // namespace compiler |
| 2266 } // namespace internal | 2276 } // namespace internal |
| 2267 } // namespace v8 | 2277 } // namespace v8 |
| OLD | NEW |