@@ -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 {
88958904class 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 {
90379052class 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 {
91599180class 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 {
92509278class 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