Chromium Code Reviews| 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 |