| OLD | NEW |
| 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 1734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1745 // Forward declarations. | 1745 // Forward declarations. |
| 1746 const int kStringBuilderConcatHelperLengthBits = 11; | 1746 const int kStringBuilderConcatHelperLengthBits = 11; |
| 1747 const int kStringBuilderConcatHelperPositionBits = 19; | 1747 const int kStringBuilderConcatHelperPositionBits = 19; |
| 1748 | 1748 |
| 1749 template <typename schar> | 1749 template <typename schar> |
| 1750 static inline void StringBuilderConcatHelper(String*, | 1750 static inline void StringBuilderConcatHelper(String*, |
| 1751 schar*, | 1751 schar*, |
| 1752 FixedArray*, | 1752 FixedArray*, |
| 1753 int); | 1753 int); |
| 1754 | 1754 |
| 1755 STATIC_ASSERT(kStringBuilderConcatHelperLengthBits + |
| 1756 kStringBuilderConcatHelperPositionBits <= kSmiValueSize); |
| 1755 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits> | 1757 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits> |
| 1756 StringBuilderSubstringLength; | 1758 StringBuilderSubstringLength; |
| 1757 typedef BitField<int, | 1759 typedef BitField<int, |
| 1758 kStringBuilderConcatHelperLengthBits, | 1760 kStringBuilderConcatHelperLengthBits, |
| 1759 kStringBuilderConcatHelperPositionBits> | 1761 kStringBuilderConcatHelperPositionBits> |
| 1760 StringBuilderSubstringPosition; | 1762 StringBuilderSubstringPosition; |
| 1761 | 1763 |
| 1762 | 1764 |
| 1763 class ReplacementStringBuilder { | 1765 class ReplacementStringBuilder { |
| 1764 public: | 1766 public: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1791 } | 1793 } |
| 1792 | 1794 |
| 1793 | 1795 |
| 1794 void EnsureCapacity(int elements) { | 1796 void EnsureCapacity(int elements) { |
| 1795 array_builder_.EnsureCapacity(elements); | 1797 array_builder_.EnsureCapacity(elements); |
| 1796 } | 1798 } |
| 1797 | 1799 |
| 1798 | 1800 |
| 1799 void AddSubjectSlice(int from, int to) { | 1801 void AddSubjectSlice(int from, int to) { |
| 1800 AddSubjectSlice(&array_builder_, from, to); | 1802 AddSubjectSlice(&array_builder_, from, to); |
| 1801 // Can we encode the slice in 11 bits for length and 19 bits for | |
| 1802 // start position - as used by StringBuilderConcatHelper? | |
| 1803 IncrementCharacterCount(to - from); | 1803 IncrementCharacterCount(to - from); |
| 1804 } | 1804 } |
| 1805 | 1805 |
| 1806 | 1806 |
| 1807 void AddString(Handle<String> string) { | 1807 void AddString(Handle<String> string) { |
| 1808 int length = string->length(); | 1808 int length = string->length(); |
| 1809 ASSERT(length > 0); | 1809 ASSERT(length > 0); |
| 1810 AddElement(*string); | 1810 AddElement(*string); |
| 1811 if (!string->IsAsciiRepresentation()) { | 1811 if (!string->IsAsciiRepresentation()) { |
| 1812 is_ascii_ = false; | 1812 is_ascii_ = false; |
| (...skipping 3607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5420 static Object* Runtime_StringAdd(Arguments args) { | 5420 static Object* Runtime_StringAdd(Arguments args) { |
| 5421 NoHandleAllocation ha; | 5421 NoHandleAllocation ha; |
| 5422 ASSERT(args.length() == 2); | 5422 ASSERT(args.length() == 2); |
| 5423 CONVERT_CHECKED(String, str1, args[0]); | 5423 CONVERT_CHECKED(String, str1, args[0]); |
| 5424 CONVERT_CHECKED(String, str2, args[1]); | 5424 CONVERT_CHECKED(String, str2, args[1]); |
| 5425 Counters::string_add_runtime.Increment(); | 5425 Counters::string_add_runtime.Increment(); |
| 5426 return Heap::AllocateConsString(str1, str2); | 5426 return Heap::AllocateConsString(str1, str2); |
| 5427 } | 5427 } |
| 5428 | 5428 |
| 5429 | 5429 |
| 5430 template<typename sinkchar> | 5430 template <typename sinkchar> |
| 5431 static inline void StringBuilderConcatHelper(String* special, | 5431 static inline void StringBuilderConcatHelper(String* special, |
| 5432 sinkchar* sink, | 5432 sinkchar* sink, |
| 5433 FixedArray* fixed_array, | 5433 FixedArray* fixed_array, |
| 5434 int array_length) { | 5434 int array_length) { |
| 5435 int position = 0; | 5435 int position = 0; |
| 5436 for (int i = 0; i < array_length; i++) { | 5436 for (int i = 0; i < array_length; i++) { |
| 5437 Object* element = fixed_array->get(i); | 5437 Object* element = fixed_array->get(i); |
| 5438 if (element->IsSmi()) { | 5438 if (element->IsSmi()) { |
| 5439 // Smi encoding of position and length. | 5439 // Smi encoding of position and length. |
| 5440 int encoded_slice = Smi::cast(element)->value(); | 5440 int encoded_slice = Smi::cast(element)->value(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5491 | 5491 |
| 5492 if (array_length == 0) { | 5492 if (array_length == 0) { |
| 5493 return Heap::empty_string(); | 5493 return Heap::empty_string(); |
| 5494 } else if (array_length == 1) { | 5494 } else if (array_length == 1) { |
| 5495 Object* first = fixed_array->get(0); | 5495 Object* first = fixed_array->get(0); |
| 5496 if (first->IsString()) return first; | 5496 if (first->IsString()) return first; |
| 5497 } | 5497 } |
| 5498 | 5498 |
| 5499 bool ascii = special->IsAsciiRepresentation(); | 5499 bool ascii = special->IsAsciiRepresentation(); |
| 5500 int position = 0; | 5500 int position = 0; |
| 5501 int increment = 0; | |
| 5502 for (int i = 0; i < array_length; i++) { | 5501 for (int i = 0; i < array_length; i++) { |
| 5502 int increment = 0; |
| 5503 Object* elt = fixed_array->get(i); | 5503 Object* elt = fixed_array->get(i); |
| 5504 if (elt->IsSmi()) { | 5504 if (elt->IsSmi()) { |
| 5505 // Smi encoding of position and length. | 5505 // Smi encoding of position and length. |
| 5506 int len = Smi::cast(elt)->value(); | 5506 int smi_value = Smi::cast(elt)->value(); |
| 5507 if (len > 0) { | 5507 int pos; |
| 5508 int len; |
| 5509 if (smi_value > 0) { |
| 5508 // Position and length encoded in one smi. | 5510 // Position and length encoded in one smi. |
| 5509 int pos = len >> 11; | 5511 pos = StringBuilderSubstringPosition::decode(smi_value); |
| 5510 len &= 0x7ff; | 5512 len = StringBuilderSubstringLength::decode(smi_value); |
| 5511 if (pos + len > special_length) { | |
| 5512 return Top::Throw(Heap::illegal_argument_symbol()); | |
| 5513 } | |
| 5514 increment = len; | |
| 5515 } else { | 5513 } else { |
| 5516 // Position and length encoded in two smis. | 5514 // Position and length encoded in two smis. |
| 5517 increment = (-len); | 5515 len = -smi_value; |
| 5518 // Get the position and check that it is also a smi. | 5516 // Get the position and check that it is a positive smi. |
| 5519 i++; | 5517 i++; |
| 5520 if (i >= array_length) { | 5518 if (i >= array_length) { |
| 5521 return Top::Throw(Heap::illegal_argument_symbol()); | 5519 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5522 } | 5520 } |
| 5523 Object* pos = fixed_array->get(i); | 5521 Object* next_smi = fixed_array->get(i); |
| 5524 if (!pos->IsSmi()) { | 5522 if (!next_smi->IsSmi()) { |
| 5523 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5524 } |
| 5525 pos = Smi::cast(next_smi)->value(); |
| 5526 if (pos < 0) { |
| 5525 return Top::Throw(Heap::illegal_argument_symbol()); | 5527 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5526 } | 5528 } |
| 5527 } | 5529 } |
| 5530 ASSERT(pos >= 0); |
| 5531 ASSERT(len >= 0); |
| 5532 if (pos > special_length || len > special_length - pos) { |
| 5533 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5534 } |
| 5535 increment = len; |
| 5528 } else if (elt->IsString()) { | 5536 } else if (elt->IsString()) { |
| 5529 String* element = String::cast(elt); | 5537 String* element = String::cast(elt); |
| 5530 int element_length = element->length(); | 5538 int element_length = element->length(); |
| 5531 increment = element_length; | 5539 increment = element_length; |
| 5532 if (ascii && !element->IsAsciiRepresentation()) { | 5540 if (ascii && !element->IsAsciiRepresentation()) { |
| 5533 ascii = false; | 5541 ascii = false; |
| 5534 } | 5542 } |
| 5535 } else { | 5543 } else { |
| 5536 return Top::Throw(Heap::illegal_argument_symbol()); | 5544 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5537 } | 5545 } |
| (...skipping 4655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10193 } else { | 10201 } else { |
| 10194 // Handle last resort GC and make sure to allow future allocations | 10202 // Handle last resort GC and make sure to allow future allocations |
| 10195 // to grow the heap without causing GCs (if possible). | 10203 // to grow the heap without causing GCs (if possible). |
| 10196 Counters::gc_last_resort_from_js.Increment(); | 10204 Counters::gc_last_resort_from_js.Increment(); |
| 10197 Heap::CollectAllGarbage(false); | 10205 Heap::CollectAllGarbage(false); |
| 10198 } | 10206 } |
| 10199 } | 10207 } |
| 10200 | 10208 |
| 10201 | 10209 |
| 10202 } } // namespace v8::internal | 10210 } } // namespace v8::internal |
| OLD | NEW |