Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Unified Diff: src/heap.cc

Issue 114943004: Reland "Handlify concat string and substring." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix test case. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap.h ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 6921bb653f8a97c905fcc0800736c5044e6e38d4..d4ae9893008aeea9bf5a4561bab3ac4ae409a0d1 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -3794,264 +3794,6 @@ MaybeObject* Heap::AllocateJSMessageObject(String* type,
}
-
-// Returns true for a character in a range. Both limits are inclusive.
-static inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
- // This makes uses of the the unsigned wraparound.
- return character - from <= to - from;
-}
-
-
-MUST_USE_RESULT static inline MaybeObject* MakeOrFindTwoCharacterString(
- Heap* heap,
- uint16_t c1,
- uint16_t c2) {
- String* result;
- // Numeric strings have a different hash algorithm not known by
- // LookupTwoCharsStringIfExists, so we skip this step for such strings.
- if ((!Between(c1, '0', '9') || !Between(c2, '0', '9')) &&
- heap->string_table()->LookupTwoCharsStringIfExists(c1, c2, &result)) {
- return result;
- // Now we know the length is 2, we might as well make use of that fact
- // when building the new string.
- } else if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
- // We can do this.
- ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this.
- Object* result;
- { MaybeObject* maybe_result = heap->AllocateRawOneByteString(2);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
- dest[0] = static_cast<uint8_t>(c1);
- dest[1] = static_cast<uint8_t>(c2);
- return result;
- } else {
- Object* result;
- { MaybeObject* maybe_result = heap->AllocateRawTwoByteString(2);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- uc16* dest = SeqTwoByteString::cast(result)->GetChars();
- dest[0] = c1;
- dest[1] = c2;
- return result;
- }
-}
-
-
-MaybeObject* Heap::AllocateConsString(String* first, String* second) {
- int first_length = first->length();
- if (first_length == 0) {
- return second;
- }
-
- int second_length = second->length();
- if (second_length == 0) {
- return first;
- }
-
- int length = first_length + second_length;
-
- // Optimization for 2-byte strings often used as keys in a decompression
- // dictionary. Check whether we already have the string in the string
- // table to prevent creation of many unneccesary strings.
- if (length == 2) {
- uint16_t c1 = first->Get(0);
- uint16_t c2 = second->Get(0);
- return MakeOrFindTwoCharacterString(this, c1, c2);
- }
-
- bool first_is_one_byte = first->IsOneByteRepresentation();
- bool second_is_one_byte = second->IsOneByteRepresentation();
- bool is_one_byte = first_is_one_byte && second_is_one_byte;
- // Make sure that an out of memory exception is thrown if the length
- // of the new cons string is too large.
- if (length > String::kMaxLength || length < 0) {
- isolate()->context()->mark_out_of_memory();
- return Failure::OutOfMemoryException(0x4);
- }
-
- bool is_one_byte_data_in_two_byte_string = false;
- if (!is_one_byte) {
- // At least one of the strings uses two-byte representation so we
- // can't use the fast case code for short ASCII strings below, but
- // we can try to save memory if all chars actually fit in ASCII.
- is_one_byte_data_in_two_byte_string =
- first->HasOnlyOneByteChars() && second->HasOnlyOneByteChars();
- if (is_one_byte_data_in_two_byte_string) {
- isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment();
- }
- }
-
- // If the resulting string is small make a flat string.
- if (length < ConsString::kMinLength) {
- // Note that neither of the two inputs can be a slice because:
- STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength);
- ASSERT(first->IsFlat());
- ASSERT(second->IsFlat());
- if (is_one_byte) {
- Object* result;
- { MaybeObject* maybe_result = AllocateRawOneByteString(length);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- // Copy the characters into the new object.
- uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
- // Copy first part.
- const uint8_t* src;
- if (first->IsExternalString()) {
- src = ExternalAsciiString::cast(first)->GetChars();
- } else {
- src = SeqOneByteString::cast(first)->GetChars();
- }
- for (int i = 0; i < first_length; i++) *dest++ = src[i];
- // Copy second part.
- if (second->IsExternalString()) {
- src = ExternalAsciiString::cast(second)->GetChars();
- } else {
- src = SeqOneByteString::cast(second)->GetChars();
- }
- for (int i = 0; i < second_length; i++) *dest++ = src[i];
- return result;
- } else {
- if (is_one_byte_data_in_two_byte_string) {
- Object* result;
- { MaybeObject* maybe_result = AllocateRawOneByteString(length);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- // Copy the characters into the new object.
- uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
- String::WriteToFlat(first, dest, 0, first_length);
- String::WriteToFlat(second, dest + first_length, 0, second_length);
- isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment();
- return result;
- }
-
- Object* result;
- { MaybeObject* maybe_result = AllocateRawTwoByteString(length);
- if (!maybe_result->ToObject(&result)) return maybe_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);
- return result;
- }
- }
-
- Map* map = (is_one_byte || is_one_byte_data_in_two_byte_string) ?
- cons_ascii_string_map() : cons_string_map();
-
- Object* result;
- { MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
-
- DisallowHeapAllocation no_gc;
- ConsString* cons_string = ConsString::cast(result);
- WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc);
- cons_string->set_length(length);
- cons_string->set_hash_field(String::kEmptyHashField);
- cons_string->set_first(first, mode);
- cons_string->set_second(second, mode);
- return result;
-}
-
-
-MaybeObject* Heap::AllocateSubString(String* buffer,
- int start,
- int end,
- PretenureFlag pretenure) {
- int length = end - start;
- if (length <= 0) {
- return empty_string();
- }
-
- // Make an attempt to flatten the buffer to reduce access time.
- buffer = buffer->TryFlattenGetString();
-
- if (length == 1) {
- return LookupSingleCharacterStringFromCode(buffer->Get(start));
- } else if (length == 2) {
- // Optimization for 2-byte strings often used as keys in a decompression
- // dictionary. Check whether we already have the string in the string
- // table to prevent creation of many unnecessary strings.
- uint16_t c1 = buffer->Get(start);
- uint16_t c2 = buffer->Get(start + 1);
- return MakeOrFindTwoCharacterString(this, c1, c2);
- }
-
- if (!FLAG_string_slices ||
- !buffer->IsFlat() ||
- length < SlicedString::kMinLength ||
- pretenure == TENURED) {
- Object* result;
- // WriteToFlat takes care of the case when an indirect string has a
- // different encoding from its underlying string. These encodings may
- // differ because of externalization.
- bool is_one_byte = buffer->IsOneByteRepresentation();
- { MaybeObject* maybe_result = is_one_byte
- ? AllocateRawOneByteString(length, pretenure)
- : AllocateRawTwoByteString(length, pretenure);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- String* string_result = String::cast(result);
- // Copy the characters into the new object.
- if (is_one_byte) {
- ASSERT(string_result->IsOneByteRepresentation());
- uint8_t* dest = SeqOneByteString::cast(string_result)->GetChars();
- String::WriteToFlat(buffer, dest, start, end);
- } else {
- ASSERT(string_result->IsTwoByteRepresentation());
- uc16* dest = SeqTwoByteString::cast(string_result)->GetChars();
- String::WriteToFlat(buffer, dest, start, end);
- }
- return result;
- }
-
- ASSERT(buffer->IsFlat());
-#if VERIFY_HEAP
- if (FLAG_verify_heap) {
- buffer->StringVerify();
- }
-#endif
-
- Object* result;
- // When slicing an indirect string we use its encoding for a newly created
- // slice and don't check the encoding of the underlying string. This is safe
- // even if the encodings are different because of externalization. If an
- // indirect ASCII string is pointing to a two-byte string, the two-byte char
- // codes of the underlying string must still fit into ASCII (because
- // externalization must not change char codes).
- { Map* map = buffer->IsOneByteRepresentation()
- ? sliced_ascii_string_map()
- : sliced_string_map();
- MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
-
- DisallowHeapAllocation no_gc;
- SlicedString* sliced_string = SlicedString::cast(result);
- sliced_string->set_length(length);
- sliced_string->set_hash_field(String::kEmptyHashField);
- if (buffer->IsConsString()) {
- ConsString* cons = ConsString::cast(buffer);
- ASSERT(cons->second()->length() == 0);
- sliced_string->set_parent(cons->first());
- sliced_string->set_offset(start);
- } else if (buffer->IsSlicedString()) {
- // Prevent nesting sliced strings.
- SlicedString* parent_slice = SlicedString::cast(buffer);
- sliced_string->set_parent(parent_slice->parent());
- sliced_string->set_offset(start + parent_slice->offset());
- } else {
- sliced_string->set_parent(buffer);
- sliced_string->set_offset(start);
- }
- ASSERT(sliced_string->parent()->IsSeqString() ||
- sliced_string->parent()->IsExternalString());
- return result;
-}
-
-
MaybeObject* Heap::AllocateExternalStringFromAscii(
const ExternalAsciiString::Resource* resource) {
size_t length = resource->length();
« no previous file with comments | « src/heap.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698