[string] Skip length checks in IsEqualTo

Make the IsEqualTo equality type parameter a template parameter, and add
an option to skip the length check for cases where the length is known
(e.g. in string table key comparisons).

Change-Id: I893ac880ec1e830a50ba6d8f58f375ed96d6e14e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2562247
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71435}
This commit is contained in:
Leszek Swirski 2020-11-26 14:56:21 +01:00 committed by Commit Bot
parent dbffd66e35
commit 3688dd61f7
4 changed files with 25 additions and 41 deletions

View File

@ -984,8 +984,6 @@ namespace {
template <typename Char>
bool Matches(const Vector<const Char>& chars, Handle<String> string) {
DCHECK(!string.is_null());
if (chars.length() != string->length()) return false;
return string->IsEqualTo(chars);
}

View File

@ -320,7 +320,7 @@ class SequentialStringKey final : public StringTableKey {
template <typename LocalIsolate>
bool IsMatch(LocalIsolate* isolate, String s) {
return s.IsEqualTo(isolate, chars_);
return s.IsEqualTo<String::EqualityType::kNoLengthCheck>(chars_, isolate);
}
Handle<String> AsHandle(Isolate* isolate) {
@ -386,7 +386,7 @@ class SeqSubStringKey final : public StringTableKey {
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(string));
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*string_));
DisallowGarbageCollection no_gc;
return string.IsEqualTo(
return string.IsEqualTo<String::EqualityType::kNoLengthCheck>(
Vector<const Char>(string_->GetChars(no_gc) + from_, length()));
}
@ -434,33 +434,34 @@ bool String::Equals(Isolate* isolate, Handle<String> one, Handle<String> two) {
return SlowEquals(isolate, one, two);
}
template <typename Char>
bool String::IsEqualTo(Vector<const Char> str,
String::EqualityType eq_type) const {
template <String::EqualityType kEqType, typename Char>
bool String::IsEqualTo(Vector<const Char> str, Isolate* isolate) const {
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*this));
return IsEqualToImpl(str, eq_type,
SharedStringAccessGuardIfNeeded::NotNeeded());
return IsEqualToImpl<kEqType>(str,
SharedStringAccessGuardIfNeeded::NotNeeded());
}
template <typename Char>
bool String::IsEqualTo(LocalIsolate* isolate, Vector<const Char> str,
String::EqualityType eq_type) const {
template <String::EqualityType kEqType, typename Char>
bool String::IsEqualTo(Vector<const Char> str, LocalIsolate* isolate) const {
SharedStringAccessGuardIfNeeded access_guard(isolate);
return IsEqualToImpl(str, eq_type, access_guard);
return IsEqualToImpl<kEqType>(str, access_guard);
}
template <typename Char>
template <String::EqualityType kEqType, typename Char>
bool String::IsEqualToImpl(
Vector<const Char> str, String::EqualityType eq_type,
Vector<const Char> str,
const SharedStringAccessGuardIfNeeded& access_guard) const {
size_t len = str.size();
switch (eq_type) {
switch (kEqType) {
case EqualityType::kWholeString:
if (static_cast<size_t>(length()) != len) return false;
break;
case EqualityType::kPrefix:
if (static_cast<size_t>(length()) < len) return false;
break;
case EqualityType::kNoLengthCheck:
DCHECK_EQ(length(), len);
break;
}
DisallowGarbageCollection no_gc;

View File

@ -1311,7 +1311,7 @@ Object String::LastIndexOf(Isolate* isolate, Handle<Object> receiver,
}
bool String::HasOneBytePrefix(Vector<const char> str) {
return IsEqualTo(str, EqualityType::kPrefix);
return IsEqualTo<EqualityType::kPrefix>(str);
}
namespace {

View File

@ -317,39 +317,24 @@ class String : public TorqueGeneratedString<String, Name> {
inline static bool Equals(Isolate* isolate, Handle<String> one,
Handle<String> two);
enum class EqualityType { kWholeString, kPrefix };
// Check if this string matches the given vector of characters, either as a
// whole string or just a prefix.
//
// This overload should only be called on the main thread.
template <typename Char>
inline bool IsEqualTo(
Vector<const Char> str,
EqualityType eq_type = EqualityType::kWholeString) const;
enum class EqualityType { kWholeString, kPrefix, kNoLengthCheck };
// Check if this string matches the given vector of characters, either as a
// whole string or just a prefix.
//
// The Isolate is passed as "evidence" that this call is on the main thread,
// and to distiguish from the LocalIsolate overload. It is otherwise
// equivalent to the no-Isolate overload.
template <typename Char>
inline bool IsEqualTo(
Isolate* isolate, Vector<const Char> str,
EqualityType eq_type = EqualityType::kWholeString) const {
return IsEqualTo(str, eq_type);
}
// and to distiguish from the LocalIsolate overload.
template <EqualityType kEqType = EqualityType::kWholeString, typename Char>
inline bool IsEqualTo(Vector<const Char> str,
Isolate* isolate = nullptr) const;
// Check if this string matches the given vector of characters, either as a
// whole string or just a prefix.
//
// The LocalIsolate is passed to provide access to the string access lock,
// which is taken when reading the string's contents on a background thread.
template <typename Char>
inline bool IsEqualTo(
LocalIsolate* isolate, Vector<const Char> str,
EqualityType eq_type = EqualityType::kWholeString) const;
template <EqualityType kEqType = EqualityType::kWholeString, typename Char>
inline bool IsEqualTo(Vector<const Char> str, LocalIsolate* isolate) const;
V8_EXPORT_PRIVATE bool HasOneBytePrefix(Vector<const char> str);
V8_EXPORT_PRIVATE inline bool IsOneByteEqualTo(Vector<const char> str);
@ -546,9 +531,9 @@ class String : public TorqueGeneratedString<String, Name> {
V8_INLINE uint16_t GetImpl(int index);
// Implementation of the IsEqualTo() public methods. Do not use directly.
template <typename Char>
template <EqualityType kEqType, typename Char>
V8_INLINE bool IsEqualToImpl(
Vector<const Char> str, EqualityType eq_type,
Vector<const Char> str,
const SharedStringAccessGuardIfNeeded& access_guard) const;
V8_EXPORT_PRIVATE static Handle<String> SlowFlatten(