OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2267 } | 2267 } |
2268 | 2268 |
2269 | 2269 |
2270 Handle<String> ToString() { | 2270 Handle<String> ToString() { |
2271 if (array_builder_.length() == 0) { | 2271 if (array_builder_.length() == 0) { |
2272 return heap_->isolate()->factory()->empty_string(); | 2272 return heap_->isolate()->factory()->empty_string(); |
2273 } | 2273 } |
2274 | 2274 |
2275 Handle<String> joined_string; | 2275 Handle<String> joined_string; |
2276 if (is_ascii_) { | 2276 if (is_ascii_) { |
2277 joined_string = NewRawAsciiString(character_count_); | 2277 Handle<SeqAsciiString> seq = NewRawAsciiString(character_count_); |
2278 AssertNoAllocation no_alloc; | 2278 AssertNoAllocation no_alloc; |
2279 SeqAsciiString* seq = SeqAsciiString::cast(*joined_string); | |
2280 char* char_buffer = seq->GetChars(); | 2279 char* char_buffer = seq->GetChars(); |
2281 StringBuilderConcatHelper(*subject_, | 2280 StringBuilderConcatHelper(*subject_, |
2282 char_buffer, | 2281 char_buffer, |
2283 *array_builder_.array(), | 2282 *array_builder_.array(), |
2284 array_builder_.length()); | 2283 array_builder_.length()); |
| 2284 joined_string = Handle<String>::cast(seq); |
2285 } else { | 2285 } else { |
2286 // Non-ASCII. | 2286 // Non-ASCII. |
2287 joined_string = NewRawTwoByteString(character_count_); | 2287 Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_); |
2288 AssertNoAllocation no_alloc; | 2288 AssertNoAllocation no_alloc; |
2289 SeqTwoByteString* seq = SeqTwoByteString::cast(*joined_string); | |
2290 uc16* char_buffer = seq->GetChars(); | 2289 uc16* char_buffer = seq->GetChars(); |
2291 StringBuilderConcatHelper(*subject_, | 2290 StringBuilderConcatHelper(*subject_, |
2292 char_buffer, | 2291 char_buffer, |
2293 *array_builder_.array(), | 2292 *array_builder_.array(), |
2294 array_builder_.length()); | 2293 array_builder_.length()); |
| 2294 joined_string = Handle<String>::cast(seq); |
2295 } | 2295 } |
2296 return joined_string; | 2296 return joined_string; |
2297 } | 2297 } |
2298 | 2298 |
2299 | 2299 |
2300 void IncrementCharacterCount(int by) { | 2300 void IncrementCharacterCount(int by) { |
2301 if (character_count_ > String::kMaxLength - by) { | 2301 if (character_count_ > String::kMaxLength - by) { |
2302 V8::FatalProcessOutOfMemory("String.replace result too large."); | 2302 V8::FatalProcessOutOfMemory("String.replace result too large."); |
2303 } | 2303 } |
2304 character_count_ += by; | 2304 character_count_ += by; |
2305 } | 2305 } |
2306 | 2306 |
2307 Handle<JSArray> GetParts() { | 2307 Handle<JSArray> GetParts() { |
2308 return array_builder_.ToJSArray(); | 2308 return array_builder_.ToJSArray(); |
2309 } | 2309 } |
2310 | 2310 |
2311 private: | 2311 private: |
2312 Handle<String> NewRawAsciiString(int size) { | 2312 Handle<SeqAsciiString> NewRawAsciiString(int length) { |
2313 CALL_HEAP_FUNCTION(heap_->isolate(), | 2313 return heap_->isolate()->factory()->NewRawAsciiString(length); |
2314 heap_->AllocateRawAsciiString(size), String); | |
2315 } | 2314 } |
2316 | 2315 |
2317 | 2316 |
2318 Handle<String> NewRawTwoByteString(int size) { | 2317 Handle<SeqTwoByteString> NewRawTwoByteString(int length) { |
2319 CALL_HEAP_FUNCTION(heap_->isolate(), | 2318 return heap_->isolate()->factory()->NewRawTwoByteString(length); |
2320 heap_->AllocateRawTwoByteString(size), String); | |
2321 } | 2319 } |
2322 | 2320 |
2323 | 2321 |
2324 void AddElement(Object* element) { | 2322 void AddElement(Object* element) { |
2325 ASSERT(element->IsSmi() || element->IsString()); | 2323 ASSERT(element->IsSmi() || element->IsString()); |
2326 ASSERT(array_builder_.capacity() > array_builder_.length()); | 2324 ASSERT(array_builder_.capacity() > array_builder_.length()); |
2327 array_builder_.Add(element); | 2325 array_builder_.Add(element); |
2328 } | 2326 } |
2329 | 2327 |
2330 Heap* heap_; | 2328 Heap* heap_; |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3165 } while (!match->IsNull()); | 3163 } while (!match->IsNull()); |
3166 int matches = offsets.length() / 2; | 3164 int matches = offsets.length() / 2; |
3167 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches); | 3165 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches); |
3168 Handle<String> substring = isolate->factory()-> | 3166 Handle<String> substring = isolate->factory()-> |
3169 NewSubString(subject, offsets.at(0), offsets.at(1)); | 3167 NewSubString(subject, offsets.at(0), offsets.at(1)); |
3170 elements->set(0, *substring); | 3168 elements->set(0, *substring); |
3171 for (int i = 1; i < matches ; i++) { | 3169 for (int i = 1; i < matches ; i++) { |
3172 int from = offsets.at(i * 2); | 3170 int from = offsets.at(i * 2); |
3173 int to = offsets.at(i * 2 + 1); | 3171 int to = offsets.at(i * 2 + 1); |
3174 Handle<String> substring = isolate->factory()-> | 3172 Handle<String> substring = isolate->factory()-> |
3175 NewStrictSubString(subject, from, to); | 3173 NewProperSubString(subject, from, to); |
3176 elements->set(i, *substring); | 3174 elements->set(i, *substring); |
3177 } | 3175 } |
3178 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements); | 3176 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements); |
3179 result->set_length(Smi::FromInt(matches)); | 3177 result->set_length(Smi::FromInt(matches)); |
3180 return *result; | 3178 return *result; |
3181 } | 3179 } |
3182 | 3180 |
3183 | 3181 |
3184 // Two smis before and after the match, for very long strings. | 3182 // Two smis before and after the match, for very long strings. |
3185 const int kMaxBuilderEntriesPerRegExpMatch = 5; | 3183 const int kMaxBuilderEntriesPerRegExpMatch = 5; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3335 match_start = register_vector[0]; | 3333 match_start = register_vector[0]; |
3336 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); | 3334 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
3337 if (match_end < match_start) { | 3335 if (match_end < match_start) { |
3338 ReplacementStringBuilder::AddSubjectSlice(builder, | 3336 ReplacementStringBuilder::AddSubjectSlice(builder, |
3339 match_end, | 3337 match_end, |
3340 match_start); | 3338 match_start); |
3341 } | 3339 } |
3342 match_end = register_vector[1]; | 3340 match_end = register_vector[1]; |
3343 HandleScope loop_scope(isolate); | 3341 HandleScope loop_scope(isolate); |
3344 if (!first) { | 3342 if (!first) { |
3345 builder->Add(*isolate->factory()->NewStrictSubString(subject, | 3343 builder->Add(*isolate->factory()->NewProperSubString(subject, |
3346 match_start, | 3344 match_start, |
3347 match_end)); | 3345 match_end)); |
3348 } else { | 3346 } else { |
3349 builder->Add(*isolate->factory()->NewSubString(subject, | 3347 builder->Add(*isolate->factory()->NewSubString(subject, |
3350 match_start, | 3348 match_start, |
3351 match_end)); | 3349 match_end)); |
3352 } | 3350 } |
3353 if (match_start != match_end) { | 3351 if (match_start != match_end) { |
3354 pos = match_end; | 3352 pos = match_end; |
3355 } else { | 3353 } else { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3427 | 3425 |
3428 { | 3426 { |
3429 // Avoid accumulating new handles inside loop. | 3427 // Avoid accumulating new handles inside loop. |
3430 HandleScope temp_scope(isolate); | 3428 HandleScope temp_scope(isolate); |
3431 // Arguments array to replace function is match, captures, index and | 3429 // Arguments array to replace function is match, captures, index and |
3432 // subject, i.e., 3 + capture count in total. | 3430 // subject, i.e., 3 + capture count in total. |
3433 Handle<FixedArray> elements = | 3431 Handle<FixedArray> elements = |
3434 isolate->factory()->NewFixedArray(3 + capture_count); | 3432 isolate->factory()->NewFixedArray(3 + capture_count); |
3435 Handle<String> match; | 3433 Handle<String> match; |
3436 if (!first) { | 3434 if (!first) { |
3437 match = isolate->factory()->NewStrictSubString(subject, | 3435 match = isolate->factory()->NewProperSubString(subject, |
3438 match_start, | 3436 match_start, |
3439 match_end); | 3437 match_end); |
3440 } else { | 3438 } else { |
3441 match = isolate->factory()->NewSubString(subject, | 3439 match = isolate->factory()->NewSubString(subject, |
3442 match_start, | 3440 match_start, |
3443 match_end); | 3441 match_end); |
3444 } | 3442 } |
3445 elements->set(0, *match); | 3443 elements->set(0, *match); |
3446 for (int i = 1; i <= capture_count; i++) { | 3444 for (int i = 1; i <= capture_count; i++) { |
3447 int start = register_vector[i * 2]; | 3445 int start = register_vector[i * 2]; |
3448 if (start >= 0) { | 3446 if (start >= 0) { |
3449 int end = register_vector[i * 2 + 1]; | 3447 int end = register_vector[i * 2 + 1]; |
3450 ASSERT(start <= end); | 3448 ASSERT(start <= end); |
3451 Handle<String> substring; | 3449 Handle<String> substring; |
3452 if (!first) { | 3450 if (!first) { |
3453 substring = isolate->factory()->NewStrictSubString(subject, | 3451 substring = isolate->factory()->NewProperSubString(subject, |
3454 start, | 3452 start, |
3455 end); | 3453 end); |
3456 } else { | 3454 } else { |
3457 substring = isolate->factory()->NewSubString(subject, start, end); | 3455 substring = isolate->factory()->NewSubString(subject, start, end); |
3458 } | 3456 } |
3459 elements->set(i, *substring); | 3457 elements->set(i, *substring); |
3460 } else { | 3458 } else { |
3461 ASSERT(register_vector[i * 2 + 1] < 0); | 3459 ASSERT(register_vector[i * 2 + 1] < 0); |
3462 elements->set(i, isolate->heap()->undefined_value()); | 3460 elements->set(i, isolate->heap()->undefined_value()); |
3463 } | 3461 } |
(...skipping 2384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5848 FixedArray::cast(result->elements())->set(0, *subject); | 5846 FixedArray::cast(result->elements())->set(0, *subject); |
5849 return *result; | 5847 return *result; |
5850 } | 5848 } |
5851 | 5849 |
5852 Handle<FixedArray> elements(FixedArray::cast(result->elements())); | 5850 Handle<FixedArray> elements(FixedArray::cast(result->elements())); |
5853 int part_start = 0; | 5851 int part_start = 0; |
5854 for (int i = 0; i < part_count; i++) { | 5852 for (int i = 0; i < part_count; i++) { |
5855 HandleScope local_loop_handle; | 5853 HandleScope local_loop_handle; |
5856 int part_end = indices.at(i); | 5854 int part_end = indices.at(i); |
5857 Handle<String> substring = | 5855 Handle<String> substring = |
5858 isolate->factory()->NewStrictSubString(subject, part_start, part_end); | 5856 isolate->factory()->NewProperSubString(subject, part_start, part_end); |
5859 elements->set(i, *substring); | 5857 elements->set(i, *substring); |
5860 part_start = part_end + pattern_length; | 5858 part_start = part_end + pattern_length; |
5861 } | 5859 } |
5862 | 5860 |
5863 return *result; | 5861 return *result; |
5864 } | 5862 } |
5865 | 5863 |
5866 | 5864 |
5867 // Copies ascii characters to the given fixed array looking up | 5865 // Copies ascii characters to the given fixed array looking up |
5868 // one-char strings in the cache. Gives up on the first char that is | 5866 // one-char strings in the cache. Gives up on the first char that is |
(...skipping 6614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12483 } else { | 12481 } else { |
12484 // Handle last resort GC and make sure to allow future allocations | 12482 // Handle last resort GC and make sure to allow future allocations |
12485 // to grow the heap without causing GCs (if possible). | 12483 // to grow the heap without causing GCs (if possible). |
12486 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12484 isolate->counters()->gc_last_resort_from_js()->Increment(); |
12487 isolate->heap()->CollectAllGarbage(false); | 12485 isolate->heap()->CollectAllGarbage(false); |
12488 } | 12486 } |
12489 } | 12487 } |
12490 | 12488 |
12491 | 12489 |
12492 } } // namespace v8::internal | 12490 } } // namespace v8::internal |
OLD | NEW |