| Index: src/factory.cc
|
| diff --git a/src/factory.cc b/src/factory.cc
|
| index f131e508abdd850f5996e7608237a50c9ac603f9..cccc3e76297b20a2ade4272efcd978e7d0c2f06b 100644
|
| --- a/src/factory.cc
|
| +++ b/src/factory.cc
|
| @@ -287,43 +287,11 @@ Handle<SeqTwoByteString> Factory::NewRawTwoByteString(int length,
|
| }
|
|
|
|
|
| -// 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;
|
| -}
|
| -
|
| -
|
| -static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
|
| - uint16_t c1,
|
| - uint16_t c2) {
|
| - // 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')) {
|
| - String* result;
|
| - StringTable* table = isolate->heap()->string_table();
|
| - if (table->LookupTwoCharsStringIfExists(c1, c2, &result)) {
|
| - return handle(result);
|
| - }
|
| - }
|
| -
|
| - // Now we know the length is 2, we might as well make use of that fact
|
| - // when building the new string.
|
| - if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
|
| - // We can do this.
|
| - ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this.
|
| - Handle<SeqOneByteString> str = isolate->factory()->NewRawOneByteString(2);
|
| - uint8_t* dest = str->GetChars();
|
| - dest[0] = static_cast<uint8_t>(c1);
|
| - dest[1] = static_cast<uint8_t>(c2);
|
| - return str;
|
| - } else {
|
| - Handle<SeqTwoByteString> str = isolate->factory()->NewRawTwoByteString(2);
|
| - uc16* dest = str->GetChars();
|
| - dest[0] = c1;
|
| - dest[1] = c2;
|
| - return str;
|
| - }
|
| +Handle<String> Factory::NewConsString(Handle<String> first,
|
| + Handle<String> second) {
|
| + CALL_HEAP_FUNCTION(isolate(),
|
| + isolate()->heap()->AllocateConsString(*first, *second),
|
| + String);
|
| }
|
|
|
|
|
| @@ -339,99 +307,6 @@ Handle<String> ConcatStringContent(Handle<StringType> result,
|
| }
|
|
|
|
|
| -Handle<ConsString> Factory::NewRawConsString(String::Encoding encoding) {
|
| - Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING)
|
| - ? cons_ascii_string_map() : cons_string_map();
|
| - CALL_HEAP_FUNCTION(isolate(),
|
| - isolate()->heap()->Allocate(*map, NEW_SPACE),
|
| - ConsString);
|
| -}
|
| -
|
| -
|
| -Handle<String> Factory::NewConsString(Handle<String> left,
|
| - Handle<String> right) {
|
| - int left_length = left->length();
|
| - if (left_length == 0) return right;
|
| - int right_length = right->length();
|
| - if (right_length == 0) return left;
|
| -
|
| - int length = left_length + right_length;
|
| -
|
| - if (length == 2) {
|
| - uint16_t c1 = left->Get(0);
|
| - uint16_t c2 = right->Get(0);
|
| - return MakeOrFindTwoCharacterString(isolate(), c1, c2);
|
| - }
|
| -
|
| - // 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();
|
| - V8::FatalProcessOutOfMemory("String concatenation result too large.");
|
| - UNREACHABLE();
|
| - return Handle<String>::null();
|
| - }
|
| -
|
| - bool left_is_one_byte = left->IsOneByteRepresentation();
|
| - bool right_is_one_byte = right->IsOneByteRepresentation();
|
| - bool is_one_byte = left_is_one_byte && right_is_one_byte;
|
| - 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 =
|
| - left->HasOnlyOneByteChars() && right->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(left->IsFlat());
|
| - ASSERT(right->IsFlat());
|
| -
|
| - if (is_one_byte) {
|
| - Handle<SeqOneByteString> result = NewRawOneByteString(length);
|
| - DisallowHeapAllocation no_gc;
|
| - uint8_t* dest = result->GetChars();
|
| - // Copy left part.
|
| - const uint8_t* src = left->IsExternalString()
|
| - ? Handle<ExternalAsciiString>::cast(left)->GetChars()
|
| - : Handle<SeqOneByteString>::cast(left)->GetChars();
|
| - for (int i = 0; i < left_length; i++) *dest++ = src[i];
|
| - // Copy right part.
|
| - src = right->IsExternalString()
|
| - ? Handle<ExternalAsciiString>::cast(right)->GetChars()
|
| - : Handle<SeqOneByteString>::cast(right)->GetChars();
|
| - for (int i = 0; i < right_length; i++) *dest++ = src[i];
|
| - return result;
|
| - }
|
| -
|
| - return (is_one_byte_data_in_two_byte_string)
|
| - ? ConcatStringContent<uint8_t>(NewRawOneByteString(length), left, right)
|
| - : ConcatStringContent<uc16>(NewRawTwoByteString(length), left, right);
|
| - }
|
| -
|
| - Handle<ConsString> result = NewRawConsString(
|
| - (is_one_byte || is_one_byte_data_in_two_byte_string)
|
| - ? String::ONE_BYTE_ENCODING
|
| - : String::TWO_BYTE_ENCODING);
|
| -
|
| - DisallowHeapAllocation no_gc;
|
| - WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
|
| -
|
| - result->set_hash_field(String::kEmptyHashField);
|
| - result->set_length(length);
|
| - result->set_first(*left, mode);
|
| - result->set_second(*right, mode);
|
| - return result;
|
| -}
|
| -
|
| -
|
| Handle<String> Factory::NewFlatConcatString(Handle<String> first,
|
| Handle<String> second) {
|
| int total_length = first->length() + second->length();
|
| @@ -446,89 +321,22 @@ Handle<String> Factory::NewFlatConcatString(Handle<String> first,
|
| }
|
|
|
|
|
| -Handle<SlicedString> Factory::NewRawSlicedString(String::Encoding encoding) {
|
| - Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING)
|
| - ? sliced_ascii_string_map() : sliced_string_map();
|
| +Handle<String> Factory::NewSubString(Handle<String> str,
|
| + int begin,
|
| + int end) {
|
| CALL_HEAP_FUNCTION(isolate(),
|
| - isolate()->heap()->Allocate(*map, NEW_SPACE),
|
| - SlicedString);
|
| + str->SubString(begin, end),
|
| + String);
|
| }
|
|
|
|
|
| Handle<String> Factory::NewProperSubString(Handle<String> str,
|
| int begin,
|
| int end) {
|
| -#if VERIFY_HEAP
|
| - if (FLAG_verify_heap) str->StringVerify();
|
| -#endif
|
| ASSERT(begin > 0 || end < str->length());
|
| -
|
| - int length = end - begin;
|
| - if (length <= 0) return empty_string();
|
| - if (length == 1) {
|
| - return LookupSingleCharacterStringFromCode(isolate(), str->Get(begin));
|
| - }
|
| - 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 = str->Get(begin);
|
| - uint16_t c2 = str->Get(begin + 1);
|
| - return MakeOrFindTwoCharacterString(isolate(), c1, c2);
|
| - }
|
| -
|
| - if (!FLAG_string_slices || length < SlicedString::kMinLength) {
|
| - if (str->IsOneByteRepresentation()) {
|
| - Handle<SeqOneByteString> result = NewRawOneByteString(length);
|
| - uint8_t* dest = result->GetChars();
|
| - DisallowHeapAllocation no_gc;
|
| - String::WriteToFlat(*str, dest, begin, end);
|
| - return result;
|
| - } else {
|
| - Handle<SeqTwoByteString> result = NewRawTwoByteString(length);
|
| - uc16* dest = result->GetChars();
|
| - DisallowHeapAllocation no_gc;
|
| - String::WriteToFlat(*str, dest, begin, end);
|
| - return result;
|
| - }
|
| - }
|
| -
|
| - int offset = begin;
|
| -
|
| - while (str->IsConsString()) {
|
| - Handle<ConsString> cons = Handle<ConsString>::cast(str);
|
| - int split = cons->first()->length();
|
| - if (split <= offset) {
|
| - // Slice is fully contained in the second part.
|
| - str = Handle<String>(cons->second(), isolate());
|
| - offset -= split; // Adjust for offset.
|
| - continue;
|
| - } else if (offset + length <= split) {
|
| - // Slice is fully contained in the first part.
|
| - str = Handle<String>(cons->first(), isolate());
|
| - continue;
|
| - }
|
| - break;
|
| - }
|
| -
|
| - if (str->IsSlicedString()) {
|
| - Handle<SlicedString> slice = Handle<SlicedString>::cast(str);
|
| - str = Handle<String>(slice->parent(), isolate());
|
| - offset += slice->offset();
|
| - } else {
|
| - str = FlattenGetString(str);
|
| - }
|
| -
|
| - ASSERT(str->IsSeqString() || str->IsExternalString());
|
| - Handle<SlicedString> slice = NewRawSlicedString(
|
| - str->IsOneByteRepresentation() ? String::ONE_BYTE_ENCODING
|
| - : String::TWO_BYTE_ENCODING);
|
| -
|
| - slice->set_hash_field(String::kEmptyHashField);
|
| - slice->set_length(length);
|
| - slice->set_parent(*str);
|
| - slice->set_offset(offset);
|
| - return slice;
|
| + CALL_HEAP_FUNCTION(isolate(),
|
| + isolate()->heap()->AllocateSubString(*str, begin, end),
|
| + String);
|
| }
|
|
|
|
|
|
|