Commit 6e8c85dc authored by antonm@chromium.org's avatar antonm@chromium.org

Expose a hint which communicates that string might be written many times.

Review URL: http://codereview.chromium.org/1609021

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4400 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f720592a
...@@ -859,18 +859,23 @@ class V8EXPORT String : public Primitive { ...@@ -859,18 +859,23 @@ class V8EXPORT String : public Primitive {
* \return The number of bytes copied to the buffer * \return The number of bytes copied to the buffer
* excluding the NULL terminator. * excluding the NULL terminator.
*/ */
int Write(uint16_t* buffer, int start = 0, int length = -1) const; // UTF-16 enum WriteHints {
int WriteAscii(char* buffer, int start = 0, int length = -1) const; // ASCII NO_HINTS = 0,
HINT_MANY_WRITES_EXPECTED = 1
};
int Write(uint16_t* buffer,
int start = 0,
int length = -1,
WriteHints hints = NO_HINTS) const; // UTF-16
int WriteAscii(char* buffer,
int start = 0,
int length = -1,
WriteHints hints = NO_HINTS) const; // ASCII
int WriteUtf8(char* buffer, int WriteUtf8(char* buffer,
int length = -1, int length = -1,
int* nchars_ref = NULL) const; // UTF-8 int* nchars_ref = NULL,
WriteHints hints = NO_HINTS) const; // UTF-8
/**
* Flatten internal memory. Operations on the string tend to run faster
* after flattening especially if the string is a concatenation of many
* others.
*/
void Flatten();
/** /**
* A zero length string. * A zero length string.
......
...@@ -2641,12 +2641,20 @@ int String::Utf8Length() const { ...@@ -2641,12 +2641,20 @@ int String::Utf8Length() const {
} }
int String::WriteUtf8(char* buffer, int capacity, int* nchars_ref) const { int String::WriteUtf8(char* buffer,
int capacity,
int* nchars_ref,
WriteHints hints) const {
if (IsDeadCheck("v8::String::WriteUtf8()")) return 0; if (IsDeadCheck("v8::String::WriteUtf8()")) return 0;
LOG_API("String::WriteUtf8"); LOG_API("String::WriteUtf8");
ENTER_V8; ENTER_V8;
i::Handle<i::String> str = Utils::OpenHandle(this); i::Handle<i::String> str = Utils::OpenHandle(this);
StringTracker::RecordWrite(str); StringTracker::RecordWrite(str);
if (hints & HINT_MANY_WRITES_EXPECTED) {
// Flatten the string for efficiency. This applies whether we are
// using StringInputBuffer or Get(i) to access the characters.
str->TryFlatten();
}
write_input_buffer.Reset(0, *str); write_input_buffer.Reset(0, *str);
int len = str->length(); int len = str->length();
// Encode the first K - 3 bytes directly into the buffer since we // Encode the first K - 3 bytes directly into the buffer since we
...@@ -2688,16 +2696,21 @@ int String::WriteUtf8(char* buffer, int capacity, int* nchars_ref) const { ...@@ -2688,16 +2696,21 @@ int String::WriteUtf8(char* buffer, int capacity, int* nchars_ref) const {
} }
int String::WriteAscii(char* buffer, int start, int length) const { int String::WriteAscii(char* buffer,
int start,
int length,
WriteHints hints) const {
if (IsDeadCheck("v8::String::WriteAscii()")) return 0; if (IsDeadCheck("v8::String::WriteAscii()")) return 0;
LOG_API("String::WriteAscii"); LOG_API("String::WriteAscii");
ENTER_V8; ENTER_V8;
ASSERT(start >= 0 && length >= -1); ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(this); i::Handle<i::String> str = Utils::OpenHandle(this);
StringTracker::RecordWrite(str); StringTracker::RecordWrite(str);
// Flatten the string for efficiency. This applies whether we are if (hints & HINT_MANY_WRITES_EXPECTED) {
// using StringInputBuffer or Get(i) to access the characters. // Flatten the string for efficiency. This applies whether we are
str->TryFlatten(); // using StringInputBuffer or Get(i) to access the characters.
str->TryFlatten();
}
int end = length; int end = length;
if ( (length == -1) || (length > str->length() - start) ) if ( (length == -1) || (length > str->length() - start) )
end = str->length() - start; end = str->length() - start;
...@@ -2715,13 +2728,21 @@ int String::WriteAscii(char* buffer, int start, int length) const { ...@@ -2715,13 +2728,21 @@ int String::WriteAscii(char* buffer, int start, int length) const {
} }
int String::Write(uint16_t* buffer, int start, int length) const { int String::Write(uint16_t* buffer,
int start,
int length,
WriteHints hints) const {
if (IsDeadCheck("v8::String::Write()")) return 0; if (IsDeadCheck("v8::String::Write()")) return 0;
LOG_API("String::Write"); LOG_API("String::Write");
ENTER_V8; ENTER_V8;
ASSERT(start >= 0 && length >= -1); ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(this); i::Handle<i::String> str = Utils::OpenHandle(this);
StringTracker::RecordWrite(str); StringTracker::RecordWrite(str);
if (hints & HINT_MANY_WRITES_EXPECTED) {
// Flatten the string for efficiency. This applies whether we are
// using StringInputBuffer or Get(i) to access the characters.
str->TryFlatten();
}
int end = length; int end = length;
if ( (length == -1) || (length > str->length() - start) ) if ( (length == -1) || (length > str->length() - start) )
end = str->length() - start; end = str->length() - start;
...@@ -2733,13 +2754,6 @@ int String::Write(uint16_t* buffer, int start, int length) const { ...@@ -2733,13 +2754,6 @@ int String::Write(uint16_t* buffer, int start, int length) const {
} }
void v8::String::Flatten() {
if (IsDeadCheck("v8::String::Flatten()")) return;
i::Handle<i::String> str = Utils::OpenHandle(this);
i::FlattenString(str);
}
bool v8::String::IsExternal() const { bool v8::String::IsExternal() const {
EnsureInitialized("v8::String::IsExternal()"); EnsureInitialized("v8::String::IsExternal()");
i::Handle<i::String> str = Utils::OpenHandle(this); i::Handle<i::String> str = Utils::OpenHandle(this);
......
...@@ -347,38 +347,6 @@ TEST(Utf8Conversion) { ...@@ -347,38 +347,6 @@ TEST(Utf8Conversion) {
} }
TEST(StringConcatFlatten) {
InitializeVM();
v8::HandleScope handle_scope;
const char* stringA = "0123456789";
const char* stringB = "ABCDEFGHIJ";
v8::Local<v8::String> a = v8::String::New(stringA);
v8::Local<v8::String> b = v8::String::New(stringB);
v8::Local<v8::String> cons = v8::String::Concat(a, b);
i::Handle<i::String> str = v8::Utils::OpenHandle(*cons);
CHECK(!str->IsFlat());
cons->Flatten();
CHECK(str->IsFlat());
char buffer[21];
cons->WriteUtf8(buffer);
for (int i = 0; i < 10; i++) {
CHECK_EQ(stringA[i], buffer[i]);
}
for (int i = 0; i < 10; i++) {
CHECK_EQ(stringB[i], buffer[i + 10]);
}
}
TEST(ExternalShortStringAdd) { TEST(ExternalShortStringAdd) {
ZoneScope zone(DELETE_ON_EXIT); ZoneScope zone(DELETE_ON_EXIT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment