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 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1517 StringBuilderConcatHelper(*subject_, | 1517 StringBuilderConcatHelper(*subject_, |
1518 char_buffer, | 1518 char_buffer, |
1519 *parts_, | 1519 *parts_, |
1520 part_count_); | 1520 part_count_); |
1521 } | 1521 } |
1522 return joined_string; | 1522 return joined_string; |
1523 } | 1523 } |
1524 | 1524 |
1525 | 1525 |
1526 void IncrementCharacterCount(int by) { | 1526 void IncrementCharacterCount(int by) { |
1527 if (character_count_ > Smi::kMaxValue - by) { | 1527 if (character_count_ > String::kMaxLength - by) { |
1528 V8::FatalProcessOutOfMemory("String.replace result too large."); | 1528 V8::FatalProcessOutOfMemory("String.replace result too large."); |
1529 } | 1529 } |
1530 character_count_ += by; | 1530 character_count_ += by; |
1531 } | 1531 } |
1532 | 1532 |
1533 private: | 1533 private: |
1534 | 1534 |
1535 Handle<String> NewRawAsciiString(int size) { | 1535 Handle<String> NewRawAsciiString(int size) { |
1536 CALL_HEAP_FUNCTION(Heap::AllocateRawAsciiString(size), String); | 1536 CALL_HEAP_FUNCTION(Heap::AllocateRawAsciiString(size), String); |
1537 } | 1537 } |
(...skipping 1839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3377 while (buffer->has_more()) { | 3377 while (buffer->has_more()) { |
3378 uint16_t character = buffer->GetNext(); | 3378 uint16_t character = buffer->GetNext(); |
3379 if (character >= 256) { | 3379 if (character >= 256) { |
3380 escaped_length += 6; | 3380 escaped_length += 6; |
3381 } else if (IsNotEscaped(character)) { | 3381 } else if (IsNotEscaped(character)) { |
3382 escaped_length++; | 3382 escaped_length++; |
3383 } else { | 3383 } else { |
3384 escaped_length += 3; | 3384 escaped_length += 3; |
3385 } | 3385 } |
3386 // We don't allow strings that are longer than a maximal length. | 3386 // We don't allow strings that are longer than a maximal length. |
| 3387 ASSERT(String::kMaxLength < 0x7fffffff - 6); // Cannot overflow. |
3387 if (escaped_length > String::kMaxLength) { | 3388 if (escaped_length > String::kMaxLength) { |
3388 Top::context()->mark_out_of_memory(); | 3389 Top::context()->mark_out_of_memory(); |
3389 return Failure::OutOfMemoryException(); | 3390 return Failure::OutOfMemoryException(); |
3390 } | 3391 } |
3391 } | 3392 } |
3392 } | 3393 } |
3393 // No length change implies no change. Return original string if no change. | 3394 // No length change implies no change. Return original string if no change. |
3394 if (escaped_length == length) { | 3395 if (escaped_length == length) { |
3395 return source; | 3396 return source; |
3396 } | 3397 } |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3910 // Position and length encoded in two smis. | 3911 // Position and length encoded in two smis. |
3911 Object* obj = fixed_array->get(++i); | 3912 Object* obj = fixed_array->get(++i); |
3912 ASSERT(obj->IsSmi()); | 3913 ASSERT(obj->IsSmi()); |
3913 pos = Smi::cast(obj)->value(); | 3914 pos = Smi::cast(obj)->value(); |
3914 len = -encoded_slice; | 3915 len = -encoded_slice; |
3915 } | 3916 } |
3916 String::WriteToFlat(special, | 3917 String::WriteToFlat(special, |
3917 sink + position, | 3918 sink + position, |
3918 pos, | 3919 pos, |
3919 pos + len); | 3920 pos + len); |
| 3921 ASSERT(special->length() - position >= len); |
3920 position += len; | 3922 position += len; |
3921 } else { | 3923 } else { |
3922 String* string = String::cast(element); | 3924 String* string = String::cast(element); |
3923 int element_length = string->length(); | 3925 int element_length = string->length(); |
3924 String::WriteToFlat(string, sink + position, 0, element_length); | 3926 String::WriteToFlat(string, sink + position, 0, element_length); |
| 3927 ASSERT(special->length() - position >= element_length); |
3925 position += element_length; | 3928 position += element_length; |
3926 } | 3929 } |
3927 } | 3930 } |
3928 } | 3931 } |
3929 | 3932 |
3930 | 3933 |
3931 static Object* Runtime_StringBuilderConcat(Arguments args) { | 3934 static Object* Runtime_StringBuilderConcat(Arguments args) { |
3932 NoHandleAllocation ha; | 3935 NoHandleAllocation ha; |
3933 ASSERT(args.length() == 3); | 3936 ASSERT(args.length() == 3); |
3934 CONVERT_CHECKED(JSArray, array, args[0]); | 3937 CONVERT_CHECKED(JSArray, array, args[0]); |
(...skipping 18 matching lines...) Expand all Loading... |
3953 | 3956 |
3954 if (array_length == 0) { | 3957 if (array_length == 0) { |
3955 return Heap::empty_string(); | 3958 return Heap::empty_string(); |
3956 } else if (array_length == 1) { | 3959 } else if (array_length == 1) { |
3957 Object* first = fixed_array->get(0); | 3960 Object* first = fixed_array->get(0); |
3958 if (first->IsString()) return first; | 3961 if (first->IsString()) return first; |
3959 } | 3962 } |
3960 | 3963 |
3961 bool ascii = special->IsAsciiRepresentation(); | 3964 bool ascii = special->IsAsciiRepresentation(); |
3962 int position = 0; | 3965 int position = 0; |
| 3966 int increment = 0; |
3963 for (int i = 0; i < array_length; i++) { | 3967 for (int i = 0; i < array_length; i++) { |
3964 Object* elt = fixed_array->get(i); | 3968 Object* elt = fixed_array->get(i); |
3965 if (elt->IsSmi()) { | 3969 if (elt->IsSmi()) { |
3966 // Smi encoding of position and length. | 3970 // Smi encoding of position and length. |
3967 int len = Smi::cast(elt)->value(); | 3971 int len = Smi::cast(elt)->value(); |
3968 if (len > 0) { | 3972 if (len > 0) { |
3969 // Position and length encoded in one smi. | 3973 // Position and length encoded in one smi. |
3970 int pos = len >> 11; | 3974 int pos = len >> 11; |
3971 len &= 0x7ff; | 3975 len &= 0x7ff; |
3972 if (pos + len > special_length) { | 3976 if (pos + len > special_length) { |
3973 return Top::Throw(Heap::illegal_argument_symbol()); | 3977 return Top::Throw(Heap::illegal_argument_symbol()); |
3974 } | 3978 } |
3975 position += len; | 3979 increment = len; |
3976 } else { | 3980 } else { |
3977 // Position and length encoded in two smis. | 3981 // Position and length encoded in two smis. |
3978 position += (-len); | 3982 increment = (-len); |
3979 // Get the position and check that it is also a smi. | 3983 // Get the position and check that it is also a smi. |
3980 i++; | 3984 i++; |
3981 if (i >= array_length) { | 3985 if (i >= array_length) { |
3982 return Top::Throw(Heap::illegal_argument_symbol()); | 3986 return Top::Throw(Heap::illegal_argument_symbol()); |
3983 } | 3987 } |
3984 Object* pos = fixed_array->get(i); | 3988 Object* pos = fixed_array->get(i); |
3985 if (!pos->IsSmi()) { | 3989 if (!pos->IsSmi()) { |
3986 return Top::Throw(Heap::illegal_argument_symbol()); | 3990 return Top::Throw(Heap::illegal_argument_symbol()); |
3987 } | 3991 } |
3988 } | 3992 } |
3989 } else if (elt->IsString()) { | 3993 } else if (elt->IsString()) { |
3990 String* element = String::cast(elt); | 3994 String* element = String::cast(elt); |
3991 int element_length = element->length(); | 3995 int element_length = element->length(); |
3992 position += element_length; | 3996 increment = element_length; |
3993 if (ascii && !element->IsAsciiRepresentation()) { | 3997 if (ascii && !element->IsAsciiRepresentation()) { |
3994 ascii = false; | 3998 ascii = false; |
3995 } | 3999 } |
3996 } else { | 4000 } else { |
3997 return Top::Throw(Heap::illegal_argument_symbol()); | 4001 return Top::Throw(Heap::illegal_argument_symbol()); |
3998 } | 4002 } |
3999 if (position > String::kMaxLength) { | 4003 if (increment > String::kMaxLength - position) { |
4000 Top::context()->mark_out_of_memory(); | 4004 Top::context()->mark_out_of_memory(); |
4001 return Failure::OutOfMemoryException(); | 4005 return Failure::OutOfMemoryException(); |
4002 } | 4006 } |
| 4007 position += increment; |
4003 } | 4008 } |
4004 | 4009 |
4005 int length = position; | 4010 int length = position; |
4006 Object* object; | 4011 Object* object; |
4007 | 4012 |
4008 if (ascii) { | 4013 if (ascii) { |
4009 object = Heap::AllocateRawAsciiString(length); | 4014 object = Heap::AllocateRawAsciiString(length); |
4010 if (object->IsFailure()) return object; | 4015 if (object->IsFailure()) return object; |
4011 SeqAsciiString* answer = SeqAsciiString::cast(object); | 4016 SeqAsciiString* answer = SeqAsciiString::cast(object); |
4012 StringBuilderConcatHelper(special, | 4017 StringBuilderConcatHelper(special, |
(...skipping 4064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8077 } else { | 8082 } else { |
8078 // Handle last resort GC and make sure to allow future allocations | 8083 // Handle last resort GC and make sure to allow future allocations |
8079 // to grow the heap without causing GCs (if possible). | 8084 // to grow the heap without causing GCs (if possible). |
8080 Counters::gc_last_resort_from_js.Increment(); | 8085 Counters::gc_last_resort_from_js.Increment(); |
8081 Heap::CollectAllGarbage(false); | 8086 Heap::CollectAllGarbage(false); |
8082 } | 8087 } |
8083 } | 8088 } |
8084 | 8089 |
8085 | 8090 |
8086 } } // namespace v8::internal | 8091 } } // namespace v8::internal |
OLD | NEW |