Revision: 10049
Author:   yang...@chromium.org
Date:     Wed Nov 23 01:58:58 2011
Log:      Introduce short external strings without pointer cache.

BUG=
TEST=

Review URL: http://codereview.chromium.org/8635011
http://code.google.com/p/v8/source/detail?r=10049

Modified:
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/heap-inl.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/ia32/codegen-ia32.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects-printer.cc
 /branches/bleeding_edge/src/objects-visiting.cc
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/serialize.cc
 /branches/bleeding_edge/test/cctest/test-api.cc
 /branches/bleeding_edge/test/mjsunit/string-externalize.js

=======================================
--- /branches/bleeding_edge/src/api.cc  Tue Nov 15 14:48:55 2011
+++ /branches/bleeding_edge/src/api.cc  Wed Nov 23 01:58:58 2011
@@ -4556,12 +4556,9 @@
   i::Handle<i::String> obj = Utils::OpenHandle(this);
   i::Isolate* isolate = obj->GetIsolate();
   if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false;
-  if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
-    return false;
-  }
+  if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
   int size = obj->Size();  // Byte size of the original string.
-  if (size < i::ExternalString::kSize)
-    return false;
+  if (size < i::ExternalString::kShortSize) return false;
   i::StringShape shape(*obj);
   return !shape.IsExternal();
 }
=======================================
--- /branches/bleeding_edge/src/heap-inl.h      Mon Nov 21 02:18:47 2011
+++ /branches/bleeding_edge/src/heap-inl.h      Wed Nov 23 01:58:58 2011
@@ -255,16 +255,11 @@
           ExternalString::kResourceOffset -
           kHeapObjectTag);

-  // Clear pointer cache.
-  ExternalString::cast(string)->clear_data_cache();
-
   // Dispose of the C++ object if it has not already been disposed.
   if (*resource_addr != NULL) {
     (*resource_addr)->Dispose();
-  }
-
-  // Clear the resource pointer in the string.
-  *resource_addr = NULL;
+    *resource_addr = NULL;
+  }
 }


=======================================
--- /branches/bleeding_edge/src/heap.cc Thu Nov 17 09:05:12 2011
+++ /branches/bleeding_edge/src/heap.cc Wed Nov 23 01:58:58 2011
@@ -3997,6 +3997,15 @@
   if (map == external_string_with_ascii_data_map()) {
     return external_symbol_with_ascii_data_map();
   }
+  if (map == short_external_string_map()) {
+    return short_external_symbol_map();
+  }
+  if (map == short_external_ascii_string_map()) {
+    return short_external_ascii_symbol_map();
+  }
+  if (map == short_external_string_with_ascii_data_map()) {
+    return short_external_symbol_with_ascii_data_map();
+  }

   // No match found.
   return NULL;
=======================================
--- /branches/bleeding_edge/src/heap.h  Mon Nov 21 02:18:47 2011
+++ /branches/bleeding_edge/src/heap.h  Wed Nov 23 01:58:58 2011
@@ -110,6 +110,16 @@
V(Map, external_string_map, ExternalStringMap) \ V(Map, external_string_with_ascii_data_map, ExternalStringWithAsciiDataMap) \ V(Map, external_ascii_string_map, ExternalAsciiStringMap) \ + V(Map, short_external_symbol_map, ShortExternalSymbolMap) \ + V(Map, \ + short_external_symbol_with_ascii_data_map, \ + ShortExternalSymbolWithAsciiDataMap) \ + V(Map, short_external_ascii_symbol_map, ShortExternalAsciiSymbolMap) \ + V(Map, short_external_string_map, ShortExternalStringMap) \ + V(Map, \ + short_external_string_with_ascii_data_map, \ + ShortExternalStringWithAsciiDataMap) \ + V(Map, short_external_ascii_string_map, ShortExternalAsciiStringMap) \ V(Map, undetectable_string_map, UndetectableStringMap) \ V(Map, undetectable_ascii_string_map, UndetectableAsciiStringMap) \ V(Map, external_pixel_array_map, ExternalPixelArrayMap) \
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Thu Nov 17 09:05:12 2011 +++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Nov 23 01:58:58 2011
@@ -563,15 +563,17 @@
     __ Assert(zero, "external string expected, but not found");
   }
