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

Side by Side Diff: courgette/encoded_program.cc

Issue 1935203002: [Courgette] Using LabelManager to reduce Courgette-apply peak RAM by 25%. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sync. Created 4 years, 7 months 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 | « courgette/encoded_program.h ('k') | courgette/encoded_program_unittest.cc » ('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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium 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 "courgette/encoded_program.h" 5 #include "courgette/encoded_program.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 } // namespace 130 } // namespace
131 131
132 //////////////////////////////////////////////////////////////////////////////// 132 ////////////////////////////////////////////////////////////////////////////////
133 133
134 // Constructor is here rather than in the header. Although the constructor 134 // Constructor is here rather than in the header. Although the constructor
135 // appears to do nothing it is fact quite large because of the implicit calls to 135 // appears to do nothing it is fact quite large because of the implicit calls to
136 // field constructors. Ditto for the destructor. 136 // field constructors. Ditto for the destructor.
137 EncodedProgram::EncodedProgram() {} 137 EncodedProgram::EncodedProgram() {}
138 EncodedProgram::~EncodedProgram() {} 138 EncodedProgram::~EncodedProgram() {}
139 139
140 CheckBool EncodedProgram::DefineLabels(const RVAToLabel& abs32_labels, 140 CheckBool EncodedProgram::ImportLabels(
141 const RVAToLabel& rel32_labels) { 141 const LabelManager& abs32_label_manager,
142 // which == 0 => abs32; which == 1 => rel32. 142 const LabelManager& rel32_label_manager) {
143 for (int which = 0; which < 2; ++which) { 143 if (!WriteRvasToList(abs32_label_manager, &abs32_rva_) ||
144 const RVAToLabel& labels = which == 0 ? abs32_labels : rel32_labels; 144 !WriteRvasToList(rel32_label_manager, &rel32_rva_)) {
145 RvaVector& rvas = which == 0 ? abs32_rva_ : rel32_rva_; 145 return false;
146
147 if (!rvas.resize(LabelManager::GetIndexBound(labels), kUnassignedRVA))
148 return false;
149
150 // For each Label, write its RVA to assigned index.
151 for (const auto& rva_and_label : labels) {
152 const Label& label = *rva_and_label.second;
153 DCHECK_EQ(rva_and_label.first, label.rva_);
154 DCHECK_NE(label.index_, Label::kNoIndex);
155 DCHECK_EQ(rvas[label.index_], kUnassignedRVA)
156 << "DefineLabels() double assigned " << label.index_;
157 rvas[label.index_] = label.rva_;
158 }
159
160 // Replace all unassigned slots with the value at the previous index so they
161 // delta-encode to zero. (There might be better values than zero. The way to
162 // get that is have the higher level assembly program assign the unassigned
163 // slots.)
164 RVA previous = 0;
165 for (RVA& rva : rvas) {
166 if (rva == kUnassignedRVA)
167 rva = previous;
168 else
169 previous = rva;
170 }
171 } 146 }
147 FillUnassignedRvaSlots(&abs32_rva_);
148 FillUnassignedRvaSlots(&rel32_rva_);
172 return true; 149 return true;
173 } 150 }
174 151
175 CheckBool EncodedProgram::AddOrigin(RVA origin) { 152 CheckBool EncodedProgram::AddOrigin(RVA origin) {
176 return ops_.push_back(ORIGIN) && origins_.push_back(origin); 153 return ops_.push_back(ORIGIN) && origins_.push_back(origin);
177 } 154 }
178 155
179 CheckBool EncodedProgram::AddCopy(size_t count, const void* bytes) { 156 CheckBool EncodedProgram::AddCopy(size_t count, const void* bytes) {
180 const uint8_t* source = static_cast<const uint8_t*>(bytes); 157 const uint8_t* source = static_cast<const uint8_t*>(bytes);
181 158
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 Add(0); 703 Add(0);
727 } 704 }
728 ok = buffer->Write(&pod, pod.block_size); 705 ok = buffer->Write(&pod, pod.block_size);
729 pod.block_size = 8; 706 pod.block_size = 8;
730 } 707 }
731 return ok; 708 return ok;
732 } 709 }
733 RelocBlockPOD pod; 710 RelocBlockPOD pod;
734 }; 711 };
735 712
713 // static
714 // Updates |rvas| so |rvas[label.index_] == label.rva_| for each |label| in
715 // |label_manager|, assuming |label.index_| is properly assigned. Takes care of
716 // |rvas| resizing. Unused slots in |rvas| are assigned |kUnassignedRVA|.
717 // Returns true on success, and false otherwise.
718 CheckBool EncodedProgram::WriteRvasToList(const LabelManager& label_manager,
719 RvaVector* rvas) {
720 rvas->clear();
721 int index_bound = LabelManager::GetLabelIndexBound(label_manager.Labels());
722 if (!rvas->resize(index_bound, kUnassignedRVA))
723 return false;
724
725 // For each Label, write its RVA to assigned index.
726 for (const Label& label : label_manager.Labels()) {
727 DCHECK_NE(label.index_, Label::kNoIndex);
728 DCHECK_EQ((*rvas)[label.index_], kUnassignedRVA)
729 << "ExportToList() double assigned " << label.index_;
730 (*rvas)[label.index_] = label.rva_;
731 }
732 return true;
733 }
734
735 // static
736 // Replaces all unassigned slots in |rvas| with the value at the previous index
737 // so they delta-encode to zero. (There might be better values than zero. The
738 // way to get that is have the higher level assembly program assign the
739 // unassigned slots.)
740 void EncodedProgram::FillUnassignedRvaSlots(RvaVector* rvas) {
741 RVA previous = 0;
742 for (RVA& rva : *rvas) {
743 if (rva == kUnassignedRVA)
744 rva = previous;
745 else
746 previous = rva;
747 }
748 }
749
736 CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer, 750 CheckBool EncodedProgram::GeneratePeRelocations(SinkStream* buffer,
737 uint8_t type) { 751 uint8_t type) {
738 std::sort(abs32_relocs_.begin(), abs32_relocs_.end()); 752 std::sort(abs32_relocs_.begin(), abs32_relocs_.end());
739 DCHECK(abs32_relocs_.empty() || abs32_relocs_.back() != kUnassignedRVA); 753 DCHECK(abs32_relocs_.empty() || abs32_relocs_.back() != kUnassignedRVA);
740 754
741 RelocBlock block; 755 RelocBlock block;
742 756
743 bool ok = true; 757 bool ok = true;
744 for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) { 758 for (size_t i = 0; ok && i < abs32_relocs_.size(); ++i) {
745 uint32_t rva = abs32_relocs_[i]; 759 uint32_t rva = abs32_relocs_[i];
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 } 806 }
793 807
794 Status Assemble(EncodedProgram* encoded, SinkStream* buffer) { 808 Status Assemble(EncodedProgram* encoded, SinkStream* buffer) {
795 bool assembled = encoded->AssembleTo(buffer); 809 bool assembled = encoded->AssembleTo(buffer);
796 if (assembled) 810 if (assembled)
797 return C_OK; 811 return C_OK;
798 return C_ASSEMBLY_FAILED; 812 return C_ASSEMBLY_FAILED;
799 } 813 }
800 814
801 } // namespace courgette 815 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/encoded_program.h ('k') | courgette/encoded_program_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698