Remove sliced string string type
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 10 Nov 2009 13:23:05 +0000 (13:23 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 10 Nov 2009 13:23:05 +0000 (13:23 +0000)
As a first step to reduce the complexity of the string hierachy the sliced string type is removed. Whenever a sub-string is created it is allocated as a fresh flat string.
Review URL: http://codereview.chromium.org/385004

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

18 files changed:
src/conversions.cc
src/factory.cc
src/factory.h
src/handles.cc
src/heap.cc
src/heap.h
src/ia32/codegen-ia32.cc
src/mark-compact.cc
src/objects-debug.cc
src/objects-inl.h
src/objects.cc
src/objects.h
src/regexp-macro-assembler.cc
src/runtime.cc
src/runtime.h
src/string.js
src/x64/codegen-x64.cc
test/cctest/test-strings.cc

index 3e66d28..e20065c 100644 (file)
@@ -125,9 +125,9 @@ static inline bool SubStringEquals(String* str, int index, const char* other) {
   int end = index + other_length < str_length ?
             index + other_length :
             str_length;
-  Handle<String> slice =
-      Factory::NewStringSlice(Handle<String>(str), index, end);
-  return slice->IsEqualTo(Vector<const char>(other, other_length));
+  Handle<String> substring =
+      Factory::NewSubString(Handle<String>(str), index, end);
+  return substring->IsEqualTo(Vector<const char>(other, other_length));
 }
 
 
index 32b69db..c63e005 100644 (file)
@@ -106,10 +106,10 @@ Handle<String> Factory::NewConsString(Handle<String> first,
 }
 
 
-Handle<String> Factory::NewStringSlice(Handle<String> str,
-                                       int begin,
-                                       int end) {
-  CALL_HEAP_FUNCTION(str->Slice(begin, end), String);
+Handle<String> Factory::NewSubString(Handle<String> str,
+                                     int begin,
+                                     int end) {
+  CALL_HEAP_FUNCTION(str->SubString(begin, end), String);
 }
 
 
index cb438e9..951c043 100644 (file)
@@ -106,11 +106,10 @@ class Factory : public AllStatic {
   static Handle<String> NewConsString(Handle<String> first,
                                       Handle<String> second);
 
-  // Create a new sliced string object which represents a substring of a
-  // backing string.
-  static Handle<String> NewStringSlice(Handle<String> str,
-                                       int begin,
-                                       int end);
+  // Create a new string object which holds a substring of a string.
+  static Handle<String> NewSubString(Handle<String> str,
+                                     int begin,
+                                     int end);
 
   // Creates a new external String object.  There are two String encodings
   // in the system: ASCII and two byte.  Unlike other String types, it does
index 9fbec27..3d93e70 100644 (file)
@@ -354,7 +354,7 @@ Handle<Object> LookupSingleCharacterStringFromCode(uint32_t index) {
 
 
 Handle<String> SubString(Handle<String> str, int start, int end) {
-  CALL_HEAP_FUNCTION(str->Slice(start, end), String);
+  CALL_HEAP_FUNCTION(str->SubString(start, end), String);
 }
 
 
index 783b5ff..685cbea 100644 (file)
@@ -1763,10 +1763,14 @@ Object* Heap::AllocateSharedFunctionInfo(Object* name) {
 
 Object* Heap::AllocateConsString(String* first, String* second) {
   int first_length = first->length();
-  if (first_length == 0) return second;
+  if (first_length == 0) {
+    return second;
+  }
 
   int second_length = second->length();
-  if (second_length == 0) return first;
+  if (second_length == 0) {
+    return first;
+  }
 
   int length = first_length + second_length;
   bool is_ascii = first->IsAsciiRepresentation()
@@ -1829,43 +1833,6 @@ Object* Heap::AllocateConsString(String* first, String* second) {
 }
 
 
-Object* Heap::AllocateSlicedString(String* buffer,
-                                   int start,
-                                   int end) {
-  int length = end - start;
-
-  // If the resulting string is small make a sub string.
-  if (length <= String::kMinNonFlatLength) {
-    return Heap::AllocateSubString(buffer, start, end);
-  }
-
-  Map* map;
-  if (length <= String::kMaxShortSize) {
-    map = buffer->IsAsciiRepresentation() ?
-      short_sliced_ascii_string_map() :
-      short_sliced_string_map();
-  } else if (length <= String::kMaxMediumSize) {
-    map = buffer->IsAsciiRepresentation() ?
-      medium_sliced_ascii_string_map() :
-      medium_sliced_string_map();
-  } else {
-    map = buffer->IsAsciiRepresentation() ?
-      long_sliced_ascii_string_map() :
-      long_sliced_string_map();
-  }
-
-  Object* result = Allocate(map, NEW_SPACE);
-  if (result->IsFailure()) return result;
-
-  SlicedString* sliced_string = SlicedString::cast(result);
-  sliced_string->set_buffer(buffer);
-  sliced_string->set_start(start);
-  sliced_string->set_length(length);
-
-  return result;
-}
-
-
 Object* Heap::AllocateSubString(String* buffer,
                                 int start,
                                 int end) {
@@ -1885,22 +1852,19 @@ Object* Heap::AllocateSubString(String* buffer,
       ? AllocateRawAsciiString(length)
       : AllocateRawTwoByteString(length);
   if (result->IsFailure()) return result;
+  String* string_result = String::cast(result);
 
   // Copy the characters into the new object.
-  String* string_result = String::cast(result);
-  StringHasher hasher(length);
-  int i = 0;
-  for (; i < length && hasher.is_array_index(); i++) {
-    uc32 c = buffer->Get(start + i);
-    hasher.AddCharacter(c);
-    string_result->Set(i, c);
-  }
-  for (; i < length; i++) {
-    uc32 c = buffer->Get(start + i);
-    hasher.AddCharacterNoIndex(c);
-    string_result->Set(i, c);
+  if (buffer->IsAsciiRepresentation()) {
+    ASSERT(string_result->IsAsciiRepresentation());
+    char* dest = SeqAsciiString::cast(string_result)->GetChars();
+    String::WriteToFlat(buffer, dest, start, end);
+  } else {
+    ASSERT(string_result->IsTwoByteRepresentation());
+    uc16* dest = SeqTwoByteString::cast(string_result)->GetChars();
+    String::WriteToFlat(buffer, dest, start, end);
   }
-  string_result->set_length_field(hasher.GetHashField());
+
   return result;
 }
 
@@ -2600,20 +2564,6 @@ Map* Heap::SymbolMapForString(String* string) {
     return long_cons_ascii_symbol_map();
   }
 
-  if (map == short_sliced_string_map()) return short_sliced_symbol_map();
-  if (map == medium_sliced_string_map()) return medium_sliced_symbol_map();
-  if (map == long_sliced_string_map()) return long_sliced_symbol_map();
-
-  if (map == short_sliced_ascii_string_map()) {
-    return short_sliced_ascii_symbol_map();
-  }
-  if (map == medium_sliced_ascii_string_map()) {
-    return medium_sliced_ascii_symbol_map();
-  }
-  if (map == long_sliced_ascii_string_map()) {
-    return long_sliced_ascii_symbol_map();
-  }
-
   if (map == short_external_string_map()) {
     return short_external_symbol_map();
   }
index cde04ed..8c1bb18 100644 (file)
@@ -77,12 +77,6 @@ namespace internal {
   V(Map, short_cons_ascii_symbol_map, ShortConsAsciiSymbolMap)                 \
   V(Map, medium_cons_ascii_symbol_map, MediumConsAsciiSymbolMap)               \
   V(Map, long_cons_ascii_symbol_map, LongConsAsciiSymbolMap)                   \
-  V(Map, short_sliced_symbol_map, ShortSlicedSymbolMap)                        \
-  V(Map, medium_sliced_symbol_map, MediumSlicedSymbolMap)                      \
-  V(Map, long_sliced_symbol_map, LongSlicedSymbolMap)                          \
-  V(Map, short_sliced_ascii_symbol_map, ShortSlicedAsciiSymbolMap)             \
-  V(Map, medium_sliced_ascii_symbol_map, MediumSlicedAsciiSymbolMap)           \
-  V(Map, long_sliced_ascii_symbol_map, LongSlicedAsciiSymbolMap)               \
   V(Map, short_external_symbol_map, ShortExternalSymbolMap)                    \
   V(Map, medium_external_symbol_map, MediumExternalSymbolMap)                  \
   V(Map, long_external_symbol_map, LongExternalSymbolMap)                      \
@@ -95,12 +89,6 @@ namespace internal {
   V(Map, short_cons_ascii_string_map, ShortConsAsciiStringMap)                 \
   V(Map, medium_cons_ascii_string_map, MediumConsAsciiStringMap)               \
   V(Map, long_cons_ascii_string_map, LongConsAsciiStringMap)                   \
-  V(Map, short_sliced_string_map, ShortSlicedStringMap)                        \
-  V(Map, medium_sliced_string_map, MediumSlicedStringMap)                      \
-  V(Map, long_sliced_string_map, LongSlicedStringMap)                          \
-  V(Map, short_sliced_ascii_string_map, ShortSlicedAsciiStringMap)             \
-  V(Map, medium_sliced_ascii_string_map, MediumSlicedAsciiStringMap)           \
-  V(Map, long_sliced_ascii_string_map, LongSlicedAsciiStringMap)               \
   V(Map, short_external_string_map, ShortExternalStringMap)                    \
   V(Map, medium_external_string_map, MediumExternalStringMap)                  \
   V(Map, long_external_string_map, LongExternalStringMap)                      \
@@ -587,16 +575,6 @@ class Heap : public AllStatic {
   // Please note this does not perform a garbage collection.
   static Object* AllocateConsString(String* first, String* second);
 
-  // Allocates a new sliced string object which is a slice of an underlying
-  // string buffer stretching from the index start (inclusive) to the index
-  // end (exclusive).
-  // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
-  // failed.
-  // Please note this does not perform a garbage collection.
-  static Object* AllocateSlicedString(String* buffer,
-                                      int start,
-                                      int end);
-
   // Allocates a new sub string object which is a substring of an underlying
   // string buffer stretching from the index start (inclusive) to the index
   // end (exclusive).
index a3b5570..9aeebdf 100644 (file)
@@ -4677,10 +4677,10 @@ void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
 
 // This generates code that performs a charCodeAt() call or returns
 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
-// It can handle flat and sliced strings, 8 and 16 bit characters and
-// cons strings where the answer is found in the left hand branch of the
-// cons.  The slow case will flatten the string, which will ensure that
-// the answer is in the left hand side the next time around.
+// It can handle flat, 8 and 16 bit characters and cons strings where the
+// answer is found in the left hand branch of the cons.  The slow case will
+// flatten the string, which will ensure that the answer is in the left hand
+// side the next time around.
 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
   Comment(masm_, "[ GenerateFastCharCodeAt");
   ASSERT(args->length() == 2);
@@ -4688,7 +4688,6 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
   Label slow_case;
   Label end;
   Label not_a_flat_string;
-  Label a_cons_string;
   Label try_again_with_new_string;
   Label ascii_string;
   Label got_char_code;
@@ -4810,21 +4809,10 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
   __ bind(&not_a_flat_string);
   __ and_(temp.reg(), kStringRepresentationMask);
   __ cmp(temp.reg(), kConsStringTag);
-  __ j(equal, &a_cons_string);
-  __ cmp(temp.reg(), kSlicedStringTag);
   __ j(not_equal, &slow_case);
 
-  // SlicedString.
-  // Add the offset to the index and trigger the slow case on overflow.
-  __ add(index.reg(), FieldOperand(object.reg(), SlicedString::kStartOffset));
-  __ j(overflow, &slow_case);
-  // Getting the underlying string is done by running the cons string code.
-
   // ConsString.
-  __ bind(&a_cons_string);
-  // Get the first of the two strings.  Both sliced and cons strings
-  // store their source string at the same offset.
-  ASSERT(SlicedString::kBufferOffset == ConsString::kFirstOffset);
+  // Get the first of the two strings.
   __ mov(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset));
   __ jmp(&try_again_with_new_string);
 
index 785462e..1145c2c 100644 (file)
@@ -572,9 +572,8 @@ class SymbolMarkingVisitor : public ObjectVisitor {
 void MarkCompactCollector::MarkSymbolTable() {
   // Objects reachable from symbols are marked as live so as to ensure
   // that if the symbol itself remains alive after GC for any reason,
-  // and if it is a sliced string or a cons string backed by an
-  // external string (even indirectly), then the external string does
-  // not receive a weak reference callback.
+  // and if it is a cons string backed by an external string (even indirectly),
+  // then the external string does not receive a weak reference callback.
   SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
   // Mark the symbol table itself.
   SetMark(symbol_table);
index 10ad294..55438ec 100644 (file)
@@ -553,12 +553,6 @@ static const char* TypeToString(InstanceType type) {
     case SHORT_ASCII_SYMBOL_TYPE:
     case MEDIUM_ASCII_SYMBOL_TYPE:
     case LONG_ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
-    case SHORT_SLICED_SYMBOL_TYPE:
-    case MEDIUM_SLICED_SYMBOL_TYPE:
-    case LONG_SLICED_SYMBOL_TYPE: return "SLICED_SYMBOL";
-    case SHORT_SLICED_ASCII_SYMBOL_TYPE:
-    case MEDIUM_SLICED_ASCII_SYMBOL_TYPE:
-    case LONG_SLICED_ASCII_SYMBOL_TYPE: return "SLICED_ASCII_SYMBOL";
     case SHORT_CONS_SYMBOL_TYPE:
     case MEDIUM_CONS_SYMBOL_TYPE:
     case LONG_CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
@@ -583,12 +577,6 @@ static const char* TypeToString(InstanceType type) {
     case SHORT_CONS_ASCII_STRING_TYPE:
     case MEDIUM_CONS_ASCII_STRING_TYPE:
     case LONG_CONS_ASCII_STRING_TYPE: return "CONS_STRING";
-    case SHORT_SLICED_STRING_TYPE:
-    case MEDIUM_SLICED_STRING_TYPE:
-    case LONG_SLICED_STRING_TYPE:
-    case SHORT_SLICED_ASCII_STRING_TYPE:
-    case MEDIUM_SLICED_ASCII_STRING_TYPE:
-    case LONG_SLICED_ASCII_STRING_TYPE: return "SLICED_STRING";
     case SHORT_EXTERNAL_ASCII_STRING_TYPE:
     case MEDIUM_EXTERNAL_ASCII_STRING_TYPE:
     case LONG_EXTERNAL_ASCII_STRING_TYPE:
index e03b3c4..8de9d36 100644 (file)
@@ -203,12 +203,6 @@ bool Object::IsExternalTwoByteString() {
 }
 
 
-bool Object::IsSlicedString() {
-  if (!IsString()) return false;
-  return StringShape(String::cast(this)).IsSliced();
-}
-
-
 StringShape::StringShape(String* str)
   : type_(str->map()->instance_type()) {
   set_valid();
@@ -238,9 +232,6 @@ bool StringShape::IsSymbol() {
 
 bool String::IsAsciiRepresentation() {
   uint32_t type = map()->instance_type();
-  if ((type & kStringRepresentationMask) == kSlicedStringTag) {
-    return SlicedString::cast(this)->buffer()->IsAsciiRepresentation();
-  }
   if ((type & kStringRepresentationMask) == kConsStringTag &&
       ConsString::cast(this)->second()->length() == 0) {
     return ConsString::cast(this)->first()->IsAsciiRepresentation();
@@ -251,9 +242,7 @@ bool String::IsAsciiRepresentation() {
 
 bool String::IsTwoByteRepresentation() {
   uint32_t type = map()->instance_type();
-  if ((type & kStringRepresentationMask) == kSlicedStringTag) {
-    return SlicedString::cast(this)->buffer()->IsTwoByteRepresentation();
-  } else if ((type & kStringRepresentationMask) == kConsStringTag &&
+  if ((type & kStringRepresentationMask) == kConsStringTag &&
              ConsString::cast(this)->second()->length() == 0) {
     return ConsString::cast(this)->first()->IsTwoByteRepresentation();
   }
@@ -266,11 +255,6 @@ bool StringShape::IsCons() {
 }
 
 
-bool StringShape::IsSliced() {
-  return (type_ & kStringRepresentationMask) == kSlicedStringTag;
-}
-
-
 bool StringShape::IsExternal() {
   return (type_ & kStringRepresentationMask) == kExternalStringTag;
 }
@@ -1602,7 +1586,6 @@ CAST_ACCESSOR(SeqString)
 CAST_ACCESSOR(SeqAsciiString)
 CAST_ACCESSOR(SeqTwoByteString)
 CAST_ACCESSOR(ConsString)
-CAST_ACCESSOR(SlicedString)
 CAST_ACCESSOR(ExternalString)
 CAST_ACCESSOR(ExternalAsciiString)
 CAST_ACCESSOR(ExternalTwoByteString)
@@ -1713,9 +1696,6 @@ uint16_t String::Get(int index) {
     case kConsStringTag | kAsciiStringTag:
     case kConsStringTag | kTwoByteStringTag:
       return ConsString::cast(this)->ConsStringGet(index);
-    case kSlicedStringTag | kAsciiStringTag:
-    case kSlicedStringTag | kTwoByteStringTag:
-      return SlicedString::cast(this)->SlicedStringGet(index);
     case kExternalStringTag | kAsciiStringTag:
       return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
     case kExternalStringTag | kTwoByteStringTag:
@@ -1746,11 +1726,6 @@ bool String::IsFlat() {
       // Only flattened strings have second part empty.
       return second->length() == 0;
     }
-    case kSlicedStringTag: {
-      StringRepresentationTag tag =
-          StringShape(SlicedString::cast(this)->buffer()).representation_tag();
-      return tag == kSeqStringTag || tag == kExternalStringTag;
-    }
     default:
       return true;
   }
@@ -1864,27 +1839,6 @@ void ConsString::set_second(String* value, WriteBarrierMode mode) {
 }
 
 
-String* SlicedString::buffer() {
-  return String::cast(READ_FIELD(this, kBufferOffset));
-}
-
-
-void SlicedString::set_buffer(String* buffer) {
-  WRITE_FIELD(this, kBufferOffset, buffer);
-  WRITE_BARRIER(this, kBufferOffset);
-}
-
-
-int SlicedString::start() {
-  return READ_INT_FIELD(this, kStartOffset);
-}
-
-
-void SlicedString::set_start(int start) {
-  WRITE_INT_FIELD(this, kStartOffset, start);
-}
-
-
 ExternalAsciiString::Resource* ExternalAsciiString::resource() {
   return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
 }
index 3415266..6582fc1 100644 (file)
@@ -683,23 +683,6 @@ Object* String::TryFlatten() {
 #endif
 
   switch (StringShape(this).representation_tag()) {
-    case kSlicedStringTag: {
-      SlicedString* ss = SlicedString::cast(this);
-      // The SlicedString constructor should ensure that there are no
-      // SlicedStrings that are constructed directly on top of other
-      // SlicedStrings.
-      String* buf = ss->buffer();
-      ASSERT(!buf->IsSlicedString());
-      Object* ok = buf->TryFlatten();
-      if (ok->IsFailure()) return ok;
-      // Under certain circumstances (TryFlattenIfNotFlat fails in
-      // String::Slice) we can have a cons string under a slice.
-      // In this case we need to get the flat string out of the cons!
-      if (StringShape(String::cast(ok)).IsCons()) {
-        ss->set_buffer(ConsString::cast(ok)->first());
-      }
-      return this;
-    }
     case kConsStringTag: {
       ConsString* cs = ConsString::cast(this);
       if (cs->second()->length() == 0) {
@@ -1135,9 +1118,6 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
       case kConsStringTag:
         reinterpret_cast<ConsString*>(this)->ConsStringIterateBody(v);
         break;
-      case kSlicedStringTag:
-        reinterpret_cast<SlicedString*>(this)->SlicedStringIterateBody(v);
-        break;
       case kExternalStringTag:
         if ((type & kStringEncodingMask) == kAsciiStringTag) {
           reinterpret_cast<ExternalAsciiString*>(this)->
@@ -3571,12 +3551,7 @@ Vector<const char> String::ToAsciiVector() {
   int length = this->length();
   StringRepresentationTag string_tag = StringShape(this).representation_tag();
   String* string = this;
-  if (string_tag == kSlicedStringTag) {
-    SlicedString* sliced = SlicedString::cast(string);
-    offset += sliced->start();
-    string = sliced->buffer();
-    string_tag = StringShape(string).representation_tag();
-  } else if (string_tag == kConsStringTag) {
+  if (string_tag == kConsStringTag) {
     ConsString* cons = ConsString::cast(string);
     ASSERT(cons->second()->length() == 0);
     string = cons->first();
@@ -3602,12 +3577,7 @@ Vector<const uc16> String::ToUC16Vector() {
   int length = this->length();
   StringRepresentationTag string_tag = StringShape(this).representation_tag();
   String* string = this;
-  if (string_tag == kSlicedStringTag) {
-    SlicedString* sliced = SlicedString::cast(string);
-    offset += sliced->start();
-    string = String::cast(sliced->buffer());
-    string_tag = StringShape(string).representation_tag();
-  } else if (string_tag == kConsStringTag) {
+  if (string_tag == kConsStringTag) {
     ConsString* cons = ConsString::cast(string);
     ASSERT(cons->second()->length() == 0);
     string = cons->first();
@@ -3698,17 +3668,6 @@ const uc16* String::GetTwoByteData(unsigned start) {
     case kExternalStringTag:
       return ExternalTwoByteString::cast(this)->
         ExternalTwoByteStringGetData(start);
-    case kSlicedStringTag: {
-      SlicedString* sliced_string = SlicedString::cast(this);
-      String* buffer = sliced_string->buffer();
-      if (StringShape(buffer).IsCons()) {
-        ConsString* cs = ConsString::cast(buffer);
-        // Flattened string.
-        ASSERT(cs->second()->length() == 0);
-        buffer = cs->first();
-      }
-      return buffer->GetTwoByteData(start + sliced_string->start());
-    }
     case kConsStringTag:
       UNREACHABLE();
       return NULL;
@@ -3863,22 +3822,6 @@ const unibrow::byte* ConsString::ConsStringReadBlock(ReadBlockBuffer* rbb,
 }
 
 
-const unibrow::byte* SlicedString::SlicedStringReadBlock(ReadBlockBuffer* rbb,
-                                                         unsigned* offset_ptr,
-                                                         unsigned max_chars) {
-  String* backing = buffer();
-  unsigned offset = start() + *offset_ptr;
-  unsigned length = backing->length();
-  if (max_chars > length - offset) {
-    max_chars = length - offset;
-  }
-  const unibrow::byte* answer =
-      String::ReadBlock(backing, rbb, &offset, max_chars);
-  *offset_ptr = offset - start();
-  return answer;
-}
-
-
 uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
   ASSERT(index >= 0 && index < length());
   return resource()->data()[index];
@@ -4002,10 +3945,6 @@ const unibrow::byte* String::ReadBlock(String* input,
       return ConsString::cast(input)->ConsStringReadBlock(rbb,
                                                           offset_ptr,
                                                           max_chars);
-    case kSlicedStringTag:
-      return SlicedString::cast(input)->SlicedStringReadBlock(rbb,
-                                                              offset_ptr,
-                                                              max_chars);
     case kExternalStringTag:
       if (input->IsAsciiRepresentation()) {
         return ExternalAsciiString::cast(input)->ExternalAsciiStringReadBlock(
@@ -4148,11 +4087,6 @@ void String::ReadBlockIntoBuffer(String* input,
                                                              offset_ptr,
                                                              max_chars);
       return;
-    case kSlicedStringTag:
-      SlicedString::cast(input)->SlicedStringReadBlockIntoBuffer(rbb,
-                                                                 offset_ptr,
-                                                                 max_chars);
-      return;
     case kExternalStringTag:
       if (input->IsAsciiRepresentation()) {
         ExternalAsciiString::cast(input)->
@@ -4267,20 +4201,6 @@ void ConsString::ConsStringReadBlockIntoBuffer(ReadBlockBuffer* rbb,
 }
 
 
-void SlicedString::SlicedStringReadBlockIntoBuffer(ReadBlockBuffer* rbb,
-                                                   unsigned* offset_ptr,
-                                                   unsigned max_chars) {
-  String* backing = buffer();
-  unsigned offset = start() + *offset_ptr;
-  unsigned length = backing->length();
-  if (max_chars > length - offset) {
-    max_chars = length - offset;
-  }
-  String::ReadBlockIntoBuffer(backing, rbb, &offset, max_chars);
-  *offset_ptr = offset - start();
-}
-
-
 void ConsString::ConsStringIterateBody(ObjectVisitor* v) {
   IteratePointers(v, kFirstOffset, kSecondOffset + kPointerSize);
 }
@@ -4359,15 +4279,6 @@ void String::WriteToFlat(String* src,
                   to - from);
         return;
       }
-      case kAsciiStringTag | kSlicedStringTag:
-      case kTwoByteStringTag | kSlicedStringTag: {
-        SlicedString* sliced_string = SlicedString::cast(source);
-        int start = sliced_string->start();
-        from += start;
-        to += start;
-        source = String::cast(sliced_string->buffer());
-        break;
-      }
       case kAsciiStringTag | kConsStringTag:
       case kTwoByteStringTag | kConsStringTag: {
         ConsString* cons_string = ConsString::cast(source);
@@ -4403,10 +4314,6 @@ void String::WriteToFlat(String* src,
 }
 
 
-void SlicedString::SlicedStringIterateBody(ObjectVisitor* v) {
-  IteratePointer(v, kBufferOffset);
-}
-
 #define FIELD_ADDR(p, offset) \
   (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
 
@@ -4425,14 +4332,6 @@ void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
 
 #undef FIELD_ADDR
 
-uint16_t SlicedString::SlicedStringGet(int index) {
-  ASSERT(index >= 0 && index < this->length());
-  // Delegate to the buffer string.
-  String* underlying = buffer();
-  return underlying->Get(start() + index);
-}
-
-
 template <typename IteratorA, typename IteratorB>
 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) {
   // General slow case check.  We know that the ia and ib iterators
@@ -4731,43 +4630,10 @@ uint32_t String::ComputeLengthAndHashField(unibrow::CharacterStream* buffer,
 }
 
 
-Object* String::Slice(int start, int end) {
+Object* String::SubString(int start, int end) {
   if (start == 0 && end == length()) return this;
-  if (StringShape(this).representation_tag() == kSlicedStringTag) {
-    // Translate slices of a SlicedString into slices of the
-    // underlying string buffer.
-    SlicedString* str = SlicedString::cast(this);
-    String* buf = str->buffer();
-    return Heap::AllocateSlicedString(buf,
-                                      str->start() + start,
-                                      str->start() + end);
-  }
-  Object* result = Heap::AllocateSlicedString(this, start, end);
-  if (result->IsFailure()) {
-    return result;
-  }
-  // Due to the way we retry after GC on allocation failure we are not allowed
-  // to fail on allocation after this point.  This is the one-allocation rule.
-
-  // Try to flatten a cons string that is under the sliced string.
-  // This is to avoid memory leaks and possible stack overflows caused by
-  // building 'towers' of sliced strings on cons strings.
-  // This may fail due to an allocation failure (when a GC is needed), but it
-  // will succeed often enough to avoid the problem.  We only have to do this
-  // if Heap::AllocateSlicedString actually returned a SlicedString.  It will
-  // return flat strings for small slices for efficiency reasons.
-  String* answer = String::cast(result);
-  if (StringShape(answer).IsSliced() &&
-      StringShape(this).representation_tag() == kConsStringTag) {
-    TryFlatten();
-    // If the flatten succeeded we might as well make the sliced string point
-    // to the flat string rather than the cons string.
-    String* second = ConsString::cast(this)->second();
-    if (second->length() == 0) {
-      SlicedString::cast(answer)->set_buffer(ConsString::cast(this)->first());
-    }
-  }
-  return answer;
+  Object* result = Heap::AllocateSubString(this, start, end);
+  return result;
 }
 
 
@@ -5020,7 +4886,7 @@ void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator,
     return;
   }
 
-  // Get the slice of the source for this function.
+  // Get the source for the script which this function came from.
   // Don't use String::cast because we don't want more assertion errors while
   // we are already creating a stack dump.
   String* script_source =
index 93769c9..f802246 100644 (file)
@@ -78,7 +78,6 @@
 //           - SeqAsciiString
 //           - SeqTwoByteString
 //         - ConsString
-//         - SlicedString
 //         - ExternalString
 //           - ExternalAsciiString
 //           - ExternalTwoByteString
@@ -210,7 +209,7 @@ enum PropertyNormalizationMode {
 // considered TWO_BYTE.  It is not mentioned in the name.  ASCII encoding is
 // mentioned explicitly in the name.  Likewise, the default representation is
 // considered sequential.  It is not mentioned in the name.  The other
-// representations (eg, CONS, SLICED, EXTERNAL) are explicitly mentioned.
+// representations (eg, CONS, EXTERNAL) are explicitly mentioned.
 // Finally, the string is either a SYMBOL_TYPE (if it is a symbol) or a
 // STRING_TYPE (if it is not a symbol).
 //
@@ -235,12 +234,6 @@ enum PropertyNormalizationMode {
   V(SHORT_CONS_ASCII_SYMBOL_TYPE)               \
   V(MEDIUM_CONS_ASCII_SYMBOL_TYPE)              \
   V(LONG_CONS_ASCII_SYMBOL_TYPE)                \
-  V(SHORT_SLICED_SYMBOL_TYPE)                   \
-  V(MEDIUM_SLICED_SYMBOL_TYPE)                  \
-  V(LONG_SLICED_SYMBOL_TYPE)                    \
-  V(SHORT_SLICED_ASCII_SYMBOL_TYPE)             \
-  V(MEDIUM_SLICED_ASCII_SYMBOL_TYPE)            \
-  V(LONG_SLICED_ASCII_SYMBOL_TYPE)              \
   V(SHORT_EXTERNAL_SYMBOL_TYPE)                 \
   V(MEDIUM_EXTERNAL_SYMBOL_TYPE)                \
   V(LONG_EXTERNAL_SYMBOL_TYPE)                  \
@@ -259,12 +252,6 @@ enum PropertyNormalizationMode {
   V(SHORT_CONS_ASCII_STRING_TYPE)               \
   V(MEDIUM_CONS_ASCII_STRING_TYPE)              \
   V(LONG_CONS_ASCII_STRING_TYPE)                \
-  V(SHORT_SLICED_STRING_TYPE)                   \
-  V(MEDIUM_SLICED_STRING_TYPE)                  \
-  V(LONG_SLICED_STRING_TYPE)                    \
-  V(SHORT_SLICED_ASCII_STRING_TYPE)             \
-  V(MEDIUM_SLICED_ASCII_STRING_TYPE)            \
-  V(LONG_SLICED_ASCII_STRING_TYPE)              \
   V(SHORT_EXTERNAL_STRING_TYPE)                 \
   V(MEDIUM_EXTERNAL_STRING_TYPE)                \
   V(LONG_EXTERNAL_STRING_TYPE)                  \
@@ -380,30 +367,6 @@ enum PropertyNormalizationMode {
     ConsString::kSize,                                                         \
     long_cons_ascii_symbol,                                                    \
     LongConsAsciiSymbol)                                                       \
-  V(SHORT_SLICED_SYMBOL_TYPE,                                                  \
-    SlicedString::kSize,                                                       \
-    short_sliced_symbol,                                                       \
-    ShortSlicedSymbol)                                                         \
-  V(MEDIUM_SLICED_SYMBOL_TYPE,                                                 \
-    SlicedString::kSize,                                                       \
-    medium_sliced_symbol,                                                      \
-    MediumSlicedSymbol)                                                        \
-  V(LONG_SLICED_SYMBOL_TYPE,                                                   \
-    SlicedString::kSize,                                                       \
-    long_sliced_symbol,                                                        \
-    LongSlicedSymbol)                                                          \
-  V(SHORT_SLICED_ASCII_SYMBOL_TYPE,                                            \
-    SlicedString::kSize,                                                       \
-    short_sliced_ascii_symbol,                                                 \
-    ShortSlicedAsciiSymbol)                                                    \
-  V(MEDIUM_SLICED_ASCII_SYMBOL_TYPE,                                           \
-    SlicedString::kSize,                                                       \
-    medium_sliced_ascii_symbol,                                                \
-    MediumSlicedAsciiSymbol)                                                   \
-  V(LONG_SLICED_ASCII_SYMBOL_TYPE,                                             \
-    SlicedString::kSize,                                                       \
-    long_sliced_ascii_symbol,                                                  \
-    LongSlicedAsciiSymbol)                                                     \
   V(SHORT_EXTERNAL_SYMBOL_TYPE,                                                \
     ExternalTwoByteString::kSize,                                              \
     short_external_symbol,                                                     \
@@ -476,30 +439,6 @@ enum PropertyNormalizationMode {
     ConsString::kSize,                                                         \
     long_cons_ascii_string,                                                    \
     LongConsAsciiString)                                                       \
-  V(SHORT_SLICED_STRING_TYPE,                                                  \
-    SlicedString::kSize,                                                       \
-    short_sliced_string,                                                       \
-    ShortSlicedString)                                                         \
-  V(MEDIUM_SLICED_STRING_TYPE,                                                 \
-    SlicedString::kSize,                                                       \
-    medium_sliced_string,                                                      \
-    MediumSlicedString)                                                        \
-  V(LONG_SLICED_STRING_TYPE,                                                   \
-    SlicedString::kSize,                                                       \
-    long_sliced_string,                                                        \
-    LongSlicedString)                                                          \
-  V(SHORT_SLICED_ASCII_STRING_TYPE,                                            \
-    SlicedString::kSize,                                                       \
-    short_sliced_ascii_string,                                                 \
-    ShortSlicedAsciiString)                                                    \
-  V(MEDIUM_SLICED_ASCII_STRING_TYPE,                                           \
-    SlicedString::kSize,                                                       \
-    medium_sliced_ascii_string,                                                \
-    MediumSlicedAsciiString)                                                   \
-  V(LONG_SLICED_ASCII_STRING_TYPE,                                             \
-    SlicedString::kSize,                                                       \
-    long_sliced_ascii_string,                                                  \
-    LongSlicedAsciiString)                                                     \
   V(SHORT_EXTERNAL_STRING_TYPE,                                                \
     ExternalTwoByteString::kSize,                                              \
     short_external_string,                                                     \
@@ -591,7 +530,6 @@ const uint32_t kStringRepresentationMask = 0x03;
 enum StringRepresentationTag {
   kSeqStringTag = 0x0,
   kConsStringTag = 0x1,
-  kSlicedStringTag = 0x2,
   kExternalStringTag = 0x3
 };
 
@@ -627,15 +565,6 @@ enum InstanceType {
       kMediumStringTag | kAsciiStringTag | kSymbolTag | kConsStringTag,
   LONG_CONS_ASCII_SYMBOL_TYPE =
       kLongStringTag | kAsciiStringTag | kSymbolTag | kConsStringTag,
-  SHORT_SLICED_SYMBOL_TYPE = kShortStringTag | kSymbolTag | kSlicedStringTag,
-  MEDIUM_SLICED_SYMBOL_TYPE = kMediumStringTag | kSymbolTag | kSlicedStringTag,
-  LONG_SLICED_SYMBOL_TYPE = kLongStringTag | kSymbolTag | kSlicedStringTag,
-  SHORT_SLICED_ASCII_SYMBOL_TYPE =
-      kShortStringTag | kAsciiStringTag | kSymbolTag | kSlicedStringTag,
-  MEDIUM_SLICED_ASCII_SYMBOL_TYPE =
-      kMediumStringTag | kAsciiStringTag | kSymbolTag | kSlicedStringTag,
-  LONG_SLICED_ASCII_SYMBOL_TYPE =
-      kLongStringTag | kAsciiStringTag | kSymbolTag | kSlicedStringTag,
   SHORT_EXTERNAL_SYMBOL_TYPE =
       kShortStringTag | kSymbolTag | kExternalStringTag,
   MEDIUM_EXTERNAL_SYMBOL_TYPE =
@@ -662,15 +591,6 @@ enum InstanceType {
       kMediumStringTag | kAsciiStringTag | kConsStringTag,
   LONG_CONS_ASCII_STRING_TYPE =
       kLongStringTag | kAsciiStringTag | kConsStringTag,
-  SHORT_SLICED_STRING_TYPE = kShortStringTag | kSlicedStringTag,
-  MEDIUM_SLICED_STRING_TYPE = kMediumStringTag | kSlicedStringTag,
-  LONG_SLICED_STRING_TYPE = kLongStringTag | kSlicedStringTag,
-  SHORT_SLICED_ASCII_STRING_TYPE =
-      kShortStringTag | kAsciiStringTag | kSlicedStringTag,
-  MEDIUM_SLICED_ASCII_STRING_TYPE =
-      kMediumStringTag | kAsciiStringTag | kSlicedStringTag,
-  LONG_SLICED_ASCII_STRING_TYPE =
-      kLongStringTag | kAsciiStringTag | kSlicedStringTag,
   SHORT_EXTERNAL_STRING_TYPE = kShortStringTag | kExternalStringTag,
   MEDIUM_EXTERNAL_STRING_TYPE = kMediumStringTag | kExternalStringTag,
   LONG_EXTERNAL_STRING_TYPE = kLongStringTag | kExternalStringTag,
@@ -792,7 +712,6 @@ class Object BASE_EMBEDDED {
   inline bool IsSymbol();
   // See objects-inl.h for more details
   inline bool IsSeqString();
-  inline bool IsSlicedString();
   inline bool IsExternalString();
   inline bool IsExternalTwoByteString();
   inline bool IsExternalAsciiString();
@@ -3920,7 +3839,6 @@ class StringShape BASE_EMBEDDED {
   inline bool IsSequential();
   inline bool IsExternal();
   inline bool IsCons();
-  inline bool IsSliced();
   inline bool IsExternalAscii();
   inline bool IsExternalTwoByte();
   inline bool IsSequentialAscii();
@@ -3978,9 +3896,8 @@ class String: public HeapObject {
   inline uint16_t Get(int index);
 
   // Try to flatten the top level ConsString that is hiding behind this
-  // string.  This is a no-op unless the string is a ConsString or a
-  // SlicedString.  Flatten mutates the ConsString and might return a
-  // failure.
+  // string.  This is a no-op unless the string is a ConsString.  Flatten
+  // mutates the ConsString and might return a failure.
   Object* TryFlatten();
 
   // Try to flatten the string.  Checks first inline to see if it is necessary.
@@ -3996,8 +3913,8 @@ class String: public HeapObject {
   // ascii and two byte string types.
   bool MarkAsUndetectable();
 
-  // Slice the string and return a substring.
-  Object* Slice(int from, int to);
+  // Return a substring.
+  Object* SubString(int from, int to);
 
   // String equality operations.
   inline bool Equals(String* other);
@@ -4082,7 +3999,7 @@ class String: public HeapObject {
   static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar;
   static const int kMaxUC16CharCode = 0xffff;
 
-  // Minimum length for a cons or sliced string.
+  // Minimum length for a cons string.
   static const int kMinNonFlatLength = 13;
 
   // Mask constant for checking if a string has a computed hash code
@@ -4155,12 +4072,6 @@ class String: public HeapObject {
     unsigned       remaining;
   };
 
-  // NOTE: If you call StringInputBuffer routines on strings that are
-  // too deeply nested trees of cons and slice strings, then this
-  // routine will overflow the stack. Strings that are merely deeply
-  // nested trees of cons strings do not have a problem apart from
-  // performance.
-
   static inline const unibrow::byte* ReadBlock(String* input,
                                                ReadBlockBuffer* buffer,
                                                unsigned* offset,
@@ -4345,56 +4256,6 @@ class ConsString: public String {
 };
 
 
-// The SlicedString class describes string values that are slices of
-// some other string.  SlicedStrings consist of a reference to an
-// underlying heap-allocated string value, a start index, and the
-// length field common to all strings.
-class SlicedString: public String {
- public:
-  // The underlying string buffer.
-  inline String* buffer();
-  inline void set_buffer(String* buffer);
-
-  // The start index of the slice.
-  inline int start();
-  inline void set_start(int start);
-
-  // Dispatched behavior.
-  uint16_t SlicedStringGet(int index);
-
-  // Casting.
-  static inline SlicedString* cast(Object* obj);
-
-  // Garbage collection support.
-  void SlicedStringIterateBody(ObjectVisitor* v);
-
-  // Layout description
-#if V8_HOST_ARCH_64_BIT
-  // Optimizations expect buffer to be located at same offset as a ConsString's
-  // first substring. In 64 bit mode we have room for the start offset before
-  // the buffer.
-  static const int kStartOffset = String::kSize;
-  static const int kBufferOffset = kStartOffset + kIntSize;
-  static const int kSize = kBufferOffset + kPointerSize;
-#else
-  static const int kBufferOffset = String::kSize;
-  static const int kStartOffset = kBufferOffset + kPointerSize;
-  static const int kSize = kStartOffset + kIntSize;
-#endif
-
-  // Support for StringInputBuffer.
-  inline const unibrow::byte* SlicedStringReadBlock(ReadBlockBuffer* buffer,
-                                                    unsigned* offset_ptr,
-                                                    unsigned chars);
-  inline void SlicedStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
-                                              unsigned* offset_ptr,
-                                              unsigned chars);
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
-};
-
-
 // The ExternalString class describes string values that are backed by
 // a string resource that lies outside the V8 heap.  ExternalStrings
 // consist of the length field common to all strings, a pointer to the
index 77b92a9..9ae19d7 100644 (file)
@@ -124,11 +124,6 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match(
 
   if (StringShape(subject_ptr).IsCons()) {
     subject_ptr = ConsString::cast(subject_ptr)->first();
-  } else if (StringShape(subject_ptr).IsSliced()) {
-    SlicedString* slice = SlicedString::cast(subject_ptr);
-    start_offset += slice->start();
-    end_offset += slice->start();
-    subject_ptr = slice->buffer();
   }
   // Ensure that an underlying string has the same ascii-ness.
   ASSERT(subject_ptr->IsAsciiRepresentation() == is_ascii);
index a219160..46d641a 100644 (file)
@@ -1643,16 +1643,14 @@ void CompiledReplacement::Compile(Handle<String> replacement,
                             capture_count,
                             subject_length);
   }
-  // Find substrings of replacement string and create them as String objects..
+  // Find substrings of replacement string and create them as String objects.
   int substring_index = 0;
   for (int i = 0, n = parts_.length(); i < n; i++) {
     int tag = parts_[i].tag;
     if (tag <= 0) {  // A replacement string slice.
       int from = -tag;
       int to = parts_[i].data;
-      replacement_substrings_.Add(Factory::NewStringSlice(replacement,
-                                                          from,
-                                                          to));
+      replacement_substrings_.Add(Factory::NewSubString(replacement, from, to));
       parts_[i].tag = REPLACEMENT_SUBSTRING;
       parts_[i].data = substring_index;
       substring_index++;
@@ -2351,7 +2349,7 @@ static Object* Runtime_StringLocaleCompare(Arguments args) {
 }
 
 
-static Object* Runtime_StringSlice(Arguments args) {
+static Object* Runtime_SubString(Arguments args) {
   NoHandleAllocation ha;
   ASSERT(args.length() == 3);
 
@@ -2365,7 +2363,7 @@ static Object* Runtime_StringSlice(Arguments args) {
   RUNTIME_ASSERT(end >= start);
   RUNTIME_ASSERT(start >= 0);
   RUNTIME_ASSERT(end <= value->length());
-  return value->Slice(start, end);
+  return value->SubString(start, end);
 }
 
 
@@ -2412,7 +2410,7 @@ static Object* Runtime_StringMatch(Arguments args) {
   for (int i = 0; i < matches ; i++) {
     int from = offsets.at(i * 2);
     int to = offsets.at(i * 2 + 1);
-    elements->set(i, *Factory::NewStringSlice(subject, from, to));
+    elements->set(i, *Factory::NewSubString(subject, from, to));
   }
   Handle<JSArray> result = Factory::NewJSArrayWithElements(elements);
   result->set_length(Smi::FromInt(matches));
@@ -3613,7 +3611,7 @@ static Object* Runtime_StringTrim(Arguments args) {
       right--;
     }
   }
-  return s->Slice(left, right);
+  return s->SubString(left, right);
 }
 
 bool Runtime::IsUpperCaseChar(uint16_t ch) {
index a55ef25..c05ae6b 100644 (file)
@@ -149,7 +149,7 @@ namespace internal {
   F(StringIndexOf, 3, 1) \
   F(StringLastIndexOf, 3, 1) \
   F(StringLocaleCompare, 2, 1) \
-  F(StringSlice, 3, 1) \
+  F(SubString, 3, 1) \
   F(StringReplaceRegExpWithString, 4, 1) \
   F(StringMatch, 3, 1) \
   F(StringTrim, 3, 1) \
index c9e9386..4f9957a 100644 (file)
@@ -180,7 +180,7 @@ function SubString(string, start, end) {
     }
     return %CharFromCode(char_code);
   }
-  return %StringSlice(string, start, end);
+  return %SubString(string, start, end);
 }
 
 
index 210076d..bef1965 100644 (file)
@@ -3656,7 +3656,6 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
   Label slow_case;
   Label end;
   Label not_a_flat_string;
-  Label a_cons_string;
   Label try_again_with_new_string;
   Label ascii_string;
   Label got_char_code;
@@ -3774,21 +3773,10 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
   __ bind(&not_a_flat_string);
   __ and_(temp.reg(), Immediate(kStringRepresentationMask));
   __ cmpb(temp.reg(), Immediate(kConsStringTag));
-  __ j(equal, &a_cons_string);
-  __ cmpb(temp.reg(), Immediate(kSlicedStringTag));
   __ j(not_equal, &slow_case);
 
-  // SlicedString.
-  // Add the offset to the index and trigger the slow case on overflow.
-  __ addl(index.reg(), FieldOperand(object.reg(), SlicedString::kStartOffset));
-  __ j(overflow, &slow_case);
-  // Getting the underlying string is done by running the cons string code.
-
   // ConsString.
-  __ bind(&a_cons_string);
-  // Get the first of the two strings.  Both sliced and cons strings
-  // store their source string at the same offset.
-  ASSERT(SlicedString::kBufferOffset == ConsString::kFirstOffset);
+  // Get the first of the two strings.
   __ movq(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset));
   __ jmp(&try_again_with_new_string);
 
index bb9a6f9..3fc3769 100644 (file)
@@ -241,17 +241,6 @@ TEST(Traverse) {
   printf("6\n");
   TraverseFirst(left_asymmetric, right_deep_asymmetric, 65536);
   printf("7\n");
-  Handle<String> right_deep_slice =
-      Factory::NewStringSlice(left_deep_asymmetric,
-                              left_deep_asymmetric->length() - 1050,
-                              left_deep_asymmetric->length() - 50);
-  Handle<String> left_deep_slice =
-      Factory::NewStringSlice(right_deep_asymmetric,
-                              right_deep_asymmetric->length() - 1050,
-                              right_deep_asymmetric->length() - 50);
-  printf("8\n");
-  Traverse(right_deep_slice, left_deep_slice);
-  printf("9\n");
   FlattenString(left_asymmetric);
   printf("10\n");
   Traverse(flat, left_asymmetric);
@@ -269,60 +258,6 @@ TEST(Traverse) {
 }
 
 
-static Handle<String> SliceOf(Handle<String> underlying) {
-  int start = gen() % underlying->length();
-  int end = start + gen() % (underlying->length() - start);
-  return Factory::NewStringSlice(underlying,
-                                 start,
-                                 end);
-}
-
-
-static Handle<String> ConstructSliceTree(
-    Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS],
-    int from,
-    int to) {
-  CHECK(to > from);
-  if (to - from <= 1)
-    return SliceOf(building_blocks[from % NUMBER_OF_BUILDING_BLOCKS]);
-  if (to - from == 2) {
-    Handle<String> lhs = building_blocks[from % NUMBER_OF_BUILDING_BLOCKS];
-    if (gen() % 2 == 0)
-      lhs = SliceOf(lhs);
-    Handle<String> rhs = building_blocks[(from+1) % NUMBER_OF_BUILDING_BLOCKS];
-    if (gen() % 2 == 0)
-      rhs = SliceOf(rhs);
-    return Factory::NewConsString(lhs, rhs);
-  }
-  Handle<String> part1 =
-    ConstructBalancedHelper(building_blocks, from, from + ((to - from) / 2));
-  Handle<String> part2 =
-    ConstructBalancedHelper(building_blocks, from + ((to - from) / 2), to);
-  Handle<String> branch = Factory::NewConsString(part1, part2);
-  if (gen() % 2 == 0)
-    return branch;
-  return(SliceOf(branch));
-}
-
-
-TEST(Slice) {
-  printf("TestSlice\n");
-  InitializeVM();
-  v8::HandleScope scope;
-  Handle<String> building_blocks[NUMBER_OF_BUILDING_BLOCKS];
-  ZoneScope zone(DELETE_ON_EXIT);
-  InitializeBuildingBlocks(building_blocks);
-
-  seed = 42;
-  Handle<String> slice_tree =
-      ConstructSliceTree(building_blocks, 0, DEEP_DEPTH);
-  seed = 42;
-  Handle<String> flat_slice_tree =
-      ConstructSliceTree(building_blocks, 0, DEEP_DEPTH);
-  FlattenString(flat_slice_tree);
-  Traverse(flat_slice_tree, slice_tree);
-}
-
 static const int DEEP_ASCII_DEPTH = 100000;
 
 
@@ -414,105 +349,3 @@ class TwoByteResource: public v8::String::ExternalStringResource {
   size_t length_;
   bool* destructed_;
 };
-
-
-// Regression test case for http://crbug.com/9746. The problem was
-// that when we marked objects reachable only through weak pointers,
-// we ended up keeping a sliced symbol alive, even though we already
-// invoked the weak callback on the underlying external string thus
-// deleting its resource.
-TEST(Regress9746) {
-  InitializeVM();
-
-  // Setup lengths that guarantee we'll get slices instead of simple
-  // flat strings.
-  static const int kFullStringLength = String::kMinNonFlatLength * 2;
-  static const int kSliceStringLength = String::kMinNonFlatLength + 1;
-
-  uint16_t* source = new uint16_t[kFullStringLength];
-  for (int i = 0; i < kFullStringLength; i++) source[i] = '1';
-  char* key = new char[kSliceStringLength];
-  for (int i = 0; i < kSliceStringLength; i++) key[i] = '1';
-  Vector<const char> key_vector(key, kSliceStringLength);
-
-  // Allocate an external string resource that keeps track of when it
-  // is destructed.
-  bool resource_destructed = false;
-  TwoByteResource* resource =
-      new TwoByteResource(source, kFullStringLength, &resource_destructed);
-
-  {
-    v8::HandleScope scope;
-
-    // Allocate an external string resource and external string. We
-    // have to go through the API to get the weak handle and the
-    // automatic destruction going.
-    Handle<String> string =
-        v8::Utils::OpenHandle(*v8::String::NewExternal(resource));
-
-    // Create a slice of the external string.
-    Handle<String> slice =
-        Factory::NewStringSlice(string, 0, kSliceStringLength);
-    CHECK_EQ(kSliceStringLength, slice->length());
-    CHECK(StringShape(*slice).IsSliced());
-
-    // Make sure the slice ends up in old space so we can morph it
-    // into a symbol.
-    while (Heap::InNewSpace(*slice)) {
-      Heap::PerformScavenge();
-    }
-
-    // Force the slice into the symbol table.
-    slice = Factory::SymbolFromString(slice);
-    CHECK(slice->IsSymbol());
-    CHECK(StringShape(*slice).IsSliced());
-
-    Handle<String> buffer(Handle<SlicedString>::cast(slice)->buffer());
-    CHECK(StringShape(*buffer).IsExternal());
-    CHECK(buffer->IsTwoByteRepresentation());
-
-    // Finally, base a script on the slice of the external string and
-    // get its wrapper. This allocates yet another weak handle that
-    // indirectly refers to the external string.
-    Handle<Script> script = Factory::NewScript(slice);
-    Handle<JSObject> wrapper = GetScriptWrapper(script);
-  }
-
-  // When we collect all garbage, we cannot get rid of the sliced
-  // symbol entry in the symbol table because it is used by the script
-  // kept alive by the weak wrapper. Make sure we don't destruct the
-  // external string.
-  Heap::CollectAllGarbage(false);
-  CHECK(!resource_destructed);
-
-  {
-    v8::HandleScope scope;
-
-    // Make sure the sliced symbol is still in the table.
-    Handle<String> symbol = Factory::LookupSymbol(key_vector);
-    CHECK(StringShape(*symbol).IsSliced());
-
-    // Make sure the buffer is still a two-byte external string.
-    Handle<String> buffer(Handle<SlicedString>::cast(symbol)->buffer());
-    CHECK(StringShape(*buffer).IsExternal());
-    CHECK(buffer->IsTwoByteRepresentation());
-  }
-
-  // Forcing another garbage collection should let us get rid of the
-  // slice from the symbol table. The external string remains in the
-  // heap until the next GC.
-  Heap::CollectAllGarbage(false);
-  CHECK(!resource_destructed);
-  v8::HandleScope scope;
-  Handle<String> key_string = Factory::NewStringFromAscii(key_vector);
-  String* out;
-  CHECK(!Heap::LookupSymbolIfExists(*key_string, &out));
-
-  // Forcing yet another garbage collection must allow us to finally
-  // get rid of the external string.
-  Heap::CollectAllGarbage(false);
-  CHECK(resource_destructed);
-
-  delete[] source;
-  delete[] key;
-}