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( ...@@ -645,9 +645,10 @@ MaybeHandle<String> FactoryBase<Impl>::NewConsString(
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
SharedStringAccessGuardIfNeeded access_guard(isolate()); SharedStringAccessGuardIfNeeded access_guard(isolate());
base::uc16* sink = result->GetChars(no_gc, access_guard); base::uc16* sink = result->GetChars(no_gc, access_guard);
String::WriteToFlat(*left, sink, 0, left->length(), access_guard); String::WriteToFlat(*left, sink, 0, left->length(), isolate(),
String::WriteToFlat(*right, sink + left->length(), 0, right->length(),
access_guard); access_guard);
String::WriteToFlat(*right, sink + left->length(), 0, right->length(),
isolate(), access_guard);
return result; return result;
} }
......
...@@ -1425,7 +1425,7 @@ base::Optional<double> TryStringToDouble(LocalIsolate* isolate, ...@@ -1425,7 +1425,7 @@ base::Optional<double> TryStringToDouble(LocalIsolate* isolate,
const int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY; const int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
auto buffer = std::make_unique<base::uc16[]>(max_length_for_conversion); auto buffer = std::make_unique<base::uc16[]>(max_length_for_conversion);
SharedStringAccessGuardIfNeeded access_guard(isolate); 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); base::Vector<const base::uc16> v(buffer.get(), length);
return StringToDouble(v, flags); return StringToDouble(v, flags);
} }
......
...@@ -1507,7 +1507,8 @@ ConcurrentLookupIterator::Result ConcurrentLookupIterator::TryGetOwnChar( ...@@ -1507,7 +1507,8 @@ ConcurrentLookupIterator::Result ConcurrentLookupIterator::TryGetOwnChar(
uint16_t charcode; uint16_t charcode;
{ {
SharedStringAccessGuardIfNeeded access_guard(local_isolate); 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; if (charcode > unibrow::Latin1::kMaxChar) return kGaveUp;
......
...@@ -119,6 +119,12 @@ StringShape::StringShape(const String str) ...@@ -119,6 +119,12 @@ StringShape::StringShape(const String str)
DCHECK_EQ(type_ & kIsNotStringMask, kStringTag); 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()) { StringShape::StringShape(Map map) : type_(map.instance_type()) {
set_valid(); set_valid();
DCHECK_EQ(type_ & kIsNotStringMask, kStringTag); DCHECK_EQ(type_ & kIsNotStringMask, kStringTag);
...@@ -617,45 +623,53 @@ Handle<String> String::Flatten(LocalIsolate* isolate, Handle<String> string, ...@@ -617,45 +623,53 @@ Handle<String> String::Flatten(LocalIsolate* isolate, Handle<String> string,
return 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 { uint16_t String::Get(int index, Isolate* isolate) const {
SharedStringAccessGuardIfNeeded scope(isolate); SharedStringAccessGuardIfNeeded scope(isolate);
return GetImpl(index, scope); return GetImpl(index, isolate, scope);
} }
uint16_t String::Get(int index, LocalIsolate* local_isolate) const { uint16_t String::Get(int index, LocalIsolate* local_isolate) const {
SharedStringAccessGuardIfNeeded scope(local_isolate); SharedStringAccessGuardIfNeeded scope(local_isolate);
return GetImpl(index, scope); return GetImpl(index, local_isolate, scope);
} }
uint16_t String::Get( uint16_t String::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const { int index, PtrComprCageBase cage_base,
return GetImpl(index, access_guard); const SharedStringAccessGuardIfNeeded& access_guard) const {
return GetImpl(index, cage_base, access_guard);
} }
uint16_t String::GetImpl( 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()); DCHECK(index >= 0 && index < length());
class StringGetDispatcher : public AllStatic { class StringGetDispatcher : public AllStatic {
public: public:
#define DEFINE_METHOD(Type) \ #define DEFINE_METHOD(Type) \
static inline uint16_t Handle##Type( \ static inline uint16_t Handle##Type( \
Type str, int index, \ Type str, int index, PtrComprCageBase cage_base, \
const SharedStringAccessGuardIfNeeded& access_guard) { \ const SharedStringAccessGuardIfNeeded& access_guard) { \
return str.Get(index, access_guard); \ return str.Get(index, cage_base, access_guard); \
} }
STRING_CLASS_TYPES(DEFINE_METHOD) STRING_CLASS_TYPES(DEFINE_METHOD)
#undef DEFINE_METHOD #undef DEFINE_METHOD
static inline uint16_t HandleInvalidString( static inline uint16_t HandleInvalidString(
String str, int index, String str, int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) { const SharedStringAccessGuardIfNeeded& access_guard) {
UNREACHABLE(); UNREACHABLE();
} }
}; };
return StringShape(*this) return StringShape(*this)
.DispatchToSpecificType<StringGetDispatcher, uint16_t>(*this, index, .DispatchToSpecificType<StringGetDispatcher, uint16_t>(
access_guard); *this, index, cage_base, access_guard);
} }
void String::Set(int index, uint16_t value) { void String::Set(int index, uint16_t value) {
...@@ -667,9 +681,11 @@ 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); : SeqTwoByteString::cast(*this).SeqTwoByteStringSet(index, value);
} }
bool String::IsFlat() const { bool String::IsFlat() const { return IsFlat(GetPtrComprCageBase(*this)); }
if (!StringShape(*this).IsCons()) return true;
return ConsString::cast(*this).second().length() == 0; 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 { String String::GetUnderlying() const {
...@@ -771,11 +787,13 @@ inline base::Vector<const base::uc16> String::GetCharVector( ...@@ -771,11 +787,13 @@ inline base::Vector<const base::uc16> String::GetCharVector(
uint8_t SeqOneByteString::Get(int index) const { uint8_t SeqOneByteString::Get(int index) const {
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*this)); DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*this));
return Get(index, SharedStringAccessGuardIfNeeded::NotNeeded()); return Get(index, GetPtrComprCageBase(*this),
SharedStringAccessGuardIfNeeded::NotNeeded());
} }
uint8_t SeqOneByteString::Get( uint8_t SeqOneByteString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const { int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(access_guard); USE(access_guard);
DCHECK(index >= 0 && index < length()); DCHECK(index >= 0 && index < length());
return ReadField<byte>(kHeaderSize + index * kCharSize); return ReadField<byte>(kHeaderSize + index * kCharSize);
...@@ -825,7 +843,8 @@ base::uc16* SeqTwoByteString::GetChars( ...@@ -825,7 +843,8 @@ base::uc16* SeqTwoByteString::GetChars(
} }
uint16_t SeqTwoByteString::Get( uint16_t SeqTwoByteString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const { int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(access_guard); USE(access_guard);
DCHECK(index >= 0 && index < length()); DCHECK(index >= 0 && index < length());
return ReadField<uint16_t>(kHeaderSize + index * kShortSize); return ReadField<uint16_t>(kHeaderSize + index * kShortSize);
...@@ -977,7 +996,8 @@ const uint8_t* ExternalOneByteString::GetChars() const { ...@@ -977,7 +996,8 @@ const uint8_t* ExternalOneByteString::GetChars() const {
} }
uint8_t ExternalOneByteString::Get( uint8_t ExternalOneByteString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const { int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(access_guard); USE(access_guard);
DCHECK(index >= 0 && index < length()); DCHECK(index >= 0 && index < length());
return GetChars()[index]; return GetChars()[index];
...@@ -1044,7 +1064,8 @@ const uint16_t* ExternalTwoByteString::GetChars() const { ...@@ -1044,7 +1064,8 @@ const uint16_t* ExternalTwoByteString::GetChars() const {
} }
uint16_t ExternalTwoByteString::Get( uint16_t ExternalTwoByteString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const { int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(access_guard); USE(access_guard);
DCHECK(index >= 0 && index < length()); DCHECK(index >= 0 && index < length());
return GetChars()[index]; return GetChars()[index];
......
...@@ -647,53 +647,52 @@ std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls, ...@@ -647,53 +647,52 @@ std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
template <typename sinkchar> template <typename sinkchar>
void String::WriteToFlat(String source, sinkchar* sink, int from, int to) { void String::WriteToFlat(String source, sinkchar* sink, int from, int to) {
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(source)); DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(source));
return WriteToFlat(source, sink, from, to, return WriteToFlat(source, sink, from, to, GetPtrComprCageBase(source),
SharedStringAccessGuardIfNeeded::NotNeeded()); SharedStringAccessGuardIfNeeded::NotNeeded());
} }
// static // static
template <typename sinkchar> template <typename sinkchar>
void String::WriteToFlat(String source, sinkchar* sink, int from, int to, void String::WriteToFlat(String source, sinkchar* sink, int from, int to,
PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) { const SharedStringAccessGuardIfNeeded& access_guard) {
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
while (from < to) { if (from == to) return;
while (true) {
DCHECK_LT(from, to);
DCHECK_LE(0, from); DCHECK_LE(0, from);
DCHECK_LE(to, source.length()); DCHECK_LE(to, source.length());
switch (StringShape(source).full_representation_tag()) { switch (StringShape(source, cage_base).full_representation_tag()) {
case kOneByteStringTag | kExternalStringTag: { case kOneByteStringTag | kExternalStringTag:
CopyChars(sink, ExternalOneByteString::cast(source).GetChars() + from, CopyChars(sink, ExternalOneByteString::cast(source).GetChars() + from,
to - from); to - from);
return; return;
} case kTwoByteStringTag | kExternalStringTag:
case kTwoByteStringTag | kExternalStringTag: { CopyChars(sink, ExternalTwoByteString::cast(source).GetChars() + from,
const base::uc16* data = ExternalTwoByteString::cast(source).GetChars(); to - from);
CopyChars(sink, data + from, to - from);
return; return;
} case kOneByteStringTag | kSeqStringTag:
case kOneByteStringTag | kSeqStringTag: {
CopyChars( CopyChars(
sink, sink,
SeqOneByteString::cast(source).GetChars(no_gc, access_guard) + from, SeqOneByteString::cast(source).GetChars(no_gc, access_guard) + from,
to - from); to - from);
return; return;
} case kTwoByteStringTag | kSeqStringTag:
case kTwoByteStringTag | kSeqStringTag: {
CopyChars( CopyChars(
sink, sink,
SeqTwoByteString::cast(source).GetChars(no_gc, access_guard) + from, SeqTwoByteString::cast(source).GetChars(no_gc, access_guard) + from,
to - from); to - from);
return; return;
}
case kOneByteStringTag | kConsStringTag: case kOneByteStringTag | kConsStringTag:
case kTwoByteStringTag | kConsStringTag: { case kTwoByteStringTag | kConsStringTag: {
ConsString cons_string = ConsString::cast(source); ConsString cons_string = ConsString::cast(source);
String first = cons_string.first(); String first = cons_string.first(cage_base);
int boundary = first.length(); int boundary = first.length();
if (to - boundary >= boundary - from) { if (to - boundary >= boundary - from) {
// Right hand side is longer. Recurse over left. // Right hand side is longer. Recurse over left.
if (from < boundary) { if (from < boundary) {
WriteToFlat(first, sink, from, boundary, access_guard); WriteToFlat(first, sink, from, boundary, cage_base, access_guard);
if (from == 0 && cons_string.second() == first) { if (from == 0 && cons_string.second(cage_base) == first) {
CopyChars(sink + boundary, sink, boundary); CopyChars(sink + boundary, sink, boundary);
return; return;
} }
...@@ -703,46 +702,50 @@ void String::WriteToFlat(String source, sinkchar* sink, int from, int to, ...@@ -703,46 +702,50 @@ void String::WriteToFlat(String source, sinkchar* sink, int from, int to,
from -= boundary; from -= boundary;
} }
to -= boundary; to -= boundary;
source = cons_string.second(); source = cons_string.second(cage_base);
} else { } else {
// Left hand side is longer. Recurse over right. // Left hand side is longer. Recurse over right.
if (to > boundary) { if (to > boundary) {
String second = cons_string.second(); String second = cons_string.second(cage_base);
// When repeatedly appending to a string, we get a cons string that // When repeatedly appending to a string, we get a cons string that
// is unbalanced to the left, a list, essentially. We inline the // is unbalanced to the left, a list, essentially. We inline the
// common case of sequential one-byte right child. // common case of sequential one-byte right child.
if (to - boundary == 1) { if (to - boundary == 1) {
sink[boundary - from] = static_cast<sinkchar>(second.Get(0)); sink[boundary - from] =
} else if (second.IsSeqOneByteString()) { static_cast<sinkchar>(second.Get(0, cage_base, access_guard));
} else if (second.IsSeqOneByteString(cage_base)) {
CopyChars( CopyChars(
sink + boundary - from, sink + boundary - from,
SeqOneByteString::cast(second).GetChars(no_gc, access_guard), SeqOneByteString::cast(second).GetChars(no_gc, access_guard),
to - boundary); to - boundary);
} else { } else {
WriteToFlat(second, sink + boundary - from, 0, to - boundary, WriteToFlat(second, sink + boundary - from, 0, to - boundary,
access_guard); cage_base, access_guard);
} }
to = boundary; to = boundary;
} }
source = first; source = first;
} }
break; if (from == to) return;
continue;
} }
case kOneByteStringTag | kSlicedStringTag: case kOneByteStringTag | kSlicedStringTag:
case kTwoByteStringTag | kSlicedStringTag: { case kTwoByteStringTag | kSlicedStringTag: {
SlicedString slice = SlicedString::cast(source); SlicedString slice = SlicedString::cast(source);
unsigned offset = slice.offset(); unsigned offset = slice.offset();
WriteToFlat(slice.parent(), sink, from + offset, to + offset, source = slice.parent(cage_base);
access_guard); from += offset;
return; to += offset;
continue;
} }
case kOneByteStringTag | kThinStringTag: case kOneByteStringTag | kThinStringTag:
case kTwoByteStringTag | kThinStringTag: case kTwoByteStringTag | kThinStringTag:
source = ThinString::cast(source).actual(); source = ThinString::cast(source).actual(cage_base);
break; continue;
} }
UNREACHABLE();
} }
DCHECK_EQ(from, to); UNREACHABLE();
} }
template <typename SourceChar> template <typename SourceChar>
...@@ -819,12 +822,15 @@ bool String::SlowEquals( ...@@ -819,12 +822,15 @@ bool String::SlowEquals(
if (len != other.length()) return false; if (len != other.length()) return false;
if (len == 0) return true; if (len == 0) return true;
PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
// Fast check: if at least one ThinString is involved, dereference it/them // Fast check: if at least one ThinString is involved, dereference it/them
// and restart. // and restart.
if (this->IsThinString() || other.IsThinString()) { if (this->IsThinString(cage_base) || other.IsThinString(cage_base)) {
if (other.IsThinString()) other = ThinString::cast(other).actual(); if (other.IsThinString(cage_base))
if (this->IsThinString()) { other = ThinString::cast(other).actual(cage_base);
return ThinString::cast(*this).actual().Equals(other); if (this->IsThinString(cage_base)) {
return ThinString::cast(*this).actual(cage_base).Equals(other);
} else { } else {
return this->Equals(other); return this->Equals(other);
} }
...@@ -852,7 +858,9 @@ bool String::SlowEquals( ...@@ -852,7 +858,9 @@ bool String::SlowEquals(
// We know the strings are both non-empty. Compare the first chars // We know the strings are both non-empty. Compare the first chars
// before we try to flatten the strings. // before we try to flatten the strings.
if (this->Get(0, access_guard) != other.Get(0, access_guard)) return false; if (this->Get(0, cage_base, access_guard) !=
other.Get(0, cage_base, access_guard))
return false;
if (IsSeqOneByteString() && other.IsSeqOneByteString()) { if (IsSeqOneByteString() && other.IsSeqOneByteString()) {
const uint8_t* str1 = const uint8_t* str1 =
...@@ -1348,6 +1356,7 @@ namespace { ...@@ -1348,6 +1356,7 @@ namespace {
template <typename Char> template <typename Char>
uint32_t HashString(String string, size_t start, int length, uint64_t seed, uint32_t HashString(String string, size_t start, int length, uint64_t seed,
PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) { const SharedStringAccessGuardIfNeeded& access_guard) {
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
...@@ -1358,11 +1367,12 @@ uint32_t HashString(String string, size_t start, int length, uint64_t seed, ...@@ -1358,11 +1367,12 @@ uint32_t HashString(String string, size_t start, int length, uint64_t seed,
std::unique_ptr<Char[]> buffer; std::unique_ptr<Char[]> buffer;
const Char* chars; const Char* chars;
if (string.IsConsString()) { if (string.IsConsString(cage_base)) {
DCHECK_EQ(0, start); DCHECK_EQ(0, start);
DCHECK(!string.IsFlat()); DCHECK(!string.IsFlat());
buffer.reset(new Char[length]); buffer.reset(new Char[length]);
String::WriteToFlat(string, buffer.get(), 0, length, access_guard); String::WriteToFlat(string, buffer.get(), 0, length, cage_base,
access_guard);
chars = buffer.get(); chars = buffer.get();
} else { } else {
chars = string.GetChars<Char>(no_gc, access_guard) + start; chars = string.GetChars<Char>(no_gc, access_guard) + start;
...@@ -1387,25 +1397,32 @@ uint32_t String::ComputeAndSetHash( ...@@ -1387,25 +1397,32 @@ uint32_t String::ComputeAndSetHash(
uint64_t seed = HashSeed(GetReadOnlyRoots()); uint64_t seed = HashSeed(GetReadOnlyRoots());
size_t start = 0; size_t start = 0;
String string = *this; String string = *this;
if (string.IsSlicedString()) { PtrComprCageBase cage_base = GetPtrComprCageBase(string);
StringShape shape(string, cage_base);
if (shape.IsSliced()) {
SlicedString sliced = SlicedString::cast(string); SlicedString sliced = SlicedString::cast(string);
start = sliced.offset(); start = sliced.offset();
string = sliced.parent(); string = sliced.parent(cage_base);
shape = StringShape(string, cage_base);
} }
if (string.IsConsString() && string.IsFlat()) { if (shape.IsCons() && string.IsFlat(cage_base)) {
string = ConsString::cast(string).first(); string = ConsString::cast(string).first(cage_base);
shape = StringShape(string, cage_base);
} }
if (string.IsThinString()) { if (shape.IsThin()) {
string = ThinString::cast(string).actual(); string = ThinString::cast(string).actual(cage_base);
shape = StringShape(string, cage_base);
if (length() == string.length()) { if (length() == string.length()) {
set_raw_hash_field(string.raw_hash_field()); set_raw_hash_field(string.raw_hash_field());
return hash(); return hash();
} }
} }
uint32_t raw_hash_field = uint32_t raw_hash_field =
string.IsOneByteRepresentation() shape.encoding_tag() == kOneByteStringTag
? HashString<uint8_t>(string, start, length(), seed, access_guard) ? HashString<uint8_t>(string, start, length(), seed, cage_base,
: HashString<uint16_t>(string, start, length(), seed, access_guard); access_guard)
: HashString<uint16_t>(string, start, length(), seed, cage_base,
access_guard);
set_raw_hash_field(raw_hash_field); set_raw_hash_field(raw_hash_field);
// Check the hash code is there. // Check the hash code is there.
...@@ -1509,29 +1526,30 @@ void SeqTwoByteString::clear_padding() { ...@@ -1509,29 +1526,30 @@ void SeqTwoByteString::clear_padding() {
} }
uint16_t ConsString::Get( uint16_t ConsString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const { int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const {
DCHECK(index >= 0 && index < this->length()); DCHECK(index >= 0 && index < this->length());
// Check for a flattened cons string // Check for a flattened cons string
if (second().length() == 0) { if (second(cage_base).length() == 0) {
String left = first(); String left = first(cage_base);
return left.Get(index); return left.Get(index);
} }
String string = String::cast(*this); String string = String::cast(*this);
while (true) { while (true) {
if (StringShape(string).IsCons()) { if (StringShape(string, cage_base).IsCons()) {
ConsString cons_string = ConsString::cast(string); ConsString cons_string = ConsString::cast(string);
String left = cons_string.first(); String left = cons_string.first();
if (left.length() > index) { if (left.length() > index) {
string = left; string = left;
} else { } else {
index -= left.length(); index -= left.length();
string = cons_string.second(); string = cons_string.second(cage_base);
} }
} else { } else {
return string.Get(index, access_guard); return string.Get(index, cage_base, access_guard);
} }
} }
...@@ -1539,13 +1557,15 @@ uint16_t ConsString::Get( ...@@ -1539,13 +1557,15 @@ uint16_t ConsString::Get(
} }
uint16_t ThinString::Get( uint16_t ThinString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const { int index, PtrComprCageBase cage_base,
return actual().Get(index, access_guard); const SharedStringAccessGuardIfNeeded& access_guard) const {
return actual(cage_base).Get(index, cage_base, access_guard);
} }
uint16_t SlicedString::Get( uint16_t SlicedString::Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const { int index, PtrComprCageBase cage_base,
return parent().Get(offset() + index, access_guard); const SharedStringAccessGuardIfNeeded& access_guard) const {
return parent(cage_base).Get(offset() + index, cage_base, access_guard);
} }
int ExternalString::ExternalPayloadSize() const { int ExternalString::ExternalPayloadSize() const {
...@@ -1744,10 +1764,10 @@ template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void String::WriteToFlat( ...@@ -1744,10 +1764,10 @@ template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void String::WriteToFlat(
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void String::WriteToFlat( template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void String::WriteToFlat(
String source, uint8_t* sink, int from, int to); String source, uint8_t* sink, int from, int to);
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void String::WriteToFlat( template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void String::WriteToFlat(
String source, uint16_t* sink, int from, int to, String source, uint16_t* sink, int from, int to, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded&); const SharedStringAccessGuardIfNeeded&);
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void String::WriteToFlat( template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void String::WriteToFlat(
String source, uint8_t* sink, int from, int to, String source, uint8_t* sink, int from, int to, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded&); const SharedStringAccessGuardIfNeeded&);
namespace { namespace {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/base/export-template.h" #include "src/base/export-template.h"
#include "src/base/strings.h" #include "src/base/strings.h"
#include "src/common/globals.h"
#include "src/objects/instance-type.h" #include "src/objects/instance-type.h"
#include "src/objects/name.h" #include "src/objects/name.h"
#include "src/objects/smi.h" #include "src/objects/smi.h"
...@@ -43,6 +44,7 @@ enum RobustnessFlag { ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL }; ...@@ -43,6 +44,7 @@ enum RobustnessFlag { ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL };
class StringShape { class StringShape {
public: public:
inline explicit StringShape(const String s); inline explicit StringShape(const String s);
inline explicit StringShape(const String s, PtrComprCageBase cage_base);
inline explicit StringShape(Map s); inline explicit StringShape(Map s);
inline explicit StringShape(InstanceType t); inline explicit StringShape(InstanceType t);
inline bool IsSequential() const; inline bool IsSequential() const;
...@@ -220,13 +222,15 @@ class String : public TorqueGeneratedString<String, Name> { ...@@ -220,13 +222,15 @@ class String : public TorqueGeneratedString<String, Name> {
// to this method are not efficient unless the string is flat. // to this method are not efficient unless the string is flat.
// If it is called from a background thread, the LocalIsolate version should // If it is called from a background thread, the LocalIsolate version should
// be used. // 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; V8_INLINE uint16_t Get(int index, LocalIsolate* local_isolate) const;
// Method to pass down the access_guard. Useful for recursive calls such as // 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 // ThinStrings where we go String::Get into ThinString::Get into String::Get
// again for the internalized string. // again for the internalized string.
V8_INLINE uint16_t 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 // ES6 section 7.1.3.1 ToNumber Applied to the String Type
static Handle<Object> ToNumber(Isolate* isolate, Handle<String> subject); static Handle<Object> ToNumber(Isolate* isolate, Handle<String> subject);
...@@ -429,6 +433,7 @@ class String : public TorqueGeneratedString<String, Name> { ...@@ -429,6 +433,7 @@ class String : public TorqueGeneratedString<String, Name> {
DECL_VERIFIER(String) DECL_VERIFIER(String)
inline bool IsFlat() const; inline bool IsFlat() const;
inline bool IsFlat(PtrComprCageBase cage_base) const;
// Max char codes. // Max char codes.
static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar; static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
...@@ -474,6 +479,7 @@ class String : public TorqueGeneratedString<String, Name> { ...@@ -474,6 +479,7 @@ class String : public TorqueGeneratedString<String, Name> {
static void WriteToFlat(String source, sinkchar* sink, int from, int to); static void WriteToFlat(String source, sinkchar* sink, int from, int to);
template <typename sinkchar> template <typename sinkchar>
static void WriteToFlat(String source, sinkchar* sink, int from, int to, static void WriteToFlat(String source, sinkchar* sink, int from, int to,
PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded&); const SharedStringAccessGuardIfNeeded&);
static inline bool IsAscii(const char* chars, int length) { static inline bool IsAscii(const char* chars, int length) {
...@@ -551,7 +557,8 @@ class String : public TorqueGeneratedString<String, Name> { ...@@ -551,7 +557,8 @@ class String : public TorqueGeneratedString<String, Name> {
// Implementation of the Get() public methods. Do not use directly. // Implementation of the Get() public methods. Do not use directly.
V8_INLINE uint16_t 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. // Implementation of the IsEqualTo() public methods. Do not use directly.
template <EqualityType kEqType, typename Char> template <EqualityType kEqType, typename Char>
...@@ -596,11 +603,13 @@ void String::WriteToFlat(String source, uint8_t* sink, int from, int to); ...@@ -596,11 +603,13 @@ void String::WriteToFlat(String source, uint8_t* sink, int from, int to);
extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
void String::WriteToFlat(String source, uint16_t* sink, int from, int to); void String::WriteToFlat(String source, uint16_t* sink, int from, int to);
extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
void String::WriteToFlat(String source, uint8_t* sink, int from, int to , void String::WriteToFlat(String source, uint8_t* sink, int from, int to,
const SharedStringAccessGuardIfNeeded&); PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded&);
extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
void String::WriteToFlat(String source, uint16_t* sink, int from, int to, void String::WriteToFlat(String source, uint16_t* sink, int from, int to,
const SharedStringAccessGuardIfNeeded&); PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded&);
// clang-format on // clang-format on
class SubStringRange { class SubStringRange {
...@@ -650,7 +659,7 @@ class SeqOneByteString ...@@ -650,7 +659,7 @@ class SeqOneByteString
// defined for convenience and it will check that the access guard is not // defined for convenience and it will check that the access guard is not
// needed. // needed.
inline uint8_t Get(int index) const; 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; const SharedStringAccessGuardIfNeeded& access_guard) const;
inline void SeqOneByteStringSet(int index, uint16_t value); inline void SeqOneByteStringSet(int index, uint16_t value);
...@@ -698,7 +707,8 @@ class SeqTwoByteString ...@@ -698,7 +707,8 @@ class SeqTwoByteString
// Dispatched behavior. // Dispatched behavior.
inline uint16_t Get( 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); inline void SeqTwoByteStringSet(int index, uint16_t value);
// Get the address of the characters in this string. // Get the address of the characters in this string.
...@@ -756,7 +766,8 @@ class ConsString : public TorqueGeneratedConsString<ConsString, String> { ...@@ -756,7 +766,8 @@ class ConsString : public TorqueGeneratedConsString<ConsString, String> {
// Dispatched behavior. // Dispatched behavior.
V8_EXPORT_PRIVATE uint16_t 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. // Minimum length for a cons string.
static const int kMinLength = 13; static const int kMinLength = 13;
...@@ -780,7 +791,8 @@ class ThinString : public TorqueGeneratedThinString<ThinString, String> { ...@@ -780,7 +791,8 @@ class ThinString : public TorqueGeneratedThinString<ThinString, String> {
DECL_GETTER(unchecked_actual, HeapObject) DECL_GETTER(unchecked_actual, HeapObject)
V8_EXPORT_PRIVATE uint16_t 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) DECL_VERIFIER(ThinString)
...@@ -805,7 +817,8 @@ class SlicedString : public TorqueGeneratedSlicedString<SlicedString, String> { ...@@ -805,7 +817,8 @@ class SlicedString : public TorqueGeneratedSlicedString<SlicedString, String> {
WriteBarrierMode mode = UPDATE_WRITE_BARRIER); WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// Dispatched behavior. // Dispatched behavior.
V8_EXPORT_PRIVATE uint16_t 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. // Minimum length for a sliced string.
static const int kMinLength = 13; static const int kMinLength = 13;
...@@ -891,7 +904,7 @@ class ExternalOneByteString ...@@ -891,7 +904,7 @@ class ExternalOneByteString
inline const uint8_t* GetChars() const; inline const uint8_t* GetChars() const;
// Dispatched behavior. // Dispatched behavior.
inline uint8_t Get(int index, inline uint8_t Get(int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const; const SharedStringAccessGuardIfNeeded& access_guard) const;
class BodyDescriptor; class BodyDescriptor;
...@@ -935,7 +948,8 @@ class ExternalTwoByteString ...@@ -935,7 +948,8 @@ class ExternalTwoByteString
// Dispatched behavior. // Dispatched behavior.
inline uint16_t Get( inline uint16_t Get(
int index, const SharedStringAccessGuardIfNeeded& access_guard) const; int index, PtrComprCageBase cage_base,
const SharedStringAccessGuardIfNeeded& access_guard) const;
// For regexp code. // For regexp code.
inline const uint16_t* ExternalTwoByteStringGetData(unsigned start); 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