Replace StringPiece with std::string_view in Signature.
And also in Signature-related code. Remove the function
DexFile::CreateSignature() which was used only in a test
as the test can use method searching functions that take
std::string_view instead.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 123750182
Change-Id: I3f24c8f4f677e2e40503dbab347df1eb031b4132
diff --git a/libartbase/base/string_view_cpp20.h b/libartbase/base/string_view_cpp20.h
new file mode 100644
index 0000000..2c11a2f
--- /dev/null
+++ b/libartbase/base/string_view_cpp20.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 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_STRING_VIEW_CPP20_H_
+#define ART_LIBARTBASE_BASE_STRING_VIEW_CPP20_H_
+
+#include <string_view>
+
+namespace art {
+
+// Replacement functions for std::string_view::starts_with(), ends_with()
+// which shall be available in C++20.
+#if __cplusplus >= 202000L
+#error "When upgrading to C++20, remove this error and file a bug to remove this workaround."
+#endif
+
+inline bool StartsWith(std::string_view sv, std::string_view prefix) {
+ return sv.substr(0u, prefix.size()) == prefix;
+}
+
+inline bool EndsWith(std::string_view sv, std::string_view suffix) {
+ return sv.size() >= suffix.size() && sv.substr(sv.size() - suffix.size()) == suffix;
+}
+
+} // namespace art
+
+#endif // ART_LIBARTBASE_BASE_STRING_VIEW_CPP20_H_
diff --git a/libdexfile/dex/dex_file-inl.h b/libdexfile/dex/dex_file-inl.h
index 2af1e04..15ba9cc 100644
--- a/libdexfile/dex/dex_file-inl.h
+++ b/libdexfile/dex/dex_file-inl.h
@@ -22,7 +22,6 @@
#include "base/casts.h"
#include "base/iteration_range.h"
#include "base/leb128.h"
-#include "base/stringpiece.h"
#include "base/utils.h"
#include "class_iterator.h"
#include "compact_dex_file.h"
diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc
index 39377a3..7db4de0 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -400,7 +400,7 @@
}
// Given a signature place the type ids into the given vector
-bool DexFile::CreateTypeList(const StringPiece& signature,
+bool DexFile::CreateTypeList(std::string_view signature,
dex::TypeIndex* return_type_idx,
std::vector<dex::TypeIndex>* param_type_idxs) const {
if (signature[0] != '(') {
@@ -450,20 +450,6 @@
return false; // failed to correctly parse return type
}
-const Signature DexFile::CreateSignature(const StringPiece& signature) const {
- dex::TypeIndex return_type_idx;
- std::vector<dex::TypeIndex> param_type_indices;
- bool success = CreateTypeList(signature, &return_type_idx, ¶m_type_indices);
- if (!success) {
- return Signature::NoSignature();
- }
- const ProtoId* proto_id = FindProtoId(return_type_idx, param_type_indices);
- if (proto_id == nullptr) {
- return Signature::NoSignature();
- }
- return Signature(this, *proto_id);
-}
-
int32_t DexFile::FindTryItem(const TryItem* try_items, uint32_t tries_size, uint32_t address) {
uint32_t min = 0;
uint32_t max = tries_size;
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index 8ea3c09..4dae1c0 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -19,6 +19,7 @@
#include <memory>
#include <string>
+#include <string_view>
#include <vector>
#include <android-base/logging.h>
@@ -44,7 +45,6 @@
class MemMap;
class OatDexFile;
class StandardDexFile;
-class StringPiece;
class ZipArchive;
// Some instances of DexFile own the storage referred to by DexFile. Clients who create
@@ -479,14 +479,10 @@
}
// Given a signature place the type ids into the given vector, returns true on success
- bool CreateTypeList(const StringPiece& signature,
+ bool CreateTypeList(std::string_view signature,
dex::TypeIndex* return_type_idx,
std::vector<dex::TypeIndex>* param_type_idxs) const;
- // Create a Signature from the given string signature or return Signature::NoSignature if not
- // possible.
- const Signature CreateSignature(const StringPiece& signature) const;
-
// Returns the short form method descriptor for the given prototype.
const char* GetShorty(dex::ProtoIndex proto_idx) const;
diff --git a/libdexfile/dex/signature-inl.h b/libdexfile/dex/signature-inl.h
index ccc7ea9..12ad1b3 100644
--- a/libdexfile/dex/signature-inl.h
+++ b/libdexfile/dex/signature-inl.h
@@ -19,7 +19,6 @@
#include "signature.h"
-#include "base/stringpiece.h"
#include "dex_file-inl.h"
namespace art {
@@ -37,13 +36,13 @@
uint32_t lhs_shorty_len; // For a shorty utf16 length == mutf8 length.
const char* lhs_shorty_data = dex_file_->StringDataAndUtf16LengthByIdx(proto_id_->shorty_idx_,
&lhs_shorty_len);
- StringPiece lhs_shorty(lhs_shorty_data, lhs_shorty_len);
+ std::string_view lhs_shorty(lhs_shorty_data, lhs_shorty_len);
{
uint32_t rhs_shorty_len;
const char* rhs_shorty_data =
rhs.dex_file_->StringDataAndUtf16LengthByIdx(rhs.proto_id_->shorty_idx_,
&rhs_shorty_len);
- StringPiece rhs_shorty(rhs_shorty_data, rhs_shorty_len);
+ std::string_view rhs_shorty(rhs_shorty_data, rhs_shorty_len);
if (lhs_shorty != rhs_shorty) {
return false; // Shorty mismatch.
}
@@ -57,7 +56,7 @@
return false; // Return type mismatch.
}
}
- if (lhs_shorty.find('L', 1) != StringPiece::npos) {
+ if (lhs_shorty.find('L', 1) != std::string_view::npos) {
const dex::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
const dex::TypeList* rhs_params = rhs.dex_file_->GetProtoParameters(*rhs.proto_id_);
// We found a reference parameter in the matching shorty, so both lists must be non-empty.
diff --git a/libdexfile/dex/signature.cc b/libdexfile/dex/signature.cc
index 34b4b55..ac00428 100644
--- a/libdexfile/dex/signature.cc
+++ b/libdexfile/dex/signature.cc
@@ -21,6 +21,8 @@
#include <ostream>
#include <type_traits>
+#include "base/string_view_cpp20.h"
+
namespace art {
using dex::TypeList;
@@ -55,26 +57,26 @@
return strcmp(return_type, "V") == 0;
}
-bool Signature::operator==(const StringPiece& rhs) const {
+bool Signature::operator==(std::string_view rhs) const {
if (dex_file_ == nullptr) {
return false;
}
- StringPiece tail(rhs);
- if (!tail.starts_with("(")) {
+ std::string_view tail(rhs);
+ if (!StartsWith(tail, "(")) {
return false; // Invalid signature
}
tail.remove_prefix(1); // "(";
const TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
if (params != nullptr) {
for (uint32_t i = 0; i < params->Size(); ++i) {
- StringPiece param(dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_));
- if (!tail.starts_with(param)) {
+ std::string_view param(dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_));
+ if (!StartsWith(tail, param)) {
return false;
}
tail.remove_prefix(param.length());
}
}
- if (!tail.starts_with(")")) {
+ if (!StartsWith(tail, ")")) {
return false;
}
tail.remove_prefix(1); // ")";
diff --git a/libdexfile/dex/signature.h b/libdexfile/dex/signature.h
index 235f37c..3fbb543 100644
--- a/libdexfile/dex/signature.h
+++ b/libdexfile/dex/signature.h
@@ -19,6 +19,7 @@
#include <iosfwd>
#include <string>
+#include <string_view>
#include <android-base/logging.h>
@@ -30,7 +31,6 @@
struct ProtoId;
} // namespace dex
class DexFile;
-class StringPiece;
// Abstract the signature of a method.
class Signature : public ValueObject {
@@ -49,7 +49,7 @@
return !(*this == rhs);
}
- bool operator==(const StringPiece& rhs) const;
+ bool operator==(std::string_view rhs) const;
private:
Signature(const DexFile* dex, const dex::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc
index 3d175a8..eb4bada 100644
--- a/openjdkjvmti/ti_redefine.cc
+++ b/openjdkjvmti/ti_redefine.cc
@@ -32,6 +32,7 @@
#include "ti_redefine.h"
#include <limits>
+#include <string_view>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
@@ -40,7 +41,6 @@
#include "art_jvmti.h"
#include "art_method-inl.h"
#include "base/array_ref.h"
-#include "base/stringpiece.h"
#include "class_linker-inl.h"
#include "class_root.h"
#include "debugger.h"
@@ -597,7 +597,7 @@
// Try and get the declared method. First try to get a virtual method then a direct method if that's
// not found.
static art::ArtMethod* FindMethod(art::Handle<art::mirror::Class> klass,
- art::StringPiece name,
+ std::string_view name,
art::Signature sig) REQUIRES_SHARED(art::Locks::mutator_lock_) {
DCHECK(!klass->IsProxyClass());
for (art::ArtMethod& m : klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize)) {
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 2f37123..a2775d2 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -1254,7 +1254,7 @@
EXPECT_TRUE(K->IsAssignableFrom(B.Get()));
EXPECT_TRUE(J->IsAssignableFrom(B.Get()));
- const Signature void_sig = I->GetDexCache()->GetDexFile()->CreateSignature("()V");
+ const std::string_view void_sig("()V");
ArtMethod* Ii = I->FindClassMethod("i", void_sig, kRuntimePointerSize);
ArtMethod* Jj1 = J->FindClassMethod("j1", void_sig, kRuntimePointerSize);
ArtMethod* Jj2 = J->FindClassMethod("j2", void_sig, kRuntimePointerSize);
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index af86cc0..7c0db30 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -442,8 +442,8 @@
template <bool kNative>
static ArtMethod* FindMethod(ObjPtr<mirror::Class> c,
- const StringPiece& name,
- const StringPiece& sig)
+ std::string_view name,
+ std::string_view sig)
REQUIRES_SHARED(Locks::mutator_lock_) {
auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
for (auto& method : c->GetMethods(pointer_size)) {
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index c3f7ad7..872095a 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -21,7 +21,6 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/logging.h" // For VLOG.
-#include "base/stringpiece.h"
#include "base/utils.h"
#include "class-inl.h"
#include "class_ext.h"
@@ -482,9 +481,7 @@
ArtMethod* Class::FindInterfaceMethod(std::string_view name,
std::string_view signature,
PointerSize pointer_size) {
- // TODO: Change Signature::operator==() to accept std::string_view instead of StringPiece.
- StringPiece sp_signature(signature.data(), signature.size());
- return FindInterfaceMethodWithSignature(this, name, sp_signature, pointer_size);
+ return FindInterfaceMethodWithSignature(this, name, signature, pointer_size);
}
ArtMethod* Class::FindInterfaceMethod(std::string_view name,
@@ -597,9 +594,7 @@
ArtMethod* Class::FindClassMethod(std::string_view name,
std::string_view signature,
PointerSize pointer_size) {
- // TODO: Change Signature::operator==() to accept std::string_view instead of StringPiece.
- StringPiece sp_signature(signature.data(), signature.size());
- return FindClassMethodWithSignature(this, name, sp_signature, pointer_size);
+ return FindClassMethodWithSignature(this, name, signature, pointer_size);
}
ArtMethod* Class::FindClassMethod(std::string_view name,
@@ -707,13 +702,11 @@
}
ArtMethod* Class::FindConstructor(std::string_view signature, PointerSize pointer_size) {
- // TODO: Change Signature::operator==() to accept std::string_view instead of StringPiece.
- StringPiece sp_signature(signature.data(), signature.size());
// Internal helper, never called on proxy classes. We can skip GetInterfaceMethodIfProxy().
DCHECK(!IsProxyClass());
std::string_view name("<init>");
for (ArtMethod& method : GetDirectMethodsSliceUnchecked(pointer_size)) {
- if (method.GetName() == name && method.GetSignature() == sp_signature) {
+ if (method.GetName() == name && method.GetSignature() == signature) {
return &method;
}
}