Replace StringPiece with std::string_view.

This replaces the last few StringPiece uses and removes
the stringpiece.h.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 123750182
Change-Id: I1bb5d05df47319b6ca386db01e14ce048ae54daf
diff --git a/cmdline/cmdline.h b/cmdline/cmdline.h
index 81a2179..90be30b 100644
--- a/cmdline/cmdline.h
+++ b/cmdline/cmdline.h
@@ -23,13 +23,14 @@
 #include <fstream>
 #include <iostream>
 #include <string>
+#include <string_view>
 
 #include "android-base/stringprintf.h"
 
 #include "base/file_utils.h"
 #include "base/logging.h"
 #include "base/mutex.h"
-#include "base/stringpiece.h"
+#include "base/string_view_cpp20.h"
 #include "noop_compiler_callbacks.h"
 #include "runtime.h"
 
@@ -151,14 +152,15 @@
 
     std::string error_msg;
     for (int i = 0; i < argc; i++) {
-      const StringPiece option(argv[i]);
-      if (option.starts_with("--boot-image=")) {
-        boot_image_location_ = option.substr(strlen("--boot-image=")).data();
-      } else if (option.starts_with("--instruction-set=")) {
-        StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data();
-        instruction_set_ = GetInstructionSetFromString(instruction_set_str.data());
+      const char* const raw_option = argv[i];
+      const std::string_view option(raw_option);
+      if (StartsWith(option, "--boot-image=")) {
+        boot_image_location_ = raw_option + strlen("--boot-image=");
+      } else if (StartsWith(option, "--instruction-set=")) {
+        const char* const instruction_set_str = raw_option + strlen("--instruction-set=");
+        instruction_set_ = GetInstructionSetFromString(instruction_set_str);
         if (instruction_set_ == InstructionSet::kNone) {
-          fprintf(stderr, "Unsupported instruction set %s\n", instruction_set_str.data());
+          fprintf(stderr, "Unsupported instruction set %s\n", instruction_set_str);
           PrintUsage();
           return false;
         }
@@ -170,8 +172,8 @@
         }
         ++i;
         runtime_args_.push_back(argv[i]);
-      } else if (option.starts_with("--output=")) {
-        output_name_ = option.substr(strlen("--output=")).ToString();
+      } else if (StartsWith(option, "--output=")) {
+        output_name_ = std::string(option.substr(strlen("--output=")));
         const char* filename = output_name_.c_str();
         out_.reset(new std::ofstream(filename));
         if (!out_->good()) {
@@ -181,7 +183,7 @@
         }
         os_ = out_.get();
       } else {
-        ParseStatus parse_status = ParseCustom(option, &error_msg);
+        ParseStatus parse_status = ParseCustom(raw_option, option.length(), &error_msg);
 
         if (parse_status == kParseUnknownArgument) {
           fprintf(stderr, "Unknown argument %s\n", option.data());
@@ -315,7 +317,8 @@
   }
 
  protected:
-  virtual ParseStatus ParseCustom(const StringPiece& option ATTRIBUTE_UNUSED,
+  virtual ParseStatus ParseCustom(const char* raw_option ATTRIBUTE_UNUSED,
+                                  size_t raw_option_length ATTRIBUTE_UNUSED,
                                   std::string* error_msg ATTRIBUTE_UNUSED) {
     return kParseUnknownArgument;
   }
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index 4d7ae9b..2c20b32 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -22,7 +22,7 @@
 #include "arch/instruction_set_features.h"
 #include "art_method-inl.h"
 #include "base/logging.h"  // For VLOG
-#include "base/stringpiece.h"
+#include "base/string_view_cpp20.h"
 #include "base/systrace.h"
 #include "base/time_utils.h"
 #include "base/timing_logger.h"
@@ -71,19 +71,19 @@
     DCHECK_EQ(instruction_set, kRuntimeISA);
   }
   std::unique_ptr<const InstructionSetFeatures> instruction_set_features;
-  for (const StringPiece option : runtime->GetCompilerOptions()) {
+  for (const std::string& option : runtime->GetCompilerOptions()) {
     VLOG(compiler) << "JIT compiler option " << option;
     std::string error_msg;
-    if (option.starts_with("--instruction-set-variant=")) {
-      StringPiece str = option.substr(strlen("--instruction-set-variant=")).data();
+    if (StartsWith(option, "--instruction-set-variant=")) {
+      const char* str = option.c_str() + strlen("--instruction-set-variant=");
       VLOG(compiler) << "JIT instruction set variant " << str;
       instruction_set_features = InstructionSetFeatures::FromVariant(
-          instruction_set, str.as_string(), &error_msg);
+          instruction_set, str, &error_msg);
       if (instruction_set_features == nullptr) {
         LOG(WARNING) << "Error parsing " << option << " message=" << error_msg;
       }
-    } else if (option.starts_with("--instruction-set-features=")) {
-      StringPiece str = option.substr(strlen("--instruction-set-features=")).data();
+    } else if (StartsWith(option, "--instruction-set-features=")) {
+      const char* str = option.c_str() + strlen("--instruction-set-features=");
       VLOG(compiler) << "JIT instruction set features " << str;
       if (instruction_set_features == nullptr) {
         instruction_set_features = InstructionSetFeatures::FromVariant(
@@ -93,7 +93,7 @@
         }
       }
       instruction_set_features =
-          instruction_set_features->AddFeaturesFromString(str.as_string(), &error_msg);
+          instruction_set_features->AddFeaturesFromString(str, &error_msg);
       if (instruction_set_features == nullptr) {
         LOG(WARNING) << "Error parsing " << option << " message=" << error_msg;
       }
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index ad1dda4..1f18172 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -49,7 +49,6 @@
 #include "base/os.h"
 #include "base/scoped_flock.h"
 #include "base/stl_util.h"
-#include "base/stringpiece.h"
 #include "base/time_utils.h"
 #include "base/timing_logger.h"
 #include "base/unix_file/fd_file.h"
diff --git a/dexlayout/dexdiag.cc b/dexlayout/dexdiag.cc
index 28d4048..ca9018d 100644
--- a/dexlayout/dexdiag.cc
+++ b/dexlayout/dexdiag.cc
@@ -22,12 +22,14 @@
 
 #include <iostream>
 #include <memory>
+#include <string>
+#include <string_view>
 #include <vector>
 
 #include "android-base/stringprintf.h"
 
 #include "base/logging.h"  // For InitLogging.
-#include "base/stringpiece.h"
+#include "base/string_view_cpp20.h"
 
 #include "dexlayout.h"
 #include "dex/dex_file.h"
@@ -462,14 +464,14 @@
   std::vector<std::string> name_filters;
   // TODO: add option to track usage by class name, etc.
   for (int i = 1; i < argc - 1; ++i) {
-    const StringPiece option(argv[i]);
+    const std::string_view option(argv[i]);
     if (option == "--help") {
       Usage(argv[0]);
       return EXIT_SUCCESS;
     } else if (option == "--verbose") {
       g_verbose = true;
-    } else if (option.starts_with("--contains=")) {
-      std::string contains(option.substr(strlen("--contains=")).data());
+    } else if (StartsWith(option, "--contains=")) {
+      std::string contains(option.substr(strlen("--contains=")));
       name_filters.push_back(contains);
     } else {
       Usage(argv[0]);
diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc
index a1edd00..5cd77e0 100644
--- a/imgdiag/imgdiag.cc
+++ b/imgdiag/imgdiag.cc
@@ -1674,23 +1674,27 @@
  protected:
   using Base = CmdlineArgs;
 
-  ParseStatus ParseCustom(const StringPiece& option, std::string* error_msg) override {
+  ParseStatus ParseCustom(const char* raw_option,
+                          size_t raw_option_length,
+                          std::string* error_msg) override {
+    DCHECK_EQ(strlen(raw_option), raw_option_length);
     {
-      ParseStatus base_parse = Base::ParseCustom(option, error_msg);
+      ParseStatus base_parse = Base::ParseCustom(raw_option, raw_option_length, error_msg);
       if (base_parse != kParseUnknownArgument) {
         return base_parse;
       }
     }
 
-    if (option.starts_with("--image-diff-pid=")) {
-      const char* image_diff_pid = option.substr(strlen("--image-diff-pid=")).data();
+    std::string_view option(raw_option, raw_option_length);
+    if (StartsWith(option, "--image-diff-pid=")) {
+      const char* image_diff_pid = raw_option + strlen("--image-diff-pid=");
 
       if (!android::base::ParseInt(image_diff_pid, &image_diff_pid_)) {
         *error_msg = "Image diff pid out of range";
         return kParseError;
       }
-    } else if (option.starts_with("--zygote-diff-pid=")) {
-      const char* zygote_diff_pid = option.substr(strlen("--zygote-diff-pid=")).data();
+    } else if (StartsWith(option, "--zygote-diff-pid=")) {
+      const char* zygote_diff_pid = raw_option + strlen("--zygote-diff-pid=");
 
       if (!android::base::ParseInt(zygote_diff_pid, &zygote_diff_pid_)) {
         *error_msg = "Zygote diff pid out of range";
diff --git a/libartbase/base/stringpiece.h b/libartbase/base/stringpiece.h
deleted file mode 100644
index e8cc2c3..0000000
--- a/libartbase/base/stringpiece.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_LIBARTBASE_BASE_STRINGPIECE_H_
-#define ART_LIBARTBASE_BASE_STRINGPIECE_H_
-
-#include <string.h>
-#include <string>
-
-#include <android-base/logging.h>
-
-namespace art {
-
-// A string-like object that points to a sized piece of memory.
-//
-// Functions or methods may use const StringPiece& parameters to accept either
-// a "const char*" or a "string" value that will be implicitly converted to
-// a StringPiece.  The implicit conversion means that it is often appropriate
-// to include this .h file in other files rather than forward-declaring
-// StringPiece as would be appropriate for most other Google classes.
-class StringPiece {
- public:
-  // standard STL container boilerplate
-  typedef char value_type;
-  typedef const char* pointer;
-  typedef const char& reference;
-  typedef const char& const_reference;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  static constexpr size_type npos = size_type(-1);
-  typedef const char* const_iterator;
-  typedef const char* iterator;
-  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-  typedef std::reverse_iterator<iterator> reverse_iterator;
-
-  // We provide non-explicit singleton constructors so users can pass
-  // in a "const char*" or a "string" wherever a "StringPiece" is
-  // expected.
-  StringPiece() : ptr_(nullptr), length_(0) { }
-  StringPiece(const char* str)  // NOLINT implicit constructor desired
-    : ptr_(str), length_((str == nullptr) ? 0 : strlen(str)) { }
-  StringPiece(const std::string& str)  // NOLINT implicit constructor desired
-    : ptr_(str.data()), length_(str.size()) { }
-  StringPiece(const char* offset, size_t len) : ptr_(offset), length_(len) { }
-
-  // data() may return a pointer to a buffer with embedded NULs, and the
-  // returned buffer may or may not be null terminated.  Therefore it is
-  // typically a mistake to pass data() to a routine that expects a NUL
-  // terminated string.
-  const char* data() const { return ptr_; }
-  size_type size() const { return length_; }
-  size_type length() const { return length_; }
-  bool empty() const { return length_ == 0; }
-
-  void clear() {
-    ptr_ = nullptr;
-    length_ = 0;
-  }
-  void set(const char* data_in, size_type len) {
-    ptr_ = data_in;
-    length_ = len;
-  }
-  void set(const char* str) {
-    ptr_ = str;
-    if (str != nullptr) {
-      length_ = strlen(str);
-    } else {
-      length_ = 0;
-    }
-  }
-  void set(const void* data_in, size_type len) {
-    ptr_ = reinterpret_cast<const char*>(data_in);
-    length_ = len;
-  }
-
-  char operator[](size_type i) const {
-    DCHECK_LT(i, length_);
-    return ptr_[i];
-  }
-
-  void remove_prefix(size_type n) {
-    ptr_ += n;
-    length_ -= n;
-  }
-
-  void remove_suffix(size_type n) {
-    length_ -= n;
-  }
-
-  int compare(const StringPiece& x) const {
-    int r = memcmp(ptr_, x.ptr_, std::min(length_, x.length_));
-    if (r == 0) {
-      if (length_ < x.length_) r = -1;
-      else if (length_ > x.length_) r = +1;
-    }
-    return r;
-  }
-
-  std::string as_string() const {
-    return std::string(data(), size());
-  }
-  // We also define ToString() here, since many other string-like
-  // interfaces name the routine that converts to a C++ string
-  // "ToString", and it's confusing to have the method that does that
-  // for a StringPiece be called "as_string()".  We also leave the
-  // "as_string()" method defined here for existing code.
-  std::string ToString() const {
-    return std::string(data(), size());
-  }
-
-  void CopyToString(std::string* target) const {
-    target->assign(ptr_, length_);
-  }
-
-  void AppendToString(std::string* target) const;
-
-  // Does "this" start with "x"
-  bool starts_with(const StringPiece& x) const {
-    return ((length_ >= x.length_) &&
-            (memcmp(ptr_, x.ptr_, x.length_) == 0));
-  }
-
-  // Does "this" end with "x"
-  bool ends_with(const StringPiece& x) const {
-    return ((length_ >= x.length_) &&
-            (memcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
-  }
-
-  iterator begin() const { return ptr_; }
-  iterator end() const { return ptr_ + length_; }
-  const_reverse_iterator rbegin() const {
-    return const_reverse_iterator(ptr_ + length_);
-  }
-  const_reverse_iterator rend() const {
-    return const_reverse_iterator(ptr_);
-  }
-
-  size_type copy(char* buf, size_type n, size_type pos = 0) const {
-    size_type ret = std::min(length_ - pos, n);
-    memcpy(buf, ptr_ + pos, ret);
-    return ret;
-  }
-
-  size_type find(const StringPiece& s, size_type pos = 0) const {
-    if (length_ == 0 || pos > static_cast<size_type>(length_)) {
-      return npos;
-    }
-    const char* result = std::search(ptr_ + pos, ptr_ + length_, s.ptr_, s.ptr_ + s.length_);
-    const size_type xpos = result - ptr_;
-    return xpos + s.length_ <= length_ ? xpos : npos;
-  }
-
-  size_type find(char c, size_type pos = 0) const {
-    if (length_ == 0 || pos >= length_) {
-      return npos;
-    }
-    const char* result = std::find(ptr_ + pos, ptr_ + length_, c);
-    return result != ptr_ + length_ ? result - ptr_ : npos;
-  }
-
-  size_type rfind(const StringPiece& s, size_type pos = npos) const {
-    if (length_ < s.length_) return npos;
-    const size_t ulen = length_;
-    if (s.length_ == 0) return std::min(ulen, pos);
-
-    const char* last = ptr_ + std::min(ulen - s.length_, pos) + s.length_;
-    const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
-    return result != last ? result - ptr_ : npos;
-  }
-
-  size_type rfind(char c, size_type pos = npos) const {
-    if (length_ == 0) return npos;
-    for (int i = std::min(pos, static_cast<size_type>(length_ - 1));
-         i >= 0; --i) {
-      if (ptr_[i] == c) {
-        return i;
-      }
-    }
-    return npos;
-  }
-
-  StringPiece substr(size_type pos, size_type n = npos) const {
-    if (pos > static_cast<size_type>(length_)) pos = length_;
-    if (n > length_ - pos) n = length_ - pos;
-    return StringPiece(ptr_ + pos, n);
-  }
-
-  int Compare(const StringPiece& rhs) const {
-    const int r = memcmp(data(), rhs.data(), std::min(size(), rhs.size()));
-    if (r != 0) {
-      return r;
-    }
-    if (size() < rhs.size()) {
-      return -1;
-    } else if (size() > rhs.size()) {
-      return 1;
-    }
-    return 0;
-  }
-
- private:
-  // Pointer to char data, not necessarily zero terminated.
-  const char* ptr_;
-  // Length of data.
-  size_type length_;
-};
-
-// This large function is defined inline so that in a fairly common case where
-// one of the arguments is a literal, the compiler can elide a lot of the
-// following comparisons.
-inline bool operator==(const StringPiece& x, const StringPiece& y) {
-  StringPiece::size_type len = x.size();
-  if (len != y.size()) {
-    return false;
-  }
-
-  const char* p1 = x.data();
-  const char* p2 = y.data();
-  if (p1 == p2) {
-    return true;
-  }
-  if (len == 0) {
-    return true;
-  }
-
-  // Test last byte in case strings share large common prefix
-  if (p1[len-1] != p2[len-1]) return false;
-  if (len == 1) return true;
-
-  // At this point we can, but don't have to, ignore the last byte.  We use
-  // this observation to fold the odd-length case into the even-length case.
-  len &= ~1;
-
-  return memcmp(p1, p2, len) == 0;
-}
-
-inline bool operator==(const StringPiece& x, const char* y) {
-  if (y == nullptr) {
-    return x.size() == 0;
-  } else {
-    return strncmp(x.data(), y, x.size()) == 0 && y[x.size()] == '\0';
-  }
-}
-
-inline bool operator!=(const StringPiece& x, const StringPiece& y) {
-  return !(x == y);
-}
-
-inline bool operator!=(const StringPiece& x, const char* y) {
-  return !(x == y);
-}
-
-inline bool operator<(const StringPiece& x, const StringPiece& y) {
-  return x.Compare(y) < 0;
-}
-
-inline bool operator>(const StringPiece& x, const StringPiece& y) {
-  return y < x;
-}
-
-inline bool operator<=(const StringPiece& x, const StringPiece& y) {
-  return !(x > y);
-}
-
-inline bool operator>=(const StringPiece& x, const StringPiece& y) {
-  return !(x < y);
-}
-
-inline std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
-  o.write(piece.data(), piece.size());
-  return o;
-}
-
-}  // namespace art
-
-#endif  // ART_LIBARTBASE_BASE_STRINGPIECE_H_
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 89826c6..655c2c9 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -3358,20 +3358,24 @@
  protected:
   using Base = CmdlineArgs;
 
-  ParseStatus ParseCustom(const StringPiece& option, std::string* error_msg) override {
+  ParseStatus ParseCustom(const char* raw_option,
+                          size_t raw_option_length,
+                          std::string* error_msg) override {
+    DCHECK_EQ(strlen(raw_option), raw_option_length);
     {
-      ParseStatus base_parse = Base::ParseCustom(option, error_msg);
+      ParseStatus base_parse = Base::ParseCustom(raw_option, raw_option_length, error_msg);
       if (base_parse != kParseUnknownArgument) {
         return base_parse;
       }
     }
 
-    if (option.starts_with("--oat-file=")) {
-      oat_filename_ = option.substr(strlen("--oat-file=")).data();
-    } else if (option.starts_with("--dex-file=")) {
-      dex_filename_ = option.substr(strlen("--dex-file=")).data();
-    } else if (option.starts_with("--image=")) {
-      image_location_ = option.substr(strlen("--image=")).data();
+    std::string_view option(raw_option, raw_option_length);
+    if (StartsWith(option, "--oat-file=")) {
+      oat_filename_ = raw_option + strlen("--oat-file=");
+    } else if (StartsWith(option, "--dex-file=")) {
+      dex_filename_ = raw_option + strlen("--dex-file=");
+    } else if (StartsWith(option, "--image=")) {
+      image_location_ = raw_option + strlen("--image=");
     } else if (option == "--no-dump:vmap") {
       dump_vmap_ = false;
     } else if (option =="--dump:code_info_stack_maps") {
@@ -3380,32 +3384,32 @@
       disassemble_code_ = false;
     } else if (option =="--header-only") {
       dump_header_only_ = true;
-    } else if (option.starts_with("--symbolize=")) {
-      oat_filename_ = option.substr(strlen("--symbolize=")).data();
+    } else if (StartsWith(option, "--symbolize=")) {
+      oat_filename_ = raw_option + strlen("--symbolize=");
       symbolize_ = true;
-    } else if (option.starts_with("--only-keep-debug")) {
+    } else if (StartsWith(option, "--only-keep-debug")) {
       only_keep_debug_ = true;
-    } else if (option.starts_with("--class-filter=")) {
-      class_filter_ = option.substr(strlen("--class-filter=")).data();
-    } else if (option.starts_with("--method-filter=")) {
-      method_filter_ = option.substr(strlen("--method-filter=")).data();
-    } else if (option.starts_with("--list-classes")) {
+    } else if (StartsWith(option, "--class-filter=")) {
+      class_filter_ = raw_option + strlen("--class-filter=");
+    } else if (StartsWith(option, "--method-filter=")) {
+      method_filter_ = raw_option + strlen("--method-filter=");
+    } else if (StartsWith(option, "--list-classes")) {
       list_classes_ = true;
-    } else if (option.starts_with("--list-methods")) {
+    } else if (StartsWith(option, "--list-methods")) {
       list_methods_ = true;
-    } else if (option.starts_with("--export-dex-to=")) {
-      export_dex_location_ = option.substr(strlen("--export-dex-to=")).data();
-    } else if (option.starts_with("--addr2instr=")) {
-      if (!android::base::ParseUint(option.substr(strlen("--addr2instr=")).data(), &addr2instr_)) {
+    } else if (StartsWith(option, "--export-dex-to=")) {
+      export_dex_location_ = raw_option + strlen("--export-dex-to=");
+    } else if (StartsWith(option, "--addr2instr=")) {
+      if (!android::base::ParseUint(raw_option + strlen("--addr2instr="), &addr2instr_)) {
         *error_msg = "Address conversion failed";
         return kParseError;
       }
-    } else if (option.starts_with("--app-image=")) {
-      app_image_ = option.substr(strlen("--app-image=")).data();
-    } else if (option.starts_with("--app-oat=")) {
-      app_oat_ = option.substr(strlen("--app-oat=")).data();
-    } else if (option.starts_with("--dump-imt=")) {
-      imt_dump_ = option.substr(strlen("--dump-imt=")).data();
+    } else if (StartsWith(option, "--app-image=")) {
+      app_image_ = raw_option + strlen("--app-image=");
+    } else if (StartsWith(option, "--app-oat=")) {
+      app_oat_ = raw_option + strlen("--app-oat=");
+    } else if (StartsWith(option, "--dump-imt=")) {
+      imt_dump_ = std::string(option.substr(strlen("--dump-imt=")));
     } else if (option == "--dump-imt-stats") {
       imt_stat_dump_ = true;
     } else {
diff --git a/tools/art_verifier/art_verifier.cc b/tools/art_verifier/art_verifier.cc
index 0ef6c06..b4aa678 100644
--- a/tools/art_verifier/art_verifier.cc
+++ b/tools/art_verifier/art_verifier.cc
@@ -92,28 +92,32 @@
  protected:
   using Base = CmdlineArgs;
 
-  ParseStatus ParseCustom(const StringPiece& option, std::string* error_msg) override {
+  ParseStatus ParseCustom(const char* raw_option,
+                          size_t raw_option_length,
+                          std::string* error_msg) override {
+    DCHECK_EQ(strlen(raw_option), raw_option_length);
     {
-      ParseStatus base_parse = Base::ParseCustom(option, error_msg);
+      ParseStatus base_parse = Base::ParseCustom(raw_option, raw_option_length, error_msg);
       if (base_parse != kParseUnknownArgument) {
         return base_parse;
       }
     }
 
-    if (option.starts_with("--dex-file=")) {
-      dex_filename_ = option.substr(strlen("--dex-file=")).data();
+    std::string_view option(raw_option, raw_option_length);
+    if (StartsWith(option, "--dex-file=")) {
+      dex_filename_ = raw_option + strlen("--dex-file=");
     } else if (option == "--dex-file-verifier") {
       dex_file_verifier_ = true;
     } else if (option == "--verbose") {
       method_verifier_verbose_ = true;
     } else if (option == "--verbose-debug") {
       method_verifier_verbose_debug_ = true;
-    } else if (option.starts_with("--repetitions=")) {
+    } else if (StartsWith(option, "--repetitions=")) {
       char* end;
-      repetitions_ = strtoul(option.substr(strlen("--repetitions=")).data(), &end, 10);
-    } else if (option.starts_with("--api-level=")) {
+      repetitions_ = strtoul(raw_option + strlen("--repetitions="), &end, 10);
+    } else if (StartsWith(option, "--api-level=")) {
       char* end;
-      api_level_ = strtoul(option.substr(strlen("--api-level=")).data(), &end, 10);
+      api_level_ = strtoul(raw_option + strlen("--api-level="), &end, 10);
     } else {
       return kParseUnknownArgument;
     }