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

Side by Side Diff: src/objects.cc

Issue 8568013: Introduce read buffer for external strings when using charAt (ia32). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698