From 405e8eaf7aa3a839285500425408b7bdb83bb4eb Mon Sep 17 00:00:00 2001 From: "ulan@chromium.org" Date: Wed, 29 Jan 2014 14:31:34 +0000 Subject: [PATCH] Generalize internalization of substrings. 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 | 8 +++++++- src/factory.h | 6 +++--- src/objects-inl.h | 35 ++++++++++++++++++++++------------- src/objects.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/factory.cc b/src/factory.cc index 0513297..aead7be 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -227,7 +227,7 @@ Handle Factory::InternalizeOneByteString(Vector string) { Handle Factory::InternalizeOneByteString( Handle string, int from, int length) { - SubStringOneByteStringKey key(string, from, length); + SubStringKey key(string, from, length); return InternalizeStringWithKey(&key); } @@ -246,6 +246,12 @@ Handle Factory::InternalizeStringWithKey(StringTableKey* key) { } +template Handle Factory::InternalizeStringWithKey< + SubStringKey > (SubStringKey* key); +template Handle Factory::InternalizeStringWithKey< + SubStringKey > (SubStringKey* key); + + Handle Factory::NewStringFromOneByte(Vector string, PretenureFlag pretenure) { CALL_HEAP_FUNCTION( diff --git a/src/factory.h b/src/factory.h index 8ca9d48..db25b09 100644 --- a/src/factory.h +++ b/src/factory.h @@ -99,9 +99,9 @@ class Factory { } Handle InternalizeString(Handle str); Handle InternalizeOneByteString(Vector str); - Handle InternalizeOneByteString(Handle, - int from, - int length); + Handle InternalizeOneByteString( + Handle, int from, int length); + Handle InternalizeTwoByteString(Vector str); template diff --git a/src/objects-inl.h b/src/objects-inl.h index f86e847..3f178c0 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -499,17 +499,21 @@ class OneByteStringKey : public SequentialStringKey { }; -class SubStringOneByteStringKey : public HashTableKey { +template +class SubStringKey : public HashTableKey { public: - explicit SubStringOneByteStringKey(Handle string, - int from, - int length) - : string_(string), from_(from), length_(length) { } + SubStringKey(Handle string, int from, int length) + : string_(string), from_(from), length_(length) { + if (string_->IsSlicedString()) { + string_ = Handle(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 chars(string_->GetChars() + from_, length_); - return String::cast(string)->IsOneByteEqualTo(chars); - } - + virtual bool IsMatch(Object* string); virtual MaybeObject* AsObject(Heap* heap); private: - Handle 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_; int from_; int length_; uint32_t hash_field_; diff --git a/src/objects.cc b/src/objects.cc index 392c158..a30489e 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -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::GetChars() { + return string_->IsSeqOneByteString() + ? SeqOneByteString::cast(*string_)->GetChars() + : ExternalAsciiString::cast(*string_)->GetChars(); +} + + +template<> +const uint16_t* SubStringKey::GetChars() { + return string_->IsSeqTwoByteString() + ? SeqTwoByteString::cast(*string_)->GetChars() + : ExternalTwoByteString::cast(*string_)->GetChars(); +} + + +template<> +MaybeObject* SubStringKey::AsObject(Heap* heap) { if (hash_field_ == 0) Hash(); - Vector chars(string_->GetChars() + from_, length_); + Vector chars(GetChars() + from_, length_); return heap->AllocateOneByteInternalizedString(chars, hash_field_); } -MaybeObject* TwoByteStringKey::AsObject(Heap* heap) { +template<> +MaybeObject* SubStringKey::AsObject( + Heap* heap) { if (hash_field_ == 0) Hash(); - return heap->AllocateTwoByteInternalizedString(string_, hash_field_); + Vector chars(GetChars() + from_, length_); + return heap->AllocateTwoByteInternalizedString(chars, hash_field_); +} + + +template<> +bool SubStringKey::IsMatch(Object* string) { + Vector chars(GetChars() + from_, length_); + return String::cast(string)->IsOneByteEqualTo(chars); } +template<> +bool SubStringKey::IsMatch(Object* string) { + Vector chars(GetChars() + from_, length_); + return String::cast(string)->IsTwoByteEqualTo(chars); +} + + +template class SubStringKey; +template class SubStringKey; + + // InternalizedStringKey carries a string/internalized-string object as key. class InternalizedStringKey : public HashTableKey { public: -- 2.7.4