Skip to content

Commit 1561cc3

Browse files
mkustermanncommit-bot@chromium.org
authored and
commit-bot@chromium.org
committed
[vm] Allow usage of String::StartsWith() without handle allocation.
This is extracted from another CL. Change-Id: I09fda96b55bd259b5caecf44fff0788dc56445ae Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153981 Reviewed-by: Tess Strickland <sstrickl@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
1 parent 3d5df93 commit 1561cc3

File tree

2 files changed

+75
-33
lines changed

2 files changed

+75
-33
lines changed

runtime/vm/object.cc

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3660,7 +3660,11 @@ bool Library::FindPragma(Thread* T,
36603660
}
36613661

36623662
bool Function::IsDynamicInvocationForwarderName(const String& name) {
3663-
return name.StartsWith(Symbols::DynamicPrefix());
3663+
return IsDynamicInvocationForwarderName(name.raw());
3664+
}
3665+
3666+
bool Function::IsDynamicInvocationForwarderName(StringPtr name) {
3667+
return String::StartsWith(name, Symbols::DynamicPrefix().raw());
36643668
}
36653669

36663670
StringPtr Function::DemangleDynamicInvocationForwarderName(const String& name) {
@@ -21288,22 +21292,6 @@ intptr_t String::Hash(const int32_t* characters, intptr_t len) {
2128821292
return HashImpl(characters, len);
2128921293
}
2129021294

21291-
uint16_t String::CharAt(intptr_t index) const {
21292-
intptr_t class_id = raw()->GetClassId();
21293-
ASSERT(IsStringClassId(class_id));
21294-
if (class_id == kOneByteStringCid) {
21295-
return OneByteString::CharAt(*this, index);
21296-
}
21297-
if (class_id == kTwoByteStringCid) {
21298-
return TwoByteString::CharAt(*this, index);
21299-
}
21300-
if (class_id == kExternalOneByteStringCid) {
21301-
return ExternalOneByteString::CharAt(*this, index);
21302-
}
21303-
ASSERT(class_id == kExternalTwoByteStringCid);
21304-
return ExternalTwoByteString::CharAt(*this, index);
21305-
}
21306-
2130721295
intptr_t String::CharSize() const {
2130821296
intptr_t class_id = raw()->GetClassId();
2130921297
if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) {
@@ -21449,13 +21437,15 @@ intptr_t String::CompareTo(const String& other) const {
2144921437
return 0;
2145021438
}
2145121439

21452-
bool String::StartsWith(const String& other) const {
21453-
if (other.IsNull() || (other.Length() > this->Length())) {
21454-
return false;
21455-
}
21456-
intptr_t slen = other.Length();
21457-
for (int i = 0; i < slen; i++) {
21458-
if (this->CharAt(i) != other.CharAt(i)) {
21440+
bool String::StartsWith(StringPtr str, StringPtr prefix) {
21441+
if (prefix == String::null()) return false;
21442+
21443+
const intptr_t length = String::LengthOf(str);
21444+
const intptr_t prefix_length = String::LengthOf(prefix);
21445+
if (prefix_length > length) return false;
21446+
21447+
for (intptr_t i = 0; i < prefix_length; i++) {
21448+
if (String::CharAt(str, i) != String::CharAt(prefix, i)) {
2145921449
return false;
2146021450
}
2146121451
}

runtime/vm/object.h

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3498,6 +3498,7 @@ class Function : public Object {
34983498
FunctionPtr GetMethodExtractor(const String& getter_name) const;
34993499

35003500
static bool IsDynamicInvocationForwarderName(const String& name);
3501+
static bool IsDynamicInvocationForwarderName(StringPtr name);
35013502

35023503
static StringPtr DemangleDynamicInvocationForwarderName(const String& name);
35033504

@@ -8607,7 +8608,10 @@ class String : public Instance {
86078608
DISALLOW_IMPLICIT_CONSTRUCTORS(CodePointIterator);
86088609
};
86098610

8610-
intptr_t Length() const { return Smi::Value(raw_ptr()->length_); }
8611+
intptr_t Length() const { return LengthOf(raw()); }
8612+
static intptr_t LengthOf(StringPtr obj) {
8613+
return Smi::Value(obj->ptr()->length_);
8614+
}
86118615
static intptr_t length_offset() { return OFFSET_OF(StringLayout, length_); }
86128616

86138617
intptr_t Hash() const {
@@ -8644,7 +8648,8 @@ class String : public Instance {
86448648

86458649
virtual ObjectPtr HashCode() const { return Integer::New(Hash()); }
86468650

8647-
uint16_t CharAt(intptr_t index) const;
8651+
uint16_t CharAt(intptr_t index) const { return CharAt(raw(), index); }
8652+
static uint16_t CharAt(StringPtr str, intptr_t index);
86488653

86498654
intptr_t CharSize() const;
86508655

@@ -8682,7 +8687,11 @@ class String : public Instance {
86828687

86838688
intptr_t CompareTo(const String& other) const;
86848689

8685-
bool StartsWith(const String& other) const;
8690+
bool StartsWith(const String& other) const {
8691+
NoSafepointScope no_safepoint;
8692+
return StartsWith(raw(), other.raw());
8693+
}
8694+
static bool StartsWith(StringPtr str, StringPtr prefix);
86868695
bool EndsWith(const String& other) const;
86878696

86888697
// Strings are canonicalized using the symbol table.
@@ -8895,9 +8904,15 @@ class String : public Instance {
88958904
class OneByteString : public AllStatic {
88968905
public:
88978906
static uint16_t CharAt(const String& str, intptr_t index) {
8898-
ASSERT((index >= 0) && (index < str.Length()));
88998907
ASSERT(str.IsOneByteString());
8900-
return raw_ptr(str)->data()[index];
8908+
NoSafepointScope no_safepoint;
8909+
return OneByteString::CharAt(static_cast<OneByteStringPtr>(str.raw()),
8910+
index);
8911+
}
8912+
8913+
static uint16_t CharAt(OneByteStringPtr str, intptr_t index) {
8914+
ASSERT(index >= 0 && index < String::LengthOf(str));
8915+
return str->ptr()->data()[index];
89018916
}
89028917

89038918
static void SetCharAt(const String& str, intptr_t index, uint8_t code_unit) {
@@ -9037,9 +9052,15 @@ class OneByteString : public AllStatic {
90379052
class TwoByteString : public AllStatic {
90389053
public:
90399054
static uint16_t CharAt(const String& str, intptr_t index) {
9040-
ASSERT((index >= 0) && (index < str.Length()));
90419055
ASSERT(str.IsTwoByteString());
9042-
return raw_ptr(str)->data()[index];
9056+
NoSafepointScope no_safepoint;
9057+
return TwoByteString::CharAt(static_cast<TwoByteStringPtr>(str.raw()),
9058+
index);
9059+
}
9060+
9061+
static uint16_t CharAt(TwoByteStringPtr str, intptr_t index) {
9062+
ASSERT(index >= 0 && index < String::LengthOf(str));
9063+
return str->ptr()->data()[index];
90439064
}
90449065

90459066
static void SetCharAt(const String& str, intptr_t index, uint16_t ch) {
@@ -9159,8 +9180,15 @@ class TwoByteString : public AllStatic {
91599180
class ExternalOneByteString : public AllStatic {
91609181
public:
91619182
static uint16_t CharAt(const String& str, intptr_t index) {
9183+
ASSERT(str.IsExternalOneByteString());
91629184
NoSafepointScope no_safepoint;
9163-
return *CharAddr(str, index);
9185+
return ExternalOneByteString::CharAt(
9186+
static_cast<ExternalOneByteStringPtr>(str.raw()), index);
9187+
}
9188+
9189+
static uint16_t CharAt(ExternalOneByteStringPtr str, intptr_t index) {
9190+
ASSERT(index >= 0 && index < String::LengthOf(str));
9191+
return str->ptr()->external_data_[index];
91649192
}
91659193

91669194
static void* GetPeer(const String& str) { return raw_ptr(str)->peer_; }
@@ -9250,8 +9278,15 @@ class ExternalOneByteString : public AllStatic {
92509278
class ExternalTwoByteString : public AllStatic {
92519279
public:
92529280
static uint16_t CharAt(const String& str, intptr_t index) {
9281+
ASSERT(str.IsExternalTwoByteString());
92539282
NoSafepointScope no_safepoint;
9254-
return *CharAddr(str, index);
9283+
return ExternalTwoByteString::CharAt(
9284+
static_cast<ExternalTwoByteStringPtr>(str.raw()), index);
9285+
}
9286+
9287+
static uint16_t CharAt(ExternalTwoByteStringPtr str, intptr_t index) {
9288+
ASSERT(index >= 0 && index < String::LengthOf(str));
9289+
return str->ptr()->external_data_[index];
92559290
}
92569291

92579292
static void* GetPeer(const String& str) { return raw_ptr(str)->peer_; }
@@ -11202,6 +11237,23 @@ inline void TypeArguments::SetHash(intptr_t value) const {
1120211237
StoreSmi(&raw_ptr()->hash_, Smi::New(value));
1120311238
}
1120411239

11240+
inline uint16_t String::CharAt(StringPtr str, intptr_t index) {
11241+
switch (str->GetClassId()) {
11242+
case kOneByteStringCid:
11243+
return OneByteString::CharAt(static_cast<OneByteStringPtr>(str), index);
11244+
case kTwoByteStringCid:
11245+
return TwoByteString::CharAt(static_cast<TwoByteStringPtr>(str), index);
11246+
case kExternalOneByteStringCid:
11247+
return ExternalOneByteString::CharAt(
11248+
static_cast<ExternalOneByteStringPtr>(str), index);
11249+
case kExternalTwoByteStringCid:
11250+
return ExternalTwoByteString::CharAt(
11251+
static_cast<ExternalTwoByteStringPtr>(str), index);
11252+
}
11253+
UNREACHABLE();
11254+
return 0;
11255+
}
11256+
1120511257
// A view on an [Array] as a list of tuples, optionally starting at an offset.
1120611258
//
1120711259
// Example: We store a list of (kind, function, code) tuples into the

0 commit comments

Comments
 (0)