| 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/adjustment_method.h" | 5 #include "courgette/adjustment_method.h" | 
| 6 | 6 | 
|  | 7 #include <stddef.h> | 
|  | 8 #include <stdint.h> | 
|  | 9 | 
| 7 #include <algorithm> | 10 #include <algorithm> | 
| 8 #include <limits> | 11 #include <limits> | 
| 9 #include <list> | 12 #include <list> | 
| 10 #include <map> | 13 #include <map> | 
| 11 #include <set> | 14 #include <set> | 
| 12 #include <string> | 15 #include <string> | 
| 13 #include <vector> | 16 #include <vector> | 
| 14 | 17 | 
| 15 #include "base/basictypes.h" |  | 
| 16 #include "base/format_macros.h" | 18 #include "base/format_macros.h" | 
| 17 #include "base/logging.h" | 19 #include "base/logging.h" | 
|  | 20 #include "base/macros.h" | 
| 18 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" | 
| 19 #include "base/time/time.h" | 22 #include "base/time/time.h" | 
| 20 #include "courgette/assembly_program.h" | 23 #include "courgette/assembly_program.h" | 
| 21 #include "courgette/courgette.h" | 24 #include "courgette/courgette.h" | 
| 22 #include "courgette/encoded_program.h" | 25 #include "courgette/encoded_program.h" | 
| 23 | 26 | 
| 24 /* | 27 /* | 
| 25 | 28 | 
| 26 Shingle weighting matching. | 29 Shingle weighting matching. | 
| 27 | 30 | 
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 169       : label_(NULL), is_model_(false), debug_index_(0), refs_(0), | 172       : label_(NULL), is_model_(false), debug_index_(0), refs_(0), | 
| 170         assignment_(NULL), candidates_(NULL) | 173         assignment_(NULL), candidates_(NULL) | 
| 171   {} | 174   {} | 
| 172 | 175 | 
| 173   ~LabelInfo(); | 176   ~LabelInfo(); | 
| 174 | 177 | 
| 175   AssignmentCandidates* candidates(); | 178   AssignmentCandidates* candidates(); | 
| 176 | 179 | 
| 177   Label* label_;             // The label that this info a surrogate for. | 180   Label* label_;             // The label that this info a surrogate for. | 
| 178 | 181 | 
| 179   uint32 is_model_ : 1;      // Is the label in the model? | 182   uint32_t is_model_ : 1;      // Is the label in the model? | 
| 180   uint32 debug_index_ : 31;  // A small number for naming the label in debug | 183   uint32_t debug_index_ : 31;  // A small number for naming the label in debug | 
| 181                              // output. The pair (is_model_, debug_index_) is | 184                                // output. The pair (is_model_, debug_index_) is | 
| 182                              // unique. | 185                                // unique. | 
| 183 | 186 | 
| 184   int refs_;                 // Number of times this Label is referenced. | 187   int refs_;                 // Number of times this Label is referenced. | 
| 185 | 188 | 
| 186   LabelInfo* assignment_;    // Label from other program corresponding to this. | 189   LabelInfo* assignment_;    // Label from other program corresponding to this. | 
| 187 | 190 | 
| 188   std::vector<uint32> positions_;  // Offsets into the trace of references. | 191   std::vector<uint32_t> positions_;  // Offsets into the trace of references. | 
| 189 | 192 | 
| 190  private: | 193  private: | 
| 191   AssignmentCandidates* candidates_; | 194   AssignmentCandidates* candidates_; | 
| 192 | 195 | 
| 193   void operator=(const LabelInfo*);  // Disallow assignment only. | 196   void operator=(const LabelInfo*);  // Disallow assignment only. | 
| 194   // Public compiler generated copy constructor is needed to constuct | 197   // Public compiler generated copy constructor is needed to constuct | 
| 195   // std::pair<Label*, LabelInfo> so that fresh LabelInfos can be allocated | 198   // std::pair<Label*, LabelInfo> so that fresh LabelInfos can be allocated | 
| 196   // inside a std::map. | 199   // inside a std::map. | 
| 197 }; | 200 }; | 
| 198 | 201 | 
| 199 typedef std::vector<LabelInfo*> Trace; | 202 typedef std::vector<LabelInfo*> Trace; | 
| 200 | 203 | 
| 201 std::string ToString(const LabelInfo* info) { | 204 std::string ToString(const LabelInfo* info) { | 
| 202   std::string s; | 205   std::string s; | 
| 203   base::StringAppendF(&s, "%c%d", "pm"[info->is_model_], info->debug_index_); | 206   base::StringAppendF(&s, "%c%d", "pm"[info->is_model_], info->debug_index_); | 
| 204   if (info->label_->index_ != Label::kNoIndex) | 207   if (info->label_->index_ != Label::kNoIndex) | 
| 205     base::StringAppendF(&s, " (%d)", info->label_->index_); | 208     base::StringAppendF(&s, " (%d)", info->label_->index_); | 
| 206 | 209 | 
| 207   base::StringAppendF(&s, " #%u", info->refs_); | 210   base::StringAppendF(&s, " #%u", info->refs_); | 
| 208   return s; | 211   return s; | 
| 209 } | 212 } | 
| 210 | 213 | 
| 211 // LabelInfoMaker maps labels to their surrogate LabelInfo objects. | 214 // LabelInfoMaker maps labels to their surrogate LabelInfo objects. | 
| 212 class LabelInfoMaker { | 215 class LabelInfoMaker { | 
| 213  public: | 216  public: | 
| 214   LabelInfoMaker() : debug_label_index_gen_(0) {} | 217   LabelInfoMaker() : debug_label_index_gen_(0) {} | 
| 215 | 218 | 
| 216   LabelInfo* MakeLabelInfo(Label* label, bool is_model, uint32 position) { | 219   LabelInfo* MakeLabelInfo(Label* label, bool is_model, uint32_t position) { | 
| 217     LabelInfo& slot = label_infos_[label]; | 220     LabelInfo& slot = label_infos_[label]; | 
| 218     if (slot.label_ == NULL) { | 221     if (slot.label_ == NULL) { | 
| 219       slot.label_ = label; | 222       slot.label_ = label; | 
| 220       slot.is_model_ = is_model; | 223       slot.is_model_ = is_model; | 
| 221       slot.debug_index_ = ++debug_label_index_gen_; | 224       slot.debug_index_ = ++debug_label_index_gen_; | 
| 222     } | 225     } | 
| 223     slot.positions_.push_back(position); | 226     slot.positions_.push_back(position); | 
| 224     ++slot.refs_; | 227     ++slot.refs_; | 
| 225     return &slot; | 228     return &slot; | 
| 226   } | 229   } | 
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 357 | 360 | 
| 358 LabelInfo::~LabelInfo() { | 361 LabelInfo::~LabelInfo() { | 
| 359   delete candidates_; | 362   delete candidates_; | 
| 360 } | 363 } | 
| 361 | 364 | 
| 362 // A Shingle is a short fixed-length string of LabelInfos that actually occurs | 365 // A Shingle is a short fixed-length string of LabelInfos that actually occurs | 
| 363 // in a Trace.  A Shingle may occur many times.  We repesent the Shingle by the | 366 // in a Trace.  A Shingle may occur many times.  We repesent the Shingle by the | 
| 364 // position of one of the occurrences in the Trace. | 367 // position of one of the occurrences in the Trace. | 
| 365 class Shingle { | 368 class Shingle { | 
| 366  public: | 369  public: | 
| 367   static const uint8 kWidth = 5; | 370   static const uint8_t kWidth = 5; | 
| 368 | 371 | 
| 369   struct InterningLess { | 372   struct InterningLess { | 
| 370     bool operator()(const Shingle& a, const Shingle& b) const; | 373     bool operator()(const Shingle& a, const Shingle& b) const; | 
| 371   }; | 374   }; | 
| 372 | 375 | 
| 373   typedef std::set<Shingle, InterningLess> OwningSet; | 376   typedef std::set<Shingle, InterningLess> OwningSet; | 
| 374 | 377 | 
| 375   static Shingle* Find(const Trace& trace, size_t position, | 378   static Shingle* Find(const Trace& trace, size_t position, | 
| 376                        OwningSet* owning_set) { | 379                        OwningSet* owning_set) { | 
| 377     std::pair<OwningSet::iterator, bool> pair = | 380     std::pair<OwningSet::iterator, bool> pair = | 
| 378         owning_set->insert(Shingle(trace, position)); | 381         owning_set->insert(Shingle(trace, position)); | 
| 379     // pair.first iterator 'points' to the newly inserted Shingle or the | 382     // pair.first iterator 'points' to the newly inserted Shingle or the | 
| 380     // previouly inserted one that looks the same according to the comparator. | 383     // previouly inserted one that looks the same according to the comparator. | 
| 381 | 384 | 
| 382     // const_cast required because key is const.  We modify the Shingle | 385     // const_cast required because key is const.  We modify the Shingle | 
| 383     // extensively but not in a way that affects InterningLess. | 386     // extensively but not in a way that affects InterningLess. | 
| 384     Shingle* shingle = const_cast<Shingle*>(&*pair.first); | 387     Shingle* shingle = const_cast<Shingle*>(&*pair.first); | 
| 385     shingle->add_position(position); | 388     shingle->add_position(position); | 
| 386     return shingle; | 389     return shingle; | 
| 387   } | 390   } | 
| 388 | 391 | 
| 389   LabelInfo* at(size_t i) const { return trace_[exemplar_position_ + i]; } | 392   LabelInfo* at(size_t i) const { return trace_[exemplar_position_ + i]; } | 
| 390   void add_position(size_t position) { | 393   void add_position(size_t position) { | 
| 391     positions_.push_back(static_cast<uint32>(position)); | 394     positions_.push_back(static_cast<uint32_t>(position)); | 
| 392   } | 395   } | 
| 393   int position_count() const { return static_cast<int>(positions_.size()); } | 396   int position_count() const { return static_cast<int>(positions_.size()); } | 
| 394 | 397 | 
| 395   bool InModel() const { return at(0)->is_model_; } | 398   bool InModel() const { return at(0)->is_model_; } | 
| 396 | 399 | 
| 397   ShinglePattern* pattern() const { return pattern_; } | 400   ShinglePattern* pattern() const { return pattern_; } | 
| 398   void set_pattern(ShinglePattern* pattern) { pattern_ = pattern; } | 401   void set_pattern(ShinglePattern* pattern) { pattern_ = pattern; } | 
| 399 | 402 | 
| 400   struct PointerLess { | 403   struct PointerLess { | 
| 401     bool operator()(const Shingle* a, const Shingle* b) const { | 404     bool operator()(const Shingle* a, const Shingle* b) const { | 
| 402       // Arbitrary but repeatable (memory-address) independent ordering: | 405       // Arbitrary but repeatable (memory-address) independent ordering: | 
| 403       return a->exemplar_position_ < b->exemplar_position_; | 406       return a->exemplar_position_ < b->exemplar_position_; | 
| 404       // return InterningLess()(*a, *b); | 407       // return InterningLess()(*a, *b); | 
| 405     } | 408     } | 
| 406   }; | 409   }; | 
| 407 | 410 | 
| 408  private: | 411  private: | 
| 409   Shingle(const Trace& trace, size_t exemplar_position) | 412   Shingle(const Trace& trace, size_t exemplar_position) | 
| 410       : trace_(trace), | 413       : trace_(trace), | 
| 411         exemplar_position_(exemplar_position), | 414         exemplar_position_(exemplar_position), | 
| 412         pattern_(NULL) { | 415         pattern_(NULL) { | 
| 413   } | 416   } | 
| 414 | 417 | 
| 415   const Trace& trace_;             // The shingle lives inside trace_. | 418   const Trace& trace_;             // The shingle lives inside trace_. | 
| 416   size_t exemplar_position_;       // At this position (and other positions). | 419   size_t exemplar_position_;       // At this position (and other positions). | 
| 417   std::vector<uint32> positions_;  // Includes exemplar_position_. | 420   std::vector<uint32_t> positions_;  // Includes exemplar_position_. | 
| 418 | 421 | 
| 419   ShinglePattern* pattern_;       // Pattern changes as LabelInfos are assigned. | 422   ShinglePattern* pattern_;       // Pattern changes as LabelInfos are assigned. | 
| 420 | 423 | 
| 421   friend std::string ToString(const Shingle* instance); | 424   friend std::string ToString(const Shingle* instance); | 
| 422 | 425 | 
| 423   // We can't disallow the copy constructor because we use std::set<Shingle> and | 426   // We can't disallow the copy constructor because we use std::set<Shingle> and | 
| 424   // VS2005's implementation of std::set<T>::set() requires T to have a copy | 427   // VS2005's implementation of std::set<T>::set() requires T to have a copy | 
| 425   // constructor. | 428   // constructor. | 
| 426   //   DISALLOW_COPY_AND_ASSIGN(Shingle); | 429   //   DISALLOW_COPY_AND_ASSIGN(Shingle); | 
| 427   void operator=(const Shingle&);  // Disallow assignment only. | 430   void operator=(const Shingle&);  // Disallow assignment only. | 
| 428 }; | 431 }; | 
| 429 | 432 | 
| 430 std::string ToString(const Shingle* instance) { | 433 std::string ToString(const Shingle* instance) { | 
| 431   std::string s; | 434   std::string s; | 
| 432   const char* sep = "<"; | 435   const char* sep = "<"; | 
| 433   for (uint8 i = 0; i < Shingle::kWidth; ++i) { | 436   for (uint8_t i = 0; i < Shingle::kWidth; ++i) { | 
| 434     // base::StringAppendF(&s, "%s%x ", sep, instance.at(i)->label_->rva_); | 437     // base::StringAppendF(&s, "%s%x ", sep, instance.at(i)->label_->rva_); | 
| 435     s += sep; | 438     s += sep; | 
| 436     s += ToString(instance->at(i)); | 439     s += ToString(instance->at(i)); | 
| 437     sep = ", "; | 440     sep = ", "; | 
| 438   } | 441   } | 
| 439   base::StringAppendF(&s, ">(%" PRIuS ")@{%d}", | 442   base::StringAppendF(&s, ">(%" PRIuS ")@{%d}", | 
| 440                       instance->exemplar_position_, | 443                       instance->exemplar_position_, | 
| 441                       instance->position_count()); | 444                       instance->position_count()); | 
| 442   return s; | 445   return s; | 
| 443 } | 446 } | 
| 444 | 447 | 
| 445 | 448 | 
| 446 bool Shingle::InterningLess::operator()( | 449 bool Shingle::InterningLess::operator()( | 
| 447     const Shingle& a, | 450     const Shingle& a, | 
| 448     const Shingle& b) const { | 451     const Shingle& b) const { | 
| 449   for (uint8 i = 0; i < kWidth; ++i) { | 452   for (uint8_t i = 0; i < kWidth; ++i) { | 
| 450     LabelInfo* info_a = a.at(i); | 453     LabelInfo* info_a = a.at(i); | 
| 451     LabelInfo* info_b = b.at(i); | 454     LabelInfo* info_b = b.at(i); | 
| 452     if (info_a->label_->rva_ < info_b->label_->rva_) | 455     if (info_a->label_->rva_ < info_b->label_->rva_) | 
| 453       return true; | 456       return true; | 
| 454     if (info_a->label_->rva_ > info_b->label_->rva_) | 457     if (info_a->label_->rva_ > info_b->label_->rva_) | 
| 455       return false; | 458       return false; | 
| 456     if (info_a->is_model_ < info_b->is_model_) | 459     if (info_a->is_model_ < info_b->is_model_) | 
| 457       return true; | 460       return true; | 
| 458     if (info_a->is_model_ > info_b->is_model_) | 461     if (info_a->is_model_ > info_b->is_model_) | 
| 459       return false; | 462       return false; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 471          kVariable = 8     // kind & kVariable == 1  => variable. | 474          kVariable = 8     // kind & kVariable == 1  => variable. | 
| 472          }; | 475          }; | 
| 473   // sequence[position + (kinds_[i] & kOffsetMask)] gives LabelInfo for position | 476   // sequence[position + (kinds_[i] & kOffsetMask)] gives LabelInfo for position | 
| 474   // i of shingle.  Below, second 'A' is duplicate of position 1, second '102' | 477   // i of shingle.  Below, second 'A' is duplicate of position 1, second '102' | 
| 475   // is duplicate of position 0. | 478   // is duplicate of position 0. | 
| 476   // | 479   // | 
| 477   //   <102, A, 103, A , 102> | 480   //   <102, A, 103, A , 102> | 
| 478   //      --> <kFixed+0, kVariable+1, kFixed+2, kVariable+1, kFixed+0> | 481   //      --> <kFixed+0, kVariable+1, kFixed+2, kVariable+1, kFixed+0> | 
| 479   struct Index { | 482   struct Index { | 
| 480     explicit Index(const Shingle* instance); | 483     explicit Index(const Shingle* instance); | 
| 481     uint8 kinds_[Shingle::kWidth]; | 484     uint8_t kinds_[Shingle::kWidth]; | 
| 482     uint8 variables_; | 485     uint8_t variables_; | 
| 483     uint8 unique_variables_; | 486     uint8_t unique_variables_; | 
| 484     uint8 first_variable_index_; | 487     uint8_t first_variable_index_; | 
| 485     uint32 hash_; | 488     uint32_t hash_; | 
| 486     int assigned_indexes_[Shingle::kWidth]; | 489     int assigned_indexes_[Shingle::kWidth]; | 
| 487   }; | 490   }; | 
| 488 | 491 | 
| 489   // ShinglePattern keeps histograms of member Shingle instances, ordered by | 492   // ShinglePattern keeps histograms of member Shingle instances, ordered by | 
| 490   // decreasing number of occurrences.  We don't have a pair (occurrence count, | 493   // decreasing number of occurrences.  We don't have a pair (occurrence count, | 
| 491   // Shingle instance), so we use a FreqView adapter to make the instance | 494   // Shingle instance), so we use a FreqView adapter to make the instance | 
| 492   // pointer look like the pair. | 495   // pointer look like the pair. | 
| 493   class FreqView { | 496   class FreqView { | 
| 494    public: | 497    public: | 
| 495     explicit FreqView(const Shingle* instance) : instance_(instance) {} | 498     explicit FreqView(const Shingle* instance) : instance_(instance) {} | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 519   int program_coverage_; | 522   int program_coverage_; | 
| 520 }; | 523 }; | 
| 521 | 524 | 
| 522 std::string ToString(const ShinglePattern::Index* index) { | 525 std::string ToString(const ShinglePattern::Index* index) { | 
| 523   std::string s; | 526   std::string s; | 
| 524   if (index == NULL) { | 527   if (index == NULL) { | 
| 525     s = "<null>"; | 528     s = "<null>"; | 
| 526   } else { | 529   } else { | 
| 527     base::StringAppendF(&s, "<%d: ", index->variables_); | 530     base::StringAppendF(&s, "<%d: ", index->variables_); | 
| 528     const char* sep = ""; | 531     const char* sep = ""; | 
| 529     for (uint8 i = 0; i < Shingle::kWidth; ++i) { | 532     for (uint8_t i = 0; i < Shingle::kWidth; ++i) { | 
| 530       s += sep; | 533       s += sep; | 
| 531       sep = ", "; | 534       sep = ", "; | 
| 532       uint32 kind = index->kinds_[i]; | 535       uint32_t kind = index->kinds_[i]; | 
| 533       int offset = kind & ShinglePattern::kOffsetMask; | 536       int offset = kind & ShinglePattern::kOffsetMask; | 
| 534       if (kind & ShinglePattern::kVariable) | 537       if (kind & ShinglePattern::kVariable) | 
| 535         base::StringAppendF(&s, "V%d", offset); | 538         base::StringAppendF(&s, "V%d", offset); | 
| 536       else | 539       else | 
| 537         base::StringAppendF(&s, "%d", index->assigned_indexes_[offset]); | 540         base::StringAppendF(&s, "%d", index->assigned_indexes_[offset]); | 
| 538      } | 541      } | 
| 539     base::StringAppendF(&s, " %x", index->hash_); | 542     base::StringAppendF(&s, " %x", index->hash_); | 
| 540     s += ">"; | 543     s += ">"; | 
| 541   } | 544   } | 
| 542   return s; | 545   return s; | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 615   s += HistogramToStringFull(pattern->program_histogram_, "    ", max); | 618   s += HistogramToStringFull(pattern->program_histogram_, "    ", max); | 
| 616   return s; | 619   return s; | 
| 617 } | 620 } | 
| 618 | 621 | 
| 619 struct ShinglePatternIndexLess { | 622 struct ShinglePatternIndexLess { | 
| 620   bool operator()(const ShinglePattern::Index& a, | 623   bool operator()(const ShinglePattern::Index& a, | 
| 621                   const ShinglePattern::Index& b) const { | 624                   const ShinglePattern::Index& b) const { | 
| 622     if (a.hash_ < b.hash_) return true; | 625     if (a.hash_ < b.hash_) return true; | 
| 623     if (a.hash_ > b.hash_) return false; | 626     if (a.hash_ > b.hash_) return false; | 
| 624 | 627 | 
| 625     for (uint8 i = 0; i < Shingle::kWidth; ++i) { | 628     for (uint8_t i = 0; i < Shingle::kWidth; ++i) { | 
| 626       if (a.kinds_[i] < b.kinds_[i]) return true; | 629       if (a.kinds_[i] < b.kinds_[i]) return true; | 
| 627       if (a.kinds_[i] > b.kinds_[i]) return false; | 630       if (a.kinds_[i] > b.kinds_[i]) return false; | 
| 628       if ((a.kinds_[i] & ShinglePattern::kVariable) == 0) { | 631       if ((a.kinds_[i] & ShinglePattern::kVariable) == 0) { | 
| 629         if (a.assigned_indexes_[i] < b.assigned_indexes_[i]) | 632         if (a.assigned_indexes_[i] < b.assigned_indexes_[i]) | 
| 630           return true; | 633           return true; | 
| 631         if (a.assigned_indexes_[i] > b.assigned_indexes_[i]) | 634         if (a.assigned_indexes_[i] > b.assigned_indexes_[i]) | 
| 632           return false; | 635           return false; | 
| 633       } | 636       } | 
| 634     } | 637     } | 
| 635     return false; | 638     return false; | 
| 636   } | 639   } | 
| 637 }; | 640 }; | 
| 638 | 641 | 
| 639 static uint32 hash_combine(uint32 h, uint32 v) { | 642 static uint32_t hash_combine(uint32_t h, uint32_t v) { | 
| 640   h += v; | 643   h += v; | 
| 641   return (h * (37 + 0x0000d100)) ^ (h >> 13); | 644   return (h * (37 + 0x0000d100)) ^ (h >> 13); | 
| 642 } | 645 } | 
| 643 | 646 | 
| 644 ShinglePattern::Index::Index(const Shingle* instance) { | 647 ShinglePattern::Index::Index(const Shingle* instance) { | 
| 645   uint32 hash = 0; | 648   uint32_t hash = 0; | 
| 646   variables_ = 0; | 649   variables_ = 0; | 
| 647   unique_variables_ = 0; | 650   unique_variables_ = 0; | 
| 648   first_variable_index_ = 255; | 651   first_variable_index_ = 255; | 
| 649 | 652 | 
| 650   for (uint8 i = 0; i < Shingle::kWidth; ++i) { | 653   for (uint8_t i = 0; i < Shingle::kWidth; ++i) { | 
| 651     LabelInfo* info = instance->at(i); | 654     LabelInfo* info = instance->at(i); | 
| 652     uint8 kind = 0; | 655     uint8_t kind = 0; | 
| 653     int code = -1; | 656     int code = -1; | 
| 654     uint8 j = 0; | 657     uint8_t j = 0; | 
| 655     for ( ; j < i; ++j) { | 658     for ( ; j < i; ++j) { | 
| 656       if (info == instance->at(j)) {  // Duplicate LabelInfo | 659       if (info == instance->at(j)) {  // Duplicate LabelInfo | 
| 657         kind = kinds_[j]; | 660         kind = kinds_[j]; | 
| 658         break; | 661         break; | 
| 659       } | 662       } | 
| 660     } | 663     } | 
| 661     if (j == i) {  // Not found above. | 664     if (j == i) {  // Not found above. | 
| 662       if (info->assignment_) { | 665       if (info->assignment_) { | 
| 663         code = info->label_->index_; | 666         code = info->label_->index_; | 
| 664         assigned_indexes_[i] = code; | 667         assigned_indexes_[i] = code; | 
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 935     for (Shingle::OwningSet::iterator p = shingle_instances_.begin(); | 938     for (Shingle::OwningSet::iterator p = shingle_instances_.begin(); | 
| 936          p != shingle_instances_.end(); | 939          p != shingle_instances_.end(); | 
| 937          ++p) { | 940          ++p) { | 
| 938       // GCC's set<T>::iterator::operator *() returns a const object. | 941       // GCC's set<T>::iterator::operator *() returns a const object. | 
| 939       Reclassify(const_cast<Shingle*>(&*p)); | 942       Reclassify(const_cast<Shingle*>(&*p)); | 
| 940     } | 943     } | 
| 941   } | 944   } | 
| 942 | 945 | 
| 943   // For the positions in |info|, find the shingles that overlap that position. | 946   // For the positions in |info|, find the shingles that overlap that position. | 
| 944   void AddAffectedPositions(LabelInfo* info, ShingleSet* affected_shingles) { | 947   void AddAffectedPositions(LabelInfo* info, ShingleSet* affected_shingles) { | 
| 945     const uint8 kWidth = Shingle::kWidth; | 948     const uint8_t kWidth = Shingle::kWidth; | 
| 946     for (size_t i = 0;  i < info->positions_.size();  ++i) { | 949     for (size_t i = 0;  i < info->positions_.size();  ++i) { | 
| 947       size_t position = info->positions_[i]; | 950       size_t position = info->positions_[i]; | 
| 948       // Find bounds to the subrange of |trace_| we are in. | 951       // Find bounds to the subrange of |trace_| we are in. | 
| 949       size_t start = position < model_end_ ? 0 : model_end_; | 952       size_t start = position < model_end_ ? 0 : model_end_; | 
| 950       size_t end = position < model_end_ ? model_end_ : trace_.size(); | 953       size_t end = position < model_end_ ? model_end_ : trace_.size(); | 
| 951 | 954 | 
| 952       // Clip [position-kWidth+1, position+1) | 955       // Clip [position-kWidth+1, position+1) | 
| 953       size_t low = | 956       size_t low = | 
| 954           position > start + kWidth - 1 ? position - kWidth + 1 : start; | 957           position > start + kWidth - 1 ? position - kWidth + 1 : start; | 
| 955       size_t high = position + kWidth < end ? position + 1 : end - kWidth + 1; | 958       size_t high = position + kWidth < end ? position + 1 : end - kWidth + 1; | 
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1052            program_iter != pattern->program_histogram_.end(); | 1055            program_iter != pattern->program_histogram_.end(); | 
| 1053            ++program_iter) { | 1056            ++program_iter) { | 
| 1054         if (++n_program_samples > kUnwieldy) break; | 1057         if (++n_program_samples > kUnwieldy) break; | 
| 1055         const ShinglePattern::FreqView& program_freq = *program_iter; | 1058         const ShinglePattern::FreqView& program_freq = *program_iter; | 
| 1056         int p1 = program_freq.count(); | 1059         int p1 = program_freq.count(); | 
| 1057         const Shingle* program_instance = program_freq.instance(); | 1060         const Shingle* program_instance = program_freq.instance(); | 
| 1058 | 1061 | 
| 1059         // int score = p1;  // ? weigh all equally?? | 1062         // int score = p1;  // ? weigh all equally?? | 
| 1060         int score = std::min(p1, m1); | 1063         int score = std::min(p1, m1); | 
| 1061 | 1064 | 
| 1062         for (uint8 i = 0; i < Shingle::kWidth; ++i) { | 1065         for (uint8_t i = 0; i < Shingle::kWidth; ++i) { | 
| 1063           LabelInfo* program_info = program_instance->at(i); | 1066           LabelInfo* program_info = program_instance->at(i); | 
| 1064           LabelInfo* model_info = model_instance->at(i); | 1067           LabelInfo* model_info = model_instance->at(i); | 
| 1065           if ((model_info->assignment_ == NULL) != | 1068           if ((model_info->assignment_ == NULL) != | 
| 1066               (program_info->assignment_ == NULL)) { | 1069               (program_info->assignment_ == NULL)) { | 
| 1067             VLOG(2) << "ERROR " << i | 1070             VLOG(2) << "ERROR " << i | 
| 1068                     << "\n\t"  << ToString(pattern, 10) | 1071                     << "\n\t"  << ToString(pattern, 10) | 
| 1069                     << "\n\t" << ToString(program_instance) | 1072                     << "\n\t" << ToString(program_instance) | 
| 1070                     << "\n\t" << ToString(model_instance); | 1073                     << "\n\t" << ToString(model_instance); | 
| 1071           } | 1074           } | 
| 1072           if (!program_info->assignment_ && !model_info->assignment_) { | 1075           if (!program_info->assignment_ && !model_info->assignment_) { | 
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1268 | 1271 | 
| 1269   void Solve(const Trace& model, size_t model_end) { | 1272   void Solve(const Trace& model, size_t model_end) { | 
| 1270     base::Time start_time = base::Time::Now(); | 1273     base::Time start_time = base::Time::Now(); | 
| 1271     AssignmentProblem a(model, model_end); | 1274     AssignmentProblem a(model, model_end); | 
| 1272     a.Solve(); | 1275     a.Solve(); | 
| 1273     VLOG(1) << " Adjuster::Solve " | 1276     VLOG(1) << " Adjuster::Solve " | 
| 1274             << (base::Time::Now() - start_time).InSecondsF(); | 1277             << (base::Time::Now() - start_time).InSecondsF(); | 
| 1275   } | 1278   } | 
| 1276 | 1279 | 
| 1277   void ReferenceLabel(Trace* trace, Label* label, bool is_model) { | 1280   void ReferenceLabel(Trace* trace, Label* label, bool is_model) { | 
| 1278     trace->push_back( | 1281     trace->push_back(label_info_maker_.MakeLabelInfo( | 
| 1279         label_info_maker_.MakeLabelInfo(label, is_model, | 1282         label, is_model, static_cast<uint32_t>(trace->size()))); | 
| 1280                                         static_cast<uint32>(trace->size()))); |  | 
| 1281   } | 1283   } | 
| 1282 | 1284 | 
| 1283   AssemblyProgram* prog_;         // Program to be adjusted, owned by caller. | 1285   AssemblyProgram* prog_;         // Program to be adjusted, owned by caller. | 
| 1284   const AssemblyProgram* model_;  // Program to be mimicked, owned by caller. | 1286   const AssemblyProgram* model_;  // Program to be mimicked, owned by caller. | 
| 1285 | 1287 | 
| 1286   LabelInfoMaker label_info_maker_; | 1288   LabelInfoMaker label_info_maker_; | 
| 1287 | 1289 | 
| 1288  private: | 1290  private: | 
| 1289   DISALLOW_COPY_AND_ASSIGN(Adjuster); | 1291   DISALLOW_COPY_AND_ASSIGN(Adjuster); | 
| 1290 }; | 1292 }; | 
| 1291 | 1293 | 
| 1292 //////////////////////////////////////////////////////////////////////////////// | 1294 //////////////////////////////////////////////////////////////////////////////// | 
| 1293 | 1295 | 
| 1294 }  // namespace adjustment_method_2 | 1296 }  // namespace adjustment_method_2 | 
| 1295 | 1297 | 
| 1296 AdjustmentMethod* AdjustmentMethod::MakeShingleAdjustmentMethod() { | 1298 AdjustmentMethod* AdjustmentMethod::MakeShingleAdjustmentMethod() { | 
| 1297   return new adjustment_method_2::Adjuster(); | 1299   return new adjustment_method_2::Adjuster(); | 
| 1298 } | 1300 } | 
| 1299 | 1301 | 
| 1300 }  // namespace courgette | 1302 }  // namespace courgette | 
| OLD | NEW | 
|---|