__ mov(result, FieldOperand(string, ExternalString::kResourceDataOffset));
-  // Assert that the external string has not been finalized yet.
-  __ test(result, result);
-  __ j(zero, call_runtime);
   Register scratch = string;
   __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset));
-  __ cmp(scratch, Immediate(factory->external_ascii_string_map()));
-  __ j(equal, &ascii_external, Label::kNear);
-  __ cmp(scratch, Immediate(factory->external_ascii_symbol_map()));
-  __ j(equal, &ascii_external, Label::kNear);
+  __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
+  // Rule out short external strings.
+  STATIC_CHECK(kShortExternalStringTag != 0);
+  __ test_b(scratch, kShortExternalStringMask);
+  __ j(not_zero, call_runtime);
+  // Check encoding.
+  STATIC_ASSERT(kTwoByteStringTag == 0);
+  __ test_b(scratch, kStringEncodingMask);
+  __ j(not_equal, &ascii_external, Label::kNear);
   // Two-byte string.
   __ movzx_w(result, Operand(result, index, times_2, 0));
   __ jmp(&done);
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Tue Nov 22 11:46:00 2011
+++ /branches/bleeding_edge/src/objects-inl.h   Wed Nov 23 01:58:58 2011
@@ -2297,29 +2297,35 @@
 }


-void ExternalString::clear_data_cache() {
-  WRITE_INTPTR_FIELD(this, kResourceDataOffset, 0);
+bool ExternalString::is_short() {
+  InstanceType type = map()->instance_type();
+  return (type & kShortExternalStringMask) == kShortExternalStringTag;
 }


 const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
   return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
 }
+
+
+void ExternalAsciiString::update_data_cache() {
+  if (is_short()) return;
+  const char** data_field =
+ reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
+  *data_field = resource()->data();
+}


 void ExternalAsciiString::set_resource(
     const ExternalAsciiString::Resource* resource) {
   *reinterpret_cast<const Resource**>(
       FIELD_ADDR(this, kResourceOffset)) = resource;
-  clear_data_cache();
+  if (resource != NULL) update_data_cache();
 }


 const char* ExternalAsciiString::GetChars() {
-  const char** data_field =
- reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
-  if (*data_field == NULL) *data_field = resource()->data();
-  return *data_field;
+  return resource()->data();
 }


@@ -2332,21 +2338,26 @@
 const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
   return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
 }
+
+
+void ExternalTwoByteString::update_data_cache() {
+  if (is_short()) return;
+  const uint16_t** data_field =
+ reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
+  *data_field = resource()->data();
+}


 void ExternalTwoByteString::set_resource(
     const ExternalTwoByteString::Resource* resource) {
   *reinterpret_cast<const Resource**>(
       FIELD_ADDR(this, kResourceOffset)) = resource;
-  clear_data_cache();
+  if (resource != NULL) update_data_cache();
 }


 const uint16_t* ExternalTwoByteString::GetChars() {
-  const uint16_t** data_field =
- reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
-  if (*data_field == NULL) *data_field = resource()->data();
-  return *data_field;
+  return resource()->data();
 }


=======================================
--- /branches/bleeding_edge/src/objects-printer.cc      Tue Nov  8 00:42:13 2011
+++ /branches/bleeding_edge/src/objects-printer.cc      Wed Nov 23 01:58:58 2011
@@ -446,6 +446,9 @@
     case EXTERNAL_ASCII_SYMBOL_TYPE:
     case EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE:
     case EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
+    case SHORT_EXTERNAL_ASCII_SYMBOL_TYPE:
+    case SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE:
+    case SHORT_EXTERNAL_SYMBOL_TYPE: return "SHORT_EXTERNAL_SYMBOL";
     case ASCII_STRING_TYPE: return "ASCII_STRING";
     case STRING_TYPE: return "TWO_BYTE_STRING";
     case CONS_STRING_TYPE:
@@ -453,6 +456,9 @@
     case EXTERNAL_ASCII_STRING_TYPE:
     case EXTERNAL_STRING_WITH_ASCII_DATA_TYPE:
     case EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
+    case SHORT_EXTERNAL_ASCII_STRING_TYPE:
+    case SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE:
+    case SHORT_EXTERNAL_STRING_TYPE: return "SHORT_EXTERNAL_STRING";
     case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
     case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
     case FREE_SPACE_TYPE: return "FREE_SPACE";
