| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 // There's little point in putting the flat string in new space if the | 520 // There's little point in putting the flat string in new space if the |
| 521 // cons string is in old space. It can never get GCed until there is | 521 // cons string is in old space. It can never get GCed until there is |
| 522 // an old space GC. | 522 // an old space GC. |
| 523 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED : TENURED; | 523 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED : TENURED; |
| 524 int len = length(); | 524 int len = length(); |
| 525 Object* object = IsAscii() ? | 525 Object* object = IsAscii() ? |
| 526 Heap::AllocateRawAsciiString(len, tenure) : | 526 Heap::AllocateRawAsciiString(len, tenure) : |
| 527 Heap::AllocateRawTwoByteString(len, tenure); | 527 Heap::AllocateRawTwoByteString(len, tenure); |
| 528 if (object->IsFailure()) return object; | 528 if (object->IsFailure()) return object; |
| 529 String* result = String::cast(object); | 529 String* result = String::cast(object); |
| 530 StringHasher hasher(len); | 530 Flatten(this, result, 0, len, 0); |
| 531 Flatten(this, result, 0, len, 0, &hasher); | |
| 532 if (hasher.is_valid()) { | |
| 533 #ifdef DEBUG | |
| 534 result->ComputeAndSetHash(); | |
| 535 ASSERT(result->length_field() == hasher.GetHashField()); | |
| 536 #else | |
| 537 result->set_length_field(hasher.GetHashField()); | |
| 538 #endif | |
| 539 Heap::LookupSymbolIfExists(result, &result); | |
| 540 } | |
| 541 cs->set_first(result); | 531 cs->set_first(result); |
| 542 cs->set_second(Heap::empty_string()); | 532 cs->set_second(Heap::empty_string()); |
| 543 return this; | 533 return this; |
| 544 } | 534 } |
| 545 default: | 535 default: |
| 546 return this; | 536 return this; |
| 547 } | 537 } |
| 548 } | 538 } |
| 549 | 539 |
| 550 | 540 |
| (...skipping 3063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3614 if (ok->IsFailure()) return ok; | 3604 if (ok->IsFailure()) return ok; |
| 3615 } | 3605 } |
| 3616 return this; | 3606 return this; |
| 3617 } | 3607 } |
| 3618 | 3608 |
| 3619 | 3609 |
| 3620 void String::Flatten(String* src, | 3610 void String::Flatten(String* src, |
| 3621 String* sink, | 3611 String* sink, |
| 3622 int f, | 3612 int f, |
| 3623 int t, | 3613 int t, |
| 3624 int so, | 3614 int so) { |
| 3625 StringHasher* hasher) { | |
| 3626 String* source = src; | 3615 String* source = src; |
| 3627 int from = f; | 3616 int from = f; |
| 3628 int to = t; | 3617 int to = t; |
| 3629 int sink_offset = so; | 3618 int sink_offset = so; |
| 3630 while (true) { | 3619 while (true) { |
| 3631 ASSERT(0 <= from && from <= to && to <= source->length()); | 3620 ASSERT(0 <= from && from <= to && to <= source->length()); |
| 3632 ASSERT(0 <= sink_offset && sink_offset < sink->length()); | 3621 ASSERT(0 <= sink_offset && sink_offset < sink->length()); |
| 3633 switch (source->representation_tag()) { | 3622 switch (source->representation_tag()) { |
| 3634 case kSeqStringTag: | 3623 case kSeqStringTag: |
| 3635 case kExternalStringTag: { | 3624 case kExternalStringTag: { |
| 3636 Access<StringInputBuffer> buffer(&string_input_buffer); | 3625 Access<StringInputBuffer> buffer(&string_input_buffer); |
| 3637 buffer->Reset(from, source); | 3626 buffer->Reset(from, source); |
| 3638 int j = sink_offset; | 3627 int j = sink_offset; |
| 3639 for (int i = from; i < to; i++) { | 3628 for (int i = from; i < to; i++) { |
| 3640 uc32 c = buffer->GetNext(); | 3629 uc32 c = buffer->GetNext(); |
| 3641 if (hasher->is_valid()) | |
| 3642 hasher->AddCharacter(c); | |
| 3643 sink->Set(j++, c); | 3630 sink->Set(j++, c); |
| 3644 } | 3631 } |
| 3645 return; | 3632 return; |
| 3646 } | 3633 } |
| 3647 case kSlicedStringTag: { | 3634 case kSlicedStringTag: { |
| 3648 SlicedString* sliced_string = SlicedString::cast(source); | 3635 SlicedString* sliced_string = SlicedString::cast(source); |
| 3649 int start = sliced_string->start(); | 3636 int start = sliced_string->start(); |
| 3650 from += start; | 3637 from += start; |
| 3651 to += start; | 3638 to += start; |
| 3652 source = String::cast(sliced_string->buffer()); | 3639 source = String::cast(sliced_string->buffer()); |
| 3653 } | 3640 } |
| 3654 break; | 3641 break; |
| 3655 case kConsStringTag: { | 3642 case kConsStringTag: { |
| 3656 ConsString* cons_string = ConsString::cast(source); | 3643 ConsString* cons_string = ConsString::cast(source); |
| 3657 String* first = String::cast(cons_string->first()); | 3644 String* first = String::cast(cons_string->first()); |
| 3658 int boundary = first->length(); | 3645 int boundary = first->length(); |
| 3659 if (to - boundary >= boundary - from) { | 3646 if (to - boundary >= boundary - from) { |
| 3660 // Right hand side is longer. Recurse over left. | 3647 // Right hand side is longer. Recurse over left. |
| 3661 if (from < boundary) { | 3648 if (from < boundary) { |
| 3662 Flatten(first, sink, from, boundary, sink_offset, hasher); | 3649 Flatten(first, sink, from, boundary, sink_offset); |
| 3663 sink_offset += boundary - from; | 3650 sink_offset += boundary - from; |
| 3664 from = 0; | 3651 from = 0; |
| 3665 } else { | 3652 } else { |
| 3666 from -= boundary; | 3653 from -= boundary; |
| 3667 } | 3654 } |
| 3668 to -= boundary; | 3655 to -= boundary; |
| 3669 source = String::cast(cons_string->second()); | 3656 source = String::cast(cons_string->second()); |
| 3670 } else { | 3657 } else { |
| 3671 // Left hand side is longer. Recurse over right. The hasher | 3658 // Left hand side is longer. Recurse over right. The hasher |
| 3672 // needs us to visit the string from left to right so doing | 3659 // needs us to visit the string from left to right so doing |
| 3673 // this invalidates that hash. | 3660 // this invalidates that hash. |
| 3674 hasher->invalidate(); | |
| 3675 if (to > boundary) { | 3661 if (to > boundary) { |
| 3676 String* second = String::cast(cons_string->second()); | 3662 String* second = String::cast(cons_string->second()); |
| 3677 Flatten(second, | 3663 Flatten(second, |
| 3678 sink, | 3664 sink, |
| 3679 0, | 3665 0, |
| 3680 to - boundary, | 3666 to - boundary, |
| 3681 sink_offset + boundary - from, | 3667 sink_offset + boundary - from); |
| 3682 hasher); | |
| 3683 to = boundary; | 3668 to = boundary; |
| 3684 } | 3669 } |
| 3685 source = first; | 3670 source = first; |
| 3686 } | 3671 } |
| 3687 } | 3672 } |
| 3688 break; | 3673 break; |
| 3689 } | 3674 } |
| 3690 } | 3675 } |
| 3691 } | 3676 } |
| 3692 | 3677 |
| (...skipping 2766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6459 // No break point. | 6444 // No break point. |
| 6460 if (break_point_objects()->IsUndefined()) return 0; | 6445 if (break_point_objects()->IsUndefined()) return 0; |
| 6461 // Single beak point. | 6446 // Single beak point. |
| 6462 if (!break_point_objects()->IsFixedArray()) return 1; | 6447 if (!break_point_objects()->IsFixedArray()) return 1; |
| 6463 // Multiple break points. | 6448 // Multiple break points. |
| 6464 return FixedArray::cast(break_point_objects())->length(); | 6449 return FixedArray::cast(break_point_objects())->length(); |
| 6465 } | 6450 } |
| 6466 | 6451 |
| 6467 | 6452 |
| 6468 } } // namespace v8::internal | 6453 } } // namespace v8::internal |
| OLD | NEW |