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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 0a3508dcccabf243d24dd5789a784cf73abeb544..ec2b2e48476812c75227e150dc5eb1d5790fb1cd 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -960,26 +960,42 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
ASSERT(size >= ExternalString::kSize);
bool is_ascii = this->IsAsciiRepresentation();
bool is_symbol = this->IsSymbol();
- int length = this->length();
- int hash_field = this->hash_field();
-
- // Morph the object to an external string by adjusting the map and
- // reinitializing the fields.
- this->set_map(is_ascii ?
- heap->external_string_with_ascii_data_map() :
- heap->external_string_map());
- ExternalTwoByteString* self = ExternalTwoByteString::cast(this);
- self->set_length(length);
- self->set_hash_field(hash_field);
- self->set_resource(resource);
- // Additionally make the object into an external symbol if the original string
- // was a symbol to start with.
- if (is_symbol) {
- self->Hash(); // Force regeneration of the hash value.
- // Now morph this external string into a external symbol.
- this->set_map(is_ascii ?
- heap->external_symbol_with_ascii_data_map() :
- heap->external_symbol_map());
+
+ ExternalTwoByteString* externalized;
+
+ if (this->length() >= ExternalString::kMinBufferedStringLength &&
+ size < ExternalString::kExtendedSize) {
+ ASSERT(this->IsConsString() || this->IsSlicedString());
+ // Cannot morph in place since size is too small.
+ externalized = ExternalTwoByteString::cast(
+ *(heap->isolate()->factory()->NewExternalStringFromTwoByte(resource)));
+ this->set_map(heap->sliced_string_map());
+ SlicedString* self = SlicedString::cast(this);
+ self->set_parent(externalized);
+ self->set_offset(0);
+ } else {
+ // Morph the string to an external string in place.
+ if (this->length() < ExternalString::kMinBufferedStringLength) {
+ this->set_map(
+ is_ascii ? (is_symbol ? heap->external_symbol_with_ascii_data_map()
+ : heap->external_string_with_ascii_data_map())
+ : (is_symbol ? heap->external_symbol_map()
+ : heap->external_string_map()));
+ } else {
+ this->set_map(
+ is_ascii
+ ? (is_symbol
+ ? heap->external_buffered_symbol_with_ascii_data_map()
+ : heap->external_buffered_string_with_ascii_data_map())
+ : (is_symbol ? heap->external_buffered_symbol_map()
+ : heap->external_buffered_string_map()));
+ }
+ externalized = ExternalTwoByteString::cast(this);
+ externalized->set_resource(resource);
+ if (is_symbol) externalized->Hash(); // Force rehashing.
+ if (externalized->IsBuffered()) {
+ externalized->set_buffer_index(ExternalString::kInvalidBufferIndex);
+ }
}
// Fill the remainder of the string with dead wood.
@@ -1013,22 +1029,34 @@ bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) {
}
ASSERT(size >= ExternalString::kSize);
bool is_symbol = this->IsSymbol();
- int length = this->length();
- int hash_field = this->hash_field();
-
- // Morph the object to an external string by adjusting the map and
- // reinitializing the fields.
- this->set_map(heap->external_ascii_string_map());
- ExternalAsciiString* self = ExternalAsciiString::cast(this);
- self->set_length(length);
- self->set_hash_field(hash_field);
- self->set_resource(resource);
- // Additionally make the object into an external symbol if the original string
- // was a symbol to start with.
- if (is_symbol) {
- self->Hash(); // Force regeneration of the hash value.
- // Now morph this external string into a external symbol.
- this->set_map(heap->external_ascii_symbol_map());
+
+ ExternalAsciiString* externalized;
+
+ if (this->length() >= ExternalString::kMinBufferedStringLength &&
+ size < ExternalString::kExtendedSize) {
+ ASSERT(this->IsConsString() || this->IsSlicedString());
+ // Cannot morph in place since size is too small.
+ externalized = ExternalAsciiString::cast(
+ *(heap->isolate()->factory()->NewExternalStringFromAscii(resource)));
+ this->set_map(heap->sliced_ascii_string_map());
+ SlicedString* self = SlicedString::cast(this);
+ self->set_parent(externalized);
+ self->set_offset(0);
+ } else {
+ // Morph the string to an external string in place.
+ if (this->length() < ExternalString::kMinBufferedStringLength) {
+ this->set_map(is_symbol ? heap->external_ascii_symbol_map()
+ : heap->external_ascii_string_map());
+ } else {
+ this->set_map(is_symbol ? heap->external_buffered_ascii_symbol_map()
+ : heap->external_buffered_ascii_string_map());
+ }
+ externalized = ExternalAsciiString::cast(this);
+ externalized->set_resource(resource);
+ if (is_symbol) externalized->Hash(); // Force rehashing.
+ if (externalized->IsBuffered()) {
+ externalized->set_buffer_index(ExternalString::kInvalidBufferIndex);
+ }
}
// Fill the remainder of the string with dead wood.
@@ -6032,9 +6060,18 @@ const unibrow::byte* ConsString::ConsStringReadBlock(ReadBlockBuffer* rbb,
}
-uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
+uint16_t ExternalAsciiString::ExternalAsciiStringGet(
+ int index, ExternalStringBufferFlag flag) {
ASSERT(index >= 0 && index < length());
- return resource()->data()[index];
+ const char* source = resource()->data();
+ if (flag == UPDATE_EXTERNAL_STRING_BUFFER && IsBuffered()) {
+ int buffer_start = Max(0, index - kBackwardBufferedChars);
+ int buffer_end = Min(length(), index + kForwardBufferedChars);
+ int size = (buffer_end - buffer_start) * kASCIISize;
+ set_buffer_index(buffer_start);
+ memcpy(buffer(), source + buffer_start, size);
+ }
+ return *(source + index);
}
@@ -6057,9 +6094,18 @@ const uc16* ExternalTwoByteString::ExternalTwoByteStringGetData(
}
-uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
+uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(
+ int index, ExternalStringBufferFlag flag) {
ASSERT(index >= 0 && index < length());
- return resource()->data()[index];
+ const uint16_t* source = resource()->data();
+ if (flag == UPDATE_EXTERNAL_STRING_BUFFER && IsBuffered()) {
+ int buffer_start = Max(0, index - kBackwardBufferedChars);
+ int buffer_end = Min(length(), index + kForwardBufferedChars);
+ int size = (buffer_end - buffer_start) * kUC16Size;
+ set_buffer_index(buffer_start);
+ memcpy(buffer(), source + buffer_start, size);
+ }
+ return *(source + index);
}
@@ -6490,13 +6536,14 @@ void ConsString::ConsStringReadBlockIntoBuffer(ReadBlockBuffer* rbb,
}
-uint16_t ConsString::ConsStringGet(int index) {
+uint16_t ConsString::ConsStringGet(
+ int index, ExternalStringBufferFlag flag) {
ASSERT(index >= 0 && index < this->length());
// Check for a flattened cons string
if (second()->length() == 0) {
String* left = first();
- return left->Get(index);
+ return left->Get(index, flag);
}
String* string = String::cast(this);
@@ -6512,7 +6559,7 @@ uint16_t ConsString::ConsStringGet(int index) {
string = cons_string->second();
}
} else {
- return string->Get(index);
+ return string->Get(index, flag);
}
}
@@ -6521,8 +6568,9 @@ uint16_t ConsString::ConsStringGet(int index) {
}
-uint16_t SlicedString::SlicedStringGet(int index) {
- return parent()->Get(offset() + index);
+uint16_t SlicedString::SlicedStringGet(
+ int index, ExternalStringBufferFlag flag) {
+ return parent()->Get(offset() + index, flag);
}
« 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