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/address-map.h" | 7 #include "src/address-map.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 | 209 |
210 // Emit a code line info recording stop event. | 210 // Emit a code line info recording stop event. |
211 void* line_info = recorder->DetachJITHandlerData(); | 211 void* line_info = recorder->DetachJITHandlerData(); |
212 LOG_CODE_EVENT(isolate(), CodeEndLinePosInfoRecordEvent(*result, line_info)); | 212 LOG_CODE_EVENT(isolate(), CodeEndLinePosInfoRecordEvent(*result, line_info)); |
213 | 213 |
214 return result; | 214 return result; |
215 } | 215 } |
216 | 216 |
217 | 217 |
218 bool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const { | 218 bool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const { |
219 return code()->InstructionBlockAt(current_block_)->ao_number().IsNext( | 219 return code() |
220 code()->InstructionBlockAt(block)->ao_number()); | 220 ->InstructionBlockAt(current_block_) |
| 221 ->ao_number() |
| 222 .IsNext(code()->InstructionBlockAt(block)->ao_number()); |
221 } | 223 } |
222 | 224 |
223 | 225 |
224 void CodeGenerator::RecordSafepoint(ReferenceMap* references, | 226 void CodeGenerator::RecordSafepoint(ReferenceMap* references, |
225 Safepoint::Kind kind, int arguments, | 227 Safepoint::Kind kind, int arguments, |
226 Safepoint::DeoptMode deopt_mode) { | 228 Safepoint::DeoptMode deopt_mode) { |
227 Safepoint safepoint = | 229 Safepoint safepoint = |
228 safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode); | 230 safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode); |
229 int stackSlotToSpillSlotDelta = | 231 int stackSlotToSpillSlotDelta = |
230 frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount(); | 232 frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount(); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 | 484 |
483 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( | 485 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( |
484 Instruction* instr, size_t frame_state_offset) { | 486 Instruction* instr, size_t frame_state_offset) { |
485 InstructionOperandConverter i(this, instr); | 487 InstructionOperandConverter i(this, instr); |
486 InstructionSequence::StateId state_id = | 488 InstructionSequence::StateId state_id = |
487 InstructionSequence::StateId::FromInt(i.InputInt32(frame_state_offset)); | 489 InstructionSequence::StateId::FromInt(i.InputInt32(frame_state_offset)); |
488 return code()->GetFrameStateDescriptor(state_id); | 490 return code()->GetFrameStateDescriptor(state_id); |
489 } | 491 } |
490 | 492 |
491 | 493 |
492 namespace { | 494 void CodeGenerator::TranslateStateValueDescriptor( |
493 | 495 StateValueDescriptor* desc, Translation* translation, |
494 struct OperandAndType { | 496 InstructionOperandIterator* iter) { |
495 InstructionOperand* const operand; | 497 if (desc->IsNested()) { |
496 MachineType const type; | 498 translation->BeginCapturedObject(static_cast<int>(desc->size())); |
497 }; | 499 for (size_t index = 0; index < desc->fields().size(); index++) { |
| 500 TranslateStateValueDescriptor(&desc->fields()[index], translation, iter); |
| 501 } |
| 502 } else if (desc->IsDuplicate()) { |
| 503 translation->DuplicateObject(static_cast<int>(desc->id())); |
| 504 } else { |
| 505 DCHECK(desc->IsPlain()); |
| 506 AddTranslationForOperand(translation, iter->instruction(), iter->Advance(), |
| 507 desc->type()); |
| 508 } |
| 509 } |
498 | 510 |
499 | 511 |
500 OperandAndType TypedOperandForFrameState(FrameStateDescriptor* descriptor, | 512 void CodeGenerator::TranslateFrameStateDescriptorOperands( |
501 Instruction* instr, | 513 FrameStateDescriptor* desc, InstructionOperandIterator* iter, |
502 size_t frame_state_offset, | 514 OutputFrameStateCombine combine, Translation* translation) { |
503 size_t index, | 515 for (size_t index = 0; index < desc->GetSize(combine); index++) { |
504 OutputFrameStateCombine combine) { | 516 switch (combine.kind()) { |
505 DCHECK(index < descriptor->GetSize(combine)); | 517 case OutputFrameStateCombine::kPushOutput: { |
506 switch (combine.kind()) { | 518 DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount()); |
507 case OutputFrameStateCombine::kPushOutput: { | 519 size_t size_without_output = |
508 DCHECK(combine.GetPushCount() <= instr->OutputCount()); | 520 desc->GetSize(OutputFrameStateCombine::Ignore()); |
509 size_t size_without_output = | 521 // If the index is past the existing stack items in values_. |
510 descriptor->GetSize(OutputFrameStateCombine::Ignore()); | 522 if (index >= size_without_output) { |
511 // If the index is past the existing stack items, return the output. | 523 // Materialize the result of the call instruction in this slot. |
512 if (index >= size_without_output) { | 524 AddTranslationForOperand( |
513 return {instr->OutputAt(index - size_without_output), | 525 translation, iter->instruction(), |
514 MachineType::AnyTagged()}; | 526 iter->instruction()->OutputAt(index - size_without_output), |
| 527 MachineType::AnyTagged()); |
| 528 continue; |
| 529 } |
| 530 break; |
515 } | 531 } |
516 break; | 532 case OutputFrameStateCombine::kPokeAt: |
| 533 // The result of the call should be placed at position |
| 534 // [index_from_top] in the stack (overwriting whatever was |
| 535 // previously there). |
| 536 size_t index_from_top = |
| 537 desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); |
| 538 if (index >= index_from_top && |
| 539 index < index_from_top + iter->instruction()->OutputCount()) { |
| 540 AddTranslationForOperand( |
| 541 translation, iter->instruction(), |
| 542 iter->instruction()->OutputAt(index - index_from_top), |
| 543 MachineType::AnyTagged()); |
| 544 iter->Advance(); // We do not use this input, but we need to |
| 545 // advace, as the input got replaced. |
| 546 continue; |
| 547 } |
| 548 break; |
517 } | 549 } |
518 case OutputFrameStateCombine::kPokeAt: | 550 StateValueDescriptor* value_desc = desc->GetStateValueDescriptor(); |
519 size_t index_from_top = | 551 TranslateStateValueDescriptor(&value_desc->fields()[index], translation, |
520 descriptor->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); | 552 iter); |
521 if (index >= index_from_top && | |
522 index < index_from_top + instr->OutputCount()) { | |
523 return {instr->OutputAt(index - index_from_top), | |
524 MachineType::AnyTagged()}; | |
525 } | |
526 break; | |
527 } | 553 } |
528 return {instr->InputAt(frame_state_offset + index), | |
529 descriptor->GetType(index)}; | |
530 } | 554 } |
531 | 555 |
532 } // namespace | |
533 | |
534 | 556 |
535 void CodeGenerator::BuildTranslationForFrameStateDescriptor( | 557 void CodeGenerator::BuildTranslationForFrameStateDescriptor( |
536 FrameStateDescriptor* descriptor, Instruction* instr, | 558 FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, |
537 Translation* translation, size_t frame_state_offset, | 559 Translation* translation, OutputFrameStateCombine state_combine) { |
538 OutputFrameStateCombine state_combine) { | |
539 // Outer-most state must be added to translation first. | 560 // Outer-most state must be added to translation first. |
540 if (descriptor->outer_state() != nullptr) { | 561 if (descriptor->outer_state() != nullptr) { |
541 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr, | 562 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter, |
542 translation, frame_state_offset, | 563 translation, |
543 OutputFrameStateCombine::Ignore()); | 564 OutputFrameStateCombine::Ignore()); |
544 } | 565 } |
545 frame_state_offset += descriptor->outer_state()->GetTotalSize(); | |
546 | 566 |
547 Handle<SharedFunctionInfo> shared_info; | 567 Handle<SharedFunctionInfo> shared_info; |
548 if (!descriptor->shared_info().ToHandle(&shared_info)) { | 568 if (!descriptor->shared_info().ToHandle(&shared_info)) { |
549 if (!info()->has_shared_info()) return; // Stub with no SharedFunctionInfo. | 569 if (!info()->has_shared_info()) { |
| 570 return; // Stub with no SharedFunctionInfo. |
| 571 } |
550 shared_info = info()->shared_info(); | 572 shared_info = info()->shared_info(); |
551 } | 573 } |
552 int shared_info_id = DefineDeoptimizationLiteral(shared_info); | 574 int shared_info_id = DefineDeoptimizationLiteral(shared_info); |
553 | 575 |
554 switch (descriptor->type()) { | 576 switch (descriptor->type()) { |
555 case FrameStateType::kJavaScriptFunction: | 577 case FrameStateType::kJavaScriptFunction: |
556 translation->BeginJSFrame( | 578 translation->BeginJSFrame( |
557 descriptor->bailout_id(), shared_info_id, | 579 descriptor->bailout_id(), shared_info_id, |
558 static_cast<unsigned int>(descriptor->GetSize(state_combine) - | 580 static_cast<unsigned int>(descriptor->GetSize(state_combine) - |
559 (1 + descriptor->parameters_count()))); | 581 (1 + descriptor->parameters_count()))); |
560 break; | 582 break; |
561 case FrameStateType::kInterpretedFunction: | 583 case FrameStateType::kInterpretedFunction: |
562 translation->BeginInterpretedFrame( | 584 translation->BeginInterpretedFrame( |
563 descriptor->bailout_id(), shared_info_id, | 585 descriptor->bailout_id(), shared_info_id, |
564 static_cast<unsigned int>(descriptor->locals_count())); | 586 static_cast<unsigned int>(descriptor->locals_count())); |
565 break; | 587 break; |
566 case FrameStateType::kArgumentsAdaptor: | 588 case FrameStateType::kArgumentsAdaptor: |
567 translation->BeginArgumentsAdaptorFrame( | 589 translation->BeginArgumentsAdaptorFrame( |
568 shared_info_id, | 590 shared_info_id, |
569 static_cast<unsigned int>(descriptor->parameters_count())); | 591 static_cast<unsigned int>(descriptor->parameters_count())); |
570 break; | 592 break; |
571 case FrameStateType::kConstructStub: | 593 case FrameStateType::kConstructStub: |
572 translation->BeginConstructStubFrame( | 594 translation->BeginConstructStubFrame( |
573 shared_info_id, | 595 shared_info_id, |
574 static_cast<unsigned int>(descriptor->parameters_count())); | 596 static_cast<unsigned int>(descriptor->parameters_count())); |
575 break; | 597 break; |
576 } | 598 } |
577 | 599 |
578 for (size_t i = 0; i < descriptor->GetSize(state_combine); i++) { | 600 TranslateFrameStateDescriptorOperands(descriptor, iter, state_combine, |
579 OperandAndType op = TypedOperandForFrameState( | 601 translation); |
580 descriptor, instr, frame_state_offset, i, state_combine); | |
581 AddTranslationForOperand(translation, instr, op.operand, op.type); | |
582 } | |
583 } | 602 } |
584 | 603 |
585 | 604 |
586 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, | 605 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, |
587 size_t frame_state_offset, | 606 size_t frame_state_offset, |
588 OutputFrameStateCombine state_combine) { | 607 OutputFrameStateCombine state_combine) { |
589 FrameStateDescriptor* descriptor = | 608 FrameStateDescriptor* descriptor = |
590 GetFrameStateDescriptor(instr, frame_state_offset); | 609 GetFrameStateDescriptor(instr, frame_state_offset); |
591 frame_state_offset++; | 610 frame_state_offset++; |
592 | 611 |
593 Translation translation( | 612 Translation translation( |
594 &translations_, static_cast<int>(descriptor->GetFrameCount()), | 613 &translations_, static_cast<int>(descriptor->GetFrameCount()), |
595 static_cast<int>(descriptor->GetJSFrameCount()), zone()); | 614 static_cast<int>(descriptor->GetJSFrameCount()), zone()); |
596 BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation, | 615 InstructionOperandIterator iter(instr, frame_state_offset); |
597 frame_state_offset, state_combine); | 616 BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation, |
| 617 state_combine); |
598 | 618 |
599 int deoptimization_id = static_cast<int>(deoptimization_states_.size()); | 619 int deoptimization_id = static_cast<int>(deoptimization_states_.size()); |
600 | 620 |
601 deoptimization_states_.push_back(new (zone()) DeoptimizationState( | 621 deoptimization_states_.push_back(new (zone()) DeoptimizationState( |
602 descriptor->bailout_id(), translation.index(), pc_offset)); | 622 descriptor->bailout_id(), translation.index(), pc_offset)); |
603 | 623 |
604 return deoptimization_id; | 624 return deoptimization_id; |
605 } | 625 } |
606 | 626 |
607 | 627 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { | 728 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { |
709 gen->ools_ = this; | 729 gen->ools_ = this; |
710 } | 730 } |
711 | 731 |
712 | 732 |
713 OutOfLineCode::~OutOfLineCode() {} | 733 OutOfLineCode::~OutOfLineCode() {} |
714 | 734 |
715 } // namespace compiler | 735 } // namespace compiler |
716 } // namespace internal | 736 } // namespace internal |
717 } // namespace v8 | 737 } // namespace v8 |
OLD | NEW |