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/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 if (instr->InputAt(2)->IsRegister()) { \ | 324 if (instr->InputAt(2)->IsRegister()) { \ |
325 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ | 325 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ |
326 } else { \ | 326 } else { \ |
327 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ | 327 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ |
328 } \ | 328 } \ |
329 __ bind(&done); \ | 329 __ bind(&done); \ |
330 } while (false) | 330 } while (false) |
331 | 331 |
332 | 332 |
333 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 333 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
| 334 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
| 335 if (sp_slot_delta > 0) { |
| 336 __ add(esp, Immediate(sp_slot_delta * kPointerSize)); |
| 337 } |
334 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 338 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
335 int stack_slots = frame()->GetSpillSlotCount(); | 339 int spill_slots = frame()->GetSpillSlotCount(); |
336 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { | 340 bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; |
337 __ mov(esp, ebp); | 341 if (has_frame) { |
338 __ pop(ebp); | 342 __ pop(ebp); |
339 } | 343 } |
340 if (stack_param_delta < 0) { | |
341 int offset = -(stack_param_delta + 1) * kPointerSize; | |
342 __ pop(Operand(esp, offset)); | |
343 if (offset != 0) { | |
344 __ add(esp, Immediate(offset)); | |
345 } | |
346 } | |
347 } | 344 } |
348 | 345 |
| 346 |
| 347 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
| 348 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
| 349 if (sp_slot_delta < 0) { |
| 350 __ sub(esp, Immediate(-sp_slot_delta * kPointerSize)); |
| 351 } |
| 352 } |
| 353 |
349 | 354 |
350 // Assembles an instruction after register allocation, producing machine code. | 355 // Assembles an instruction after register allocation, producing machine code. |
351 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 356 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
352 X87OperandConverter i(this, instr); | 357 X87OperandConverter i(this, instr); |
353 | 358 |
354 switch (ArchOpcodeField::decode(instr->opcode())) { | 359 switch (ArchOpcodeField::decode(instr->opcode())) { |
355 case kArchCallCodeObject: { | 360 case kArchCallCodeObject: { |
356 EnsureSpaceForLazyDeopt(); | 361 EnsureSpaceForLazyDeopt(); |
357 if (HasImmediateInput(instr, 0)) { | 362 if (HasImmediateInput(instr, 0)) { |
358 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 363 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 case kArchLazyBailout: { | 436 case kArchLazyBailout: { |
432 EnsureSpaceForLazyDeopt(); | 437 EnsureSpaceForLazyDeopt(); |
433 RecordCallPosition(instr); | 438 RecordCallPosition(instr); |
434 break; | 439 break; |
435 } | 440 } |
436 case kArchPrepareCallCFunction: { | 441 case kArchPrepareCallCFunction: { |
437 int const num_parameters = MiscField::decode(instr->opcode()); | 442 int const num_parameters = MiscField::decode(instr->opcode()); |
438 __ PrepareCallCFunction(num_parameters, i.TempRegister(0)); | 443 __ PrepareCallCFunction(num_parameters, i.TempRegister(0)); |
439 break; | 444 break; |
440 } | 445 } |
| 446 case kArchPrepareTailCall: |
| 447 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); |
| 448 break; |
441 case kArchCallCFunction: { | 449 case kArchCallCFunction: { |
442 int const num_parameters = MiscField::decode(instr->opcode()); | 450 int const num_parameters = MiscField::decode(instr->opcode()); |
443 if (HasImmediateInput(instr, 0)) { | 451 if (HasImmediateInput(instr, 0)) { |
444 ExternalReference ref = i.InputExternalReference(0); | 452 ExternalReference ref = i.InputExternalReference(0); |
445 __ CallCFunction(ref, num_parameters); | 453 __ CallCFunction(ref, num_parameters); |
446 } else { | 454 } else { |
447 Register func = i.InputRegister(0); | 455 Register func = i.InputRegister(0); |
448 __ CallCFunction(func, num_parameters); | 456 __ CallCFunction(func, num_parameters); |
449 } | 457 } |
450 break; | 458 break; |
(...skipping 1510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 1969 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
1962 __ Nop(padding_size); | 1970 __ Nop(padding_size); |
1963 } | 1971 } |
1964 } | 1972 } |
1965 | 1973 |
1966 #undef __ | 1974 #undef __ |
1967 | 1975 |
1968 } // namespace compiler | 1976 } // namespace compiler |
1969 } // namespace internal | 1977 } // namespace internal |
1970 } // namespace v8 | 1978 } // namespace v8 |
OLD | NEW |