| 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 1687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1698 } | 1698 } |
| 1699 | 1699 |
| 1700 | 1700 |
| 1701 void EnsureCapacity(int elements) { | 1701 void EnsureCapacity(int elements) { |
| 1702 array_builder_.EnsureCapacity(elements); | 1702 array_builder_.EnsureCapacity(elements); |
| 1703 } | 1703 } |
| 1704 | 1704 |
| 1705 | 1705 |
| 1706 void AddSubjectSlice(int from, int to) { | 1706 void AddSubjectSlice(int from, int to) { |
| 1707 AddSubjectSlice(&array_builder_, from, to); | 1707 AddSubjectSlice(&array_builder_, from, to); |
| 1708 // Can we encode the slice in 11 bits for length and 19 bits for | |
| 1709 // start position - as used by StringBuilderConcatHelper? | |
| 1710 IncrementCharacterCount(to - from); | 1708 IncrementCharacterCount(to - from); |
| 1711 } | 1709 } |
| 1712 | 1710 |
| 1713 | 1711 |
| 1714 void AddString(Handle<String> string) { | 1712 void AddString(Handle<String> string) { |
| 1715 int length = string->length(); | 1713 int length = string->length(); |
| 1716 ASSERT(length > 0); | 1714 ASSERT(length > 0); |
| 1717 AddElement(*string); | 1715 AddElement(*string); |
| 1718 if (!string->IsAsciiRepresentation()) { | 1716 if (!string->IsAsciiRepresentation()) { |
| 1719 is_ascii_ = false; | 1717 is_ascii_ = false; |
| (...skipping 3580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5300 static Object* Runtime_StringAdd(Arguments args) { | 5298 static Object* Runtime_StringAdd(Arguments args) { |
| 5301 NoHandleAllocation ha; | 5299 NoHandleAllocation ha; |
| 5302 ASSERT(args.length() == 2); | 5300 ASSERT(args.length() == 2); |
| 5303 CONVERT_CHECKED(String, str1, args[0]); | 5301 CONVERT_CHECKED(String, str1, args[0]); |
| 5304 CONVERT_CHECKED(String, str2, args[1]); | 5302 CONVERT_CHECKED(String, str2, args[1]); |
| 5305 Counters::string_add_runtime.Increment(); | 5303 Counters::string_add_runtime.Increment(); |
| 5306 return Heap::AllocateConsString(str1, str2); | 5304 return Heap::AllocateConsString(str1, str2); |
| 5307 } | 5305 } |
| 5308 | 5306 |
| 5309 | 5307 |
| 5310 template<typename sinkchar> | 5308 template <typename sinkchar> |
| 5311 static inline void StringBuilderConcatHelper(String* special, | 5309 static inline void StringBuilderConcatHelper(String* special, |
| 5312 sinkchar* sink, | 5310 sinkchar* sink, |
| 5313 FixedArray* fixed_array, | 5311 FixedArray* fixed_array, |
| 5314 int array_length) { | 5312 int array_length) { |
| 5315 int position = 0; | 5313 int position = 0; |
| 5316 for (int i = 0; i < array_length; i++) { | 5314 for (int i = 0; i < array_length; i++) { |
| 5317 Object* element = fixed_array->get(i); | 5315 Object* element = fixed_array->get(i); |
| 5318 if (element->IsSmi()) { | 5316 if (element->IsSmi()) { |
| 5319 // Smi encoding of position and length. | 5317 // Smi encoding of position and length. |
| 5320 int encoded_slice = Smi::cast(element)->value(); | 5318 int encoded_slice = Smi::cast(element)->value(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5371 | 5369 |
| 5372 if (array_length == 0) { | 5370 if (array_length == 0) { |
| 5373 return Heap::empty_string(); | 5371 return Heap::empty_string(); |
| 5374 } else if (array_length == 1) { | 5372 } else if (array_length == 1) { |
| 5375 Object* first = fixed_array->get(0); | 5373 Object* first = fixed_array->get(0); |
| 5376 if (first->IsString()) return first; | 5374 if (first->IsString()) return first; |
| 5377 } | 5375 } |
| 5378 | 5376 |
| 5379 bool ascii = special->IsAsciiRepresentation(); | 5377 bool ascii = special->IsAsciiRepresentation(); |
| 5380 int position = 0; | 5378 int position = 0; |
| 5381 int increment = 0; | |
| 5382 for (int i = 0; i < array_length; i++) { | 5379 for (int i = 0; i < array_length; i++) { |
| 5380 int increment = 0; |
| 5383 Object* elt = fixed_array->get(i); | 5381 Object* elt = fixed_array->get(i); |
| 5384 if (elt->IsSmi()) { | 5382 if (elt->IsSmi()) { |
| 5385 // Smi encoding of position and length. | 5383 // Smi encoding of position and length. |
| 5386 int len = Smi::cast(elt)->value(); | 5384 int smi_value = Smi::cast(elt)->value(); |
| 5387 if (len > 0) { | 5385 int pos; |
| 5386 int len; |
| 5387 if (smi_value > 0) { |
| 5388 // Position and length encoded in one smi. | 5388 // Position and length encoded in one smi. |
| 5389 int pos = len >> 11; | 5389 pos = StringBuilderSubstringPosition::decode(smi_value); |
| 5390 len &= 0x7ff; | 5390 len = StringBuilderSubstringLength::decode(smi_value); |
| 5391 if (pos + len > special_length) { | |
| 5392 return Top::Throw(Heap::illegal_argument_symbol()); | |
| 5393 } | |
| 5394 increment = len; | |
| 5395 } else { | 5391 } else { |
| 5396 // Position and length encoded in two smis. | 5392 // Position and length encoded in two smis. |
| 5397 increment = (-len); | 5393 len = -smi_value; |
| 5398 // Get the position and check that it is also a smi. | 5394 // Get the position and check that it is a positive smi. |
| 5399 i++; | 5395 i++; |
| 5400 if (i >= array_length) { | 5396 if (i >= array_length) { |
| 5401 return Top::Throw(Heap::illegal_argument_symbol()); | 5397 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5402 } | 5398 } |
| 5403 Object* pos = fixed_array->get(i); | 5399 Object* next_smi = fixed_array->get(i); |
| 5404 if (!pos->IsSmi()) { | 5400 if (!next_smi->IsSmi()) { |
| 5401 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5402 } |
| 5403 pos = Smi::cast(next_smi)->value(); |
| 5404 if (pos < 0) { |
| 5405 return Top::Throw(Heap::illegal_argument_symbol()); | 5405 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5406 } | 5406 } |
| 5407 } | 5407 } |
| 5408 ASSERT(pos >= 0); |
| 5409 ASSERT(len >= 0); |
| 5410 if (pos > special_length || len > special_length - pos) { |
| 5411 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5412 } |
| 5413 increment = len; |
| 5408 } else if (elt->IsString()) { | 5414 } else if (elt->IsString()) { |
| 5409 String* element = String::cast(elt); | 5415 String* element = String::cast(elt); |
| 5410 int element_length = element->length(); | 5416 int element_length = element->length(); |
| 5411 increment = element_length; | 5417 increment = element_length; |
| 5412 if (ascii && !element->IsAsciiRepresentation()) { | 5418 if (ascii && !element->IsAsciiRepresentation()) { |
| 5413 ascii = false; | 5419 ascii = false; |
| 5414 } | 5420 } |
| 5415 } else { | 5421 } else { |
| 5416 return Top::Throw(Heap::illegal_argument_symbol()); | 5422 return Top::Throw(Heap::illegal_argument_symbol()); |
| 5417 } | 5423 } |
| (...skipping 4564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9982 } else { | 9988 } else { |
| 9983 // Handle last resort GC and make sure to allow future allocations | 9989 // Handle last resort GC and make sure to allow future allocations |
| 9984 // to grow the heap without causing GCs (if possible). | 9990 // to grow the heap without causing GCs (if possible). |
| 9985 Counters::gc_last_resort_from_js.Increment(); | 9991 Counters::gc_last_resort_from_js.Increment(); |
| 9986 Heap::CollectAllGarbage(false); | 9992 Heap::CollectAllGarbage(false); |
| 9987 } | 9993 } |
| 9988 } | 9994 } |
| 9989 | 9995 |
| 9990 | 9996 |
| 9991 } } // namespace v8::internal | 9997 } } // namespace v8::internal |
| OLD | NEW |