=======================================
--- /branches/bleeding_edge/src/objects-visiting.cc     Tue Oct 25 07:14:56 2011
+++ /branches/bleeding_edge/src/objects-visiting.cc     Wed Nov 23 01:58:58 2011
@@ -64,7 +64,7 @@
       case kExternalStringTag:
         return GetVisitorIdForSize(kVisitDataObject,
                                    kVisitDataObjectGeneric,
-                                   ExternalString::kSize);
+                                   instance_size);
     }
     UNREACHABLE();
   }
=======================================
--- /branches/bleeding_edge/src/objects.cc      Fri Nov 18 06:09:41 2011
+++ /branches/bleeding_edge/src/objects.cc      Wed Nov 23 01:58:58 2011
@@ -952,33 +952,32 @@
 #endif  // DEBUG
   Heap* heap = GetHeap();
   int size = this->Size();  // Byte size of the original string.
-  if (size < ExternalString::kSize) {
+  if (size < ExternalString::kShortSize) {
     return false;
   }
-  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());
+  if (size >= ExternalString::kSize) {
+    this->set_map(
+        is_symbol
+            ? (is_ascii ?  heap->external_symbol_with_ascii_data_map()
+                        :  heap->external_symbol_map())
+            : (is_ascii ?  heap->external_string_with_ascii_data_map()
+                        :  heap->external_string_map()));
+  } else {
+    this->set_map(
+        is_symbol
+ ? (is_ascii ? heap->short_external_symbol_with_ascii_data_map()
+                        :  heap->short_external_symbol_map())
+ : (is_ascii ? heap->short_external_string_with_ascii_data_map()
+                        :  heap->short_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());
-  }
+  if (is_symbol) self->Hash();  // Force regeneration of the hash value.

   // Fill the remainder of the string with dead wood.
   int new_size = this->Size();  // Byte size of the external String object.
@@ -1004,28 +1003,23 @@
 #endif  // DEBUG
   Heap* heap = GetHeap();
   int size = this->Size();  // Byte size of the original string.
-  if (size < ExternalString::kSize) {
+  if (size < ExternalString::kShortSize) {
     return false;
   }
-  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());
+  // reinitializing the fields.  Use short version if space is limited.
+  if (size >= ExternalString::kSize) {
+    this->set_map(is_symbol ? heap->external_ascii_symbol_map()
+                            : heap->external_ascii_string_map());
+  } else {
+    this->set_map(is_symbol ? heap->short_external_ascii_symbol_map()
+                            : heap->short_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());
-  }
+  if (is_symbol) self->Hash();  // Force regeneration of the hash value.

   // Fill the remainder of the string with dead wood.
   int new_size = this->Size();  // Byte size of the external String object.
@@ -1033,7 +1027,6 @@
   if (Marking::IsBlack(Marking::MarkBitFrom(this))) {
     MemoryChunk::IncrementLiveBytes(this->address(), new_size - size);
   }
-
   return true;
 }

