Revert "Enable profiled guided compilation in dex2oat"

Test has flakes:

+art F 30865 30865 art/runtime/java_vm_ext.cc:466] JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal start byte 0x80
+art F 30865 30865 art/runtime/java_vm_ext.cc:466]     string: '��gy�'
+art F 30865 30865 art/runtime/java_vm_ext.cc:466]     input: '<0x80> 0xd8 0x67 0x79 0x8e 0x7f'
+art F 30865 30865 art/runtime/java_vm_ext.cc:466]     in call to NewStringUTF
+art F 30865 30865 art/runtime/java_vm_ext.cc:466]     from java.lang.String Main.getProfileInfoDump(java.lang.String, java.lang.Class, java.lang.Class)

This reverts commit 27e17fd81cc30e16e86c9c15498cae7f920c9dfe.

Change-Id: Id224b5970c3620c4c71fc0d39ed4a2e4755e5f29
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc
index 18ce563..39f8ee8 100644
--- a/compiler/dex/mir_analysis.cc
+++ b/compiler/dex/mir_analysis.cc
@@ -1430,4 +1430,8 @@
                                  method_lowering_infos_.data(), count);
 }
 
+bool MIRGraph::SkipCompilationByName(const std::string& methodname) {
+  return cu_->compiler_driver->SkipCompilation(methodname);
+}
+
 }  // namespace art
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 3191fe9..2da8a98 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -564,6 +564,11 @@
   bool SkipCompilation(std::string* skip_message);
 
   /*
+   * Should we skip the compilation of this method based on its name?
+   */
+  bool SkipCompilationByName(const std::string& methodname);
+
+  /*
    * Parse dex method and add MIR at current insert point.  Returns id (which is
    * actually the index of the method in the m_units_ array).
    */
diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc
index 3260a7a..05dde9f 100644
--- a/compiler/dex/quick/quick_compiler.cc
+++ b/compiler/dex/quick/quick_compiler.cc
@@ -780,6 +780,14 @@
   PassDriverMEOpts pass_driver(GetPreOptPassManager(), GetPostOptPassManager(), &cu);
   pass_driver.Launch();
 
+  /* For non-leaf methods check if we should skip compilation when the profiler is enabled. */
+  if (cu.compiler_driver->ProfilePresent()
+      && !cu.mir_graph->MethodIsLeaf()
+      && cu.mir_graph->SkipCompilationByName(PrettyMethod(method_idx, dex_file))) {
+    cu.EndTiming();
+    return nullptr;
+  }
+
   if (cu.enable_debug & (1 << kDebugDumpCheckStats)) {
     cu.mir_graph->DumpCheckStats();
   }
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 6d317d8..9d3af16 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -80,9 +80,6 @@
 // given, too all compilations.
 static constexpr bool kRestrictCompilationFiltersToImage = true;
 
-// Print additional info during profile guided compilation.
-static constexpr bool kDebugProfileGuidedCompilation = false;
-
 static double Percentage(size_t x, size_t y) {
   return 100.0 * (static_cast<double>(x)) / (static_cast<double>(x + y));
 }
@@ -347,7 +344,8 @@
                                const std::string& dump_cfg_file_name, bool dump_cfg_append,
                                CumulativeLogger* timer, int swap_fd,
                                const std::string& profile_file)
-    : compiler_options_(compiler_options),
+    : profile_present_(false),
+      compiler_options_(compiler_options),
       verification_results_(verification_results),
       method_inliner_map_(method_inliner_map),
       compiler_(Compiler::Create(this, compiler_kind)),
@@ -385,8 +383,12 @@
 
   // Read the profile file if one is provided.
   if (!profile_file.empty()) {
-    profile_compilation_info_.reset(new ProfileCompilationInfo(profile_file));
-    LOG(INFO) << "Using profile data from file " << profile_file;
+    profile_present_ = profile_file_.LoadFile(profile_file);
+    if (profile_present_) {
+      LOG(INFO) << "Using profile data form file " << profile_file;
+    } else {
+      LOG(INFO) << "Failed to load profile file " << profile_file;
+    }
   }
 }
 
@@ -567,9 +569,7 @@
         (verified_method->GetEncounteredVerificationFailures() &
             (verifier::VERIFY_ERROR_FORCE_INTERPRETER | verifier::VERIFY_ERROR_LOCKING)) == 0 &&
         // Is eligable for compilation by methods-to-compile filter.
