Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(895)

Side by Side Diff: src/runtime.cc

Issue 2762008: Track ascii-ness of data in externalized strings. (Closed)
Patch Set: Extended tests. Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4909 matching lines...) Expand 10 before | Expand all | Expand 10 after
4920 } else { 4920 } else {
4921 // If we didn't actually change anything in doing the conversion 4921 // If we didn't actually change anything in doing the conversion
4922 // we simple return the result and let the converted string 4922 // we simple return the result and let the converted string
4923 // become garbage; there is no reason to keep two identical strings 4923 // become garbage; there is no reason to keep two identical strings
4924 // alive. 4924 // alive.
4925 return s; 4925 return s;
4926 } 4926 }
4927 } 4927 }
4928 4928
4929 4929
4930 static inline SeqAsciiString* TryGetSeqAsciiString(String* s) {
4931 if (!s->IsFlat() || !s->IsAsciiRepresentation()) return NULL;
4932 if (s->IsConsString()) {
4933 ASSERT(ConsString::cast(s)->second()->length() == 0);
4934 return SeqAsciiString::cast(ConsString::cast(s)->first());
4935 }
4936 return SeqAsciiString::cast(s);
4937 }
4938
4939
4940 namespace { 4930 namespace {
4941 4931
4942 struct ToLowerTraits { 4932 struct ToLowerTraits {
4943 typedef unibrow::ToLowercase UnibrowConverter; 4933 typedef unibrow::ToLowercase UnibrowConverter;
4944 4934
4945 static bool ConvertAscii(char* dst, char* src, int length) { 4935 static bool ConvertAscii(char* dst, char* src, int length) {
4946 bool changed = false; 4936 bool changed = false;
4947 for (int i = 0; i < length; ++i) { 4937 for (int i = 0; i < length; ++i) {
4948 char c = src[i]; 4938 char c = src[i];
4949 if ('A' <= c && c <= 'Z') { 4939 if ('A' <= c && c <= 'Z') {
(...skipping 26 matching lines...) Expand all
4976 4966
4977 } // namespace 4967 } // namespace
4978 4968
4979 4969
4980 template <typename ConvertTraits> 4970 template <typename ConvertTraits>
4981 static Object* ConvertCase( 4971 static Object* ConvertCase(
4982 Arguments args, 4972 Arguments args,
4983 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { 4973 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) {
4984 NoHandleAllocation ha; 4974 NoHandleAllocation ha;
4985 CONVERT_CHECKED(String, s, args[0]); 4975 CONVERT_CHECKED(String, s, args[0]);
4986 s->TryFlatten(); 4976 s = s->TryFlattenGetString();
4987 4977
4988 const int length = s->length(); 4978 const int length = s->length();
4989 // Assume that the string is not empty; we need this assumption later 4979 // Assume that the string is not empty; we need this assumption later
4990 if (length == 0) return s; 4980 if (length == 0) return s;
4991 4981
4992 // Simpler handling of ascii strings. 4982 // Simpler handling of ascii strings.
4993 // 4983 //
4994 // NOTE: This assumes that the upper/lower case of an ascii 4984 // NOTE: This assumes that the upper/lower case of an ascii
4995 // character is also ascii. This is currently the case, but it 4985 // character is also ascii. This is currently the case, but it
4996 // might break in the future if we implement more context and locale 4986 // might break in the future if we implement more context and locale
4997 // dependent upper/lower conversions. 4987 // dependent upper/lower conversions.
4998 SeqAsciiString* seq_ascii = TryGetSeqAsciiString(s); 4988 if (s->IsSeqAsciiString()) {
4999 if (seq_ascii != NULL) {
5000 Object* o = Heap::AllocateRawAsciiString(length); 4989 Object* o = Heap::AllocateRawAsciiString(length);
5001 if (o->IsFailure()) return o; 4990 if (o->IsFailure()) return o;
5002 SeqAsciiString* result = SeqAsciiString::cast(o); 4991 SeqAsciiString* result = SeqAsciiString::cast(o);
5003 bool has_changed_character = ConvertTraits::ConvertAscii( 4992 bool has_changed_character = ConvertTraits::ConvertAscii(
5004 result->GetChars(), seq_ascii->GetChars(), length); 4993 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length);
5005 return has_changed_character ? result : s; 4994 return has_changed_character ? result : s;
5006 } 4995 }
5007 4996
5008 Object* answer = ConvertCaseHelper(s, length, length, mapping); 4997 Object* answer = ConvertCaseHelper(s, length, length, mapping);
5009 if (answer->IsSmi()) { 4998 if (answer->IsSmi()) {
5010 // Retry with correct length. 4999 // Retry with correct length.
5011 answer = ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping); 5000 answer = ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping);
5012 } 5001 }
5013 return answer; // This may be a failure. 5002 return answer; // This may be a failure.
5014 } 5003 }
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
5538 array_length = fixed_array->length(); 5527 array_length = fixed_array->length();
5539 } 5528 }
5540 5529
5541 if (array_length == 0) { 5530 if (array_length == 0) {
5542 return Heap::empty_string(); 5531 return Heap::empty_string();
5543 } else if (array_length == 1) { 5532 } else if (array_length == 1) {
5544 Object* first = fixed_array->get(0); 5533 Object* first = fixed_array->get(0);
5545 if (first->IsString()) return first; 5534 if (first->IsString()) return first;
5546 } 5535 }
5547 5536
5548 bool ascii = special->IsAsciiRepresentation(); 5537 bool ascii = special->HasAsciiChars();
5549 int position = 0; 5538 int position = 0;
5550 for (int i = 0; i < array_length; i++) { 5539 for (int i = 0; i < array_length; i++) {
5551 int increment = 0; 5540 int increment = 0;
5552 Object* elt = fixed_array->get(i); 5541 Object* elt = fixed_array->get(i);
5553 if (elt->IsSmi()) { 5542 if (elt->IsSmi()) {
5554 // Smi encoding of position and length. 5543 // Smi encoding of position and length.
5555 int smi_value = Smi::cast(elt)->value(); 5544 int smi_value = Smi::cast(elt)->value();
5556 int pos; 5545 int pos;
5557 int len; 5546 int len;
5558 if (smi_value > 0) { 5547 if (smi_value > 0) {
(...skipping 20 matching lines...) Expand all
5579 ASSERT(pos >= 0); 5568 ASSERT(pos >= 0);
5580 ASSERT(len >= 0); 5569 ASSERT(len >= 0);
5581 if (pos > special_length || len > special_length - pos) { 5570 if (pos > special_length || len > special_length - pos) {
5582 return Top::Throw(Heap::illegal_argument_symbol()); 5571 return Top::Throw(Heap::illegal_argument_symbol());
5583 } 5572 }
5584 increment = len; 5573 increment = len;
5585 } else if (elt->IsString()) { 5574 } else if (elt->IsString()) {
5586 String* element = String::cast(elt); 5575 String* element = String::cast(elt);
5587 int element_length = element->length(); 5576 int element_length = element->length();
5588 increment = element_length; 5577 increment = element_length;
5589 if (ascii && !element->IsAsciiRepresentation()) { 5578 if (ascii && !element->HasAsciiChars()) {
5590 ascii = false; 5579 ascii = false;
5591 } 5580 }
5592 } else { 5581 } else {
5593 return Top::Throw(Heap::illegal_argument_symbol()); 5582 return Top::Throw(Heap::illegal_argument_symbol());
5594 } 5583 }
5595 if (increment > String::kMaxLength - position) { 5584 if (increment > String::kMaxLength - position) {
5596 Top::context()->mark_out_of_memory(); 5585 Top::context()->mark_out_of_memory();
5597 return Failure::OutOfMemoryException(); 5586 return Failure::OutOfMemoryException();
5598 } 5587 }
5599 position += increment; 5588 position += increment;
(...skipping 4772 matching lines...) Expand 10 before | Expand all | Expand 10 after
10372 } else { 10361 } else {
10373 // Handle last resort GC and make sure to allow future allocations 10362 // Handle last resort GC and make sure to allow future allocations
10374 // to grow the heap without causing GCs (if possible). 10363 // to grow the heap without causing GCs (if possible).
10375 Counters::gc_last_resort_from_js.Increment(); 10364 Counters::gc_last_resort_from_js.Increment();
10376 Heap::CollectAllGarbage(false); 10365 Heap::CollectAllGarbage(false);
10377 } 10366 }
10378 } 10367 }
10379 10368
10380 10369
10381 } } // namespace v8::internal 10370 } } // namespace v8::internal
OLDNEW
« src/objects-inl.h ('K') | « src/objects-inl.h ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698