Merge "ART: Make switch back-edge suspension point consistent"
diff --git a/cmdline/cmdline_types.h b/cmdline/cmdline_types.h
index 156ca9e..e41d9bd 100644
--- a/cmdline/cmdline_types.h
+++ b/cmdline/cmdline_types.h
@@ -22,6 +22,8 @@
 #include "detail/cmdline_debug_detail.h"
 #include "cmdline_type_parser.h"
 
+#include "android-base/strings.h"
+
 // Includes for the types that are being specialized
 #include <string>
 #include "base/logging.h"
@@ -447,7 +449,7 @@
   }
 
   std::string Join() const {
-    return art::Join(list_, Separator);
+    return android::base::Join(list_, Separator);
   }
 
   static ParseStringList<Separator> Split(const std::string& str) {
@@ -709,43 +711,43 @@
     // The rest of these options are always the wildcard from '-Xps-*'
     std::string suffix = RemovePrefix(option);
 
-    if (StartsWith(option, "min-save-period-ms:")) {
+    if (android::base::StartsWith(option, "min-save-period-ms:")) {
       CmdlineType<unsigned int> type_parser;
       return ParseInto(existing,
              &ProfileSaverOptions::min_save_period_ms_,
              type_parser.Parse(suffix));
     }
-    if (StartsWith(option, "save-resolved-classes-delay-ms:")) {
+    if (android::base::StartsWith(option, "save-resolved-classes-delay-ms:")) {
       CmdlineType<unsigned int> type_parser;
       return ParseInto(existing,
              &ProfileSaverOptions::save_resolved_classes_delay_ms_,
              type_parser.Parse(suffix));
     }
-    if (StartsWith(option, "startup-method-samples:")) {
+    if (android::base::StartsWith(option, "startup-method-samples:")) {
       CmdlineType<unsigned int> type_parser;
       return ParseInto(existing,
              &ProfileSaverOptions::startup_method_samples_,
              type_parser.Parse(suffix));
     }
-    if (StartsWith(option, "min-methods-to-save:")) {
+    if (android::base::StartsWith(option, "min-methods-to-save:")) {
       CmdlineType<unsigned int> type_parser;
       return ParseInto(existing,
              &ProfileSaverOptions::min_methods_to_save_,
              type_parser.Parse(suffix));
     }
-    if (StartsWith(option, "min-classes-to-save:")) {
+    if (android::base::StartsWith(option, "min-classes-to-save:")) {
       CmdlineType<unsigned int> type_parser;
       return ParseInto(existing,
              &ProfileSaverOptions::min_classes_to_save_,
              type_parser.Parse(suffix));
     }
-    if (StartsWith(option, "min-notification-before-wake:")) {
+    if (android::base::StartsWith(option, "min-notification-before-wake:")) {
       CmdlineType<unsigned int> type_parser;
       return ParseInto(existing,
              &ProfileSaverOptions::min_notification_before_wake_,
              type_parser.Parse(suffix));
     }
-    if (StartsWith(option, "max-notification-before-wake:")) {
+    if (android::base::StartsWith(option, "max-notification-before-wake:")) {
       CmdlineType<unsigned int> type_parser;
       return ParseInto(existing,
              &ProfileSaverOptions::max_notification_before_wake_,
diff --git a/cmdline/detail/cmdline_parse_argument_detail.h b/cmdline/detail/cmdline_parse_argument_detail.h
index 14eac30..da03c21 100644
--- a/cmdline/detail/cmdline_parse_argument_detail.h
+++ b/cmdline/detail/cmdline_parse_argument_detail.h
@@ -25,6 +25,8 @@
 #include <numeric>
 #include <memory>
 
+#include "android-base/strings.h"
+
 #include "cmdline_parse_result.h"
 #include "cmdline_types.h"
 #include "token_range.h"
@@ -399,7 +401,7 @@
             allowed_values.push_back(name);
           }
 
-          std::string allowed_values_flat = Join(allowed_values, ',');
+          std::string allowed_values_flat = android::base::Join(allowed_values, ',');
           return CmdlineResult(CmdlineResult::kFailure,
                                "Argument value '" + argument + "' does not match any of known valid"
                                 "values: {" + allowed_values_flat + "}");
@@ -426,7 +428,7 @@
             allowed_values.push_back(arg_name);
           }
 
-          std::string allowed_values_flat = Join(allowed_values, ',');
+          std::string allowed_values_flat = android::base::Join(allowed_values, ',');
           return CmdlineResult(CmdlineResult::kFailure,
                                "Argument value '" + argument + "' does not match any of known valid"
                                 "values: {" + allowed_values_flat + "}");
diff --git a/cmdline/token_range.h b/cmdline/token_range.h
index 3358067..c22d6c8 100644
--- a/cmdline/token_range.h
+++ b/cmdline/token_range.h
@@ -23,6 +23,8 @@
 #include <algorithm>
 #include <memory>
 
+#include "android-base/strings.h"
+
 namespace art {
 // A range of tokens to make token matching algorithms easier.
 //
@@ -374,7 +376,7 @@
   // e.g. ["hello", "world"].join('$') == "hello$world"
   std::string Join(char separator) const {
     TokenList tmp(begin(), end());
-    return art::Join(tmp, separator);
+    return android::base::Join(tmp, separator);
     // TODO: Join should probably take an offset or iterators
   }
 
diff --git a/compiler/optimizing/code_generator_utils.h b/compiler/optimizing/code_generator_utils.h
index 7efed8c..a6b41c0 100644
--- a/compiler/optimizing/code_generator_utils.h
+++ b/compiler/optimizing/code_generator_utils.h
@@ -18,6 +18,8 @@
 #define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_UTILS_H_
 
 #include <cstdint>
+#include <cstdlib>
+#include <limits>
 
 namespace art {
 
@@ -32,6 +34,12 @@
 // that it has been previously visited by the InstructionCodeGenerator.
 bool IsBooleanValueOrMaterializedCondition(HInstruction* cond_input);
 
+template <typename T> T AbsOrMin(T value) {
+  return (value == std::numeric_limits<T>::min())
+      ? value
+      : std::abs(value);
+}
+
 }  // namespace art
 
 #endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_UTILS_H_
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 658b804..c615df1 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1185,6 +1185,18 @@
   RecordSimplification();
 }
 
+// Return whether x / divisor == x * (1.0f / divisor), for every float x.
+static constexpr bool CanDivideByReciprocalMultiplyFloat(int32_t divisor) {
+  // True, if the most significant bits of divisor are 0.
+  return ((divisor & 0x7fffff) == 0);
+}
+
+// Return whether x / divisor == x * (1.0 / divisor), for every double x.
+static constexpr bool CanDivideByReciprocalMultiplyDouble(int64_t divisor) {
+  // True, if the most significant bits of divisor are 0.
+  return ((divisor & ((UINT64_C(1) << 52) - 1)) == 0);
+}
+
 void InstructionSimplifierVisitor::VisitDiv(HDiv* instruction) {
   HConstant* input_cst = instruction->GetConstantRight();
   HInstruction* input_other = instruction->GetLeastConstantLeft();
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 659cdda..4a8cfcb 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -125,6 +125,11 @@
   kAnalysisSuccess,
 };
 
+template <typename T>
+static inline typename std::make_unsigned<T>::type MakeUnsigned(T x) {
+  return static_cast<typename std::make_unsigned<T>::type>(x);
+}
+
 class HInstructionList : public ValueObject {
  public:
   HInstructionList() : first_instruction_(nullptr), last_instruction_(nullptr) {}
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 64c87dc..ba7012a 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -22,6 +22,8 @@
 
 #include <stdint.h>
 
+#include "android-base/strings.h"
+
 #ifdef ART_ENABLE_CODEGEN_arm
 #include "dex_cache_array_fixups_arm.h"
 #endif
@@ -1115,7 +1117,8 @@
 bool IsCompilingWithCoreImage() {
   const std::string& image = Runtime::Current()->GetImageLocation();
   // TODO: This is under-approximating...
-  if (EndsWith(image, "core.art") || EndsWith(image, "core-optimizing.art")) {
+  if (android::base::EndsWith(image, "core.art") ||
+      android::base::EndsWith(image, "core-optimizing.art")) {
     return true;
   }
   return false;
diff --git a/compiler/utils/assembler_test_base.h b/compiler/utils/assembler_test_base.h
index ac24ee9..e7edf96 100644
--- a/compiler/utils/assembler_test_base.h
+++ b/compiler/utils/assembler_test_base.h
@@ -23,6 +23,8 @@
 #include <iterator>
 #include <sys/stat.h>
 
+#include "android-base/strings.h"
+
 #include "common_runtime_test.h"  // For ScratchFile
 #include "utils.h"
 
@@ -221,7 +223,7 @@
     args.push_back("-o");
     args.push_back(to_file);
     args.push_back(from_file);
-    std::string cmd = Join(args, ' ');
+    std::string cmd = android::base::Join(args, ' ');
 
     args.clear();
     args.push_back("/bin/sh");
@@ -257,7 +259,7 @@
     args.push_back(file);
     args.push_back(">");
     args.push_back(file+".dump");
-    std::string cmd = Join(args, ' ');
+    std::string cmd = android::base::Join(args, ' ');
 
     args.clear();
     args.push_back("/bin/sh");
@@ -338,7 +340,7 @@
     args.push_back("| sed -n \'/<.data>/,$p\' | sed -e \'s/.*://\'");
     args.push_back(">");
     args.push_back(file+".dis");
-    std::string cmd = Join(args, ' ');
+    std::string cmd = android::base::Join(args, ' ');
 
     args.clear();
     args.push_back("/bin/sh");
@@ -500,7 +502,7 @@
     std::string tmp_file = GetTmpnam();
     args.push_back(">");
     args.push_back(tmp_file);
-    std::string sh_args = Join(args, ' ');
+    std::string sh_args = android::base::Join(args, ' ');
 
     args.clear();
     args.push_back("/bin/sh");
@@ -541,7 +543,7 @@
     args.push_back("sort");
     args.push_back(">");
     args.push_back(tmp_file);
-    std::string sh_args = Join(args, ' ');
+    std::string sh_args = android::base::Join(args, ' ');
 
     args.clear();
     args.push_back("/bin/sh");
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 8fb4040..5a0f0c6 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -33,6 +33,8 @@
 #include <sys/utsname.h>
 #endif
 
+#include "android-base/strings.h"
+
 #include "arch/instruction_set_features.h"
 #include "arch/mips/instruction_set_features_mips.h"
 #include "art_method-inl.h"
@@ -96,7 +98,7 @@
   for (int i = 0; i < original_argc; ++i) {
     command.push_back(original_argv[i]);
   }
-  return Join(command, ' ');
+  return android::base::Join(command, ' ');
 }
 
 // A stripped version. Remove some less essential parameters. If we see a "--zip-fd=" parameter, be
@@ -108,7 +110,7 @@
   // Do a pre-pass to look for zip-fd.
   bool saw_zip_fd = false;
   for (int i = 0; i < original_argc; ++i) {
-    if (StartsWith(original_argv[i], "--zip-fd=")) {
+    if (android::base::StartsWith(original_argv[i], "--zip-fd=")) {
       saw_zip_fd = true;
       break;
     }
@@ -123,17 +125,17 @@
     }
 
     // Any instruction-setXXX is dropped.
-    if (StartsWith(original_argv[i], "--instruction-set")) {
+    if (android::base::StartsWith(original_argv[i], "--instruction-set")) {
       continue;
     }
 
     // The boot image is dropped.
-    if (StartsWith(original_argv[i], "--boot-image=")) {
+    if (android::base::StartsWith(original_argv[i], "--boot-image=")) {
       continue;
     }
 
     // The image format is dropped.
-    if (StartsWith(original_argv[i], "--image-format=")) {
+    if (android::base::StartsWith(original_argv[i], "--image-format=")) {
       continue;
     }
 
@@ -142,11 +144,11 @@
     // However, we prefer to drop this when we saw --zip-fd.
     if (saw_zip_fd) {
       // Drop anything --zip-X, --dex-X, --oat-X, --swap-X, or --app-image-X
-      if (StartsWith(original_argv[i], "--zip-") ||
-          StartsWith(original_argv[i], "--dex-") ||
-          StartsWith(original_argv[i], "--oat-") ||
-          StartsWith(original_argv[i], "--swap-") ||
-          StartsWith(original_argv[i], "--app-image-")) {
+      if (android::base::StartsWith(original_argv[i], "--zip-") ||
+          android::base::StartsWith(original_argv[i], "--dex-") ||
+          android::base::StartsWith(original_argv[i], "--oat-") ||
+          android::base::StartsWith(original_argv[i], "--swap-") ||
+          android::base::StartsWith(original_argv[i], "--app-image-")) {
         continue;
       }
     }
@@ -159,7 +161,7 @@
     // It seems only "/system/bin/dex2oat" is left, or not even that. Use a pretty line.
     return "Starting dex2oat.";
   }
-  return Join(command, ' ');
+  return android::base::Join(command, ' ');
 }
 
 static void UsageErrorV(const char* fmt, va_list ap) {
@@ -999,7 +1001,7 @@
       if (last_dex_dot != std::string::npos) {
         dex_file = dex_file.substr(0, last_dex_dot);
       }
-      if (StartsWith(dex_file, "core-")) {
+      if (android::base::StartsWith(dex_file, "core-")) {
         infix = dex_file.substr(strlen("core"));
       }
     }
@@ -1059,7 +1061,7 @@
         in.insert(last_dot, infix);
       }
     }
-    if (EndsWith(in, ".jar")) {
+    if (android::base::EndsWith(in, ".jar")) {
       in = in.substr(0, in.length() - strlen(".jar")) +
           (replace_suffix != nullptr ? replace_suffix : "");
     }
@@ -1484,7 +1486,7 @@
         for (const gc::space::ImageSpace* image_space : image_spaces) {
           image_filenames.push_back(image_space->GetImageFilename());
         }
-        std::string image_file_location = Join(image_filenames, ':');
+        std::string image_file_location = android::base::Join(image_filenames, ':');
         if (!image_file_location.empty()) {
           key_value_store_->Put(OatHeader::kImageLocationKey, image_file_location);
         }
@@ -1687,7 +1689,7 @@
               }
             }
 
-            if (StartsWith(dex_location, filter.c_str())) {
+            if (android::base::StartsWith(dex_location, filter.c_str())) {
               VLOG(compiler) << "Disabling inlining from " << dex_file->GetLocation();
               no_inline_from_dex_files_.push_back(dex_file);
               break;
@@ -2362,10 +2364,10 @@
     RuntimeOptions raw_options;
     if (boot_image_filename_.empty()) {
       std::string boot_class_path = "-Xbootclasspath:";
-      boot_class_path += Join(dex_filenames_, ':');
+      boot_class_path += android::base::Join(dex_filenames_, ':');
       raw_options.push_back(std::make_pair(boot_class_path, nullptr));
       std::string boot_class_path_locations = "-Xbootclasspath-locations:";
-      boot_class_path_locations += Join(dex_locations_, ':');
+      boot_class_path_locations += android::base::Join(dex_locations_, ':');
       raw_options.push_back(std::make_pair(boot_class_path_locations, nullptr));
     } else {
       std::string boot_image_option = "-Ximage:";
@@ -2579,7 +2581,7 @@
     while (in_stream.good()) {
       std::string dot;
       std::getline(in_stream, dot);
-      if (StartsWith(dot, "#") || dot.empty()) {
+      if (android::base::StartsWith(dot, "#") || dot.empty()) {
         continue;
       }
       if (process != nullptr) {
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 80c7113..e4462d8 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -26,6 +26,8 @@
 #include <unordered_set>
 #include <vector>
 
+#include "android-base/strings.h"
+
 #include "arch/instruction_set_features.h"
 #include "art_field-inl.h"
 #include "art_method-inl.h"
@@ -668,6 +670,12 @@
     }
 
   private:
+    // All of the elements from one container to another.
+    template <typename Dest, typename Src>
+    static void AddAll(Dest& dest, const Src& src) {
+      dest.insert(src.begin(), src.end());
+    }
+
     void WalkClass(const DexFile& dex_file, const DexFile::ClassDef& class_def) {
       const uint8_t* class_data = dex_file.GetClassData(class_def);
       if (class_data == nullptr) {  // empty class such as a marker interface?
@@ -2952,7 +2960,7 @@
           table_index++;
 
           std::string p_name = ptr2->PrettyMethod(true);
-          if (StartsWith(p_name, method.c_str())) {
+          if (android::base::StartsWith(p_name, method.c_str())) {
             std::cerr << "  Slot "
                       << index
                       << " ("
@@ -2965,7 +2973,7 @@
         }
       } else {
         std::string p_name = ptr->PrettyMethod(true);
-        if (StartsWith(p_name, method.c_str())) {
+        if (android::base::StartsWith(p_name, method.c_str())) {
           std::cerr << "  Slot " << index << " (1)" << std::endl;
           std::cerr << "    " << p_name << std::endl;
         } else {
@@ -2978,7 +2986,7 @@
               for (ArtMethod& iface_method : iface->GetMethods(pointer_size)) {
                 if (ImTable::GetImtIndex(&iface_method) == index) {
                   std::string i_name = iface_method.PrettyMethod(true);
-                  if (StartsWith(i_name, method.c_str())) {
+                  if (android::base::StartsWith(i_name, method.c_str())) {
                     std::cerr << "  Slot " << index << " (1)" << std::endl;
                     std::cerr << "    " << p_name << " (" << i_name << ")" << std::endl;
                   }
@@ -2997,7 +3005,7 @@
     while (in_stream.good()) {
       std::string dot;
       std::getline(in_stream, dot);
-      if (StartsWith(dot, "#") || dot.empty()) {
+      if (android::base::StartsWith(dot, "#") || dot.empty()) {
         continue;
       }
       output.push_back(dot);
diff --git a/oatdump/oatdump_test.cc b/oatdump/oatdump_test.cc
index 22db818..a2eba45 100644
--- a/oatdump/oatdump_test.cc
+++ b/oatdump/oatdump_test.cc
@@ -18,6 +18,8 @@
 #include <string>
 #include <vector>
 
+#include "android-base/strings.h"
+
 #include "common_runtime_test.h"
 
 #include "base/stringprintf.h"
@@ -143,7 +145,7 @@
       }
       argv.push_back(nullptr);
       UNUSED(execv(argv[0], &argv[0]));
-      const std::string command_line(Join(exec_argv, ' '));
+      const std::string command_line(android::base::Join(exec_argv, ' '));
       PLOG(ERROR) << "Failed to execv(" << command_line << ")";
       // _exit to avoid atexit handlers in child.
       _exit(1);
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index cb5a790..62d1ddf 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -24,6 +24,8 @@
 #include <string>
 #include <vector>
 
+#include "android-base/strings.h"
+
 #include "art_field-inl.h"
 #include "art_method-inl.h"
 #include "base/dumpable.h"
@@ -286,8 +288,8 @@
       std::string converted_image_filename = space->GetImageLocation();
       std::replace(converted_image_filename.begin() + 1, converted_image_filename.end(), '/', '@');
       std::string output_image_filename = output_directory +
-                                          (StartsWith(converted_image_filename, "/") ? "" : "/") +
-                                          converted_image_filename;
+          (android::base::StartsWith(converted_image_filename, "/") ? "" : "/") +
+          converted_image_filename;
       std::string output_vdex_filename =
           ImageHeader::GetVdexLocationFromImageLocation(output_image_filename);
       std::string output_oat_filename =
@@ -343,8 +345,8 @@
     std::string converted_image_filename = space->GetImageLocation();
     std::replace(converted_image_filename.begin() + 1, converted_image_filename.end(), '/', '@');
     std::string output_image_filename = output_directory +
-                                        (StartsWith(converted_image_filename, "/") ? "" : "/") +
-                                        converted_image_filename;
+        (android::base::StartsWith(converted_image_filename, "/") ? "" : "/") +
+        converted_image_filename;
     bool new_oat_out;
     std::unique_ptr<File>
         output_image_file(CreateOrOpen(output_image_filename.c_str(), &new_oat_out));
@@ -932,7 +934,7 @@
   for (int i = 0; i < orig_argc; ++i) {
     command.push_back(orig_argv[i]);
   }
-  return Join(command, ' ');
+  return android::base::Join(command, ' ');
 }
 
 static void UsageErrorV(const char* fmt, va_list ap) {
diff --git a/profman/profman.cc b/profman/profman.cc
index bfef834..0b2d172 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -25,6 +25,8 @@
 #include <string>
 #include <vector>
 
+#include "android-base/strings.h"
+
 #include "base/dumpable.h"
 #include "base/scoped_flock.h"
 #include "base/stringpiece.h"
@@ -48,7 +50,7 @@
   for (int i = 0; i < original_argc; ++i) {
     command.push_back(original_argv[i]);
   }
-  return Join(command, ' ');
+  return android::base::Join(command, ' ');
 }
 
 static constexpr int kInvalidFd = -1;
diff --git a/runtime/arch/arm/instruction_set_features_arm.cc b/runtime/arch/arm/instruction_set_features_arm.cc
index c81a93c..f264b82 100644
--- a/runtime/arch/arm/instruction_set_features_arm.cc
+++ b/runtime/arch/arm/instruction_set_features_arm.cc
@@ -24,6 +24,8 @@
 #include "signal.h"
 #include <fstream>
 
+#include "android-base/strings.h"
+
 #include "base/stringprintf.h"
 #include "utils.h"  // For Trim.
 
@@ -271,7 +273,7 @@
   bool has_atomic_ldrd_strd = has_atomic_ldrd_strd_;
   bool has_div = has_div_;
   for (auto i = features.begin(); i != features.end(); i++) {
-    std::string feature = Trim(*i);
+    std::string feature = android::base::Trim(*i);
     if (feature == "div") {
       has_div = true;
     } else if (feature == "-div") {
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.cc b/runtime/arch/arm64/instruction_set_features_arm64.cc
index 4e7dea3..f7b5a76 100644
--- a/runtime/arch/arm64/instruction_set_features_arm64.cc
+++ b/runtime/arch/arm64/instruction_set_features_arm64.cc
@@ -19,6 +19,8 @@
 #include <fstream>
 #include <sstream>
 
+#include "android-base/strings.h"
+
 #include "base/stl_util.h"
 #include "base/stringprintf.h"
 #include "utils.h"  // For Trim.
@@ -137,7 +139,7 @@
     const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
   bool is_a53 = fix_cortex_a53_835769_;
   for (auto i = features.begin(); i != features.end(); i++) {
-    std::string feature = Trim(*i);
+    std::string feature = android::base::Trim(*i);
     if (feature == "a53") {
       is_a53 = true;
     } else if (feature == "-a53") {
diff --git a/runtime/arch/instruction_set_features.cc b/runtime/arch/instruction_set_features.cc
index b32391f..db004e7 100644
--- a/runtime/arch/instruction_set_features.cc
+++ b/runtime/arch/instruction_set_features.cc
@@ -16,6 +16,8 @@
 
 #include "instruction_set_features.h"
 
+#include "android-base/strings.h"
+
 #include "base/casts.h"
 #include "utils.h"
 
@@ -224,7 +226,7 @@
       *error_msg = "Unexpected instruction set features after 'default'";
       return std::unique_ptr<const InstructionSetFeatures>();
     }
-    std::string feature = Trim(*it);
+    std::string feature = android::base::Trim(*it);
     bool erase = false;
     if (feature == "default") {
       if (!first) {
diff --git a/runtime/arch/mips/instruction_set_features_mips.cc b/runtime/arch/mips/instruction_set_features_mips.cc
index a95b6f6..a65c967 100644
--- a/runtime/arch/mips/instruction_set_features_mips.cc
+++ b/runtime/arch/mips/instruction_set_features_mips.cc
@@ -19,6 +19,8 @@
 #include <fstream>
 #include <sstream>
 
+#include "android-base/strings.h"
+
 #include "base/stl_util.h"
 #include "base/stringprintf.h"
 #include "utils.h"  // For Trim.
@@ -210,7 +212,7 @@
   bool mips_isa_gte2 = mips_isa_gte2_;
   bool r6 = r6_;
   for (auto i = features.begin(); i != features.end(); i++) {
-    std::string feature = Trim(*i);
+    std::string feature = android::base::Trim(*i);
     if (feature == "fpu32") {
       fpu_32bit = true;
     } else if (feature == "-fpu32") {
diff --git a/runtime/arch/mips64/instruction_set_features_mips64.cc b/runtime/arch/mips64/instruction_set_features_mips64.cc
index 490a8d2..e564d1e 100644
--- a/runtime/arch/mips64/instruction_set_features_mips64.cc
+++ b/runtime/arch/mips64/instruction_set_features_mips64.cc
@@ -19,6 +19,8 @@
 #include <fstream>
 #include <sstream>
 
+#include "android-base/strings.h"
+
 #include "base/stringprintf.h"
 #include "utils.h"  // For Trim.
 
@@ -105,7 +107,7 @@
   auto i = features.begin();
   if (i != features.end()) {
     // We don't have any features.
-    std::string feature = Trim(*i);
+    std::string feature = android::base::Trim(*i);
     *error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str());
     return nullptr;
   }
diff --git a/runtime/arch/x86/instruction_set_features_x86.cc b/runtime/arch/x86/instruction_set_features_x86.cc
index 90b55a9..cc102ec 100644
--- a/runtime/arch/x86/instruction_set_features_x86.cc
+++ b/runtime/arch/x86/instruction_set_features_x86.cc
@@ -19,6 +19,8 @@
 #include <fstream>
 #include <sstream>
 
+#include "android-base/strings.h"
+
 #include "arch/x86_64/instruction_set_features_x86_64.h"
 #include "base/stringprintf.h"
 #include "utils.h"  // For Trim.
@@ -293,7 +295,7 @@
   bool has_AVX2 = has_AVX2_;
   bool has_POPCNT = has_POPCNT_;
   for (auto i = features.begin(); i != features.end(); i++) {
-    std::string feature = Trim(*i);
+    std::string feature = android::base::Trim(*i);
     if (feature == "ssse3") {
       has_SSSE3 = true;
     } else if (feature == "-ssse3") {
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 862585a..685677b 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -19,6 +19,8 @@
 #include <memory>
 #include <string>
 
+#include "android-base/strings.h"
+
 #include "art_field-inl.h"
 #include "art_method-inl.h"
 #include "base/enums.h"
@@ -800,12 +802,12 @@
   jobject jclass_loader = LoadDex("Nested");
   std::vector<const DexFile*> dex_files(GetDexFiles(jclass_loader));
   ASSERT_EQ(dex_files.size(), 1U);
-  EXPECT_TRUE(EndsWith(dex_files[0]->GetLocation(), "Nested.jar"));
+  EXPECT_TRUE(android::base::EndsWith(dex_files[0]->GetLocation(), "Nested.jar"));
 
   jobject jclass_loader2 = LoadDex("MultiDex");
   std::vector<const DexFile*> dex_files2(GetDexFiles(jclass_loader2));
   ASSERT_EQ(dex_files2.size(), 2U);
-  EXPECT_TRUE(EndsWith(dex_files2[0]->GetLocation(), "MultiDex.jar"));
+  EXPECT_TRUE(android::base::EndsWith(dex_files2[0]->GetLocation(), "MultiDex.jar"));
 }
 
 TEST_F(ClassLinkerTest, FindClassNested) {
diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc
index 2ea7bb6..ee0f340 100644
--- a/runtime/elf_file.cc
+++ b/runtime/elf_file.cc
@@ -20,6 +20,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "android-base/strings.h"
+
 #include "arch/instruction_set.h"
 #include "base/logging.h"
 #include "base/stringprintf.h"
@@ -1451,7 +1453,7 @@
       section_headers_original_indexes.push_back(0);
       continue;
     }
-    if (StartsWith(name, ".debug")
+    if (android::base::StartsWith(name, ".debug")
         || (strcmp(name, ".strtab") == 0)
         || (strcmp(name, ".symtab") == 0)) {
       continue;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index c726944..76f3692 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -22,6 +22,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "android-base/strings.h"
+
 #include "art_method.h"
 #include "base/enums.h"
 #include "base/macros.h"
@@ -137,7 +139,7 @@
     arg_vector.push_back(compiler_options[i].c_str());
   }
 
-  std::string command_line(Join(arg_vector, ' '));
+  std::string command_line(android::base::Join(arg_vector, ' '));
   LOG(INFO) << "GenerateImage: " << command_line;
   return Exec(arg_vector, error_msg);
 }
@@ -257,7 +259,7 @@
   argv.push_back(instruction_set_arg);
   argv.push_back(base_offset_arg);
 
-  std::string command_line(Join(argv, ' '));
+  std::string command_line(android::base::Join(argv, ' '));
   LOG(INFO) << "RelocateImage: " << command_line;
   return Exec(argv, error_msg);
 }
diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc
index 11d601e..025d10c 100644
--- a/runtime/jit/profile_saver.cc
+++ b/runtime/jit/profile_saver.cc
@@ -20,6 +20,8 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
+#include "android-base/strings.h"
+
 #include "art_method-inl.h"
 #include "base/enums.h"
 #include "base/systrace.h"
@@ -412,7 +414,7 @@
   }
 
   VLOG(profiler) << "Starting profile saver using output file: " << output_filename
-      << ". Tracking: " << Join(code_paths_to_profile, ':');
+      << ". Tracking: " << android::base::Join(code_paths_to_profile, ':');
 
   instance_ = new ProfileSaver(options,
                                output_filename,
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 6a62a16..7f7b1b5 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -19,6 +19,9 @@
 #include <sstream>
 
 #include <sys/stat.h>
+
+#include "android-base/strings.h"
+
 #include "base/logging.h"
 #include "base/stringprintf.h"
 #include "compiler_filter.h"
@@ -456,7 +459,7 @@
   argv.push_back("--output-oat-file=" + oat_file_name);
   argv.push_back("--patched-image-location=" + image_info->location);
 
-  std::string command_line(Join(argv, ' '));
+  std::string command_line(android::base::Join(argv, ' '));
   if (!Exec(argv, error_msg)) {
     // Manually delete the file. This ensures there is no garbage left over if
     // the process unexpectedly died.
@@ -605,7 +608,7 @@
 
   argv.insert(argv.end(), args.begin(), args.end());
 
-  std::string command_line(Join(argv, ' '));
+  std::string command_line(android::base::Join(argv, ' '));
   return Exec(argv, error_msg);
 }
 
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 94c12af..26dbaab 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -20,6 +20,7 @@
 #include <vector>
 #include <sys/param.h>
 
+#include "android-base/strings.h"
 #include <backtrace/BacktraceMap.h>
 #include <gtest/gtest.h>
 
@@ -1057,7 +1058,7 @@
 
   // Reverse again to get the right path order, and join to get the result.
   std::reverse(target_path.begin(), target_path.end());
-  return Join(target_path, '/');
+  return android::base::Join(target_path, '/');
 }
 
 // Case: Non-absolute path to Dex location.
@@ -1134,7 +1135,7 @@
         /*dex_elements*/nullptr,
         &oat_file,
         &error_msgs);
-    CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
+    CHECK(!dex_files.empty()) << android::base::Join(error_msgs, '\n');
     CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
     loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
     CHECK_EQ(loaded_oat_file_, oat_file);
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 14628f0..59c5961 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -37,6 +37,8 @@
 #include <vector>
 #include <fcntl.h>
 
+#include "android-base/strings.h"
+
 #include "JniConstants.h"
 #include "ScopedLocalRef.h"
 #include "arch/arm/quick_method_frame_info_arm.h"
@@ -869,7 +871,7 @@
         ImageHeader::GetOatLocationFromImageLocation(image_locations[index].c_str());
     // Note: in the multi-image case, the image location may end in ".jar," and not ".art." Handle
     //       that here.
-    if (EndsWith(oat_location, ".jar")) {
+    if (android::base::EndsWith(oat_location, ".jar")) {
       oat_location.replace(oat_location.length() - 3, 3, "oat");
     }
     std::string error_msg;
@@ -1225,7 +1227,7 @@
       for (const DexFile* dex_file : boot_class_path) {
         dex_locations.push_back(dex_file->GetLocation());
       }
-      boot_class_path_string_ = Join(dex_locations, ':');
+      boot_class_path_string_ = android::base::Join(dex_locations, ':');
     }
     {
       ScopedTrace trace2("AddImageStringsToTable");
@@ -1892,7 +1894,7 @@
   }
 
   VLOG(profiler) << "Register app with " << profile_output_filename
-      << " " << Join(code_paths, ':');
+      << " " << android::base::Join(code_paths, ':');
 
   if (profile_output_filename.empty()) {
     LOG(WARNING) << "JIT profile information will not be recorded: profile filename is empty.";
diff --git a/runtime/thread.cc b/runtime/thread.cc
index bc133d1..d79bf36 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -873,6 +873,62 @@
   Dbg::DdmSendThreadNotification(this, CHUNK_TYPE("THNM"));
 }
 
+static void GetThreadStack(pthread_t thread,
+                           void** stack_base,
+                           size_t* stack_size,
+                           size_t* guard_size) {
+#if defined(__APPLE__)
+  *stack_size = pthread_get_stacksize_np(thread);
+  void* stack_addr = pthread_get_stackaddr_np(thread);
+
+  // Check whether stack_addr is the base or end of the stack.
+  // (On Mac OS 10.7, it's the end.)
+  int stack_variable;
+  if (stack_addr > &stack_variable) {
+    *stack_base = reinterpret_cast<uint8_t*>(stack_addr) - *stack_size;
+  } else {
+    *stack_base = stack_addr;
+  }
+
+  // This is wrong, but there doesn't seem to be a way to get the actual value on the Mac.
+  pthread_attr_t attributes;
+  CHECK_PTHREAD_CALL(pthread_attr_init, (&attributes), __FUNCTION__);
+  CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
+  CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
+#else
+  pthread_attr_t attributes;
+  CHECK_PTHREAD_CALL(pthread_getattr_np, (thread, &attributes), __FUNCTION__);
+  CHECK_PTHREAD_CALL(pthread_attr_getstack, (&attributes, stack_base, stack_size), __FUNCTION__);
+  CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
+  CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
+
+#if defined(__GLIBC__)
+  // If we're the main thread, check whether we were run with an unlimited stack. In that case,
+  // glibc will have reported a 2GB stack for our 32-bit process, and our stack overflow detection
+  // will be broken because we'll die long before we get close to 2GB.
+  bool is_main_thread = (::art::GetTid() == getpid());
+  if (is_main_thread) {
+    rlimit stack_limit;
+    if (getrlimit(RLIMIT_STACK, &stack_limit) == -1) {
+      PLOG(FATAL) << "getrlimit(RLIMIT_STACK) failed";
+    }
+    if (stack_limit.rlim_cur == RLIM_INFINITY) {
+      size_t old_stack_size = *stack_size;
+
+      // Use the kernel default limit as our size, and adjust the base to match.
+      *stack_size = 8 * MB;
+      *stack_base = reinterpret_cast<uint8_t*>(*stack_base) + (old_stack_size - *stack_size);
+
+      VLOG(threads) << "Limiting unlimited stack (reported as " << PrettySize(old_stack_size) << ")"
+                    << " to " << PrettySize(*stack_size)
+                    << " with base " << *stack_base;
+    }
+  }
+#endif
+
+#endif
+}
+
 bool Thread::InitStackHwm() {
   void* read_stack_base;
   size_t read_stack_size;
@@ -1322,6 +1378,32 @@
   VLOG(threads) << this << " self-reviving";
 }
 
+static std::string GetSchedulerGroupName(pid_t tid) {
+  // /proc/<pid>/cgroup looks like this:
+  // 2:devices:/
+  // 1:cpuacct,cpu:/
+  // We want the third field from the line whose second field contains the "cpu" token.
+  std::string cgroup_file;
+  if (!ReadFileToString(StringPrintf("/proc/self/task/%d/cgroup", tid), &cgroup_file)) {
+    return "";
+  }
+  std::vector<std::string> cgroup_lines;
+  Split(cgroup_file, '\n', &cgroup_lines);
+  for (size_t i = 0; i < cgroup_lines.size(); ++i) {
+    std::vector<std::string> cgroup_fields;
+    Split(cgroup_lines[i], ':', &cgroup_fields);
+    std::vector<std::string> cgroups;
+    Split(cgroup_fields[1], ',', &cgroups);
+    for (size_t j = 0; j < cgroups.size(); ++j) {
+      if (cgroups[j] == "cpu") {
+        return cgroup_fields[2].substr(1);  // Skip the leading slash.
+      }
+    }
+  }
+  return "";
+}
+
+
 void Thread::DumpState(std::ostream& os, const Thread* thread, pid_t tid) {
   std::string group_name;
   int priority;
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 66739a9..4732f59 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -25,6 +25,8 @@
 #include <unistd.h>
 #include <memory>
 
+#include "android-base/strings.h"
+
 #include "base/stl_util.h"
 #include "base/unix_file/fd_file.h"
 #include "dex_file-inl.h"
@@ -139,59 +141,6 @@
   return result;
 }
 
-void GetThreadStack(pthread_t thread, void** stack_base, size_t* stack_size, size_t* guard_size) {
-#if defined(__APPLE__)
-  *stack_size = pthread_get_stacksize_np(thread);
-  void* stack_addr = pthread_get_stackaddr_np(thread);
-
-  // Check whether stack_addr is the base or end of the stack.
-  // (On Mac OS 10.7, it's the end.)
-  int stack_variable;
-  if (stack_addr > &stack_variable) {
-    *stack_base = reinterpret_cast<uint8_t*>(stack_addr) - *stack_size;
-  } else {
-    *stack_base = stack_addr;
-  }
-
-  // This is wrong, but there doesn't seem to be a way to get the actual value on the Mac.
-  pthread_attr_t attributes;
-  CHECK_PTHREAD_CALL(pthread_attr_init, (&attributes), __FUNCTION__);
-  CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
-  CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
-#else
-  pthread_attr_t attributes;
-  CHECK_PTHREAD_CALL(pthread_getattr_np, (thread, &attributes), __FUNCTION__);
-  CHECK_PTHREAD_CALL(pthread_attr_getstack, (&attributes, stack_base, stack_size), __FUNCTION__);
-  CHECK_PTHREAD_CALL(pthread_attr_getguardsize, (&attributes, guard_size), __FUNCTION__);
-  CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
-
-#if defined(__GLIBC__)
-  // If we're the main thread, check whether we were run with an unlimited stack. In that case,
-  // glibc will have reported a 2GB stack for our 32-bit process, and our stack overflow detection
-  // will be broken because we'll die long before we get close to 2GB.
-  bool is_main_thread = (::art::GetTid() == getpid());
-  if (is_main_thread) {
-    rlimit stack_limit;
-    if (getrlimit(RLIMIT_STACK, &stack_limit) == -1) {
-      PLOG(FATAL) << "getrlimit(RLIMIT_STACK) failed";
-    }
-    if (stack_limit.rlim_cur == RLIM_INFINITY) {
-      size_t old_stack_size = *stack_size;
-
-      // Use the kernel default limit as our size, and adjust the base to match.
-      *stack_size = 8 * MB;
-      *stack_base = reinterpret_cast<uint8_t*>(*stack_base) + (old_stack_size - *stack_size);
-
-      VLOG(threads) << "Limiting unlimited stack (reported as " << PrettySize(old_stack_size) << ")"
-                    << " to " << PrettySize(*stack_size)
-                    << " with base " << *stack_base;
-    }
-  }
-#endif
-
-#endif
-}
-
 bool ReadFileToString(const std::string& file_name, std::string* result) {
   File file(file_name, O_RDONLY, false);
   if (!file.IsOpened()) {
@@ -411,6 +360,10 @@
                       negative_str, byte_count / kBytesPerUnit[i], kUnitStrings[i]);
 }
 
+static inline constexpr bool NeedsEscaping(uint16_t ch) {
+  return (ch < ' ' || ch > '~');
+}
+
 std::string PrintableChar(uint16_t ch) {
   std::string result;
   result += '\'';
@@ -782,67 +735,6 @@
   }
 }
 
-std::string Trim(const std::string& s) {
-  std::string result;
-  unsigned int start_index = 0;
-  unsigned int end_index = s.size() - 1;
-
-  // Skip initial whitespace.
-  while (start_index < s.size()) {
-    if (!isspace(s[start_index])) {
-      break;
-    }
-    start_index++;
-  }
-
-  // Skip terminating whitespace.
-  while (end_index >= start_index) {
-    if (!isspace(s[end_index])) {
-      break;
-    }
-    end_index--;
-  }
-
-  // All spaces, no beef.
-  if (end_index < start_index) {
-    return "";
-  }
-  // Start_index is the first non-space, end_index is the last one.
-  return s.substr(start_index, end_index - start_index + 1);
-}
-
-template <typename StringT>
-std::string Join(const std::vector<StringT>& strings, char separator) {
-  if (strings.empty()) {
-    return "";
-  }
-
-  std::string result(strings[0]);
-  for (size_t i = 1; i < strings.size(); ++i) {
-    result += separator;
-    result += strings[i];
-  }
-  return result;
-}
-
-// Explicit instantiations.
-template std::string Join<std::string>(const std::vector<std::string>& strings, char separator);
-template std::string Join<const char*>(const std::vector<const char*>& strings, char separator);
-
-bool StartsWith(const std::string& s, const char* prefix) {
-  return s.compare(0, strlen(prefix), prefix) == 0;
-}
-
-bool EndsWith(const std::string& s, const char* suffix) {
-  size_t suffix_length = strlen(suffix);
-  size_t string_length = s.size();
-  if (suffix_length > string_length) {
-    return false;
-  }
-  size_t offset = string_length - suffix_length;
-  return s.compare(offset, suffix_length, suffix) == 0;
-}
-
 void SetThreadName(const char* thread_name) {
   int hasAt = 0;
   int hasDot = 0;
@@ -892,31 +784,6 @@
   *task_cpu = strtoull(fields[36].c_str(), nullptr, 10);
 }
 
-std::string GetSchedulerGroupName(pid_t tid) {
-  // /proc/<pid>/cgroup looks like this:
-  // 2:devices:/
-  // 1:cpuacct,cpu:/
-  // We want the third field from the line whose second field contains the "cpu" token.
-  std::string cgroup_file;
-  if (!ReadFileToString(StringPrintf("/proc/self/task/%d/cgroup", tid), &cgroup_file)) {
-    return "";
-  }
-  std::vector<std::string> cgroup_lines;
-  Split(cgroup_file, '\n', &cgroup_lines);
-  for (size_t i = 0; i < cgroup_lines.size(); ++i) {
-    std::vector<std::string> cgroup_fields;
-    Split(cgroup_lines[i], ':', &cgroup_fields);
-    std::vector<std::string> cgroups;
-    Split(cgroup_fields[1], ',', &cgroups);
-    for (size_t j = 0; j < cgroups.size(); ++j) {
-      if (cgroups[j] == "cpu") {
-        return cgroup_fields[2].substr(1);  // Skip the leading slash.
-      }
-    }
-  }
-  return "";
-}
-
 const char* GetAndroidRoot() {
   const char* android_root = getenv("ANDROID_ROOT");
   if (android_root == nullptr) {
@@ -1005,7 +872,9 @@
     return false;
   }
   std::string cache_file(&location[1]);  // skip leading slash
-  if (!EndsWith(location, ".dex") && !EndsWith(location, ".art") && !EndsWith(location, ".oat")) {
+  if (!android::base::EndsWith(location, ".dex") &&
+      !android::base::EndsWith(location, ".art") &&
+      !android::base::EndsWith(location, ".oat")) {
     cache_file += "/";
     cache_file += DexFile::kClassesDex;
   }
@@ -1032,7 +901,7 @@
 }
 
 int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg) {
-  const std::string command_line(Join(arg_vector, ' '));
+  const std::string command_line(android::base::Join(arg_vector, ' '));
   CHECK_GE(arg_vector.size(), 1U) << command_line;
 
   // Convert the args to char pointers.
@@ -1091,7 +960,7 @@
 bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg) {
   int status = ExecAndReturnCode(arg_vector, error_msg);
   if (status != 0) {
-    const std::string command_line(Join(arg_vector, ' '));
+    const std::string command_line(android::base::Join(arg_vector, ' '));
     *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
                               command_line.c_str());
     return false;
diff --git a/runtime/utils.h b/runtime/utils.h
index 1e98057..04e0dde 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -64,45 +64,12 @@
   return true;
 }
 
-// Return whether x / divisor == x * (1.0f / divisor), for every float x.
-static constexpr bool CanDivideByReciprocalMultiplyFloat(int32_t divisor) {
-  // True, if the most significant bits of divisor are 0.
-  return ((divisor & 0x7fffff) == 0);
-}
-
-// Return whether x / divisor == x * (1.0 / divisor), for every double x.
-static constexpr bool CanDivideByReciprocalMultiplyDouble(int64_t divisor) {
-  // True, if the most significant bits of divisor are 0.
-  return ((divisor & ((UINT64_C(1) << 52) - 1)) == 0);
-}
-
 static inline uint32_t PointerToLowMemUInt32(const void* p) {
   uintptr_t intp = reinterpret_cast<uintptr_t>(p);
   DCHECK_LE(intp, 0xFFFFFFFFU);
   return intp & 0xFFFFFFFFU;
 }
 
-static inline bool NeedsEscaping(uint16_t ch) {
-  return (ch < ' ' || ch > '~');
-}
-
-template <typename T> T SafeAbs(T value) {
-  // std::abs has undefined behavior on min limits.
-  DCHECK_NE(value, std::numeric_limits<T>::min());
-  return std::abs(value);
-}
-
-template <typename T> T AbsOrMin(T value) {
-  return (value == std::numeric_limits<T>::min())
-      ? value
-      : std::abs(value);
-}
-
-template <typename T>
-inline typename std::make_unsigned<T>::type MakeUnsigned(T x) {
-  return static_cast<typename std::make_unsigned<T>::type>(x);
-}
-
 uint8_t* DecodeBase64(const char* src, size_t* dst_size);
 
 std::string PrintableChar(uint16_t ch);
@@ -111,12 +78,6 @@
 // Java escapes are used for non-ASCII characters.
 std::string PrintableString(const char* utf8);
 
-// Tests whether 's' starts with 'prefix'.
-bool StartsWith(const std::string& s, const char* prefix);
-
-// Tests whether 's' ends with 'suffix'.
-bool EndsWith(const std::string& s, const char* suffix);
-
 // Used to implement PrettyClass, PrettyField, PrettyMethod, and PrettyTypeOf,
 // one of which is probably more useful to you.
 // Returns a human-readable equivalent of 'descriptor'. So "I" would be "int",
@@ -167,27 +128,15 @@
 // strings. Empty strings will be omitted.
 void Split(const std::string& s, char separator, std::vector<std::string>* result);
 
-// Trims whitespace off both ends of the given string.
-std::string Trim(const std::string& s);
-
-// Joins a vector of strings into a single string, using the given separator.
-template <typename StringT> std::string Join(const std::vector<StringT>& strings, char separator);
-
 // Returns the calling thread's tid. (The C libraries don't expose this.)
 pid_t GetTid();
 
 // Returns the given thread's name.
 std::string GetThreadName(pid_t tid);
 
-// Returns details of the given thread's stack.
-void GetThreadStack(pthread_t thread, void** stack_base, size_t* stack_size, size_t* guard_size);
-
 // Reads data from "/proc/self/task/${tid}/stat".
 void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu);
 
-// Returns the name of the scheduler group for the given thread the current process, or the empty string.
-std::string GetSchedulerGroupName(pid_t tid);
-
 // Sets the name of the current thread. The name may be truncated to an
 // implementation-defined limit.
 void SetThreadName(const char* thread_name);
@@ -251,15 +200,6 @@
   }
 };
 
-template <typename Vector>
-void Push32(Vector* buf, int32_t data) {
-  static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-  buf->push_back(data & 0xff);
-  buf->push_back((data >> 8) & 0xff);
-  buf->push_back((data >> 16) & 0xff);
-  buf->push_back((data >> 24) & 0xff);
-}
-
 inline bool TestBitmap(size_t idx, const uint8_t* bitmap) {
   return ((bitmap[idx / kBitsPerByte] >> (idx % kBitsPerByte)) & 0x01) != 0;
 }
@@ -334,12 +274,6 @@
   return dist(rng);
 }
 
-// All of the elements from one container to another.
-template <typename Dest, typename Src>
-static void AddAll(Dest& dest, const Src& src) {
-  dest.insert(src.begin(), src.end());
-}
-
 // Return the file size in bytes or -1 if the file does not exists.
 int64_t GetFileSizeBytes(const std::string& filename);
 
diff --git a/runtime/utils_test.cc b/runtime/utils_test.cc
index be4d394..82d92fc 100644
--- a/runtime/utils_test.cc
+++ b/runtime/utils_test.cc
@@ -273,58 +273,6 @@
   EXPECT_EQ(expected, actual);
 }
 
-TEST_F(UtilsTest, Join) {
-  std::vector<std::string> strings;
-
-  strings.clear();
-  EXPECT_EQ("", Join(strings, ':'));
-
-  strings.clear();
-  strings.push_back("foo");
-  EXPECT_EQ("foo", Join(strings, ':'));
-
-  strings.clear();
-  strings.push_back("");
-  strings.push_back("foo");
-  EXPECT_EQ(":foo", Join(strings, ':'));
-
-  strings.clear();
-  strings.push_back("foo");
-  strings.push_back("");
-  EXPECT_EQ("foo:", Join(strings, ':'));
-
-  strings.clear();
-  strings.push_back("");
-  strings.push_back("foo");
-  strings.push_back("");
-  EXPECT_EQ(":foo:", Join(strings, ':'));
-
-  strings.clear();
-  strings.push_back("foo");
-  strings.push_back("bar");
-  EXPECT_EQ("foo:bar", Join(strings, ':'));
-
-  strings.clear();
-  strings.push_back("foo");
-  strings.push_back("bar");
-  strings.push_back("baz");
-  EXPECT_EQ("foo:bar:baz", Join(strings, ':'));
-}
-
-TEST_F(UtilsTest, StartsWith) {
-  EXPECT_FALSE(StartsWith("foo", "bar"));
-  EXPECT_TRUE(StartsWith("foo", "foo"));
-  EXPECT_TRUE(StartsWith("food", "foo"));
-  EXPECT_FALSE(StartsWith("fo", "foo"));
-}
-
-TEST_F(UtilsTest, EndsWith) {
-  EXPECT_FALSE(EndsWith("foo", "bar"));
-  EXPECT_TRUE(EndsWith("foo", "foo"));
-  EXPECT_TRUE(EndsWith("foofoo", "foo"));
-  EXPECT_FALSE(EndsWith("oo", "foo"));
-}
-
 TEST_F(UtilsTest, GetDalvikCacheFilename) {
   std::string name;
   std::string error;
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index 52be2df..be5c18b 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -19,6 +19,8 @@
 #include <stdio.h>
 #include <memory>
 
+#include "android-base/strings.h"
+
 #include "class_linker-inl.h"
 #include "common_runtime_test.h"
 #include "dex_file.h"
@@ -42,7 +44,7 @@
     MethodVerifier::FailureKind failure = MethodVerifier::VerifyClass(
         self, klass, nullptr, true, HardFailLogMode::kLogWarning, &error_msg);
 
-    if (StartsWith(descriptor, "Ljava/lang/invoke")) {
+    if (android::base::StartsWith(descriptor, "Ljava/lang/invoke")) {
       ASSERT_TRUE(failure == MethodVerifier::kSoftFailure ||
                   failure == MethodVerifier::kNoFailure) << error_msg;