Chromium Code Reviews| 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 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 // allowed. This is to avoid an assertion failure when allocating. | 624 // allowed. This is to avoid an assertion failure when allocating. |
| 625 // Flattening strings is the only case where we always allow | 625 // Flattening strings is the only case where we always allow |
| 626 // allocation because no GC is performed if the allocation fails. | 626 // allocation because no GC is performed if the allocation fails. |
| 627 if (!Heap::IsAllocationAllowed()) return this; | 627 if (!Heap::IsAllocationAllowed()) return this; |
| 628 #endif | 628 #endif |
| 629 | 629 |
| 630 switch (StringShape(this).representation_tag()) { | 630 switch (StringShape(this).representation_tag()) { |
| 631 case kConsStringTag: { | 631 case kConsStringTag: { |
| 632 ConsString* cs = ConsString::cast(this); | 632 ConsString* cs = ConsString::cast(this); |
| 633 if (cs->second()->length() == 0) { | 633 if (cs->second()->length() == 0) { |
| 634 return this; | 634 return cs->first(); |
| 635 } | 635 } |
| 636 // There's little point in putting the flat string in new space if the | 636 // There's little point in putting the flat string in new space if the |
| 637 // cons string is in old space. It can never get GCed until there is | 637 // cons string is in old space. It can never get GCed until there is |
| 638 // an old space GC. | 638 // an old space GC. |
| 639 PretenureFlag tenure = Heap::InNewSpace(this) ? pretenure : TENURED; | 639 PretenureFlag tenure = Heap::InNewSpace(this) ? pretenure : TENURED; |
| 640 int len = length(); | 640 int len = length(); |
| 641 Object* object; | 641 Object* object; |
| 642 String* result; | 642 String* result; |
| 643 if (IsAsciiRepresentation()) { | 643 if (IsAsciiRepresentation()) { |
| 644 object = Heap::AllocateRawAsciiString(len, tenure); | 644 object = Heap::AllocateRawAsciiString(len, tenure); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 662 int first_length = first->length(); | 662 int first_length = first->length(); |
| 663 WriteToFlat(first, dest, 0, first_length); | 663 WriteToFlat(first, dest, 0, first_length); |
| 664 String* second = cs->second(); | 664 String* second = cs->second(); |
| 665 WriteToFlat(second, | 665 WriteToFlat(second, |
| 666 dest + first_length, | 666 dest + first_length, |
| 667 0, | 667 0, |
| 668 len - first_length); | 668 len - first_length); |
| 669 } | 669 } |
| 670 cs->set_first(result); | 670 cs->set_first(result); |
| 671 cs->set_second(Heap::empty_string()); | 671 cs->set_second(Heap::empty_string()); |
| 672 return this; | 672 return result; |
| 673 } | 673 } |
| 674 default: | 674 default: |
| 675 return this; | 675 return this; |
| 676 } | 676 } |
| 677 } | 677 } |
| 678 | 678 |
| 679 | 679 |
| 680 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { | 680 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { |
| 681 #ifdef DEBUG | 681 #ifdef DEBUG |
| 682 if (FLAG_enable_slow_asserts) { | 682 if (FLAG_enable_slow_asserts) { |
| (...skipping 3890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4573 int len = length(); | 4573 int len = length(); |
| 4574 if (len != other->length()) return false; | 4574 if (len != other->length()) return false; |
| 4575 if (len == 0) return true; | 4575 if (len == 0) return true; |
| 4576 | 4576 |
| 4577 // Fast check: if hash code is computed for both strings | 4577 // Fast check: if hash code is computed for both strings |
| 4578 // a fast negative check can be performed. | 4578 // a fast negative check can be performed. |
| 4579 if (HasHashCode() && other->HasHashCode()) { | 4579 if (HasHashCode() && other->HasHashCode()) { |
| 4580 if (Hash() != other->Hash()) return false; | 4580 if (Hash() != other->Hash()) return false; |
| 4581 } | 4581 } |
| 4582 | 4582 |
| 4583 if (StringShape(this).IsSequentialAscii() && | 4583 // We know the strings are both non-empty. Compare the first chars |
| 4584 StringShape(other).IsSequentialAscii()) { | 4584 // before we try to flatten the strings. |
| 4585 const char* str1 = SeqAsciiString::cast(this)->GetChars(); | 4585 if (this->Get(0) != other->Get(0)) return false; |
| 4586 const char* str2 = SeqAsciiString::cast(other)->GetChars(); | 4586 |
| 4587 String* lhs = this->TryFlattenGetString(); | |
| 4588 String* rhs = other->TryFlattenGetString(); | |
| 4589 | |
| 4590 if (StringShape(lhs).IsSequentialAscii() && | |
|
Mads Ager (chromium)
2010/05/19 12:27:43
lhs->IsSeqAsciiString() and rhs->IsSeqAsciiString(
| |
| 4591 StringShape(rhs).IsSequentialAscii()) { | |
| 4592 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); | |
| 4593 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); | |
| 4587 return CompareRawStringContents(Vector<const char>(str1, len), | 4594 return CompareRawStringContents(Vector<const char>(str1, len), |
| 4588 Vector<const char>(str2, len)); | 4595 Vector<const char>(str2, len)); |
| 4589 } | 4596 } |
| 4590 | 4597 |
| 4591 if (this->IsFlat()) { | 4598 if (lhs->IsFlat()) { |
| 4592 if (IsAsciiRepresentation()) { | 4599 if (IsAsciiRepresentation()) { |
| 4593 Vector<const char> vec1 = this->ToAsciiVector(); | 4600 Vector<const char> vec1 = lhs->ToAsciiVector(); |
| 4594 if (other->IsFlat()) { | 4601 if (rhs->IsFlat()) { |
| 4595 if (other->IsAsciiRepresentation()) { | 4602 if (rhs->IsAsciiRepresentation()) { |
| 4596 Vector<const char> vec2 = other->ToAsciiVector(); | 4603 Vector<const char> vec2 = rhs->ToAsciiVector(); |
| 4597 return CompareRawStringContents(vec1, vec2); | 4604 return CompareRawStringContents(vec1, vec2); |
| 4598 } else { | 4605 } else { |
| 4599 VectorIterator<char> buf1(vec1); | 4606 VectorIterator<char> buf1(vec1); |
| 4600 VectorIterator<uc16> ib(other->ToUC16Vector()); | 4607 VectorIterator<uc16> ib(rhs->ToUC16Vector()); |
| 4601 return CompareStringContents(&buf1, &ib); | 4608 return CompareStringContents(&buf1, &ib); |
| 4602 } | 4609 } |
| 4603 } else { | 4610 } else { |
| 4604 VectorIterator<char> buf1(vec1); | 4611 VectorIterator<char> buf1(vec1); |
| 4605 string_compare_buffer_b.Reset(0, other); | 4612 string_compare_buffer_b.Reset(0, rhs); |
| 4606 return CompareStringContents(&buf1, &string_compare_buffer_b); | 4613 return CompareStringContents(&buf1, &string_compare_buffer_b); |
| 4607 } | 4614 } |
| 4608 } else { | 4615 } else { |
| 4609 Vector<const uc16> vec1 = this->ToUC16Vector(); | 4616 Vector<const uc16> vec1 = lhs->ToUC16Vector(); |
| 4610 if (other->IsFlat()) { | 4617 if (rhs->IsFlat()) { |
| 4611 if (other->IsAsciiRepresentation()) { | 4618 if (rhs->IsAsciiRepresentation()) { |
| 4612 VectorIterator<uc16> buf1(vec1); | 4619 VectorIterator<uc16> buf1(vec1); |
| 4613 VectorIterator<char> ib(other->ToAsciiVector()); | 4620 VectorIterator<char> ib(rhs->ToAsciiVector()); |
| 4614 return CompareStringContents(&buf1, &ib); | 4621 return CompareStringContents(&buf1, &ib); |
| 4615 } else { | 4622 } else { |
| 4616 Vector<const uc16> vec2(other->ToUC16Vector()); | 4623 Vector<const uc16> vec2(rhs->ToUC16Vector()); |
| 4617 return CompareRawStringContents(vec1, vec2); | 4624 return CompareRawStringContents(vec1, vec2); |
| 4618 } | 4625 } |
| 4619 } else { | 4626 } else { |
| 4620 VectorIterator<uc16> buf1(vec1); | 4627 VectorIterator<uc16> buf1(vec1); |
| 4621 string_compare_buffer_b.Reset(0, other); | 4628 string_compare_buffer_b.Reset(0, rhs); |
| 4622 return CompareStringContents(&buf1, &string_compare_buffer_b); | 4629 return CompareStringContents(&buf1, &string_compare_buffer_b); |
| 4623 } | 4630 } |
| 4624 } | 4631 } |
| 4625 } else { | 4632 } else { |
| 4626 string_compare_buffer_a.Reset(0, this); | 4633 string_compare_buffer_a.Reset(0, lhs); |
| 4627 return CompareStringContentsPartial(&string_compare_buffer_a, other); | 4634 return CompareStringContentsPartial(&string_compare_buffer_a, rhs); |
| 4628 } | 4635 } |
| 4629 } | 4636 } |
| 4630 | 4637 |
| 4631 | 4638 |
| 4632 bool String::MarkAsUndetectable() { | 4639 bool String::MarkAsUndetectable() { |
| 4633 if (StringShape(this).IsSymbol()) return false; | 4640 if (StringShape(this).IsSymbol()) return false; |
| 4634 | 4641 |
| 4635 Map* map = this->map(); | 4642 Map* map = this->map(); |
| 4636 if (map == Heap::string_map()) { | 4643 if (map == Heap::string_map()) { |
| 4637 this->set_map(Heap::undetectable_string_map()); | 4644 this->set_map(Heap::undetectable_string_map()); |
| (...skipping 2393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7031 return String::cast(string)->Equals(string_); | 7038 return String::cast(string)->Equals(string_); |
| 7032 } | 7039 } |
| 7033 | 7040 |
| 7034 uint32_t Hash() { return string_->Hash(); } | 7041 uint32_t Hash() { return string_->Hash(); } |
| 7035 | 7042 |
| 7036 uint32_t HashForObject(Object* other) { | 7043 uint32_t HashForObject(Object* other) { |
| 7037 return String::cast(other)->Hash(); | 7044 return String::cast(other)->Hash(); |
| 7038 } | 7045 } |
| 7039 | 7046 |
| 7040 Object* AsObject() { | 7047 Object* AsObject() { |
| 7041 // If the string is a cons string, attempt to flatten it so that | 7048 // Attempt to flatten the string, so that symbols will most often |
| 7042 // symbols will most often be flat strings. | 7049 // be flat strings. |
| 7043 if (StringShape(string_).IsCons()) { | 7050 string_ = string_->TryFlattenGetString(); |
| 7044 ConsString* cons_string = ConsString::cast(string_); | |
| 7045 cons_string->TryFlatten(); | |
| 7046 if (cons_string->second()->length() == 0) { | |
| 7047 string_ = cons_string->first(); | |
| 7048 } | |
| 7049 } | |
| 7050 // Transform string to symbol if possible. | 7051 // Transform string to symbol if possible. |
| 7051 Map* map = Heap::SymbolMapForString(string_); | 7052 Map* map = Heap::SymbolMapForString(string_); |
| 7052 if (map != NULL) { | 7053 if (map != NULL) { |
| 7053 string_->set_map(map); | 7054 string_->set_map(map); |
| 7054 ASSERT(string_->IsSymbol()); | 7055 ASSERT(string_->IsSymbol()); |
| 7055 return string_; | 7056 return string_; |
| 7056 } | 7057 } |
| 7057 // Otherwise allocate a new symbol. | 7058 // Otherwise allocate a new symbol. |
| 7058 StringInputBuffer buffer(string_); | 7059 StringInputBuffer buffer(string_); |
| 7059 return Heap::AllocateInternalSymbol(&buffer, | 7060 return Heap::AllocateInternalSymbol(&buffer, |
| (...skipping 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8548 if (break_point_objects()->IsUndefined()) return 0; | 8549 if (break_point_objects()->IsUndefined()) return 0; |
| 8549 // Single beak point. | 8550 // Single beak point. |
| 8550 if (!break_point_objects()->IsFixedArray()) return 1; | 8551 if (!break_point_objects()->IsFixedArray()) return 1; |
| 8551 // Multiple break points. | 8552 // Multiple break points. |
| 8552 return FixedArray::cast(break_point_objects())->length(); | 8553 return FixedArray::cast(break_point_objects())->length(); |
| 8553 } | 8554 } |
| 8554 #endif | 8555 #endif |
| 8555 | 8556 |
| 8556 | 8557 |
| 8557 } } // namespace v8::internal | 8558 } } // namespace v8::internal |
| OLD | NEW |