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

Side by Side Diff: src/compiler/code-generator.cc

Issue 2546113002: [turbofan] Improve memory consumption for state values descriptors. (Closed)
Patch Set: Do not store optimized-out into instructions. Created 4 years 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
« no previous file with comments | « src/compiler/code-generator.h ('k') | src/compiler/instruction.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/base/adapters.h" 8 #include "src/base/adapters.h"
9 #include "src/compilation-info.h" 9 #include "src/compilation-info.h"
10 #include "src/compiler/code-generator-impl.h" 10 #include "src/compiler/code-generator-impl.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 handlers_(code->zone()), 51 handlers_(code->zone()),
52 deoptimization_exits_(code->zone()), 52 deoptimization_exits_(code->zone()),
53 deoptimization_states_(code->zone()), 53 deoptimization_states_(code->zone()),
54 deoptimization_literals_(code->zone()), 54 deoptimization_literals_(code->zone()),
55 inlined_function_count_(0), 55 inlined_function_count_(0),
56 translations_(code->zone()), 56 translations_(code->zone()),
57 last_lazy_deopt_pc_(0), 57 last_lazy_deopt_pc_(0),
58 jump_tables_(nullptr), 58 jump_tables_(nullptr),
59 ools_(nullptr), 59 ools_(nullptr),
60 osr_pc_offset_(-1), 60 osr_pc_offset_(-1),
61 optimized_out_literal_id_(-1),
61 source_position_table_builder_(code->zone(), 62 source_position_table_builder_(code->zone(),
62 info->SourcePositionRecordingMode()), 63 info->SourcePositionRecordingMode()),
63 protected_instructions_(protected_instructions) { 64 protected_instructions_(protected_instructions) {
64 for (int i = 0; i < code->InstructionBlockCount(); ++i) { 65 for (int i = 0; i < code->InstructionBlockCount(); ++i) {
65 new (&labels_[i]) Label; 66 new (&labels_[i]) Label;
66 } 67 }
67 CreateFrameAccessState(frame); 68 CreateFrameAccessState(frame);
68 } 69 }
69 70
70 Isolate* CodeGenerator::isolate() const { return info_->isolate(); } 71 Isolate* CodeGenerator::isolate() const { return info_->isolate(); }
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 // If the pre-call frame state differs from the post-call one, produce the 634 // If the pre-call frame state differs from the post-call one, produce the
634 // pre-call frame state, too. 635 // pre-call frame state, too.
635 // TODO(jarin) We might want to avoid building the pre-call frame state 636 // TODO(jarin) We might want to avoid building the pre-call frame state
636 // because it is only used to get locals and arguments (by the debugger and 637 // because it is only used to get locals and arguments (by the debugger and
637 // f.arguments), and those are the same in the pre-call and post-call 638 // f.arguments), and those are the same in the pre-call and post-call
638 // states. 639 // states.
639 if (!descriptor->state_combine().IsOutputIgnored()) { 640 if (!descriptor->state_combine().IsOutputIgnored()) {
640 deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, 641 deopt_state_id = BuildTranslation(instr, -1, frame_state_offset,
641 OutputFrameStateCombine::Ignore()); 642 OutputFrameStateCombine::Ignore());
642 } 643 }
643 #if DEBUG
644 // Make sure all the values live in stack slots or they are immediates.
645 // (The values should not live in register because registers are clobbered
646 // by calls.)
647 for (size_t i = 0; i < descriptor->GetSize(); i++) {
648 InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i);
649 CHECK(op->IsStackSlot() || op->IsFPStackSlot() || op->IsImmediate());
650 }
651 #endif
652 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); 644 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id);
653 } 645 }
654 } 646 }
655 647
656 648
657 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { 649 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) {
658 int result = static_cast<int>(deoptimization_literals_.size()); 650 int result = static_cast<int>(deoptimization_literals_.size());
659 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { 651 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) {
660 if (deoptimization_literals_[i].is_identical_to(literal)) return i; 652 if (deoptimization_literals_[i].is_identical_to(literal)) return i;
661 } 653 }
662 deoptimization_literals_.push_back(literal); 654 deoptimization_literals_.push_back(literal);
663 return result; 655 return result;
664 } 656 }
665 657
666 DeoptimizationEntry const& CodeGenerator::GetDeoptimizationEntry( 658 DeoptimizationEntry const& CodeGenerator::GetDeoptimizationEntry(
667 Instruction* instr, size_t frame_state_offset) { 659 Instruction* instr, size_t frame_state_offset) {
668 InstructionOperandConverter i(this, instr); 660 InstructionOperandConverter i(this, instr);
669 int const state_id = i.InputInt32(frame_state_offset); 661 int const state_id = i.InputInt32(frame_state_offset);
670 return code()->GetDeoptimizationEntry(state_id); 662 return code()->GetDeoptimizationEntry(state_id);
671 } 663 }
672 664
673 DeoptimizeReason CodeGenerator::GetDeoptimizationReason( 665 DeoptimizeReason CodeGenerator::GetDeoptimizationReason(
674 int deoptimization_id) const { 666 int deoptimization_id) const {
675 size_t const index = static_cast<size_t>(deoptimization_id); 667 size_t const index = static_cast<size_t>(deoptimization_id);
676 DCHECK_LT(index, deoptimization_states_.size()); 668 DCHECK_LT(index, deoptimization_states_.size());
677 return deoptimization_states_[index]->reason(); 669 return deoptimization_states_[index]->reason();
678 } 670 }
679 671
680 void CodeGenerator::TranslateStateValueDescriptor( 672 void CodeGenerator::TranslateStateValueDescriptor(
681 StateValueDescriptor* desc, Translation* translation, 673 StateValueDescriptor* desc, StateValueList* nested,
682 InstructionOperandIterator* iter) { 674 Translation* translation, InstructionOperandIterator* iter) {
683 if (desc->IsNested()) { 675 if (desc->IsNested()) {
684 translation->BeginCapturedObject(static_cast<int>(desc->size())); 676 translation->BeginCapturedObject(static_cast<int>(nested->size()));
685 for (size_t index = 0; index < desc->fields().size(); index++) { 677 for (auto field : *nested) {
686 TranslateStateValueDescriptor(&desc->fields()[index], translation, iter); 678 TranslateStateValueDescriptor(field.desc, field.nested, translation,
679 iter);
687 } 680 }
688 } else if (desc->IsDuplicate()) { 681 } else if (desc->IsDuplicate()) {
689 translation->DuplicateObject(static_cast<int>(desc->id())); 682 translation->DuplicateObject(static_cast<int>(desc->id()));
690 } else { 683 } else if (desc->IsPlain()) {
691 DCHECK(desc->IsPlain());
692 AddTranslationForOperand(translation, iter->instruction(), iter->Advance(), 684 AddTranslationForOperand(translation, iter->instruction(), iter->Advance(),
693 desc->type()); 685 desc->type());
686 } else {
687 DCHECK(desc->IsOptimizedOut());
688 if (optimized_out_literal_id_ == -1) {
689 optimized_out_literal_id_ =
690 DefineDeoptimizationLiteral(isolate()->factory()->optimized_out());
691 }
692 translation->StoreLiteral(optimized_out_literal_id_);
694 } 693 }
695 } 694 }
696 695
697 696
698 void CodeGenerator::TranslateFrameStateDescriptorOperands( 697 void CodeGenerator::TranslateFrameStateDescriptorOperands(
699 FrameStateDescriptor* desc, InstructionOperandIterator* iter, 698 FrameStateDescriptor* desc, InstructionOperandIterator* iter,
700 OutputFrameStateCombine combine, Translation* translation) { 699 OutputFrameStateCombine combine, Translation* translation) {
701 for (size_t index = 0; index < desc->GetSize(combine); index++) { 700 size_t index = 0;
702 switch (combine.kind()) { 701 StateValueList* values = desc->GetStateValueDescriptors();
703 case OutputFrameStateCombine::kPushOutput: { 702 for (StateValueList::iterator it = values->begin(); it != values->end();
704 DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount()); 703 ++it, ++index) {
705 size_t size_without_output = 704 if (combine.kind() == OutputFrameStateCombine::kPokeAt) {
706 desc->GetSize(OutputFrameStateCombine::Ignore()); 705 // The result of the call should be placed at position
707 // If the index is past the existing stack items in values_. 706 // [index_from_top] in the stack (overwriting whatever was
708 if (index >= size_without_output) { 707 // previously there).
709 // Materialize the result of the call instruction in this slot. 708 size_t index_from_top =
710 AddTranslationForOperand( 709 desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt();
711 translation, iter->instruction(), 710 if (index >= index_from_top &&
712 iter->instruction()->OutputAt(index - size_without_output), 711 index < index_from_top + iter->instruction()->OutputCount()) {
713 MachineType::AnyTagged()); 712 AddTranslationForOperand(
714 continue; 713 translation, iter->instruction(),
715 } 714 iter->instruction()->OutputAt(index - index_from_top),
716 break; 715 MachineType::AnyTagged());
716 iter->Advance(); // We do not use this input, but we need to
717 // advace, as the input got replaced.
718 continue;
717 } 719 }
718 case OutputFrameStateCombine::kPokeAt:
719 // The result of the call should be placed at position
720 // [index_from_top] in the stack (overwriting whatever was
721 // previously there).
722 size_t index_from_top =
723 desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt();
724 if (index >= index_from_top &&
725 index < index_from_top + iter->instruction()->OutputCount()) {
726 AddTranslationForOperand(
727 translation, iter->instruction(),
728 iter->instruction()->OutputAt(index - index_from_top),
729 MachineType::AnyTagged());
730 iter->Advance(); // We do not use this input, but we need to
731 // advace, as the input got replaced.
732 continue;
733 }
734 break;
735 } 720 }
736 StateValueDescriptor* value_desc = desc->GetStateValueDescriptor(); 721 TranslateStateValueDescriptor((*it).desc, (*it).nested, translation, iter);
737 TranslateStateValueDescriptor(&value_desc->fields()[index], translation, 722 }
738 iter); 723 DCHECK_EQ(desc->GetSize(OutputFrameStateCombine::Ignore()), index);
724
725 if (combine.kind() == OutputFrameStateCombine::kPushOutput) {
726 DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount());
727 for (size_t output = 0; output < combine.GetPushCount(); output++) {
728 // Materialize the result of the call instruction in this slot.
729 AddTranslationForOperand(translation, iter->instruction(),
730 iter->instruction()->OutputAt(output),
731 MachineType::AnyTagged());
732 }
739 } 733 }
740 } 734 }
741 735
742 736
743 void CodeGenerator::BuildTranslationForFrameStateDescriptor( 737 void CodeGenerator::BuildTranslationForFrameStateDescriptor(
744 FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, 738 FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
745 Translation* translation, OutputFrameStateCombine state_combine) { 739 Translation* translation, OutputFrameStateCombine state_combine) {
746 // Outer-most state must be added to translation first. 740 // Outer-most state must be added to translation first.
747 if (descriptor->outer_state() != nullptr) { 741 if (descriptor->outer_state() != nullptr) {
748 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter, 742 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter,
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { 967 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) {
974 gen->ools_ = this; 968 gen->ools_ = this;
975 } 969 }
976 970
977 971
978 OutOfLineCode::~OutOfLineCode() {} 972 OutOfLineCode::~OutOfLineCode() {}
979 973
980 } // namespace compiler 974 } // namespace compiler
981 } // namespace internal 975 } // namespace internal
982 } // namespace v8 976 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/code-generator.h ('k') | src/compiler/instruction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698