- Specialized slow-case string equality nine ways based on the

  underlying string representation of the two strings involved.
- Renamed ascii and two byte string classes to sequential ascii and
  sequential two byte, and renamed IsAscii and friends to
  IsAsciiRepresentation.  This is to make a clear distinction between
  strings with an ascii/two-byte representation, of which there is
  four, and flat sequential ascii/two-byte string.


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@474 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f6a26964
...@@ -63,7 +63,7 @@ class SourceCodeCache BASE_EMBEDDED { ...@@ -63,7 +63,7 @@ class SourceCodeCache BASE_EMBEDDED {
bool Lookup(Vector<const char> name, Handle<JSFunction>* handle) { bool Lookup(Vector<const char> name, Handle<JSFunction>* handle) {
for (int i = 0; i < cache_->length(); i+=2) { for (int i = 0; i < cache_->length(); i+=2) {
AsciiString* str = AsciiString::cast(cache_->get(i)); SeqAsciiString* str = SeqAsciiString::cast(cache_->get(i));
if (str->IsEqualTo(name)) { if (str->IsEqualTo(name)) {
*handle = Handle<JSFunction>(JSFunction::cast(cache_->get(i + 1))); *handle = Handle<JSFunction>(JSFunction::cast(cache_->get(i + 1)));
return true; return true;
...@@ -751,7 +751,7 @@ bool Genesis::CompileScriptCached(Vector<const char> name, ...@@ -751,7 +751,7 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
// function and insert it into the cache. // function and insert it into the cache.
if (!cache->Lookup(name, &boilerplate)) { if (!cache->Lookup(name, &boilerplate)) {
#ifdef DEBUG #ifdef DEBUG
ASSERT(source->IsAscii()); ASSERT(source->IsAsciiRepresentation());
#endif #endif
Handle<String> script_name = Factory::NewStringFromUtf8(name); Handle<String> script_name = Factory::NewStringFromUtf8(name);
boilerplate = boilerplate =
......
...@@ -3156,13 +3156,14 @@ void Ia32CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { ...@@ -3156,13 +3156,14 @@ void Ia32CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
// 2-byte string. // 2-byte string.
// Load the 2-byte character code. // Load the 2-byte character code.
__ movzx_w(eax, FieldOperand(eax, ebx, times_2, TwoByteString::kHeaderSize)); __ movzx_w(eax,
FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize));
__ jmp(&got_char_code); __ jmp(&got_char_code);
// ASCII string. // ASCII string.
__ bind(&ascii_string); __ bind(&ascii_string);
// Load the byte. // Load the byte.
__ movzx_b(eax, FieldOperand(eax, ebx, times_1, AsciiString::kHeaderSize)); __ movzx_b(eax, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize));
__ bind(&got_char_code); __ bind(&got_char_code);
ASSERT(kSmiTag == 0); ASSERT(kSmiTag == 0);
......
...@@ -931,32 +931,32 @@ bool Heap::CreateInitialMaps() { ...@@ -931,32 +931,32 @@ bool Heap::CreateInitialMaps() {
STRING_TYPE_LIST(ALLOCATE_STRING_MAP); STRING_TYPE_LIST(ALLOCATE_STRING_MAP);
#undef ALLOCATE_STRING_MAP #undef ALLOCATE_STRING_MAP
obj = AllocateMap(SHORT_STRING_TYPE, TwoByteString::kHeaderSize); obj = AllocateMap(SHORT_STRING_TYPE, SeqTwoByteString::kHeaderSize);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
undetectable_short_string_map_ = Map::cast(obj); undetectable_short_string_map_ = Map::cast(obj);
undetectable_short_string_map_->set_is_undetectable(); undetectable_short_string_map_->set_is_undetectable();
obj = AllocateMap(MEDIUM_STRING_TYPE, TwoByteString::kHeaderSize); obj = AllocateMap(MEDIUM_STRING_TYPE, SeqTwoByteString::kHeaderSize);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
undetectable_medium_string_map_ = Map::cast(obj); undetectable_medium_string_map_ = Map::cast(obj);
undetectable_medium_string_map_->set_is_undetectable(); undetectable_medium_string_map_->set_is_undetectable();
obj = AllocateMap(LONG_STRING_TYPE, TwoByteString::kHeaderSize); obj = AllocateMap(LONG_STRING_TYPE, SeqTwoByteString::kHeaderSize);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
undetectable_long_string_map_ = Map::cast(obj); undetectable_long_string_map_ = Map::cast(obj);
undetectable_long_string_map_->set_is_undetectable(); undetectable_long_string_map_->set_is_undetectable();
obj = AllocateMap(SHORT_ASCII_STRING_TYPE, AsciiString::kHeaderSize); obj = AllocateMap(SHORT_ASCII_STRING_TYPE, SeqAsciiString::kHeaderSize);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
undetectable_short_ascii_string_map_ = Map::cast(obj); undetectable_short_ascii_string_map_ = Map::cast(obj);
undetectable_short_ascii_string_map_->set_is_undetectable(); undetectable_short_ascii_string_map_->set_is_undetectable();
obj = AllocateMap(MEDIUM_ASCII_STRING_TYPE, AsciiString::kHeaderSize); obj = AllocateMap(MEDIUM_ASCII_STRING_TYPE, SeqAsciiString::kHeaderSize);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
undetectable_medium_ascii_string_map_ = Map::cast(obj); undetectable_medium_ascii_string_map_ = Map::cast(obj);
undetectable_medium_ascii_string_map_->set_is_undetectable(); undetectable_medium_ascii_string_map_->set_is_undetectable();
obj = AllocateMap(LONG_ASCII_STRING_TYPE, AsciiString::kHeaderSize); obj = AllocateMap(LONG_ASCII_STRING_TYPE, SeqAsciiString::kHeaderSize);
if (obj->IsFailure()) return false; if (obj->IsFailure()) return false;
undetectable_long_ascii_string_map_ = Map::cast(obj); undetectable_long_ascii_string_map_ = Map::cast(obj);
undetectable_long_ascii_string_map_->set_is_undetectable(); undetectable_long_ascii_string_map_->set_is_undetectable();
...@@ -1328,7 +1328,8 @@ Object* Heap::AllocateSharedFunctionInfo(Object* name) { ...@@ -1328,7 +1328,8 @@ Object* Heap::AllocateSharedFunctionInfo(Object* name) {
Object* Heap::AllocateConsString(String* first, String* second) { Object* Heap::AllocateConsString(String* first, String* second) {
int length = first->length() + second->length(); int length = first->length() + second->length();
bool is_ascii = first->is_ascii() && second->is_ascii(); bool is_ascii = first->is_ascii_representation()
&& second->is_ascii_representation();
// If the resulting string is small make a flat string. // If the resulting string is small make a flat string.
if (length < ConsString::kMinLength) { if (length < ConsString::kMinLength) {
...@@ -1385,13 +1386,13 @@ Object* Heap::AllocateSlicedString(String* buffer, int start, int end) { ...@@ -1385,13 +1386,13 @@ Object* Heap::AllocateSlicedString(String* buffer, int start, int end) {
Map* map; Map* map;
if (length <= String::kMaxShortStringSize) { if (length <= String::kMaxShortStringSize) {
map = buffer->is_ascii() ? short_sliced_ascii_string_map() map = buffer->is_ascii_representation() ? short_sliced_ascii_string_map()
: short_sliced_string_map(); : short_sliced_string_map();
} else if (length <= String::kMaxMediumStringSize) { } else if (length <= String::kMaxMediumStringSize) {
map = buffer->is_ascii() ? medium_sliced_ascii_string_map() map = buffer->is_ascii_representation() ? medium_sliced_ascii_string_map()
: medium_sliced_string_map(); : medium_sliced_string_map();
} else { } else {
map = buffer->is_ascii() ? long_sliced_ascii_string_map() map = buffer->is_ascii_representation() ? long_sliced_ascii_string_map()
: long_sliced_string_map(); : long_sliced_string_map();
} }
...@@ -1417,7 +1418,7 @@ Object* Heap::AllocateSubString(String* buffer, int start, int end) { ...@@ -1417,7 +1418,7 @@ Object* Heap::AllocateSubString(String* buffer, int start, int end) {
// Make an attempt to flatten the buffer to reduce access time. // Make an attempt to flatten the buffer to reduce access time.
buffer->TryFlatten(); buffer->TryFlatten();
Object* result = buffer->is_ascii() Object* result = buffer->is_ascii_representation()
? AllocateRawAsciiString(length) ? AllocateRawAsciiString(length)
: AllocateRawTwoByteString(length); : AllocateRawTwoByteString(length);
if (result->IsFailure()) return result; if (result->IsFailure()) return result;
...@@ -1768,9 +1769,9 @@ Object* Heap::AllocateStringFromAscii(Vector<const char> string, ...@@ -1768,9 +1769,9 @@ Object* Heap::AllocateStringFromAscii(Vector<const char> string,
if (result->IsFailure()) return result; if (result->IsFailure()) return result;
// Copy the characters into the new object. // Copy the characters into the new object.
AsciiString* string_result = AsciiString::cast(result); SeqAsciiString* string_result = SeqAsciiString::cast(result);
for (int i = 0; i < string.length(); i++) { for (int i = 0; i < string.length(); i++) {
string_result->AsciiStringSet(i, string[i]); string_result->SeqAsciiStringSet(i, string[i]);
} }
return result; return result;
} }
...@@ -1918,7 +1919,7 @@ Object* Heap::AllocateSymbol(unibrow::CharacterStream* buffer, ...@@ -1918,7 +1919,7 @@ Object* Heap::AllocateSymbol(unibrow::CharacterStream* buffer,
} else { } else {
map = long_ascii_symbol_map(); map = long_ascii_symbol_map();
} }
size = AsciiString::SizeFor(chars); size = SeqAsciiString::SizeFor(chars);
} else { } else {
if (chars <= String::kMaxShortStringSize) { if (chars <= String::kMaxShortStringSize) {
map = short_symbol_map(); map = short_symbol_map();
...@@ -1927,7 +1928,7 @@ Object* Heap::AllocateSymbol(unibrow::CharacterStream* buffer, ...@@ -1927,7 +1928,7 @@ Object* Heap::AllocateSymbol(unibrow::CharacterStream* buffer,
} else { } else {
map = long_symbol_map(); map = long_symbol_map();
} }
size = TwoByteString::SizeFor(chars); size = SeqTwoByteString::SizeFor(chars);
} }
// Allocate string. // Allocate string.
...@@ -1952,7 +1953,7 @@ Object* Heap::AllocateSymbol(unibrow::CharacterStream* buffer, ...@@ -1952,7 +1953,7 @@ Object* Heap::AllocateSymbol(unibrow::CharacterStream* buffer,
Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) { Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
int size = AsciiString::SizeFor(length); int size = SeqAsciiString::SizeFor(length);
if (size > MaxHeapObjectSize()) { if (size > MaxHeapObjectSize()) {
space = LO_SPACE; space = LO_SPACE;
} }
...@@ -1982,7 +1983,7 @@ Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) { ...@@ -1982,7 +1983,7 @@ Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
Object* Heap::AllocateRawTwoByteString(int length, PretenureFlag pretenure) { Object* Heap::AllocateRawTwoByteString(int length, PretenureFlag pretenure) {
AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
int size = TwoByteString::SizeFor(length); int size = SeqTwoByteString::SizeFor(length);
if (size > MaxHeapObjectSize()) { if (size > MaxHeapObjectSize()) {
space = LO_SPACE; space = LO_SPACE;
} }
......
...@@ -128,7 +128,7 @@ Handle<String> RegExpImpl::StringToTwoByte(Handle<String> pattern) { ...@@ -128,7 +128,7 @@ Handle<String> RegExpImpl::StringToTwoByte(Handle<String> pattern) {
ASSERT(!flat_string->IsConsString()); ASSERT(!flat_string->IsConsString());
ASSERT(flat_string->IsSeqString() || flat_string->IsSlicedString() || ASSERT(flat_string->IsSeqString() || flat_string->IsSlicedString() ||
flat_string->IsExternalString()); flat_string->IsExternalString());
if (!flat_string->IsAscii()) { if (!flat_string->IsAsciiRepresentation()) {
return flat_string; return flat_string;
} }
......
...@@ -119,13 +119,25 @@ bool Object::IsSeqString() { ...@@ -119,13 +119,25 @@ bool Object::IsSeqString() {
} }
bool Object::IsAsciiString() { bool Object::IsSeqAsciiString() {
return IsString() && (String::cast(this)->is_ascii()); return IsSeqString()
&& String::cast(this)->IsAsciiRepresentation();
} }
bool Object::IsTwoByteString() { bool Object::IsSeqTwoByteString() {
return IsString() && (!String::cast(this)->is_ascii()); return IsSeqString()
&& !String::cast(this)->IsAsciiRepresentation();
}
bool Object::IsAsciiStringRepresentation() {
return IsString() && (String::cast(this)->is_ascii_representation());
}
bool Object::IsTwoByteStringRepresentation() {
return IsString() && (!String::cast(this)->is_ascii_representation());
} }
...@@ -148,12 +160,12 @@ bool Object::IsExternalString() { ...@@ -148,12 +160,12 @@ bool Object::IsExternalString() {
bool Object::IsExternalAsciiString() { bool Object::IsExternalAsciiString() {
return IsExternalString() && (String::cast(this)->is_ascii()); return IsExternalString() && (String::cast(this)->is_ascii_representation());
} }
bool Object::IsExternalTwoByteString() { bool Object::IsExternalTwoByteString() {
return IsExternalString() && (!String::cast(this)->is_ascii()); return IsExternalString() && (!String::cast(this)->is_ascii_representation());
} }
...@@ -1126,8 +1138,8 @@ CAST_ACCESSOR(CompilationCacheTable) ...@@ -1126,8 +1138,8 @@ CAST_ACCESSOR(CompilationCacheTable)
CAST_ACCESSOR(MapCache) CAST_ACCESSOR(MapCache)
CAST_ACCESSOR(String) CAST_ACCESSOR(String)
CAST_ACCESSOR(SeqString) CAST_ACCESSOR(SeqString)
CAST_ACCESSOR(AsciiString) CAST_ACCESSOR(SeqAsciiString)
CAST_ACCESSOR(TwoByteString) CAST_ACCESSOR(SeqTwoByteString)
CAST_ACCESSOR(ConsString) CAST_ACCESSOR(ConsString)
CAST_ACCESSOR(SlicedString) CAST_ACCESSOR(SlicedString)
CAST_ACCESSOR(ExternalString) CAST_ACCESSOR(ExternalString)
...@@ -1234,15 +1246,15 @@ uint16_t String::Get(int index) { ...@@ -1234,15 +1246,15 @@ uint16_t String::Get(int index) {
ASSERT(index >= 0 && index < length()); ASSERT(index >= 0 && index < length());
switch (representation_tag()) { switch (representation_tag()) {
case kSeqStringTag: case kSeqStringTag:
return is_ascii() return is_ascii_representation()
? AsciiString::cast(this)->AsciiStringGet(index) ? SeqAsciiString::cast(this)->SeqAsciiStringGet(index)
: TwoByteString::cast(this)->TwoByteStringGet(index); : SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
case kConsStringTag: case kConsStringTag:
return ConsString::cast(this)->ConsStringGet(index); return ConsString::cast(this)->ConsStringGet(index);
case kSlicedStringTag: case kSlicedStringTag:
return SlicedString::cast(this)->SlicedStringGet(index); return SlicedString::cast(this)->SlicedStringGet(index);
case kExternalStringTag: case kExternalStringTag:
return is_ascii() return is_ascii_representation()
? ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index) ? ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index)
: ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index); : ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
default: default:
...@@ -1258,14 +1270,14 @@ void String::Set(int index, uint16_t value) { ...@@ -1258,14 +1270,14 @@ void String::Set(int index, uint16_t value) {
ASSERT(index >= 0 && index < length()); ASSERT(index >= 0 && index < length());
ASSERT(IsSeqString()); ASSERT(IsSeqString());
return is_ascii() return is_ascii_representation()
? AsciiString::cast(this)->AsciiStringSet(index, value) ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
: TwoByteString::cast(this)->TwoByteStringSet(index, value); : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
} }
bool String::IsAscii() { bool String::IsAsciiRepresentation() {
return is_ascii(); return is_ascii_representation();
} }
...@@ -1299,12 +1311,12 @@ bool String::is_symbol_map(Map* map) { ...@@ -1299,12 +1311,12 @@ bool String::is_symbol_map(Map* map) {
} }
bool String::is_ascii() { bool String::is_ascii_representation() {
return is_ascii_map(map()); return is_ascii_representation_map(map());
} }
bool String::is_ascii_map(Map* map) { bool String::is_ascii_representation_map(Map* map) {
return (map->instance_type() & kStringEncodingMask) != 0; return (map->instance_type() & kStringEncodingMask) != 0;
} }
...@@ -1336,42 +1348,42 @@ bool String::IsFlat() { ...@@ -1336,42 +1348,42 @@ bool String::IsFlat() {
} }
uint16_t AsciiString::AsciiStringGet(int index) { uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
ASSERT(index >= 0 && index < length()); ASSERT(index >= 0 && index < length());
return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
} }
void AsciiString::AsciiStringSet(int index, uint16_t value) { void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode); ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
static_cast<byte>(value)); static_cast<byte>(value));
} }
Address AsciiString::GetCharsAddress() { Address SeqAsciiString::GetCharsAddress() {
return FIELD_ADDR(this, kHeaderSize); return FIELD_ADDR(this, kHeaderSize);
} }
Address TwoByteString::GetCharsAddress() { Address SeqTwoByteString::GetCharsAddress() {
return FIELD_ADDR(this, kHeaderSize); return FIELD_ADDR(this, kHeaderSize);
} }
uint16_t TwoByteString::TwoByteStringGet(int index) { uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
ASSERT(index >= 0 && index < length()); ASSERT(index >= 0 && index < length());
return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize); return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
} }
void TwoByteString::TwoByteStringSet(int index, uint16_t value) { void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
ASSERT(index >= 0 && index < length()); ASSERT(index >= 0 && index < length());
WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value); WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
} }
int TwoByteString::TwoByteStringSize(Map* map) { int SeqTwoByteString::SeqTwoByteStringSize(Map* map) {
uint32_t length = READ_INT_FIELD(this, kLengthOffset); uint32_t length = READ_INT_FIELD(this, kLengthOffset);
// Use the map (and not 'this') to compute the size tag, since // Use the map (and not 'this') to compute the size tag, since
...@@ -1393,7 +1405,7 @@ int TwoByteString::TwoByteStringSize(Map* map) { ...@@ -1393,7 +1405,7 @@ int TwoByteString::TwoByteStringSize(Map* map) {
} }
int AsciiString::AsciiStringSize(Map* map) { int SeqAsciiString::SeqAsciiStringSize(Map* map) {
uint32_t length = READ_INT_FIELD(this, kLengthOffset); uint32_t length = READ_INT_FIELD(this, kLengthOffset);
// Use the map (and not 'this') to compute the size tag, since // Use the map (and not 'this') to compute the size tag, since
......
This diff is collapsed.
...@@ -61,8 +61,8 @@ ...@@ -61,8 +61,8 @@
// - GlobalContext // - GlobalContext
// - String // - String
// - SeqString // - SeqString
// - AsciiString // - SeqAsciiString
// - TwoByteString // - SeqTwoByteString
// - ConsString // - ConsString
// - SlicedString // - SlicedString
// - ExternalString // - ExternalString
...@@ -272,12 +272,12 @@ class PropertyDetails BASE_EMBEDDED { ...@@ -272,12 +272,12 @@ class PropertyDetails BASE_EMBEDDED {
// Since string types are not consecutive, this macro is used to // Since string types are not consecutive, this macro is used to
// iterate over them. // iterate over them.
#define STRING_TYPE_LIST(V) \ #define STRING_TYPE_LIST(V) \
V(SHORT_SYMBOL_TYPE, TwoByteString::kHeaderSize, short_symbol) \ V(SHORT_SYMBOL_TYPE, SeqTwoByteString::kHeaderSize, short_symbol) \
V(MEDIUM_SYMBOL_TYPE, TwoByteString::kHeaderSize, medium_symbol) \ V(MEDIUM_SYMBOL_TYPE, SeqTwoByteString::kHeaderSize, medium_symbol) \
V(LONG_SYMBOL_TYPE, TwoByteString::kHeaderSize, long_symbol) \ V(LONG_SYMBOL_TYPE, SeqTwoByteString::kHeaderSize, long_symbol) \
V(SHORT_ASCII_SYMBOL_TYPE, AsciiString::kHeaderSize, short_ascii_symbol) \ V(SHORT_ASCII_SYMBOL_TYPE, SeqAsciiString::kHeaderSize, short_ascii_symbol) \
V(MEDIUM_ASCII_SYMBOL_TYPE, AsciiString::kHeaderSize, medium_ascii_symbol) \ V(MEDIUM_ASCII_SYMBOL_TYPE, SeqAsciiString::kHeaderSize, medium_ascii_symbol)\
V(LONG_ASCII_SYMBOL_TYPE, AsciiString::kHeaderSize, long_ascii_symbol) \ V(LONG_ASCII_SYMBOL_TYPE, SeqAsciiString::kHeaderSize, long_ascii_symbol) \
V(SHORT_CONS_SYMBOL_TYPE, ConsString::kSize, short_cons_symbol) \ V(SHORT_CONS_SYMBOL_TYPE, ConsString::kSize, short_cons_symbol) \
V(MEDIUM_CONS_SYMBOL_TYPE, ConsString::kSize, medium_cons_symbol) \ V(MEDIUM_CONS_SYMBOL_TYPE, ConsString::kSize, medium_cons_symbol) \
V(LONG_CONS_SYMBOL_TYPE, ConsString::kSize, long_cons_symbol) \ V(LONG_CONS_SYMBOL_TYPE, ConsString::kSize, long_cons_symbol) \
...@@ -314,12 +314,12 @@ class PropertyDetails BASE_EMBEDDED { ...@@ -314,12 +314,12 @@ class PropertyDetails BASE_EMBEDDED {
V(LONG_EXTERNAL_ASCII_SYMBOL_TYPE, \ V(LONG_EXTERNAL_ASCII_SYMBOL_TYPE, \
ExternalAsciiString::kSize, \ ExternalAsciiString::kSize, \
long_external_ascii_symbol) \ long_external_ascii_symbol) \
V(SHORT_STRING_TYPE, TwoByteString::kHeaderSize, short_string) \ V(SHORT_STRING_TYPE, SeqTwoByteString::kHeaderSize, short_string) \
V(MEDIUM_STRING_TYPE, TwoByteString::kHeaderSize, medium_string) \ V(MEDIUM_STRING_TYPE, SeqTwoByteString::kHeaderSize, medium_string) \
V(LONG_STRING_TYPE, TwoByteString::kHeaderSize, long_string) \ V(LONG_STRING_TYPE, SeqTwoByteString::kHeaderSize, long_string) \
V(SHORT_ASCII_STRING_TYPE, AsciiString::kHeaderSize, short_ascii_string) \ V(SHORT_ASCII_STRING_TYPE, SeqAsciiString::kHeaderSize, short_ascii_string) \
V(MEDIUM_ASCII_STRING_TYPE, AsciiString::kHeaderSize, medium_ascii_string) \ V(MEDIUM_ASCII_STRING_TYPE, SeqAsciiString::kHeaderSize, medium_ascii_string)\
V(LONG_ASCII_STRING_TYPE, AsciiString::kHeaderSize, long_ascii_string) \ V(LONG_ASCII_STRING_TYPE, SeqAsciiString::kHeaderSize, long_ascii_string) \
V(SHORT_CONS_STRING_TYPE, ConsString::kSize, short_cons_string) \ V(SHORT_CONS_STRING_TYPE, ConsString::kSize, short_cons_string) \
V(MEDIUM_CONS_STRING_TYPE, ConsString::kSize, medium_cons_string) \ V(MEDIUM_CONS_STRING_TYPE, ConsString::kSize, medium_cons_string) \
V(LONG_CONS_STRING_TYPE, ConsString::kSize, long_cons_string) \ V(LONG_CONS_STRING_TYPE, ConsString::kSize, long_cons_string) \
...@@ -584,8 +584,10 @@ class Object BASE_EMBEDDED { ...@@ -584,8 +584,10 @@ class Object BASE_EMBEDDED {
inline bool IsHeapNumber(); inline bool IsHeapNumber();
inline bool IsString(); inline bool IsString();
inline bool IsSeqString(); inline bool IsSeqString();
inline bool IsAsciiString(); inline bool IsAsciiStringRepresentation();
inline bool IsTwoByteString(); inline bool IsTwoByteStringRepresentation();
inline bool IsSeqAsciiString();
inline bool IsSeqTwoByteString();
inline bool IsConsString(); inline bool IsConsString();
inline bool IsSlicedString(); inline bool IsSlicedString();
inline bool IsExternalString(); inline bool IsExternalString();
...@@ -2928,13 +2930,16 @@ class String: public HeapObject { ...@@ -2928,13 +2930,16 @@ class String: public HeapObject {
inline void TryFlatten(); inline void TryFlatten();
// Is this string an ascii string. // Is this string an ascii string.
inline bool IsAscii(); inline bool IsAsciiRepresentation();
// Fast testing routines that assume the receiver is a string and // Fast testing routines that assume the receiver is a string and
// just check whether it is a certain kind of string. // just check whether it is a certain kind of string.
inline bool StringIsSlicedString(); inline bool StringIsSlicedString();
inline bool StringIsConsString(); inline bool StringIsConsString();
Vector<const char> ToAsciiVector();
Vector<const uc16> ToUC16Vector();
// Mark the string as an undetectable object. It only applies to // Mark the string as an undetectable object. It only applies to
// ascii and two byte string types. // ascii and two byte string types.
bool MarkAsUndetectable(); bool MarkAsUndetectable();
...@@ -3005,8 +3010,8 @@ class String: public HeapObject { ...@@ -3005,8 +3010,8 @@ class String: public HeapObject {
static inline bool is_symbol_map(Map* map); static inline bool is_symbol_map(Map* map);
// True if the string is ASCII. // True if the string is ASCII.
inline bool is_ascii(); inline bool is_ascii_representation();
static inline bool is_ascii_map(Map* map); static inline bool is_ascii_representation_map(Map* map);
// Get the representation tag. // Get the representation tag.
inline StringRepresentationTag representation_tag(); inline StringRepresentationTag representation_tag();
...@@ -3145,22 +3150,22 @@ class SeqString: public String { ...@@ -3145,22 +3150,22 @@ class SeqString: public String {
// The AsciiString class captures sequential ascii string objects. // The AsciiString class captures sequential ascii string objects.
// Each character in the AsciiString is an ascii character. // Each character in the AsciiString is an ascii character.
class AsciiString: public SeqString { class SeqAsciiString: public SeqString {
public: public:
// Dispatched behavior. // Dispatched behavior.
inline uint16_t AsciiStringGet(int index); inline uint16_t SeqAsciiStringGet(int index);
inline void AsciiStringSet(int index, uint16_t value); inline void SeqAsciiStringSet(int index, uint16_t value);
// Get the address of the characters in this string. // Get the address of the characters in this string.
inline Address GetCharsAddress(); inline Address GetCharsAddress();
// Casting // Casting
static inline AsciiString* cast(Object* obj); static inline SeqAsciiString* cast(Object* obj);
// Garbage collection support. This method is called by the // Garbage collection support. This method is called by the
// garbage collector to compute the actual size of an AsciiString // garbage collector to compute the actual size of an AsciiString
// instance. // instance.
inline int AsciiStringSize(Map* map); inline int SeqAsciiStringSize(Map* map);
// Computes the size for an AsciiString instance of a given length. // Computes the size for an AsciiString instance of a given length.
static int SizeFor(int length) { static int SizeFor(int length) {
...@@ -3171,39 +3176,39 @@ class AsciiString: public SeqString { ...@@ -3171,39 +3176,39 @@ class AsciiString: public SeqString {
static const int kHeaderSize = String::kSize; static const int kHeaderSize = String::kSize;
// Support for StringInputBuffer. // Support for StringInputBuffer.
inline void AsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
unsigned* offset, unsigned* offset,
unsigned chars); unsigned chars);
inline const unibrow::byte* AsciiStringReadBlock(unsigned* remaining, inline const unibrow::byte* SeqAsciiStringReadBlock(unsigned* remaining,
unsigned* offset, unsigned* offset,
unsigned chars); unsigned chars);
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(AsciiString); DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString);
}; };
// The TwoByteString class captures sequential unicode string objects. // The TwoByteString class captures sequential unicode string objects.
// Each character in the TwoByteString is a two-byte uint16_t. // Each character in the TwoByteString is a two-byte uint16_t.
class TwoByteString: public SeqString { class SeqTwoByteString: public SeqString {
public: public:
// Dispatched behavior. // Dispatched behavior.
inline uint16_t TwoByteStringGet(int index); inline uint16_t SeqTwoByteStringGet(int index);
inline void TwoByteStringSet(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.
inline Address GetCharsAddress(); inline Address GetCharsAddress();
// For regexp code. // For regexp code.
const uint16_t* TwoByteStringGetData(unsigned start); const uint16_t* SeqTwoByteStringGetData(unsigned start);
// Casting // Casting
static inline TwoByteString* cast(Object* obj); static inline SeqTwoByteString* cast(Object* obj);
// Garbage collection support. This method is called by the // Garbage collection support. This method is called by the
// garbage collector to compute the actual size of a TwoByteString // garbage collector to compute the actual size of a TwoByteString
// instance. // instance.
inline int TwoByteStringSize(Map* map); inline int SeqTwoByteStringSize(Map* map);
// Computes the size for a TwoByteString instance of a given length. // Computes the size for a TwoByteString instance of a given length.
static int SizeFor(int length) { static int SizeFor(int length) {
...@@ -3214,12 +3219,12 @@ class TwoByteString: public SeqString { ...@@ -3214,12 +3219,12 @@ class TwoByteString: public SeqString {
static const int kHeaderSize = String::kSize; static const int kHeaderSize = String::kSize;
// Support for StringInputBuffer. // Support for StringInputBuffer.
inline void TwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer, inline void SeqTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
unsigned* offset_ptr, unsigned* offset_ptr,
unsigned chars); unsigned chars);
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(TwoByteString); DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
}; };
...@@ -3431,6 +3436,19 @@ class SafeStringInputBuffer ...@@ -3431,6 +3436,19 @@ class SafeStringInputBuffer
}; };
template <typename T>
class VectorIterator {
public:
VectorIterator(T* d, int l) : data_(Vector<T>(d, l)), index_(0) { }
explicit VectorIterator(Vector<T> data) : data_(data), index_(0) { }
T GetNext() { return data_[index_++]; }
bool has_more() { return index_ < data_.length(); }
private:
Vector<T> data_;
int index_;
};
// The Oddball describes objects null, undefined, true, and false. // The Oddball describes objects null, undefined, true, and false.
class Oddball: public HeapObject { class Oddball: public HeapObject {
public: public:
......
...@@ -952,68 +952,6 @@ static Object* Runtime_CharFromCode(Arguments args) { ...@@ -952,68 +952,6 @@ static Object* Runtime_CharFromCode(Arguments args) {
} }
static Vector<const char> ToAsciiVector(String *string) {
ASSERT(string->IsAscii());
ASSERT(string->IsFlat());
int offset = 0;
int length = string->length();
StringRepresentationTag string_tag = string->representation_tag();
if (string_tag == kSlicedStringTag) {
SlicedString* sliced = SlicedString::cast(string);
offset += sliced->start();
string = String::cast(sliced->buffer());
string_tag = string->representation_tag();
} else if (string_tag == kConsStringTag) {
ConsString* cons = ConsString::cast(string);
ASSERT(String::cast(cons->second())->length() == 0);
string = String::cast(cons->first());
string_tag = string->representation_tag();
}
if (string_tag == kSeqStringTag) {
AsciiString* seq = AsciiString::cast(string);
char* start = reinterpret_cast<char*>(seq->GetCharsAddress());
return Vector<const char>(start + offset, length);
}
ASSERT(string_tag == kExternalStringTag);
ExternalAsciiString* ext = ExternalAsciiString::cast(string);
const char* start = ext->resource()->data();
return Vector<const char>(start + offset, length);
}
static Vector<const uc16> ToUC16Vector(String *string) {
ASSERT(string->IsTwoByteString());
ASSERT(string->IsFlat());
int offset = 0;
int length = string->length();
StringRepresentationTag string_tag = string->representation_tag();
if (string_tag == kSlicedStringTag) {
SlicedString* sliced = SlicedString::cast(string);
offset += sliced->start();
string = String::cast(sliced->buffer());
string_tag = string->representation_tag();
} else if (string_tag == kConsStringTag) {
ConsString* cons = ConsString::cast(string);
ASSERT(String::cast(cons->second())->length() == 0);
string = String::cast(cons->first());
string_tag = string->representation_tag();
}
if (string_tag == kSeqStringTag) {
TwoByteString* seq = TwoByteString::cast(string);
uc16* start = reinterpret_cast<uc16*>(seq->GetCharsAddress());
return Vector<const uc16>(start + offset, length);
}
ASSERT(string_tag == kExternalStringTag);
ExternalTwoByteString* ext = ExternalTwoByteString::cast(string);
const uc16* start =
reinterpret_cast<const uc16*>(ext->resource()->data());
return Vector<const uc16>(start + offset, length);
}
template <typename schar, typename pchar> template <typename schar, typename pchar>
static int SingleCharIndexOf(Vector<const schar> string, static int SingleCharIndexOf(Vector<const schar> string,
pchar pattern_char, pchar pattern_char,
...@@ -1202,18 +1140,18 @@ int Runtime::StringMatch(Handle<String> sub, ...@@ -1202,18 +1140,18 @@ int Runtime::StringMatch(Handle<String> sub,
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
// dispatch on type of strings // dispatch on type of strings
if (pat->is_ascii()) { if (pat->is_ascii_representation()) {
Vector<const char> pat_vector = ToAsciiVector(*pat); Vector<const char> pat_vector = pat->ToAsciiVector();
if (sub->is_ascii()) { if (sub->is_ascii_representation()) {
return StringMatchStrategy(ToAsciiVector(*sub), pat_vector, start_index); return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index);
} }
return StringMatchStrategy(ToUC16Vector(*sub), pat_vector, start_index); return StringMatchStrategy(sub->ToUC16Vector(), pat_vector, start_index);
} }
Vector<const uc16> pat_vector = ToUC16Vector(*pat); Vector<const uc16> pat_vector = pat->ToUC16Vector();
if (sub->is_ascii()) { if (sub->is_ascii_representation()) {
return StringMatchStrategy(ToAsciiVector(*sub), pat_vector, start_index); return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index);
} }
return StringMatchStrategy(ToUC16Vector(*sub), pat_vector, start_index); return StringMatchStrategy(sub->ToUC16Vector(), pat_vector, start_index);
} }
...@@ -2155,7 +2093,7 @@ static Object* ConvertCase(Arguments args, ...@@ -2155,7 +2093,7 @@ static Object* ConvertCase(Arguments args,
// character is also ascii. This is currently the case, but it // character is also ascii. This is currently the case, but it
// might break in the future if we implement more context and locale // might break in the future if we implement more context and locale
// dependent upper/lower conversions. // dependent upper/lower conversions.
Object* o = s->IsAscii() Object* o = s->IsAsciiRepresentation()
? Heap::AllocateRawAsciiString(length) ? Heap::AllocateRawAsciiString(length)
: Heap::AllocateRawTwoByteString(length); : Heap::AllocateRawTwoByteString(length);
if (o->IsFailure()) return o; if (o->IsFailure()) return o;
...@@ -2432,7 +2370,7 @@ static Object* Runtime_StringBuilderConcat(Arguments args) { ...@@ -2432,7 +2370,7 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
if (first->IsString()) return first; if (first->IsString()) return first;
} }
bool ascii = special->IsAscii(); bool ascii = special->IsAsciiRepresentation();
int position = 0; int position = 0;
for (int i = 0; i < array_length; i++) { for (int i = 0; i < array_length; i++) {
Object* elt = fixed_array->get(i); Object* elt = fixed_array->get(i);
...@@ -2452,7 +2390,7 @@ static Object* Runtime_StringBuilderConcat(Arguments args) { ...@@ -2452,7 +2390,7 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
return Failure::OutOfMemoryException(); return Failure::OutOfMemoryException();
} }
position += element_length; position += element_length;
if (ascii && !element->IsAscii()) { if (ascii && !element->IsAsciiRepresentation()) {
ascii = false; ascii = false;
} }
} else { } else {
......
...@@ -38,7 +38,7 @@ TEST(HeapMaps) { ...@@ -38,7 +38,7 @@ TEST(HeapMaps) {
CheckMap(Heap::heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); CheckMap(Heap::heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize);
CheckMap(Heap::fixed_array_map(), FIXED_ARRAY_TYPE, Array::kHeaderSize); CheckMap(Heap::fixed_array_map(), FIXED_ARRAY_TYPE, Array::kHeaderSize);
CheckMap(Heap::long_string_map(), LONG_STRING_TYPE, CheckMap(Heap::long_string_map(), LONG_STRING_TYPE,
TwoByteString::kHeaderSize); SeqTwoByteString::kHeaderSize);
} }
......
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