Merge "Profile: renamed kThresholdPercent and make it configurable"
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 15d27a7..fc1332a 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -59,6 +59,10 @@
 #include "verifier/method_verifier.h"
 #include "verifier/method_verifier-inl.h"
 
+#ifdef HAVE_ANDROID_OS
+#include "cutils/properties.h"
+#endif
+
 namespace art {
 
 static double Percentage(size_t x, size_t y) {
@@ -2052,7 +2056,7 @@
   std::vector<std::string> summary_info;
   Split(line, '/', summary_info);
   if (summary_info.size() != 3) {
-    // Bad summary info.  It should be count/total/bootpath
+    // Bad summary info.  It should be count/total/bootpath.
     return false;
   }
   // This is the number of hits in all methods.
@@ -2061,8 +2065,8 @@
     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 desceding order given by the most used methods
+  // 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()) {
@@ -2090,12 +2094,12 @@
     double usedPercent = (count * 100.0) / total_count;
 
     curTotalCount += count;
-    // Methods with the same count should be part of the same top K percentage bucket
+    // 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
+    // Add it to the profile map.
     ProfileData curData = ProfileData(methodname, count, size, usedPercent, topKPercentage);
     profile_map_[methodname] = curData;
     prevData = &curData;
@@ -2107,8 +2111,17 @@
   if (!profile_ok_) {
     return true;
   }
-  // Methods that comprise kThresholdPercent % of the total samples will be compiled
-  constexpr double kThresholdPercent = 90.0;
+  // Methods that comprise topKPercentThreshold % of the total samples will be compiled.
+  double topKPercentThreshold = 90.0;
+#ifdef HAVE_ANDROID_OS
+  char buf[PROP_VALUE_MAX];
+  property_get("dalvik.vm.profile.compile_thr", buf, "90.0");
+  topKPercentThreshold = strtod(buf, nullptr);
+#endif
+  // Test for reasonable thresholds.
+  if (topKPercentThreshold < 10.0 || topKPercentThreshold > 90.0) {
+    topKPercentThreshold = 90.0;
+  }
 
   // First find the method in the profile map.
   ProfileMap::iterator i = profile_map_.find(method_name);
@@ -2118,15 +2131,16 @@
     return true;
   }
   const ProfileData& data = i->second;
+
   // Compare against the start of the topK percentage bucket just in case the threshold
-  // falls inside a bucket
-  bool compile = data.GetTopKUsedPercentage() - data.GetUsedPercent() <= kThresholdPercent;
+  // falls inside a bucket.
+  bool compile = data.GetTopKUsedPercentage() - data.GetUsedPercent() <= topKPercentThreshold;
   if (compile) {
     LOG(INFO) << "compiling method " << method_name << " because its usage is part of top "
         << data.GetTopKUsedPercentage() << "% with a percent of " << data.GetUsedPercent() << "%";
   } else {
-    VLOG(compiler) << "not compiling method " << method_name << " because usage is too low ("
-        << data.GetUsedPercent() << "%)";
+    VLOG(compiler) << "not compiling method " << method_name << " because it's not part of leading "
+        << topKPercentThreshold << "% samples)";
   }
   return !compile;
 }