Generalize internalization of substrings.
authorulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 Jan 2014 14:31:34 +0000 (14:31 +0000)
committerulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 Jan 2014 14:31:34 +0000 (14:31 +0000)
Make a template version of SubStringKey, which allows internalization of substrings of sequential and external strings.

R=dcarney@chromium.org, svenpanne@chromium.org

Review URL: https://codereview.chromium.org/143223004

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

src/factory.cc
src/factory.h
src/objects-inl.h
src/objects.cc

index 0513297..aead7be 100644 (file)
@@ -227,7 +227,7 @@ Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) {
 
 Handle<String> Factory::InternalizeOneByteString(
     Handle<SeqOneByteString> string, int from, int length) {
-  SubStringOneByteStringKey key(string, from, length);
+  SubStringKey<uint8_t> key(string, from, length);
   return InternalizeStringWithKey(&key);
 }
 
@@ -246,6 +246,12 @@ Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) {
 }
 
 
+template Handle<String> Factory::InternalizeStringWithKey<
+    SubStringKey<uint8_t> > (SubStringKey<uint8_t>* key);
+template Handle<String> Factory::InternalizeStringWithKey<
+    SubStringKey<uint16_t> > (SubStringKey<uint16_t>* key);
+
+
 Handle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
                                              PretenureFlag pretenure) {
   CALL_HEAP_FUNCTION(
index 8ca9d48..db25b09 100644 (file)
@@ -99,9 +99,9 @@ class Factory {
   }
   Handle<String> InternalizeString(Handle<String> str);
   Handle<String> InternalizeOneByteString(Vector<const uint8_t> str);
-  Handle<String> InternalizeOneByteString(Handle<SeqOneByteString>,
-                                   int from,
-                                   int length);
+  Handle<String> InternalizeOneByteString(
+      Handle<SeqOneByteString>, int from, int length);
+
   Handle<String> InternalizeTwoByteString(Vector<const uc16> str);
 
   template<class StringTableKey>
index f86e847..3f178c0 100644 (file)
@@ -499,17 +499,21 @@ class OneByteStringKey : public SequentialStringKey<uint8_t> {
 };
 
 
-class SubStringOneByteStringKey : public HashTableKey {
+template<class Char>
+class SubStringKey : public HashTableKey {
  public:
-  explicit SubStringOneByteStringKey(Handle<SeqOneByteString> string,
-                                     int from,
-                                     int length)
-      : string_(string), from_(from), length_(length) { }
+  SubStringKey(Handle<String> string, int from, int length)
+      : string_(string), from_(from), length_(length) {
+    if (string_->IsSlicedString()) {
+      string_ = Handle<String>(Unslice(*string_, &from_));
+    }
+    ASSERT(string_->IsSeqString() || string->IsExternalString());
+  }
 
   virtual uint32_t Hash() {
     ASSERT(length_ >= 0);
     ASSERT(from_ + length_ <= string_->length());
-    uint8_t* chars = string_->GetChars() + from_;
+    const Char* chars = GetChars() + from_;
     hash_field_ = StringHasher::HashSequentialString(
         chars, length_, string_->GetHeap()->HashSeed());
     uint32_t result = hash_field_ >> String::kHashShift;
@@ -517,20 +521,25 @@ class SubStringOneByteStringKey : public HashTableKey {
     return result;
   }
 
-
   virtual uint32_t HashForObject(Object* other) {
     return String::cast(other)->Hash();
   }
 
-  virtual bool IsMatch(Object* string) {
-    Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
-    return String::cast(string)->IsOneByteEqualTo(chars);
-  }
-
+  virtual bool IsMatch(Object* string);
   virtual MaybeObject* AsObject(Heap* heap);
 
  private:
-  Handle<SeqOneByteString> string_;
+  const Char* GetChars();
+  String* Unslice(String* string, int* offset) {
+    while (string->IsSlicedString()) {
+      SlicedString* sliced = SlicedString::cast(string);
+      *offset += sliced->offset();
+      string = sliced->parent();
+    }
+    return string;
+  }
+
+  Handle<String> string_;
   int from_;
   int length_;
   uint32_t hash_field_;
index 392c158..a30489e 100644 (file)
@@ -13832,19 +13832,63 @@ MaybeObject* OneByteStringKey::AsObject(Heap* heap) {
 }
 
 
-MaybeObject* SubStringOneByteStringKey::AsObject(Heap* heap) {
+MaybeObject* TwoByteStringKey::AsObject(Heap* heap) {
+  if (hash_field_ == 0) Hash();
+  return heap->AllocateTwoByteInternalizedString(string_, hash_field_);
+}
+
+
+template<>
+const uint8_t* SubStringKey<uint8_t>::GetChars() {
+  return string_->IsSeqOneByteString()
+      ? SeqOneByteString::cast(*string_)->GetChars()
+      : ExternalAsciiString::cast(*string_)->GetChars();
+}
+
+
+template<>
+const uint16_t* SubStringKey<uint16_t>::GetChars() {
+  return string_->IsSeqTwoByteString()
+      ? SeqTwoByteString::cast(*string_)->GetChars()
+      : ExternalTwoByteString::cast(*string_)->GetChars();
+}
+
+
+template<>
+MaybeObject* SubStringKey<uint8_t>::AsObject(Heap* heap) {
   if (hash_field_ == 0) Hash();
-  Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
+  Vector<const uint8_t> chars(GetChars() + from_, length_);
   return heap->AllocateOneByteInternalizedString(chars, hash_field_);
 }
 
 
-MaybeObject* TwoByteStringKey::AsObject(Heap* heap) {
+template<>
+MaybeObject* SubStringKey<uint16_t>::AsObject(
+    Heap* heap) {
   if (hash_field_ == 0) Hash();
-  return heap->AllocateTwoByteInternalizedString(string_, hash_field_);
+  Vector<const uint16_t> chars(GetChars() + from_, length_);
+  return heap->AllocateTwoByteInternalizedString(chars, hash_field_);
+}
+
+
+template<>
+bool SubStringKey<uint8_t>::IsMatch(Object* string) {
+  Vector<const uint8_t> chars(GetChars() + from_, length_);
+  return String::cast(string)->IsOneByteEqualTo(chars);
 }
 
 
+template<>
+bool SubStringKey<uint16_t>::IsMatch(Object* string) {
+  Vector<const uint16_t> chars(GetChars() + from_, length_);
+  return String::cast(string)->IsTwoByteEqualTo(chars);
+}
+
+
+template class SubStringKey<uint8_t>;
+template class SubStringKey<uint16_t>;
+
+
 // InternalizedStringKey carries a string/internalized-string object as key.
 class InternalizedStringKey : public HashTableKey {
  public: