Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index f0e0bbed60945bc12203709621dd8499e5a810d4..8bb7ae6caaa5b119e13ec017db12a552d4e3a42a 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -4084,18 +4084,83 @@ static Object* ConvertCaseHelper(String* s, |
| } |
| -template <class Converter> |
| -static Object* ConvertCase(Arguments args, |
| - unibrow::Mapping<Converter, 128>* mapping) { |
| - NoHandleAllocation ha; |
| +static inline SeqAsciiString* TryGetSeqAsciiString(String* s) { |
| + if (!s->IsFlat() || !s->IsAsciiRepresentation()) return NULL; |
| + if (s->IsConsString()) { |
| + ASSERT(ConsString::cast(s)->second()->length() == 0); |
| + return SeqAsciiString::cast(ConsString::cast(s)->first()); |
| + } |
| + return SeqAsciiString::cast(s); |
| +} |
| + |
| + |
| +namespace { |
| + |
| +struct ToLowerTraits { |
| + typedef unibrow::ToLowercase UnibrowConverter; |
| + |
| + static bool ConvertAscii(char* dst, char* src, int length) { |
|
antonm
2010/03/03 16:20:11
just curious if this and below loops could be sped
Vitaly Repeshko
2010/03/03 16:40:46
Performance tuning is poisonous :)
GCC 4.2.4 with
|
| + bool changed = false; |
| + for (int i = 0; i < length; ++i) { |
| + char c = src[i]; |
| + if ('A' <= c && c <= 'Z') { |
| + c += ('a' - 'A'); |
| + changed = true; |
| + } |
| + dst[i] = c; |
| + } |
| + return changed; |
| + } |
| +}; |
| + |
| +struct ToUpperTraits { |
| + typedef unibrow::ToUppercase UnibrowConverter; |
| + |
| + static bool ConvertAscii(char* dst, char* src, int length) { |
| + bool changed = false; |
| + for (int i = 0; i < length; ++i) { |
| + char c = src[i]; |
| + if ('a' <= c && c <= 'z') { |
| + c -= ('a' - 'A'); |
| + changed = true; |
| + } |
| + dst[i] = c; |
| + } |
| + return changed; |
| + } |
| +}; |
| + |
| +} // namespace |
| + |
| + |
| +template <typename ConvertTraits> |
| +static Object* ConvertCase( |
| + Arguments args, |
| + unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { |
| + NoHandleAllocation ha; |
| CONVERT_CHECKED(String, s, args[0]); |
| s->TryFlatten(); |
| - int input_string_length = s->length(); |
| + const int length = s->length(); |
| // Assume that the string is not empty; we need this assumption later |
| - if (input_string_length == 0) return s; |
| - int length = input_string_length; |
| + if (length == 0) return s; |
| + |
| + // Simpler handling of ascii strings. |
| + // |
| + // NOTE: This assumes that the upper/lower case of an ascii |
| + // character is also ascii. This is currently the case, but it |
| + // might break in the future if we implement more context and locale |
| + // dependent upper/lower conversions. |
| + SeqAsciiString* seq_ascii = TryGetSeqAsciiString(s); |
| + if (seq_ascii != NULL) { |
| + Object* o = Heap::AllocateRawAsciiString(length); |
| + if (o->IsFailure()) return o; |
| + SeqAsciiString* result = SeqAsciiString::cast(o); |
| + bool has_changed_character = ConvertTraits::ConvertAscii( |
| + result->GetChars(), seq_ascii->GetChars(), length); |
| + return has_changed_character ? result : s; |
| + } |
| Object* answer = ConvertCaseHelper(s, length, length, mapping); |
| if (answer->IsSmi()) { |
| @@ -4107,18 +4172,20 @@ static Object* ConvertCase(Arguments args, |
| static Object* Runtime_StringToLowerCase(Arguments args) { |
| - return ConvertCase<unibrow::ToLowercase>(args, &to_lower_mapping); |
| + return ConvertCase<ToLowerTraits>(args, &to_lower_mapping); |
| } |
| static Object* Runtime_StringToUpperCase(Arguments args) { |
| - return ConvertCase<unibrow::ToUppercase>(args, &to_upper_mapping); |
| + return ConvertCase<ToUpperTraits>(args, &to_upper_mapping); |
| } |
| + |
| static inline bool IsTrimWhiteSpace(unibrow::uchar c) { |
| return unibrow::WhiteSpace::Is(c) || c == 0x200b; |
| } |
| + |
| static Object* Runtime_StringTrim(Arguments args) { |
| NoHandleAllocation ha; |
| ASSERT(args.length() == 3); |