OLD | NEW |
---|---|
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> |
grt (UTC plus 2)
2017/01/12 11:56:41
is this used?
huangs
2017/01/12 19:54:41
Removed.
| |
8 #include <stddef.h> | 8 #include <stddef.h> |
grt (UTC plus 2)
2017/01/12 11:56:41
std{def,int} are already included in .h
huangs
2017/01/12 19:54:41
Removed.
| |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include <memory> | 11 #include <memory> |
grt (UTC plus 2)
2017/01/12 11:56:41
already included in .h
huangs
2017/01/12 19:54:41
Done.
| |
12 #include <utility> | 12 #include <utility> |
grt (UTC plus 2)
2017/01/12 11:56:41
unused
huangs
2017/01/12 19:54:41
Done.
| |
13 #include <vector> | 13 #include <vector> |
grt (UTC plus 2)
2017/01/12 11:56:41
unused
huangs
2017/01/12 19:54:41
Done.
grt (UTC plus 2)
2017/01/13 08:27:32
This one looks hard to kill! :-)
huangs
2017/01/13 16:44:54
Oh oops! Really removed now.
| |
14 | 14 |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
grt (UTC plus 2)
2017/01/12 11:56:41
already included in .h
huangs
2017/01/12 19:54:41
Done.
| |
17 #include "courgette/courgette.h" | 17 #include "courgette/courgette.h" |
18 #include "courgette/encoded_program.h" | 18 #include "courgette/encoded_program.h" |
19 | 19 |
20 namespace courgette { | 20 namespace courgette { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // Sets the current address for the emitting instructions. | 24 // Sets the current address for the emitting instructions. |
25 class OriginInstruction : public Instruction { | 25 class OriginInstruction : public Instruction { |
26 public: | 26 public: |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 private: | 187 private: |
188 AssemblyProgram* program_; | 188 AssemblyProgram* program_; |
189 | 189 |
190 DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor); | 190 DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor); |
191 }; | 191 }; |
192 | 192 |
193 } // namespace | 193 } // namespace |
194 | 194 |
195 /******** AssemblyProgram ********/ | 195 /******** AssemblyProgram ********/ |
196 | 196 |
197 AssemblyProgram::AssemblyProgram(ExecutableType kind) | 197 AssemblyProgram::AssemblyProgram(ExecutableType kind, uint64_t image_base) |
198 : kind_(kind), image_base_(0) { | 198 : kind_(kind), image_base_(image_base) {} |
199 } | |
200 | 199 |
201 AssemblyProgram::~AssemblyProgram() { | 200 AssemblyProgram::~AssemblyProgram() { |
202 for (size_t i = 0; i < instructions_.size(); ++i) { | 201 for (size_t i = 0; i < instructions_.size(); ++i) { |
203 Instruction* instruction = instructions_[i]; | 202 Instruction* instruction = instructions_[i]; |
204 if (instruction->op() != DEFBYTE) // Owned by byte_instruction_cache_. | 203 if (instruction->op() != DEFBYTE) // Owned by byte_instruction_cache_. |
205 UncheckedDelete(instruction); | 204 UncheckedDelete(instruction); |
206 } | 205 } |
207 if (byte_instruction_cache_.get()) { | 206 if (byte_instruction_cache_.get()) { |
208 for (size_t i = 0; i < 256; ++i) | 207 for (size_t i = 0; i < 256; ++i) |
209 UncheckedDelete(byte_instruction_cache_[i]); | 208 UncheckedDelete(byte_instruction_cache_[i]); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
334 // Ownership successfully passed to instructions_. | 333 // Ownership successfully passed to instructions_. |
335 ignore_result(instruction.release()); | 334 ignore_result(instruction.release()); |
336 return true; | 335 return true; |
337 } | 336 } |
338 | 337 |
339 CheckBool AssemblyProgram::EmitShared(Instruction* instruction) { | 338 CheckBool AssemblyProgram::EmitShared(Instruction* instruction) { |
340 DCHECK(!instruction || instruction->op() == DEFBYTE); | 339 DCHECK(!instruction || instruction->op() == DEFBYTE); |
341 return instruction && instructions_.push_back(instruction); | 340 return instruction && instructions_.push_back(instruction); |
342 } | 341 } |
343 | 342 |
344 void AssemblyProgram::UnassignIndexes(RVAToLabel* labels) { | |
grt (UTC plus 2)
2017/01/12 11:56:41
hooray for code deletion!
huangs
2017/01/12 19:54:41
Acknowledged.
| |
345 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | |
346 Label* current = p->second; | |
347 current->index_ = Label::kNoIndex; | |
348 } | |
349 } | |
350 | |
351 // DefaultAssignIndexes takes a set of labels and assigns indexes in increasing | |
352 // address order. | |
353 void AssemblyProgram::DefaultAssignIndexes(RVAToLabel* labels) { | |
354 int index = 0; | |
355 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | |
356 Label* current = p->second; | |
357 if (current->index_ != Label::kNoIndex) | |
358 NOTREACHED(); | |
359 current->index_ = index; | |
360 ++index; | |
361 } | |
362 } | |
363 | |
364 // AssignRemainingIndexes assigns indexes to any addresses (labels) that are not | |
365 // yet assigned an index. | |
366 void AssemblyProgram::AssignRemainingIndexes(RVAToLabel* labels) { | |
367 // An address table compresses best when each index is associated with an | |
368 // address that is slight larger than the previous index. | |
369 | |
370 // First see which indexes have not been used. The 'available' vector could | |
371 // grow even bigger, but the number of addresses is a better starting size | |
372 // than empty. | |
373 std::vector<bool> available(labels->size(), true); | |
374 int used = 0; | |
375 | |
376 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | |
377 int index = p->second->index_; | |
378 if (index != Label::kNoIndex) { | |
379 while (static_cast<size_t>(index) >= available.size()) | |
380 available.push_back(true); | |
381 available.at(index) = false; | |
382 ++used; | |
383 } | |
384 } | |
385 | |
386 VLOG(1) << used << " of " << labels->size() << " labels pre-assigned"; | |
387 | |
388 // Are there any unused labels that happen to be adjacent following a used | |
389 // label? | |
390 int fill_forward_count = 0; | |
391 Label* prev = 0; | |
392 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | |
393 Label* current = p->second; | |
394 if (current->index_ == Label::kNoIndex) { | |
395 int index = 0; | |
396 if (prev && prev->index_ != Label::kNoIndex) | |
397 index = prev->index_ + 1; | |
398 if (index < static_cast<int>(available.size()) && available.at(index)) { | |
399 current->index_ = index; | |
400 available.at(index) = false; | |
401 ++fill_forward_count; | |
402 } | |
403 } | |
404 prev = current; | |
405 } | |
406 | |
407 // Are there any unused labels that happen to be adjacent preceeding a used | |
408 // label? | |
409 int fill_backward_count = 0; | |
410 prev = 0; | |
411 for (RVAToLabel::reverse_iterator p = labels->rbegin(); | |
412 p != labels->rend(); | |
413 ++p) { | |
414 Label* current = p->second; | |
415 if (current->index_ == Label::kNoIndex) { | |
416 int prev_index; | |
417 if (prev) | |
418 prev_index = prev->index_; | |
419 else | |
420 prev_index = static_cast<uint32_t>(available.size()); | |
421 if (prev_index != 0 && | |
422 prev_index != Label::kNoIndex && | |
423 available.at(prev_index - 1)) { | |
424 current->index_ = prev_index - 1; | |
425 available.at(current->index_) = false; | |
426 ++fill_backward_count; | |
427 } | |
428 } | |
429 prev = current; | |
430 } | |
431 | |
432 // Fill in any remaining indexes | |
433 int fill_infill_count = 0; | |
434 int index = 0; | |
435 for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) { | |
436 Label* current = p->second; | |
437 if (current->index_ == Label::kNoIndex) { | |
438 while (!available.at(index)) { | |
439 ++index; | |
440 } | |
441 current->index_ = index; | |
442 available.at(index) = false; | |
443 ++index; | |
444 ++fill_infill_count; | |
445 } | |
446 } | |
447 | |
448 VLOG(1) << " fill forward " << fill_forward_count | |
449 << " backward " << fill_backward_count | |
450 << " infill " << fill_infill_count; | |
451 } | |
452 | |
453 std::unique_ptr<EncodedProgram> AssemblyProgram::Encode() const { | 343 std::unique_ptr<EncodedProgram> AssemblyProgram::Encode() const { |
454 std::unique_ptr<EncodedProgram> encoded(new EncodedProgram()); | 344 std::unique_ptr<EncodedProgram> encoded(new EncodedProgram()); |
455 | 345 |
456 encoded->set_image_base(image_base_); | 346 encoded->set_image_base(image_base_); |
457 | 347 |
458 if (!encoded->ImportLabels(abs32_label_manager_, rel32_label_manager_)) | 348 if (!encoded->ImportLabels(abs32_label_manager_, rel32_label_manager_)) |
459 return nullptr; | 349 return nullptr; |
460 | 350 |
461 for (size_t i = 0; i < instructions_.size(); ++i) { | 351 for (size_t i = 0; i < instructions_.size(); ++i) { |
462 Instruction* instruction = instructions_[i]; | 352 Instruction* instruction = instructions_[i]; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
563 Status Encode(const AssemblyProgram& program, | 453 Status Encode(const AssemblyProgram& program, |
564 std::unique_ptr<EncodedProgram>* output) { | 454 std::unique_ptr<EncodedProgram>* output) { |
565 // Explicitly release any memory associated with the output before encoding. | 455 // Explicitly release any memory associated with the output before encoding. |
566 output->reset(); | 456 output->reset(); |
567 | 457 |
568 *output = program.Encode(); | 458 *output = program.Encode(); |
569 return (*output) ? C_OK : C_GENERAL_ERROR; | 459 return (*output) ? C_OK : C_GENERAL_ERROR; |
570 } | 460 } |
571 | 461 |
572 } // namespace courgette | 462 } // namespace courgette |
OLD | NEW |