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

Side by Side Diff: courgette/assembly_program.cc

Issue 2583373002: [Courgette] Simple AssemblyProgram and Disassembler cleanups. (Closed)
Patch Set: Sync. Created 3 years, 11 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
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>
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698