=======================================
--- /branches/bleeding_edge/src/objects.h       Tue Nov 22 08:02:26 2011
+++ /branches/bleeding_edge/src/objects.h       Wed Nov 23 01:58:58 2011
@@ -232,6 +232,9 @@
V(EXTERNAL_SYMBOL_TYPE) \ V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE) \ V(EXTERNAL_ASCII_SYMBOL_TYPE) \ + V(SHORT_EXTERNAL_SYMBOL_TYPE) \ + V(SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE) \ + V(SHORT_EXTERNAL_ASCII_SYMBOL_TYPE) \ V(STRING_TYPE) \ V(ASCII_STRING_TYPE) \ V(CONS_STRING_TYPE) \
@@ -240,6 +243,9 @@
V(EXTERNAL_STRING_TYPE) \ V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE) \ V(EXTERNAL_ASCII_STRING_TYPE) \ + V(SHORT_EXTERNAL_STRING_TYPE) \ + V(SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE) \ + V(SHORT_EXTERNAL_ASCII_STRING_TYPE) \ V(PRIVATE_EXTERNAL_ASCII_STRING_TYPE) \ \ V(MAP_TYPE) \
@@ -340,6 +346,18 @@
ExternalAsciiString::kSize, \ external_ascii_symbol, \ ExternalAsciiSymbol) \ + V(SHORT_EXTERNAL_SYMBOL_TYPE, \ + ExternalTwoByteString::kShortSize, \ + short_external_symbol, \ + ShortExternalSymbol) \ + V(SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE, \ + ExternalTwoByteString::kShortSize, \ + short_external_symbol_with_ascii_data, \ + ShortExternalSymbolWithAsciiData) \ + V(SHORT_EXTERNAL_ASCII_SYMBOL_TYPE, \ + ExternalAsciiString::kShortSize, \ + short_external_ascii_symbol, \ + ShortExternalAsciiSymbol) \ V(STRING_TYPE, \ kVariableSizeSentinel, \ string, \
@@ -375,7 +393,19 @@
V(EXTERNAL_ASCII_STRING_TYPE, \ ExternalAsciiString::kSize, \ external_ascii_string, \
-    ExternalAsciiString)
+ ExternalAsciiString) \ + V(SHORT_EXTERNAL_STRING_TYPE, \ + ExternalTwoByteString::kShortSize, \ + short_external_string, \ + ShortExternalString) \ + V(SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE, \ + ExternalTwoByteString::kShortSize, \ + short_external_string_with_ascii_data, \ + ShortExternalStringWithAsciiData) \ + V(SHORT_EXTERNAL_ASCII_STRING_TYPE, \ + ExternalAsciiString::kShortSize, \ + short_external_ascii_string, \
+    ShortExternalAsciiString)

 // A struct is a simple object a set of object-valued fields.  Including an
// object type in this causes the compiler to generate most of the boilerplate
@@ -459,6 +489,11 @@
 const uint32_t kAsciiDataHintMask = 0x08;
 const uint32_t kAsciiDataHintTag = 0x08;

+// If bit 7 is clear and string representation indicates an external string,
+// then bit 4 indicates whether the data pointer is cached.
+const uint32_t kShortExternalStringMask = 0x10;
+const uint32_t kShortExternalStringTag = 0x10;
+

 // A ConsString with an empty string as the right side is a candidate
 // for being shortcut by the garbage collector unless it is a
@@ -478,6 +513,13 @@
   ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kSeqStringTag,
   CONS_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kConsStringTag,
   CONS_ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kConsStringTag,
+  SHORT_EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag |
+ kExternalStringTag | kShortExternalStringTag,
+  SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
+      kTwoByteStringTag | kSymbolTag | kExternalStringTag |
+      kAsciiDataHintTag | kShortExternalStringTag,
+  SHORT_EXTERNAL_ASCII_SYMBOL_TYPE = kAsciiStringTag | kExternalStringTag |
+                                     kSymbolTag | kShortExternalStringTag,
EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kExternalStringTag,
   EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
kTwoByteStringTag | kSymbolTag | kExternalStringTag | kAsciiDataHintTag,
@@ -489,6 +531,13 @@
   CONS_ASCII_STRING_TYPE = kAsciiStringTag | kConsStringTag,
   SLICED_STRING_TYPE = kTwoByteStringTag | kSlicedStringTag,
   SLICED_ASCII_STRING_TYPE = kAsciiStringTag | kSlicedStringTag,
+  SHORT_EXTERNAL_STRING_TYPE =
+      kTwoByteStringTag | kExternalStringTag | kShortExternalStringTag,
+  SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
+      kTwoByteStringTag | kExternalStringTag |
+      kAsciiDataHintTag | kShortExternalStringTag,
+  SHORT_EXTERNAL_ASCII_STRING_TYPE =
+      kAsciiStringTag | kExternalStringTag | kShortExternalStringTag,
   EXTERNAL_STRING_TYPE = kTwoByteStringTag | kExternalStringTag,
   EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
       kTwoByteStringTag | kExternalStringTag | kAsciiDataHintTag,
@@ -6755,12 +6804,12 @@

   // Layout description.
   static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
+  static const int kShortSize = kResourceOffset + kPointerSize;
   static const int kResourceDataOffset = kResourceOffset + kPointerSize;
   static const int kSize = kResourceDataOffset + kPointerSize;

