Landing http://codereview.chromium.org/1594017 for Ryan.
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 8 Apr 2010 18:23:10 +0000 (18:23 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 8 Apr 2010 18:23:10 +0000 (18:23 +0000)
TBR=ager@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4367 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8.h
src/api.cc
test/cctest/test-strings.cc

index d4a323f..db739bb 100644 (file)
@@ -866,6 +866,13 @@ class V8EXPORT String : public Primitive {
                 int* nchars_ref = NULL) 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.
    */
   static v8::Local<v8::String> Empty();
index 0145db6..2c7975b 100644 (file)
@@ -2733,6 +2733,13 @@ 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 {
   EnsureInitialized("v8::String::IsExternal()");
   i::Handle<i::String> str = Utils::OpenHandle(this);
index 0e30092..aadb7d0 100644 (file)
@@ -347,6 +347,38 @@ 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) {
   ZoneScope zone(DELETE_ON_EXIT);