Tweaked profile significant_difference.

- renamed to 'change_thr'
- now it represents how much the top K leading samples need to change
(in percents) in order to trigger compilation.
- extracted ProfileData & file parsing in profiler.h

Bug: 12877748
Change-Id: I10f66120dd5e68b8a690bfa0e9914c07f63c50d5
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index fc1332a..d071805 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -19,10 +19,8 @@
 #define ATRACE_TAG ATRACE_TAG_DALVIK
 #include <utils/Trace.h>
 
-#include <fstream>
 #include <vector>
 #include <unistd.h>
-#include <utility>
 
 #include "base/stl_util.h"
 #include "base/timing_logger.h"
@@ -372,7 +370,7 @@
 
   // Read the profile file if one is provided.
   if (profile_file != "") {
-    profile_ok_ = ReadProfile(profile_file);
+    profile_ok_ = ProfileHelper::LoadProfileMap(profile_map_, profile_file);
   }
 
   dex_to_dex_compiler_ = reinterpret_cast<DexToDexCompilerFn>(ArtCompileDEX);
@@ -2030,83 +2028,6 @@
     }
   }
 
-bool CompilerDriver::ReadProfile(const std::string& filename) {
-  VLOG(compiler) << "reading profile file " << filename;
-  struct stat st;
-  int err = stat(filename.c_str(), &st);
-  if (err == -1) {
-    VLOG(compiler) << "not found";
-    return false;
-  }
-  std::ifstream in(filename.c_str());
-  if (!in) {
-    VLOG(compiler) << "profile file " << filename << " exists but can't be opened";
-    VLOG(compiler) << "file owner: " << st.st_uid << ":" << st.st_gid;
-    VLOG(compiler) << "me: " << getuid() << ":" << getgid();
-    VLOG(compiler) << "file permissions: " << std::oct << st.st_mode;
-    VLOG(compiler) << "errno: " << errno;
-    return false;
-  }
-  // The first line contains summary information.
-  std::string line;
-  std::getline(in, line);
-  if (in.eof()) {
-    return false;
-  }
-  std::vector<std::string> summary_info;
-  Split(line, '/', summary_info);
-  if (summary_info.size() != 3) {
-    // Bad summary info.  It should be count/total/bootpath.
-    return false;
-  }
-  // This is the number of hits in all methods.
-  uint32_t total_count = 0;
-  for (int i = 0 ; i < 3; ++i) {
-    total_count += atoi(summary_info[i].c_str());
-  }
-
-  // Now read each line until the end of file.  Each line consists of 3 fields separated by '/'.
-  // Store the info in descending order given by the most used methods.
-  typedef std::set<std::pair<int, std::vector<std::string>>> ProfileSet;
-  ProfileSet countSet;
-  while (!in.eof()) {
-    std::getline(in, line);
-    if (in.eof()) {
-      break;
-    }
-    std::vector<std::string> info;
-    Split(line, '/', info);
-    if (info.size() != 3) {
-      // Malformed.
-      break;
-    }
-    int count = atoi(info[1].c_str());
-    countSet.insert(std::make_pair(-count, info));
-  }
-
-  uint32_t curTotalCount = 0;
-  ProfileSet::iterator end = countSet.end();
-  const ProfileData* prevData = nullptr;
-  for (ProfileSet::iterator it = countSet.begin(); it != end ; it++) {
-    const std::string& methodname = it->second[0];
-    uint32_t count = -it->first;
-    uint32_t size = atoi(it->second[2].c_str());
-    double usedPercent = (count * 100.0) / total_count;
-
-    curTotalCount += count;
-    // Methods with the same count should be part of the same top K percentage bucket.
-    double topKPercentage = (prevData != nullptr) && (prevData->GetCount() == count)
-      ? prevData->GetTopKUsedPercentage()
-      : 100 * static_cast<double>(curTotalCount) / static_cast<double>(total_count);
-
-    // Add it to the profile map.
-    ProfileData curData = ProfileData(methodname, count, size, usedPercent, topKPercentage);
-    profile_map_[methodname] = curData;
-    prevData = &curData;
-  }
-  return true;
-}
-
 bool CompilerDriver::SkipCompilation(const std::string& method_name) {
   if (!profile_ok_) {
     return true;
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 802f859..d49523a 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -32,6 +32,7 @@
 #include "invoke_type.h"
 #include "method_reference.h"
 #include "os.h"
+#include "profiler.h"
 #include "runtime.h"
 #include "safe_map.h"
 #include "thread_pool.h"
@@ -594,43 +595,9 @@
     return cfi_info_.get();
   }
 
-  // Profile data.  This is generated from previous runs of the program and stored
-  // in a file.  It is used to determine whether to compile a particular method or not.
-  class ProfileData {
-   public:
-    ProfileData() : count_(0), method_size_(0), usedPercent_(0) {}
-    ProfileData(const std::string& method_name, uint32_t count, uint32_t method_size,
-      double usedPercent, double topKUsedPercentage) :
-      method_name_(method_name), count_(count), method_size_(method_size),
-      usedPercent_(usedPercent), topKUsedPercentage_(topKUsedPercentage) {
-      // TODO: currently method_size_ and count_ are unused.
-      UNUSED(method_size_);
-      UNUSED(count_);
-    }
-
-    bool IsAbove(double v) const { return usedPercent_ >= v; }
-    double GetUsedPercent() const { return usedPercent_; }
-    uint32_t GetCount() const { return count_; }
-    double GetTopKUsedPercentage() const { return topKUsedPercentage_; }
-
-   private:
-    std::string method_name_;    // Method name.
-    uint32_t count_;             // Number of times it has been called.
-    uint32_t method_size_;       // Size of the method on dex instructions.
-    double usedPercent_;         // Percentage of how many times this method was called.
-    double topKUsedPercentage_;  // The percentage of the group that comprise K% of the total used
-                                 // methods this methods belongs to.
-  };
-
-  // Profile data is stored in a map, indexed by the full method name.
-  typedef std::map<const std::string, ProfileData> ProfileMap;
   ProfileMap profile_map_;
   bool profile_ok_;
 
-  // Read the profile data from the given file.  Calculates the percentage for each method.
-  // Returns false if there was no profile file or it was malformed.
-  bool ReadProfile(const std::string& filename);
-
   // Should the compiler run on this method given profile information?
   bool SkipCompilation(const std::string& method_name);