Commit fbf51c7a authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[string] Add PtrComprCageBase to WriteToFlat, HashString, and Get

Also a couple of microoptimizations and consistent formatting in
WriteToFlat.

Change-Id: Ie642a4b8e0819b04603ee5c5d12eebccf6a2d59c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3151963
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76799}
parent c6bb5630
......@@ -645,9 +645,10 @@ MaybeHandle<String> FactoryBase<Impl>::NewConsString(
DisallowGarbageCollection no_gc;
SharedStringAccessGuardIfNeeded access_guard(isolate());
base::uc16* sink = result->GetChars(no_gc, access_guard);
String::WriteToFlat(*left, sink, 0, left->length(), access_guard);
String::WriteToFlat(*right, sink + left->length(), 0, right->length(),
String::WriteToFlat(*left, sink, 0, left->length(), isolate(),
access_guard);
String::WriteToFlat(*right, sink + left->length(), 0, right->length(),
isolate(), access_guard);
return result;
}
......
......@@ -1425,7 +1425,7 @@ base::Optional<double> TryStringToDouble(LocalIsolate* isolate,
const int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
auto buffer = std::make_unique<base::uc16[]>(max_length_for_conversion);
SharedStringAccessGuardIfNeeded access_guard(isolate);
String::WriteToFlat(*object, buffer.get(), 0, length, access_guard);
String::WriteToFlat(*object, buffer.get(), 0, length, isolate, access_guard);
base::Vector<const base::uc16> v(buffer.get(), length);
return StringToDouble(v, flags);
}
......
......@@ -1507,7 +1507,8 @@ ConcurrentLookupIterator::Result ConcurrentLookupIterator::TryGetOwnChar(
uint16_t charcode;
{
SharedStringAccessGuardIfNeeded access_guard(local_isolate);
charcode = string.Get(static_cast<int>(index));
charcode = string.Get(static_cast<int>(index), PtrComprCageBase(isolate),
access_guard);
}
if (charcode > unibrow::Latin1::kMaxChar) return kGaveUp;
......
......@@ -119,6 +119,12 @@ StringShape::StringShape(const String str)
DCHECK_EQ(type_ & kIsNotStringMask, kStringTag);
}
StringShape::StringShape(const String str, PtrComprCageBase cage_base)
: type_(str.map(cage_base, kAcquireLoad).instance_type()) {
set_valid();
DCHECK_EQ(type_ & kIsNotStringMask, kStringTag);
}
StringShape::StringShape(Map map) : type_(map.instance_type()) {
set_valid();
DCHECK_EQ(type_ & kIsNotStringMask, kStringTag);
......@@ -617,45 +623,53 @@ Handle<String> String::Flatten(LocalIsolate* isolate, Handle<String> string,
return string;
}
uint16_t String::Get(int index) const {
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*this));
return GetImpl(index, GetPtrComprCageBase(*this),
SharedStringAccessGuardIfNeeded::NotNeeded());
}
uint16_t String::Get(int index, Isolate* isolate) const {
SharedStringAccessGuardIfNeeded scope(isolate);
return GetImpl(index, scope);
return GetImpl(index, isolate, scope);
}
uint16_t String::Get(int index, LocalIsolate* local_isolate) const {
SharedStringAccessGuardIfNeeded scope(local_isolate);
return GetImpl(index, scope);
return GetImpl(index, local_isolate, scope);
}
uint16_t String::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const {
return GetImpl(index, access_guard);
int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
return GetImpl(index, cage_base, access_guard);
}
uint16_t String::GetImpl(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const {
int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
DCHECK(index >= 0 && index < length());
class StringGetDispatcher : public AllStatic {
public:
#define DEFINE_METHOD(Type) \
static inline uint16_t Handle##Type( \
Type str, int index, \
Type str, int index, PtrComprCageBase cage_base, \
const SharedStringAccessGuardIfNeeded& access_guard) { \
return str.Get(index, access_guard); \
return str.Get(index, cage_base, access_guard); \
}
STRING_CLASS_TYPES(DEFINE_METHOD)
#undef DEFINE_METHOD
static inline uint16_t HandleInvalidString(
String str, int index,
String str, int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) {
UNREACHABLE();
}
};
return StringShape(*this)
.DispatchToSpecificType<StringGetDispatcher, uint16_t>(*this, index,
access_guard);
.DispatchToSpecificType<StringGetDispatcher, uint16_t>(
*this, index, cage_base, access_guard);
}
void String::Set(int index, uint16_t value) {
......@@ -667,9 +681,11 @@ void String::Set(int index, uint16_t value) {
: SeqTwoByteString::cast(*this).SeqTwoByteStringSet(index, value);
}
bool String::IsFlat() const {
if (!StringShape(*this).IsCons()) return true;
return ConsString::cast(*this).second().length() == 0;
bool String::IsFlat() const { return IsFlat(GetPtrComprCageBase(*this)); }
bool String::IsFlat(PtrComprCageBase cage_base) const {
if (!StringShape(*this, cage_base).IsCons()) return true;
return ConsString::cast(*this).second(cage_base).length() == 0;
}
String String::GetUnderlying() const {
......@@ -771,11 +787,13 @@ inline base::Vector<const base::uc16> String::GetCharVector(
uint8_t SeqOneByteString::Get(int index) const {
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*this));
return Get(index, SharedStringAccessGuardIfNeeded::NotNeeded());
return Get(index, GetPtrComprCageBase(*this),
SharedStringAccessGuardIfNeeded::NotNeeded());
}
uint8_t SeqOneByteString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const {
int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(access_guard);
DCHECK(index >= 0 && index < length());
return ReadField<byte>(kHeaderSize + index * kCharSize);
......@@ -825,7 +843,8 @@ base::uc16* SeqTwoByteString::GetChars(
}
uint16_t SeqTwoByteString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const {
int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(access_guard);
DCHECK(index >= 0 && index < length());
return ReadField<uint16_t>(kHeaderSize + index * kShortSize);
......@@ -977,7 +996,8 @@ const uint8_t* ExternalOneByteString::GetChars() const {
}
uint8_t ExternalOneByteString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const {
int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(access_guard);
DCHECK(index >= 0 && index < length());
return GetChars()[index];
......@@ -1044,7 +1064,8 @@ const uint16_t* ExternalTwoByteString::GetChars() const {
}
uint16_t ExternalTwoByteString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const {
int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(access_guard);
DCHECK(index >= 0 && index < length());
return GetChars()[index];
......
This diff is collapsed.
......@@ -10,6 +10,7 @@
#include "src/base/bits.h"
#include "src/base/export-template.h"
#include "src/base/strings.h"
#include "src/common/globals.h"
#include "src/objects/instance-type.h"
#include "src/objects/name.h"
#include "src/objects/smi.h"
......@@ -43,6 +44,7 @@ enum RobustnessFlag { ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL };
class StringShape {
public:
inline explicit StringShape(const String s);
inline explicit StringShape(const String s, PtrComprCageBase cage_base);
inline explicit StringShape(Map s);
inline explicit StringShape(InstanceType t);
inline bool IsSequential() const;
......@@ -220,13 +222,15 @@ class String : public TorqueGeneratedString<String, Name> {
// to this method are not efficient unless the string is flat.
// If it is called from a background thread, the LocalIsolate version should
// be used.
V8_INLINE uint16_t Get(int index, Isolate* isolate = nullptr) const;
V8_INLINE uint16_t Get(int index) const;
V8_INLINE uint16_t Get(int index, Isolate* isolate) const;
V8_INLINE uint16_t Get(int index, LocalIsolate* local_isolate) const;
// Method to pass down the access_guard. Useful for recursive calls such as
// ThinStrings where we go String::Get into ThinString::Get into String::Get
// again for the internalized string.
V8_INLINE uint16_t
Get(int index, const SharedStringAccessGuardIfNeeded& access_guard) const;
Get(int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
// ES6 section 7.1.3.1 ToNumber Applied to the String Type
static Handle<Object> ToNumber(Isolate* isolate, Handle<String> subject);
......@@ -429,6 +433,7 @@ class String : public TorqueGeneratedString<String, Name> {
DECL_VERIFIER(String)
inline bool IsFlat() const;
inline bool IsFlat(PtrComprCageBase cage_base) const;
// Max char codes.
static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
......@@ -474,6 +479,7 @@ class String : public TorqueGeneratedString<String, Name> {
static void WriteToFlat(String source, sinkchar* sink, int from, int to);
template <typename sinkchar>
static void WriteToFlat(String source, sinkchar* sink, int from, int to,
PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded&);
static inline bool IsAscii(const char* chars, int length) {
......@@ -551,7 +557,8 @@ class String : public TorqueGeneratedString<String, Name> {
// Implementation of the Get() public methods. Do not use directly.
V8_INLINE uint16_t
GetImpl(int index, const SharedStringAccessGuardIfNeeded& access_guard) const;
GetImpl(int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
// Implementation of the IsEqualTo() public methods. Do not use directly.
template <EqualityType kEqType, typename Char>
......@@ -596,11 +603,13 @@ void String::WriteToFlat(String source, uint8_t* sink, int from, int to);
extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
void String::WriteToFlat(String source, uint16_t* sink, int from, int to);
extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
void String::WriteToFlat(String source, uint8_t* sink, int from, int to ,
const SharedStringAccessGuardIfNeeded&);
void String::WriteToFlat(String source, uint8_t* sink, int from, int to,
PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded&);
extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
void String::WriteToFlat(String source, uint16_t* sink, int from, int to,
const SharedStringAccessGuardIfNeeded&);
PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded&);
// clang-format on
class SubStringRange {
......@@ -650,7 +659,7 @@ class SeqOneByteString
// defined for convenience and it will check that the access guard is not
// needed.
inline uint8_t Get(int index) const;
inline uint8_t Get(int index,
inline uint8_t Get(int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
inline void SeqOneByteStringSet(int index, uint16_t value);
......@@ -698,7 +707,8 @@ class SeqTwoByteString
// Dispatched behavior.
inline uint16_t Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const;
int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
inline void SeqTwoByteStringSet(int index, uint16_t value);
// Get the address of the characters in this string.
......@@ -756,7 +766,8 @@ class ConsString : public TorqueGeneratedConsString<ConsString, String> {
// Dispatched behavior.
V8_EXPORT_PRIVATE uint16_t
Get(int index, const SharedStringAccessGuardIfNeeded& access_guard) const;
Get(int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
// Minimum length for a cons string.
static const int kMinLength = 13;
......@@ -780,7 +791,8 @@ class ThinString : public TorqueGeneratedThinString<ThinString, String> {
DECL_GETTER(unchecked_actual, HeapObject)
V8_EXPORT_PRIVATE uint16_t
Get(int index, const SharedStringAccessGuardIfNeeded& access_guard) const;
Get(int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
DECL_VERIFIER(ThinString)
......@@ -805,7 +817,8 @@ class SlicedString : public TorqueGeneratedSlicedString<SlicedString, String> {
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// Dispatched behavior.
V8_EXPORT_PRIVATE uint16_t
Get(int index, const SharedStringAccessGuardIfNeeded& access_guard) const;
Get(int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
// Minimum length for a sliced string.
static const int kMinLength = 13;
......@@ -891,7 +904,7 @@ class ExternalOneByteString
inline const uint8_t* GetChars() const;
// Dispatched behavior.
inline uint8_t Get(int index,
inline uint8_t Get(int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
class BodyDescriptor;
......@@ -935,7 +948,8 @@ class ExternalTwoByteString
// Dispatched behavior.
inline uint16_t Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const;
int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
// For regexp code.
inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment