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

Side by Side Diff: courgette/assembly_program.cc

Issue 2462993003: [Courgette] Refactor: Add and use Instruction*Receptor classes; call ParseFile() in 2 passes. (Closed)
Patch Set: Fix style and comments; lint; remove size param from InstructionStoreReceptor ctor. Created 4 years, 1 month 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
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/assembly_program.h" 5 #include "courgette/assembly_program.h"
6 6
7 #include <memory.h> 7 #include <memory.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 uint16_t op_size() const { return op_size_; } 100 uint16_t op_size() const { return op_size_; }
101 101
102 private: 102 private:
103 uint16_t compressed_op_; 103 uint16_t compressed_op_;
104 const uint8_t* arm_op_; 104 const uint8_t* arm_op_;
105 uint16_t op_size_; 105 uint16_t op_size_;
106 }; 106 };
107 107
108 } // namespace 108 } // namespace
109 109
110 /******** InstructionCountReceptor ********/
111
112 // TODO(huangs): 2016/11: Populate these with size_ += ...
113 CheckBool InstructionCountReceptor::EmitPeRelocs() {
114 return true;
115 }
116
117 CheckBool InstructionCountReceptor::EmitElfRelocation() {
118 return true;
119 }
120
121 CheckBool InstructionCountReceptor::EmitElfARMRelocation() {
122 return true;
123 }
124
125 CheckBool InstructionCountReceptor::EmitOrigin(RVA rva) {
126 return true;
127 }
128
129 CheckBool InstructionCountReceptor::EmitSingleByte(uint8_t byte) {
130 return true;
131 }
132
133 CheckBool InstructionCountReceptor::EmitMultipleBytes(const uint8_t* bytes,
134 size_t len) {
135 return true;
136 }
137
138 CheckBool InstructionCountReceptor::EmitRel32(Label* label) {
139 return true;
140 }
141
142 CheckBool InstructionCountReceptor::EmitRel32ARM(uint16_t op,
143 Label* label,
144 const uint8_t* arm_op,
145 uint16_t op_size) {
146 return true;
147 }
148
149 CheckBool InstructionCountReceptor::EmitAbs32(Label* label) {
150 return true;
151 }
152
153 CheckBool InstructionCountReceptor::EmitAbs64(Label* label) {
154 return true;
155 }
156
157 /******** InstructionStoreReceptor ********/
158
159 // TODO(huangs): 2016/11: Populate these.
160 InstructionStoreReceptor::InstructionStoreReceptor(AssemblyProgram* program)
161 : program_(program) {
162 CHECK(program_);
163 }
164
165 CheckBool InstructionStoreReceptor::EmitPeRelocs() {
166 return program_->EmitPeRelocs();
167 }
168
169 CheckBool InstructionStoreReceptor::EmitElfRelocation() {
170 return program_->EmitElfRelocation();
171 }
172
173 CheckBool InstructionStoreReceptor::EmitElfARMRelocation() {
174 return program_->EmitElfARMRelocation();
175 }
176
177 CheckBool InstructionStoreReceptor::EmitOrigin(RVA rva) {
178 return program_->EmitOrigin(rva);
179 }
180
181 CheckBool InstructionStoreReceptor::EmitSingleByte(uint8_t byte) {
182 return program_->EmitSingleByte(byte);
183 }
184
185 CheckBool InstructionStoreReceptor::EmitMultipleBytes(const uint8_t* bytes,
186 size_t len) {
187 return program_->EmitMultipleBytes(bytes, len);
188 }
189
190 CheckBool InstructionStoreReceptor::EmitRel32(Label* label) {
191 return program_->EmitRel32(label);
192 }
193
194 CheckBool InstructionStoreReceptor::EmitRel32ARM(uint16_t op,
195 Label* label,
196 const uint8_t* arm_op,
197 uint16_t op_size) {
198 return program_->EmitRel32ARM(op, label, arm_op, op_size);
199 }
200
201 CheckBool InstructionStoreReceptor::EmitAbs32(Label* label) {
202 return program_->EmitAbs32(label);
203 }
204
205 CheckBool InstructionStoreReceptor::EmitAbs64(Label* label) {
206 return program_->EmitAbs64(label);
207 }
208
209 /******** AssemblyProgram ********/
210
110 AssemblyProgram::AssemblyProgram(ExecutableType kind) 211 AssemblyProgram::AssemblyProgram(ExecutableType kind)
111 : kind_(kind), image_base_(0) { 212 : kind_(kind), image_base_(0) {
112 } 213 }
113 214
114 AssemblyProgram::~AssemblyProgram() { 215 AssemblyProgram::~AssemblyProgram() {
115 for (size_t i = 0; i < instructions_.size(); ++i) { 216 for (size_t i = 0; i < instructions_.size(); ++i) {
116 Instruction* instruction = instructions_[i]; 217 Instruction* instruction = instructions_[i];
117 if (instruction->op() != DEFBYTE) // Owned by byte_instruction_cache_. 218 if (instruction->op() != DEFBYTE) // Owned by byte_instruction_cache_.
118 UncheckedDelete(instruction); 219 UncheckedDelete(instruction);
119 } 220 }
120 if (byte_instruction_cache_.get()) { 221 if (byte_instruction_cache_.get()) {
121 for (size_t i = 0; i < 256; ++i) 222 for (size_t i = 0; i < 256; ++i)
122 UncheckedDelete(byte_instruction_cache_[i]); 223 UncheckedDelete(byte_instruction_cache_[i]);
123 } 224 }
124 } 225 }
125 226
126 CheckBool AssemblyProgram::EmitPeRelocsInstruction() { 227 CheckBool AssemblyProgram::EmitPeRelocs() {
127 return Emit(ScopedInstruction(UncheckedNew<PeRelocsInstruction>())); 228 return Emit(ScopedInstruction(UncheckedNew<PeRelocsInstruction>()));
128 } 229 }
129 230
130 CheckBool AssemblyProgram::EmitElfRelocationInstruction() { 231 CheckBool AssemblyProgram::EmitElfRelocation() {
131 return Emit(ScopedInstruction(UncheckedNew<ElfRelocsInstruction>())); 232 return Emit(ScopedInstruction(UncheckedNew<ElfRelocsInstruction>()));
132 } 233 }
133 234
134 CheckBool AssemblyProgram::EmitElfARMRelocationInstruction() { 235 CheckBool AssemblyProgram::EmitElfARMRelocation() {
135 return Emit(ScopedInstruction(UncheckedNew<ElfARMRelocsInstruction>())); 236 return Emit(ScopedInstruction(UncheckedNew<ElfARMRelocsInstruction>()));
136 } 237 }
137 238
138 CheckBool AssemblyProgram::EmitOriginInstruction(RVA rva) { 239 CheckBool AssemblyProgram::EmitOrigin(RVA rva) {
139 return Emit(ScopedInstruction(UncheckedNew<OriginInstruction>(rva))); 240 return Emit(ScopedInstruction(UncheckedNew<OriginInstruction>(rva)));
140 } 241 }
141 242
142 CheckBool AssemblyProgram::EmitByteInstruction(uint8_t byte) { 243 CheckBool AssemblyProgram::EmitSingleByte(uint8_t byte) {
143 return EmitShared(GetByteInstruction(byte)); 244 return EmitShared(GetByteInstruction(byte));
144 } 245 }
145 246
146 CheckBool AssemblyProgram::EmitBytesInstruction(const uint8_t* values, 247 CheckBool AssemblyProgram::EmitMultipleBytes(const uint8_t* bytes, size_t len) {
147 size_t len) { 248 return Emit(ScopedInstruction(UncheckedNew<BytesInstruction>(bytes, len)));
148 return Emit(ScopedInstruction(UncheckedNew<BytesInstruction>(values, len)));
149 } 249 }
150 250
151 CheckBool AssemblyProgram::EmitRel32(Label* label) { 251 CheckBool AssemblyProgram::EmitRel32(Label* label) {
152 return Emit( 252 return Emit(
153 ScopedInstruction(UncheckedNew<InstructionWithLabel>(REL32, label))); 253 ScopedInstruction(UncheckedNew<InstructionWithLabel>(REL32, label)));
154 } 254 }
155 255
156 CheckBool AssemblyProgram::EmitRel32ARM(uint16_t op, 256 CheckBool AssemblyProgram::EmitRel32ARM(uint16_t op,
157 Label* label, 257 Label* label,
158 const uint8_t* arm_op, 258 const uint8_t* arm_op,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 const AssemblyProgram::LabelHandlerMap& handler_map) const { 321 const AssemblyProgram::LabelHandlerMap& handler_map) const {
222 for (const Instruction* instruction : instructions_) { 322 for (const Instruction* instruction : instructions_) {
223 LabelHandlerMap::const_iterator it = handler_map.find(instruction->op()); 323 LabelHandlerMap::const_iterator it = handler_map.find(instruction->op());
224 if (it != handler_map.end()) { 324 if (it != handler_map.end()) {
225 it->second.Run( 325 it->second.Run(
226 static_cast<const InstructionWithLabel*>(instruction)->label()); 326 static_cast<const InstructionWithLabel*>(instruction)->label());
227 } 327 }
228 } 328 }
229 } 329 }
230 330
331 CheckBool AssemblyProgram::CreateInstructionCountReceptor(
332 InstructionCountReceptor** ret) {
333 DCHECK(ret);
334 DCHECK(!count_receptor_);
335 count_receptor_.reset(new InstructionCountReceptor);
336 *ret = count_receptor_.get();
337 return true;
338 }
339
340 CheckBool AssemblyProgram::CreateInstructionStoreReceptor(
341 InstructionStoreReceptor** ret) {
342 DCHECK(ret);
343 DCHECK(count_receptor_);
344 DCHECK(!store_receptor_);
345 store_receptor_.reset(new InstructionStoreReceptor(this));
346 // TODO(huangs): 2016/11: Pass |count_receptor_->size()| to |store_receptor_|
347 // to reserve space for raw data.
348 *ret = store_receptor_.get();
349 return true;
350 }
351
231 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) { 352 CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) {
232 if (!instruction || !instructions_.push_back(instruction.get())) 353 if (!instruction || !instructions_.push_back(instruction.get()))
233 return false; 354 return false;
234 // Ownership successfully passed to instructions_. 355 // Ownership successfully passed to instructions_.
235 ignore_result(instruction.release()); 356 ignore_result(instruction.release());
236 return true; 357 return true;
237 } 358 }
238 359
239 CheckBool AssemblyProgram::EmitShared(Instruction* instruction) { 360 CheckBool AssemblyProgram::EmitShared(Instruction* instruction) {
240 DCHECK(!instruction || instruction->op() == DEFBYTE); 361 DCHECK(!instruction || instruction->op() == DEFBYTE);
241 return instruction && instructions_.push_back(instruction); 362 return instruction && instructions_.push_back(instruction);
242 } 363 }
243 364
244 void AssemblyProgram::UnassignIndexes(RVAToLabel* labels) { 365 void AssemblyProgram::UnassignIndexes(RVAToLabel* labels) {
245 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { 366 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) {
246 Label* current = p->second; 367 Label* current = p->second;
247 current->index_ = Label::kNoIndex; 368 current->index_ = Label::kNoIndex;
248 } 369 }
249 } 370 }
250 371
251 // DefaultAssignIndexes takes a set of labels and assigns indexes in increasing 372 // DefaultAssignIndexes takes a set of labels and assigns indexes in increasing
252 // address order. 373 // address order.
253 //
254 void AssemblyProgram::DefaultAssignIndexes(RVAToLabel* labels) { 374 void AssemblyProgram::DefaultAssignIndexes(RVAToLabel* labels) {
255 int index = 0; 375 int index = 0;
256 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { 376 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) {
257 Label* current = p->second; 377 Label* current = p->second;
258 if (current->index_ != Label::kNoIndex) 378 if (current->index_ != Label::kNoIndex)
259 NOTREACHED(); 379 NOTREACHED();
260 current->index_ = index; 380 current->index_ = index;
261 ++index; 381 ++index;
262 } 382 }
263 } 383 }
264 384
265 // AssignRemainingIndexes assigns indexes to any addresses (labels) that are not 385 // AssignRemainingIndexes assigns indexes to any addresses (labels) that are not
266 // yet assigned an index. 386 // yet assigned an index.
267 //
268 void AssemblyProgram::AssignRemainingIndexes(RVAToLabel* labels) { 387 void AssemblyProgram::AssignRemainingIndexes(RVAToLabel* labels) {
269 // An address table compresses best when each index is associated with an 388 // An address table compresses best when each index is associated with an
270 // address that is slight larger than the previous index. 389 // address that is slight larger than the previous index.
271 390
272 // First see which indexes have not been used. The 'available' vector could 391 // First see which indexes have not been used. The 'available' vector could
273 // grow even bigger, but the number of addresses is a better starting size 392 // grow even bigger, but the number of addresses is a better starting size
274 // than empty. 393 // than empty.
275 std::vector<bool> available(labels->size(), true); 394 std::vector<bool> available(labels->size(), true);
276 int used = 0; 395 int used = 0;
277 396
278 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { 397 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) {
279 int index = p->second->index_; 398 int index = p->second->index_;
280 if (index != Label::kNoIndex) { 399 if (index != Label::kNoIndex) {
281 while (static_cast<size_t>(index) >= available.size()) 400 while (static_cast<size_t>(index) >= available.size())
282 available.push_back(true); 401 available.push_back(true);
283 available.at(index) = false; 402 available.at(index) = false;
284 ++used; 403 ++used;
285 } 404 }
286 } 405 }
287 406
288 VLOG(1) << used << " of " << labels->size() << " labels pre-assigned"; 407 VLOG(1) << used << " of " << labels->size() << " labels pre-assigned";
289 408
290 // Are there any unused labels that happen to be adjacent following a used 409 // Are there any unused labels that happen to be adjacent following a used
291 // label? 410 // label?
292 //
293 int fill_forward_count = 0; 411 int fill_forward_count = 0;
294 Label* prev = 0; 412 Label* prev = 0;
295 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { 413 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) {
296 Label* current = p->second; 414 Label* current = p->second;
297 if (current->index_ == Label::kNoIndex) { 415 if (current->index_ == Label::kNoIndex) {
298 int index = 0; 416 int index = 0;
299 if (prev && prev->index_ != Label::kNoIndex) 417 if (prev && prev->index_ != Label::kNoIndex)
300 index = prev->index_ + 1; 418 index = prev->index_ + 1;
301 if (index < static_cast<int>(available.size()) && available.at(index)) { 419 if (index < static_cast<int>(available.size()) && available.at(index)) {
302 current->index_ = index; 420 current->index_ = index;
303 available.at(index) = false; 421 available.at(index) = false;
304 ++fill_forward_count; 422 ++fill_forward_count;
305 } 423 }
306 } 424 }
307 prev = current; 425 prev = current;
308 } 426 }
309 427
310 // Are there any unused labels that happen to be adjacent preceeding a used 428 // Are there any unused labels that happen to be adjacent preceeding a used
311 // label? 429 // label?
312 //
313 int fill_backward_count = 0; 430 int fill_backward_count = 0;
314 prev = 0; 431 prev = 0;
315 for (RVAToLabel::reverse_iterator p = labels->rbegin(); 432 for (RVAToLabel::reverse_iterator p = labels->rbegin();
316 p != labels->rend(); 433 p != labels->rend();
317 ++p) { 434 ++p) {
318 Label* current = p->second; 435 Label* current = p->second;
319 if (current->index_ == Label::kNoIndex) { 436 if (current->index_ == Label::kNoIndex) {
320 int prev_index; 437 int prev_index;
321 if (prev) 438 if (prev)
322 prev_index = prev->index_; 439 prev_index = prev->index_;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 Status Encode(const AssemblyProgram& program, 584 Status Encode(const AssemblyProgram& program,
468 std::unique_ptr<EncodedProgram>* output) { 585 std::unique_ptr<EncodedProgram>* output) {
469 // Explicitly release any memory associated with the output before encoding. 586 // Explicitly release any memory associated with the output before encoding.
470 output->reset(); 587 output->reset();
471 588
472 *output = program.Encode(); 589 *output = program.Encode();
473 return (*output) ? C_OK : C_GENERAL_ERROR; 590 return (*output) ? C_OK : C_GENERAL_ERROR;
474 } 591 }
475 592
476 } // namespace courgette 593 } // namespace courgette
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698