- // Clear the cached pointer to the character array provided by the resource.
-  // This cache is updated the first time the character array is accessed.
-  inline void clear_data_cache();
+  // Return whether external string is short (data pointer is not cached).
+  inline bool is_short();

   STATIC_CHECK(kResourceOffset == Internals::kStringResourceOffset);

@@ -6781,6 +6830,12 @@
   inline const Resource* resource();
   inline void set_resource(const Resource* buffer);

+  // Update the pointer cache to the external character array.
+ // The cached pointer is always valid, as the external character array does = + // not move during lifetime. Deserialization is the only exception, after
+  // which the pointer cache has to be refreshed.
+  inline void update_data_cache();
+
   inline const char* GetChars();

   // Dispatched behavior.
@@ -6820,6 +6875,12 @@
   inline const Resource* resource();
   inline void set_resource(const Resource* buffer);

+  // Update the pointer cache to the external character array.
+ // The cached pointer is always valid, as the external character array does = + // not move during lifetime. Deserialization is the only exception, after
+  // which the pointer cache has to be refreshed.
+  inline void update_data_cache();
+
   inline const uint16_t* GetChars();

   // Dispatched behavior.
=======================================
--- /branches/bleeding_edge/src/serialize.cc    Thu Nov 17 09:05:12 2011
+++ /branches/bleeding_edge/src/serialize.cc    Wed Nov 23 01:58:58 2011
@@ -669,6 +669,14 @@

   isolate_->heap()->set_global_contexts_list(
       isolate_->heap()->undefined_value());
+
+ // Update data pointers to the external strings containing natives sources.
+  for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
+    Object* source = isolate_->heap()->natives_source_cache()->get(i);
+    if (!source->IsUndefined()) {
+      ExternalAsciiString::cast(source)->update_data_cache();
+    }
+  }
 }


@@ -1564,7 +1572,6 @@
         sink_->Put(kNativesStringResource, "NativesStringResource");
         sink_->PutSection(i, "NativesStringResourceEnd");
         bytes_processed_so_far_ += sizeof(resource);
-        string->clear_data_cache();
         return;
       }
     }
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Thu Nov 17 09:05:12 2011
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Wed Nov 23 01:58:58 2011
@@ -491,7 +491,7 @@
   HEAP->CollectGarbage(i::NEW_SPACE);
   HEAP->CollectGarbage(i::NEW_SPACE);

-  uint16_t* two_byte_string = AsciiToTwoByteString("abcdefghi");
+  uint16_t* two_byte_string = AsciiToTwoByteString("s1");
   Local<String> small_string = String::New(two_byte_string);
   i::DeleteArray(two_byte_string);

@@ -503,7 +503,7 @@
   // Old space strings should be accepted.
   CHECK(small_string->CanMakeExternal());

-  two_byte_string = AsciiToTwoByteString("abcdefghi");
+  two_byte_string = AsciiToTwoByteString("small string 2");
   small_string = String::New(two_byte_string);
   i::DeleteArray(two_byte_string);

@@ -537,7 +537,7 @@
   HEAP->CollectGarbage(i::NEW_SPACE);
   HEAP->CollectGarbage(i::NEW_SPACE);

-  Local<String> small_string = String::New("abcdefghi");
+  Local<String> small_string = String::New("s1");
   // We should refuse to externalize newly created small string.
   CHECK(!small_string->CanMakeExternal());
   // Trigger GCs so that the newly allocated string moves to old gen.
@@ -546,7 +546,7 @@
   // Old space strings should be accepted.
   CHECK(small_string->CanMakeExternal());

-  small_string = String::New("abcdefghi");
+  small_string = String::New("small string 2");
   // We should refuse externalizing newly created small string.
   CHECK(!small_string->CanMakeExternal());
   for (int i = 0; i < 100; i++) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/string-externalize.js Thu Nov 17 09:05:12 2011 +++ /branches/bleeding_edge/test/mjsunit/string-externalize.js Wed Nov 23 01:58:58 2011
@@ -39,7 +39,7 @@
   assertTrue(isAsciiString(str));

   var twoByteExternalWithAsciiData =
-      "AAAAAAAA" + (function() { return "A"; })();
+      "AA" + (function() { return "A"; })();
externalizeString(twoByteExternalWithAsciiData, true /* force two-byte */);
   assertFalse(isAsciiString(twoByteExternalWithAsciiData));

--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

Reply via email to