| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 Heap* heap = GetHeap(); | 953 Heap* heap = GetHeap(); |
| 954 int size = this->Size(); // Byte size of the original string. | 954 int size = this->Size(); // Byte size of the original string. |
| 955 if (size < ExternalString::kSize) { | 955 if (size < ExternalString::kSize) { |
| 956 // The string is too small to fit an external String in its place. This can | 956 // The string is too small to fit an external String in its place. This can |
| 957 // only happen for zero length strings. | 957 // only happen for zero length strings. |
| 958 return false; | 958 return false; |
| 959 } | 959 } |
| 960 ASSERT(size >= ExternalString::kSize); | 960 ASSERT(size >= ExternalString::kSize); |
| 961 bool is_ascii = this->IsAsciiRepresentation(); | 961 bool is_ascii = this->IsAsciiRepresentation(); |
| 962 bool is_symbol = this->IsSymbol(); | 962 bool is_symbol = this->IsSymbol(); |
| 963 int length = this->length(); | |
| 964 int hash_field = this->hash_field(); | |
| 965 | 963 |
| 966 // Morph the object to an external string by adjusting the map and | 964 ExternalTwoByteString* externalized; |
| 967 // reinitializing the fields. | 965 |
| 968 this->set_map(is_ascii ? | 966 if (this->length() >= ExternalString::kMinBufferedStringLength && |
| 969 heap->external_string_with_ascii_data_map() : | 967 size < ExternalString::kExtendedSize) { |
| 970 heap->external_string_map()); | 968 ASSERT(this->IsConsString() || this->IsSlicedString()); |
| 971 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); | 969 // Cannot morph in place since size is too small. |
| 972 self->set_length(length); | 970 externalized = ExternalTwoByteString::cast( |
| 973 self->set_hash_field(hash_field); | 971 *(heap->isolate()->factory()->NewExternalStringFromTwoByte(resource))); |
| 974 self->set_resource(resource); | 972 this->set_map(heap->sliced_string_map()); |
| 975 // Additionally make the object into an external symbol if the original string | 973 SlicedString* self = SlicedString::cast(this); |
| 976 // was a symbol to start with. | 974 self->set_parent(externalized); |
| 977 if (is_symbol) { | 975 self->set_offset(0); |
| 978 self->Hash(); // Force regeneration of the hash value. | 976 } else { |
| 979 // Now morph this external string into a external symbol. | 977 // Morph the string to an external string in place. |
| 980 this->set_map(is_ascii ? | 978 if (this->length() < ExternalString::kMinBufferedStringLength) { |
| 981 heap->external_symbol_with_ascii_data_map() : | 979 this->set_map( |
| 982 heap->external_symbol_map()); | 980 is_ascii ? (is_symbol ? heap->external_symbol_with_ascii_data_map() |
| 981 : heap->external_string_with_ascii_data_map()) |
| 982 : (is_symbol ? heap->external_symbol_map() |
| 983 : heap->external_string_map())); |
| 984 } else { |
| 985 this->set_map( |
| 986 is_ascii |
| 987 ? (is_symbol |
| 988 ? heap->external_buffered_symbol_with_ascii_data_map() |
| 989 : heap->external_buffered_string_with_ascii_data_map()) |
| 990 : (is_symbol ? heap->external_buffered_symbol_map() |
| 991 : heap->external_buffered_string_map())); |
| 992 } |
| 993 externalized = ExternalTwoByteString::cast(this); |
| 994 externalized->set_resource(resource); |
| 995 if (is_symbol) externalized->Hash(); // Force rehashing. |
| 996 if (externalized->IsBuffered()) { |
| 997 externalized->set_buffer_index(ExternalString::kInvalidBufferIndex); |
| 998 } |
| 983 } | 999 } |
| 984 | 1000 |
| 985 // Fill the remainder of the string with dead wood. | 1001 // Fill the remainder of the string with dead wood. |
| 986 int new_size = this->Size(); // Byte size of the external String object. | 1002 int new_size = this->Size(); // Byte size of the external String object. |
| 987 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 1003 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
| 988 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { | 1004 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { |
| 989 MemoryChunk::IncrementLiveBytes(this->address(), new_size - size); | 1005 MemoryChunk::IncrementLiveBytes(this->address(), new_size - size); |
| 990 } | 1006 } |
| 991 return true; | 1007 return true; |
| 992 } | 1008 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1006 #endif // DEBUG | 1022 #endif // DEBUG |
| 1007 Heap* heap = GetHeap(); | 1023 Heap* heap = GetHeap(); |
| 1008 int size = this->Size(); // Byte size of the original string. | 1024 int size = this->Size(); // Byte size of the original string. |
| 1009 if (size < ExternalString::kSize) { | 1025 if (size < ExternalString::kSize) { |
| 1010 // The string is too small to fit an external String in its place. This can | 1026 // The string is too small to fit an external String in its place. This can |
| 1011 // only happen for zero length strings. | 1027 // only happen for zero length strings. |
| 1012 return false; | 1028 return false; |
| 1013 } | 1029 } |
| 1014 ASSERT(size >= ExternalString::kSize); | 1030 ASSERT(size >= ExternalString::kSize); |
| 1015 bool is_symbol = this->IsSymbol(); | 1031 bool is_symbol = this->IsSymbol(); |
| 1016 int length = this->length(); | |
| 1017 int hash_field = this->hash_field(); | |
| 1018 | 1032 |
| 1019 // Morph the object to an external string by adjusting the map and | 1033 ExternalAsciiString* externalized; |
| 1020 // reinitializing the fields. | 1034 |
| 1021 this->set_map(heap->external_ascii_string_map()); | 1035 if (this->length() >= ExternalString::kMinBufferedStringLength && |
| 1022 ExternalAsciiString* self = ExternalAsciiString::cast(this); | 1036 size < ExternalString::kExtendedSize) { |
| 1023 self->set_length(length); | 1037 ASSERT(this->IsConsString() || this->IsSlicedString()); |
| 1024 self->set_hash_field(hash_field); | 1038 // Cannot morph in place since size is too small. |
| 1025 self->set_resource(resource); | 1039 externalized = ExternalAsciiString::cast( |
| 1026 // Additionally make the object into an external symbol if the original string | 1040 *(heap->isolate()->factory()->NewExternalStringFromAscii(resource))); |
| 1027 // was a symbol to start with. | 1041 this->set_map(heap->sliced_ascii_string_map()); |
| 1028 if (is_symbol) { | 1042 SlicedString* self = SlicedString::cast(this); |
| 1029 self->Hash(); // Force regeneration of the hash value. | 1043 self->set_parent(externalized); |
| 1030 // Now morph this external string into a external symbol. | 1044 self->set_offset(0); |
| 1031 this->set_map(heap->external_ascii_symbol_map()); | 1045 } else { |
| 1046 // Morph the string to an external string in place. |
| 1047 if (this->length() < ExternalString::kMinBufferedStringLength) { |
| 1048 this->set_map(is_symbol ? heap->external_ascii_symbol_map() |
| 1049 : heap->external_ascii_string_map()); |
| 1050 } else { |
| 1051 this->set_map(is_symbol ? heap->external_buffered_ascii_symbol_map() |
| 1052 : heap->external_buffered_ascii_string_map()); |
| 1053 } |
| 1054 externalized = ExternalAsciiString::cast(this); |
| 1055 externalized->set_resource(resource); |
| 1056 if (is_symbol) externalized->Hash(); // Force rehashing. |
| 1057 if (externalized->IsBuffered()) { |
| 1058 externalized->set_buffer_index(ExternalString::kInvalidBufferIndex); |
| 1059 } |
| 1032 } | 1060 } |
| 1033 | 1061 |
| 1034 // Fill the remainder of the string with dead wood. | 1062 // Fill the remainder of the string with dead wood. |
| 1035 int new_size = this->Size(); // Byte size of the external String object. | 1063 int new_size = this->Size(); // Byte size of the external String object. |
| 1036 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 1064 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
| 1037 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { | 1065 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { |
| 1038 MemoryChunk::IncrementLiveBytes(this->address(), new_size - size); | 1066 MemoryChunk::IncrementLiveBytes(this->address(), new_size - size); |
| 1039 } | 1067 } |
| 1040 | 1068 |
| 1041 return true; | 1069 return true; |
| (...skipping 4983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6025 rbb, | 6053 rbb, |
| 6026 &offset, | 6054 &offset, |
| 6027 max_chars > rbb->capacity ? rbb->capacity : max_chars); | 6055 max_chars > rbb->capacity ? rbb->capacity : max_chars); |
| 6028 *offset_ptr = offset + offset_correction; | 6056 *offset_ptr = offset + offset_correction; |
| 6029 return rbb->util_buffer; | 6057 return rbb->util_buffer; |
| 6030 } | 6058 } |
| 6031 } | 6059 } |
| 6032 } | 6060 } |
| 6033 | 6061 |
| 6034 | 6062 |
| 6035 uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) { | 6063 uint16_t ExternalAsciiString::ExternalAsciiStringGet( |
| 6064 int index, ExternalStringBufferFlag flag) { |
| 6036 ASSERT(index >= 0 && index < length()); | 6065 ASSERT(index >= 0 && index < length()); |
| 6037 return resource()->data()[index]; | 6066 const char* source = resource()->data(); |
| 6067 if (flag == UPDATE_EXTERNAL_STRING_BUFFER && IsBuffered()) { |
| 6068 int buffer_start = Max(0, index - kBackwardBufferedChars); |
| 6069 int buffer_end = Min(length(), index + kForwardBufferedChars); |
| 6070 int size = (buffer_end - buffer_start) * kASCIISize; |
| 6071 set_buffer_index(buffer_start); |
| 6072 memcpy(buffer(), source + buffer_start, size); |
| 6073 } |
| 6074 return *(source + index); |
| 6038 } | 6075 } |
| 6039 | 6076 |
| 6040 | 6077 |
| 6041 const unibrow::byte* ExternalAsciiString::ExternalAsciiStringReadBlock( | 6078 const unibrow::byte* ExternalAsciiString::ExternalAsciiStringReadBlock( |
| 6042 unsigned* remaining, | 6079 unsigned* remaining, |
| 6043 unsigned* offset_ptr, | 6080 unsigned* offset_ptr, |
| 6044 unsigned max_chars) { | 6081 unsigned max_chars) { |
| 6045 // Cast const char* to unibrow::byte* (signedness difference). | 6082 // Cast const char* to unibrow::byte* (signedness difference). |
| 6046 const unibrow::byte* b = | 6083 const unibrow::byte* b = |
| 6047 reinterpret_cast<const unibrow::byte*>(resource()->data()) + *offset_ptr; | 6084 reinterpret_cast<const unibrow::byte*>(resource()->data()) + *offset_ptr; |
| 6048 *remaining = max_chars; | 6085 *remaining = max_chars; |
| 6049 *offset_ptr += max_chars; | 6086 *offset_ptr += max_chars; |
| 6050 return b; | 6087 return b; |
| 6051 } | 6088 } |
| 6052 | 6089 |
| 6053 | 6090 |
| 6054 const uc16* ExternalTwoByteString::ExternalTwoByteStringGetData( | 6091 const uc16* ExternalTwoByteString::ExternalTwoByteStringGetData( |
| 6055 unsigned start) { | 6092 unsigned start) { |
| 6056 return resource()->data() + start; | 6093 return resource()->data() + start; |
| 6057 } | 6094 } |
| 6058 | 6095 |
| 6059 | 6096 |
| 6060 uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) { | 6097 uint16_t ExternalTwoByteString::ExternalTwoByteStringGet( |
| 6098 int index, ExternalStringBufferFlag flag) { |
| 6061 ASSERT(index >= 0 && index < length()); | 6099 ASSERT(index >= 0 && index < length()); |
| 6062 return resource()->data()[index]; | 6100 const uint16_t* source = resource()->data(); |
| 6101 if (flag == UPDATE_EXTERNAL_STRING_BUFFER && IsBuffered()) { |
| 6102 int buffer_start = Max(0, index - kBackwardBufferedChars); |
| 6103 int buffer_end = Min(length(), index + kForwardBufferedChars); |
| 6104 int size = (buffer_end - buffer_start) * kUC16Size; |
| 6105 set_buffer_index(buffer_start); |
| 6106 memcpy(buffer(), source + buffer_start, size); |
| 6107 } |
| 6108 return *(source + index); |
| 6063 } | 6109 } |
| 6064 | 6110 |
| 6065 | 6111 |
| 6066 void ExternalTwoByteString::ExternalTwoByteStringReadBlockIntoBuffer( | 6112 void ExternalTwoByteString::ExternalTwoByteStringReadBlockIntoBuffer( |
| 6067 ReadBlockBuffer* rbb, | 6113 ReadBlockBuffer* rbb, |
| 6068 unsigned* offset_ptr, | 6114 unsigned* offset_ptr, |
| 6069 unsigned max_chars) { | 6115 unsigned max_chars) { |
| 6070 unsigned chars_read = 0; | 6116 unsigned chars_read = 0; |
| 6071 unsigned offset = *offset_ptr; | 6117 unsigned offset = *offset_ptr; |
| 6072 const uint16_t* data = resource()->data(); | 6118 const uint16_t* data = resource()->data(); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6483 offset_correction += left_length; | 6529 offset_correction += left_length; |
| 6484 String::ReadBlockIntoBuffer(right, rbb, &offset, max_chars); | 6530 String::ReadBlockIntoBuffer(right, rbb, &offset, max_chars); |
| 6485 } | 6531 } |
| 6486 *offset_ptr = offset + offset_correction; | 6532 *offset_ptr = offset + offset_correction; |
| 6487 return; | 6533 return; |
| 6488 } | 6534 } |
| 6489 } | 6535 } |
| 6490 } | 6536 } |
| 6491 | 6537 |
| 6492 | 6538 |
| 6493 uint16_t ConsString::ConsStringGet(int index) { | 6539 uint16_t ConsString::ConsStringGet( |
| 6540 int index, ExternalStringBufferFlag flag) { |
| 6494 ASSERT(index >= 0 && index < this->length()); | 6541 ASSERT(index >= 0 && index < this->length()); |
| 6495 | 6542 |
| 6496 // Check for a flattened cons string | 6543 // Check for a flattened cons string |
| 6497 if (second()->length() == 0) { | 6544 if (second()->length() == 0) { |
| 6498 String* left = first(); | 6545 String* left = first(); |
| 6499 return left->Get(index); | 6546 return left->Get(index, flag); |
| 6500 } | 6547 } |
| 6501 | 6548 |
| 6502 String* string = String::cast(this); | 6549 String* string = String::cast(this); |
| 6503 | 6550 |
| 6504 while (true) { | 6551 while (true) { |
| 6505 if (StringShape(string).IsCons()) { | 6552 if (StringShape(string).IsCons()) { |
| 6506 ConsString* cons_string = ConsString::cast(string); | 6553 ConsString* cons_string = ConsString::cast(string); |
| 6507 String* left = cons_string->first(); | 6554 String* left = cons_string->first(); |
| 6508 if (left->length() > index) { | 6555 if (left->length() > index) { |
| 6509 string = left; | 6556 string = left; |
| 6510 } else { | 6557 } else { |
| 6511 index -= left->length(); | 6558 index -= left->length(); |
| 6512 string = cons_string->second(); | 6559 string = cons_string->second(); |
| 6513 } | 6560 } |
| 6514 } else { | 6561 } else { |
| 6515 return string->Get(index); | 6562 return string->Get(index, flag); |
| 6516 } | 6563 } |
| 6517 } | 6564 } |
| 6518 | 6565 |
| 6519 UNREACHABLE(); | 6566 UNREACHABLE(); |
| 6520 return 0; | 6567 return 0; |
| 6521 } | 6568 } |
| 6522 | 6569 |
| 6523 | 6570 |
| 6524 uint16_t SlicedString::SlicedStringGet(int index) { | 6571 uint16_t SlicedString::SlicedStringGet( |
| 6525 return parent()->Get(offset() + index); | 6572 int index, ExternalStringBufferFlag flag) { |
| 6573 return parent()->Get(offset() + index, flag); |
| 6526 } | 6574 } |
| 6527 | 6575 |
| 6528 | 6576 |
| 6529 const unibrow::byte* SlicedString::SlicedStringReadBlock( | 6577 const unibrow::byte* SlicedString::SlicedStringReadBlock( |
| 6530 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { | 6578 ReadBlockBuffer* buffer, unsigned* offset_ptr, unsigned chars) { |
| 6531 unsigned offset = this->offset(); | 6579 unsigned offset = this->offset(); |
| 6532 *offset_ptr += offset; | 6580 *offset_ptr += offset; |
| 6533 const unibrow::byte* answer = String::ReadBlock(String::cast(parent()), | 6581 const unibrow::byte* answer = String::ReadBlock(String::cast(parent()), |
| 6534 buffer, offset_ptr, chars); | 6582 buffer, offset_ptr, chars); |
| 6535 *offset_ptr -= offset; | 6583 *offset_ptr -= offset; |
| (...skipping 6000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12536 if (break_point_objects()->IsUndefined()) return 0; | 12584 if (break_point_objects()->IsUndefined()) return 0; |
| 12537 // Single break point. | 12585 // Single break point. |
| 12538 if (!break_point_objects()->IsFixedArray()) return 1; | 12586 if (!break_point_objects()->IsFixedArray()) return 1; |
| 12539 // Multiple break points. | 12587 // Multiple break points. |
| 12540 return FixedArray::cast(break_point_objects())->length(); | 12588 return FixedArray::cast(break_point_objects())->length(); |
| 12541 } | 12589 } |
| 12542 #endif // ENABLE_DEBUGGER_SUPPORT | 12590 #endif // ENABLE_DEBUGGER_SUPPORT |
| 12543 | 12591 |
| 12544 | 12592 |
| 12545 } } // namespace v8::internal | 12593 } } // namespace v8::internal |
| OLD | NEW |