-        driver->IsMethodToCompile(method_ref) &&
-        driver->ShouldCompileBasedOnProfile(method_ref);
-
+        driver->IsMethodToCompile(method_ref);
     if (compile) {
       // NOTE: if compiler declines to compile this method, it will return null.
       compiled_method = driver->GetCompiler()->Compile(code_item, access_flags, invoke_type,
@@ -766,22 +766,6 @@
   return methods_to_compile_->find(tmp.c_str()) != methods_to_compile_->end();
 }
 
-bool CompilerDriver::ShouldCompileBasedOnProfile(const MethodReference& method_ref) const {
-  if (profile_compilation_info_ == nullptr) {
-    // If we miss profile information it means that we don't do a profile guided compilation.
-    // Return true, and let the other filters decide if the method should be compiled.
-    return true;
-  }
-  bool result = profile_compilation_info_->ContainsMethod(method_ref);
-
-  if (kDebugProfileGuidedCompilation) {
-    LOG(INFO) << "[ProfileGuidedCompilation] "
-        << (result ? "Compiled" : "Skipped") << " method:"
-        << PrettyMethod(method_ref.dex_method_index, *method_ref.dex_file, true);
-  }
-  return result;
-}
-
 class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor {
  public:
   ResolveCatchBlockExceptionsClassVisitor(
@@ -2289,16 +2273,6 @@
 
 void CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
                              ThreadPool* thread_pool, TimingLogger* timings) {
-  if (profile_compilation_info_ != nullptr) {
-    if (!profile_compilation_info_->Load(dex_files)) {
-      LOG(WARNING) << "Failed to load offline profile info from "
-          << profile_compilation_info_->GetFilename()
-          << ". No methods will be compiled";
-    } else if (kDebugProfileGuidedCompilation) {
-      LOG(INFO) << "[ProfileGuidedCompilation] "
-          << profile_compilation_info_->DumpInfo();
-    }
-  }
   for (size_t i = 0; i != dex_files.size(); ++i) {
     const DexFile* dex_file = dex_files[i];
     CHECK(dex_file != nullptr);
@@ -2536,6 +2510,39 @@
   return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
 }
 
+bool CompilerDriver::SkipCompilation(const std::string& method_name) {
+  if (!profile_present_) {
+    return false;
+  }
+  // First find the method in the profile file.
+  ProfileFile::ProfileData data;
+  if (!profile_file_.GetProfileData(&data, method_name)) {
+    // Not in profile, no information can be determined.
+    if (kIsDebugBuild) {
+      VLOG(compiler) << "not compiling " << method_name << " because it's not in the profile";
+    }
+    return true;
+  }
+
+  // Methods that comprise top_k_threshold % of the total samples will be compiled.
+  // Compare against the start of the topK percentage bucket just in case the threshold
+  // falls inside a bucket.
+  bool compile = data.GetTopKUsedPercentage() - data.GetUsedPercent()
+                 <= compiler_options_->GetTopKProfileThreshold();
+  if (kIsDebugBuild) {
+    if (compile) {
+      LOG(INFO) << "compiling method " << method_name << " because its usage is part of top "
+          << data.GetTopKUsedPercentage() << "% with a percent of " << data.GetUsedPercent() << "%"
+          << " (topKThreshold=" << compiler_options_->GetTopKProfileThreshold() << ")";
+    } else {
+      VLOG(compiler) << "not compiling method " << method_name
+          << " because it's not part of leading " << compiler_options_->GetTopKProfileThreshold()
+          << "% samples)";
+    }
+  }
+  return !compile;
+}
+
 std::string CompilerDriver::GetMemoryUsageString(bool extended) const {
   std::ostringstream oss;
   Runtime* const runtime = Runtime::Current();
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index a351f6d..1347b37 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -31,11 +31,11 @@
 #include "compiler.h"
 #include "dex_file.h"
 #include "driver/compiled_method_storage.h"
-#include "jit/offline_profiling_info.h"
 #include "invoke_type.h"
 #include "method_reference.h"
 #include "mirror/class.h"  // For mirror::Class::Status.
 #include "os.h"
+#include "profiler.h"
 #include "runtime.h"
 #include "safe_map.h"
 #include "thread_pool.h"
@@ -147,6 +147,10 @@
     return compiler_.get();
   }
 
+  bool ProfilePresent() const {
+    return profile_present_;
+  }
+
   // Are we compiling and creating an image file?
   bool IsBootImage() const {
     return boot_image_;
@@ -441,10 +445,6 @@
   // Checks whether the provided method should be compiled, i.e., is in method_to_compile_.
   bool IsMethodToCompile(const MethodReference& method_ref) const;
 
-  // Checks whether profile guided compilation is enabled and if the method should be compiled
-  // according to the profile file.
-  bool ShouldCompileBasedOnProfile(const MethodReference& method_ref) const;
-
   void RecordClassStatus(ClassReference ref, mirror::Class::Status status)
       REQUIRES(!compiled_classes_lock_);
 
@@ -454,6 +454,9 @@
                                        uint16_t class_def_idx,
                                        const DexFile& dex_file) const;
 
+  // Should the compiler run on this method given profile information?
+  bool SkipCompilation(const std::string& method_name);
+
   // Get memory usage during compilation.
   std::string GetMemoryUsageString(bool extended) const;
 
@@ -592,6 +595,9 @@
                       ThreadPool* thread_pool, TimingLogger* timings)
       REQUIRES(!Locks::mutator_lock_);
 
+  ProfileFile profile_file_;
+  bool profile_present_;
+
   const CompilerOptions* const compiler_options_;
   VerificationResults* const verification_results_;
   DexFileToMethodInlinerMap* const method_inliner_map_;
@@ -641,9 +647,6 @@
   // This option may be restricted to the boot image, depending on a flag in the implementation.
   std::unique_ptr<std::unordered_set<std::string>> methods_to_compile_;
 
-  // Info for profile guided compilation.
-  std::unique_ptr<ProfileCompilationInfo> profile_compilation_info_;
-
   bool had_hard_verifier_failure_;
 
   size_t thread_count_;