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
This commit is contained in:
ulan@chromium.org 2014-01-29 14:31:34 +00:00
parent 979cd4b0f3
commit 405e8eaf7a
4 changed files with 83 additions and 24 deletions

View 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(

View 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>

View 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_;

View File

@ -13832,19 +13832,63 @@ MaybeObject* OneByteStringKey::AsObject(Heap* heap) {
}
MaybeObject* SubStringOneByteStringKey::AsObject(Heap* heap) {
if (hash_field_ == 0) Hash();
Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
return heap->AllocateOneByteInternalizedString(chars, hash_field_);
}
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(GetChars() + from_, length_);
return heap->AllocateOneByteInternalizedString(chars, hash_field_);
}
template<>
MaybeObject* SubStringKey<uint16_t>::AsObject(
Heap* heap) {
if (hash_field_ == 0) Hash();
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: