Chromium Code Reviews| Index: src/heap.cc |
| =================================================================== |
| --- src/heap.cc (revision 654) |
| +++ src/heap.cc (working copy) |
| @@ -777,13 +777,15 @@ |
| return ScavengeObjectSlow(p, object); |
| } |
| + |
| static inline bool IsShortcutCandidate(HeapObject* object, Map* map) { |
| - // A ConString object with Heap::empty_string() as the right side |
| + // A ConsString object with Heap::empty_string() as the right side |
| // is a candidate for being shortcut by the scavenger. |
| ASSERT(object->map() == map); |
| - return (map->instance_type() < FIRST_NONSTRING_TYPE) && |
| - (String::cast(object)->map_representation_tag(map) == kConsStringTag) && |
| - (ConsString::cast(object)->second() == Heap::empty_string()); |
| + if (map->instance_type() >= FIRST_NONSTRING_TYPE) return false; |
| + StringShape shape(map); |
| + return (shape.representation_tag() == kConsStringTag) && |
| + (ConsString::cast(object)->unchecked_second() == Heap::empty_string()); |
| } |
| @@ -794,7 +796,7 @@ |
| // Optimization: Bypass flattened ConsString objects. |
| if (IsShortcutCandidate(object, first_word.ToMap())) { |
| - object = HeapObject::cast(ConsString::cast(object)->first()); |
| + object = HeapObject::cast(ConsString::cast(object)->unchecked_first()); |
| *p = object; |
| // After patching *p we have to repeat the checks that object is in the |
| // active semispace of the young generation and not already copied. |
| @@ -1344,32 +1346,32 @@ |
| } |
| -Object* Heap::AllocateConsString(String* first, String* second) { |
| - int first_length = first->length(); |
| - int second_length = second->length(); |
| +Object* Heap::AllocateConsString(String* first, StringShape first_shape, String* second, StringShape second_shape) { |
|
Mads Ager (chromium)
2008/11/03 08:45:49
Isn't this line too long?
|
| + int first_length = first->length(first_shape); |
| + int second_length = second->length(second_shape); |
| int length = first_length + second_length; |
| - bool is_ascii = first->is_ascii_representation() |
| - && second->is_ascii_representation(); |
| + bool is_ascii = first_shape.IsAsciiRepresentation() |
| + && second_shape.IsAsciiRepresentation(); |
| // If the resulting string is small make a flat string. |
| if (length < String::kMinNonFlatLength) { |
| - ASSERT(first->IsFlat()); |
| - ASSERT(second->IsFlat()); |
| + ASSERT(first->IsFlat(first_shape)); |
| + ASSERT(second->IsFlat(second_shape)); |
| if (is_ascii) { |
| Object* result = AllocateRawAsciiString(length); |
| if (result->IsFailure()) return result; |
| // Copy the characters into the new object. |
| char* dest = SeqAsciiString::cast(result)->GetChars(); |
| - String::WriteToFlat(first, dest, 0, first_length); |
| - String::WriteToFlat(second, dest + first_length, 0, second_length); |
| + String::WriteToFlat(first, first_shape, dest, 0, first_length); |
| + String::WriteToFlat(second, second_shape, dest + first_length, 0, second_length); |
| return result; |
| } else { |
| Object* result = AllocateRawTwoByteString(length); |
| if (result->IsFailure()) return result; |
| // Copy the characters into the new object. |
| uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
| - String::WriteToFlat(first, dest, 0, first_length); |
| - String::WriteToFlat(second, dest + first_length, 0, second_length); |
| + String::WriteToFlat(first, first_shape, dest, 0, first_length); |
| + String::WriteToFlat(second, second_shape, dest + first_length, 0, second_length); |
| return result; |
| } |
| } |
| @@ -1397,24 +1399,30 @@ |
| } |
| -Object* Heap::AllocateSlicedString(String* buffer, int start, int end) { |
| +Object* Heap::AllocateSlicedString(String* buffer, |
| + StringShape buffer_shape, |
| + int start, |
| + int end) { |
| int length = end - start; |
| // If the resulting string is small make a sub string. |
| if (end - start <= String::kMinNonFlatLength) { |
| - return Heap::AllocateSubString(buffer, start, end); |
| + return Heap::AllocateSubString(buffer, buffer_shape, start, end); |
| } |
| Map* map; |
| if (length <= String::kMaxShortStringSize) { |
| - map = buffer->is_ascii_representation() ? short_sliced_ascii_string_map() |
| - : short_sliced_string_map(); |
| + map = buffer_shape.IsAsciiRepresentation() ? |
| + short_sliced_ascii_string_map() : |
| + short_sliced_string_map(); |
| } else if (length <= String::kMaxMediumStringSize) { |
| - map = buffer->is_ascii_representation() ? medium_sliced_ascii_string_map() |
| - : medium_sliced_string_map(); |
| + map = buffer_shape.IsAsciiRepresentation() ? |
| + medium_sliced_ascii_string_map() : |
| + medium_sliced_string_map(); |
| } else { |
| - map = buffer->is_ascii_representation() ? long_sliced_ascii_string_map() |
| - : long_sliced_string_map(); |
| + map = buffer_shape.IsAsciiRepresentation() ? |
| + long_sliced_ascii_string_map() : |
| + long_sliced_string_map(); |
| } |
| Object* result = Allocate(map, NEW_SPACE); |
| @@ -1429,34 +1437,42 @@ |
| } |
| -Object* Heap::AllocateSubString(String* buffer, int start, int end) { |
| +Object* Heap::AllocateSubString(String* buffer, |
| + StringShape buffer_shape, |
| + int start, |
| + int end) { |
| int length = end - start; |
| if (length == 1) { |
| - return Heap::LookupSingleCharacterStringFromCode(buffer->Get(start)); |
| + return Heap::LookupSingleCharacterStringFromCode( |
| + buffer->Get(buffer_shape, start)); |
| } |
| // Make an attempt to flatten the buffer to reduce access time. |
| - buffer->TryFlatten(); |
| + if (!buffer->IsFlat(buffer_shape)) { |
| + buffer->TryFlatten(buffer_shape); |
| + buffer_shape = buffer; |
|
Mads Ager (chromium)
2008/11/03 08:45:49
Please make the conversion explicit here.
|
| + } |
| - Object* result = buffer->is_ascii_representation() |
| + Object* result = buffer_shape.IsAsciiRepresentation() |
| ? AllocateRawAsciiString(length) |
| : AllocateRawTwoByteString(length); |
| if (result->IsFailure()) return result; |
| // Copy the characters into the new object. |
| String* string_result = String::cast(result); |
| + StringShape result_shape(string_result); |
| StringHasher hasher(length); |
| int i = 0; |
| for (; i < length && hasher.is_array_index(); i++) { |
| - uc32 c = buffer->Get(start + i); |
| + uc32 c = buffer->Get(buffer_shape, start + i); |
| hasher.AddCharacter(c); |
| - string_result->Set(i, c); |
| + string_result->Set(result_shape, i, c); |
| } |
| for (; i < length; i++) { |
| - uc32 c = buffer->Get(start + i); |
| + uc32 c = buffer->Get(buffer_shape, start + i); |
| hasher.AddCharacterNoIndex(c); |
| - string_result->Set(i, c); |
| + string_result->Set(result_shape, i, c); |
| } |
| string_result->set_length_field(hasher.GetHashField()); |
| return result; |
| @@ -1525,8 +1541,9 @@ |
| Object* result = Heap::AllocateRawTwoByteString(1); |
| if (result->IsFailure()) return result; |
| - String::cast(result)->Set(0, code); |
| - return result; |
| + String* answer = String::cast(result); |
| + answer->Set(StringShape(answer), 0, code); |
| + return answer; |
| } |
| @@ -1905,9 +1922,10 @@ |
| // Convert and copy the characters into the new object. |
| String* string_result = String::cast(result); |
| decoder->Reset(string.start(), string.length()); |
| + StringShape result_shape(string_result); |
| for (int i = 0; i < chars; i++) { |
| uc32 r = decoder->GetNext(); |
| - string_result->Set(i, r); |
| + string_result->Set(result_shape, i, r); |
| } |
| return result; |
| } |
| @@ -1930,8 +1948,9 @@ |
| // Copy the characters into the new object, which may be either ASCII or |
| // UTF-16. |
| String* string_result = String::cast(result); |
| + StringShape result_shape(string_result); |
| for (int i = 0; i < string.length(); i++) { |
| - string_result->Set(i, string[i]); |
| + string_result->Set(result_shape, i, string[i]); |
| } |
| return result; |
| } |
| @@ -2043,15 +2062,17 @@ |
| reinterpret_cast<HeapObject*>(result)->set_map(map); |
| // The hash value contains the length of the string. |
| - String::cast(result)->set_length_field(length_field); |
| + String* answer = String::cast(result); |
| + StringShape answer_shape(answer); |
| + answer->set_length_field(length_field); |
| - ASSERT_EQ(size, String::cast(result)->Size()); |
| + ASSERT_EQ(size, answer->Size()); |
| // Fill in the characters. |
| for (int i = 0; i < chars; i++) { |
| - String::cast(result)->Set(i, buffer->GetNext()); |
| + answer->Set(answer_shape, i, buffer->GetNext()); |
| } |
| - return result; |
| + return answer; |
| } |