// Internalized strings are created in the old generation (data space).
Handle<String> Factory::InternalizeUtf8String(Vector<const char> string) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->InternalizeUtf8String(string),
- String);
+ Utf8StringKey key(string, isolate()->heap()->HashSeed());
+ return InternalizeStringWithKey(&key);
}
Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->InternalizeOneByteString(string),
- String);
+ OneByteStringKey key(string, isolate()->heap()->HashSeed());
+ return InternalizeStringWithKey(&key);
}
Handle<String> Factory::InternalizeOneByteString(
Handle<SeqOneByteString> string, int from, int length) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->InternalizeOneByteString(
- string, from, length),
- String);
+ SubStringOneByteStringKey key(string, from, length);
+ return InternalizeStringWithKey(&key);
}
Handle<String> Factory::InternalizeTwoByteString(Vector<const uc16> string) {
+ TwoByteStringKey key(string, isolate()->heap()->HashSeed());
+ return InternalizeStringWithKey(&key);
+}
+
+
+template<class StringTableKey>
+Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) {
CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->InternalizeTwoByteString(string),
+ isolate()->heap()->InternalizeStringWithKey(key),
String);
}
int length);
Handle<String> InternalizeTwoByteString(Vector<const uc16> str);
+ template<class StringTableKey>
+ Handle<String> InternalizeStringWithKey(StringTableKey* key);
+
// String creation functions. Most of the string creation functions take
// a Heap::PretenureFlag argument to optionally request that they be
uint8_t buffer[1];
buffer[0] = static_cast<uint8_t>(code);
Object* result;
- MaybeObject* maybe_result =
- InternalizeOneByteString(Vector<const uint8_t>(buffer, 1));
+ OneByteStringKey key(Vector<const uint8_t>(buffer, 1), HashSeed());
+ MaybeObject* maybe_result = InternalizeStringWithKey(&key);
if (!maybe_result->ToObject(&result)) return maybe_result;
single_character_string_cache()->set(code, result);
SharedFunctionInfo* shared = NULL;
if (type == JS_FUNCTION_TYPE) {
String* name;
- maybe =
- InternalizeOneByteString(STATIC_ASCII_VECTOR("<freezing call trap>"));
+ OneByteStringKey key(STATIC_ASCII_VECTOR("<freezing call trap>"),
+ HashSeed());
+ maybe = InternalizeStringWithKey(&key);
if (!maybe->To<String>(&name)) return maybe;
maybe = AllocateSharedFunctionInfo(name);
if (!maybe->To<SharedFunctionInfo>(&shared)) return maybe;
MaybeObject* Heap::InternalizeUtf8String(Vector<const char> string) {
- Object* result = NULL;
- Object* new_table;
- { MaybeObject* maybe_new_table =
- string_table()->LookupUtf8String(string, &result);
- if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
- }
- // Can't use set_string_table because StringTable::cast knows that
- // StringTable is a singleton and checks for identity.
- roots_[kStringTableRootIndex] = new_table;
- ASSERT(result != NULL);
- return result;
-}
-
-
-MaybeObject* Heap::InternalizeOneByteString(Vector<const uint8_t> string) {
- Object* result = NULL;
- Object* new_table;
- { MaybeObject* maybe_new_table =
- string_table()->LookupOneByteString(string, &result);
- if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
- }
- // Can't use set_string_table because StringTable::cast knows that
- // StringTable is a singleton and checks for identity.
- roots_[kStringTableRootIndex] = new_table;
- ASSERT(result != NULL);
- return result;
+ Utf8StringKey key(string, HashSeed());
+ return InternalizeStringWithKey(&key);
}
-MaybeObject* Heap::InternalizeOneByteString(Handle<SeqOneByteString> string,
- int from,
- int length) {
+MaybeObject* Heap::InternalizeString(String* string) {
+ if (string->IsInternalizedString()) return string;
Object* result = NULL;
Object* new_table;
{ MaybeObject* maybe_new_table =
- string_table()->LookupSubStringOneByteString(string,
- from,
- length,
- &result);
+ string_table()->LookupString(string, &result);
if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
}
// Can't use set_string_table because StringTable::cast knows that
}
-MaybeObject* Heap::InternalizeTwoByteString(Vector<const uc16> string) {
- Object* result = NULL;
- Object* new_table;
- { MaybeObject* maybe_new_table =
- string_table()->LookupTwoByteString(string, &result);
- if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
+bool Heap::InternalizeStringIfExists(String* string, String** result) {
+ if (string->IsInternalizedString()) {
+ *result = string;
+ return true;
}
- // Can't use set_string_table because StringTable::cast knows that
- // StringTable is a singleton and checks for identity.
- roots_[kStringTableRootIndex] = new_table;
- ASSERT(result != NULL);
- return result;
+ return string_table()->LookupStringIfExists(string, result);
}
-MaybeObject* Heap::InternalizeString(String* string) {
- if (string->IsInternalizedString()) return string;
+MaybeObject* Heap::InternalizeStringWithKey(HashTableKey* key) {
Object* result = NULL;
Object* new_table;
{ MaybeObject* maybe_new_table =
- string_table()->LookupString(string, &result);
+ string_table()->LookupKey(key, &result);
if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
}
// Can't use set_string_table because StringTable::cast knows that
}
-bool Heap::InternalizeStringIfExists(String* string, String** result) {
- if (string->IsInternalizedString()) {
- *result = string;
- return true;
- }
- return string_table()->LookupStringIfExists(string, result);
-}
-
-
void Heap::ZapFromSpace() {
NewSpacePageIterator it(new_space_.FromSpaceStart(),
new_space_.FromSpaceEnd());
// Returns Failure::RetryAfterGC(requested_bytes, space) if allocation
// failed.
// Please note this function does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* InternalizeUtf8String(Vector<const char> str);
MUST_USE_RESULT MaybeObject* InternalizeUtf8String(const char* str) {
return InternalizeUtf8String(CStrVector(str));
}
- MUST_USE_RESULT MaybeObject* InternalizeOneByteString(
- Vector<const uint8_t> str);
- MUST_USE_RESULT MaybeObject* InternalizeTwoByteString(Vector<const uc16> str);
+ MUST_USE_RESULT MaybeObject* InternalizeUtf8String(Vector<const char> str);
+
MUST_USE_RESULT MaybeObject* InternalizeString(String* str);
- MUST_USE_RESULT MaybeObject* InternalizeOneByteString(
- Handle<SeqOneByteString> string, int from, int length);
+ MUST_USE_RESULT MaybeObject* InternalizeStringWithKey(HashTableKey* key);
bool InternalizeStringIfExists(String* str, String** result);
bool InternalizeTwoCharsStringIfExists(String* str, String** result);
}
+template <typename Char>
+class SequentialStringKey : public HashTableKey {
+ public:
+ explicit SequentialStringKey(Vector<const Char> string, uint32_t seed)
+ : string_(string), hash_field_(0), seed_(seed) { }
+
+ virtual uint32_t Hash() {
+ hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(),
+ string_.length(),
+ seed_);
+
+ uint32_t result = hash_field_ >> String::kHashShift;
+ ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
+ return result;
+ }
+
+
+ virtual uint32_t HashForObject(Object* other) {
+ return String::cast(other)->Hash();
+ }
+
+ Vector<const Char> string_;
+ uint32_t hash_field_;
+ uint32_t seed_;
+};
+
+
+class OneByteStringKey : public SequentialStringKey<uint8_t> {
+ public:
+ OneByteStringKey(Vector<const uint8_t> str, uint32_t seed)
+ : SequentialStringKey<uint8_t>(str, seed) { }
+
+ virtual bool IsMatch(Object* string) {
+ return String::cast(string)->IsOneByteEqualTo(string_);
+ }
+
+ virtual MaybeObject* AsObject(Heap* heap);
+};
+
+
+class SubStringOneByteStringKey : public HashTableKey {
+ public:
+ explicit SubStringOneByteStringKey(Handle<SeqOneByteString> string,
+ int from,
+ int length)
+ : string_(string), from_(from), length_(length) { }
+
+ virtual uint32_t Hash() {
+ ASSERT(length_ >= 0);
+ ASSERT(from_ + length_ <= string_->length());
+ uint8_t* chars = string_->GetChars() + from_;
+ hash_field_ = StringHasher::HashSequentialString(
+ chars, length_, string_->GetHeap()->HashSeed());
+ uint32_t result = hash_field_ >> String::kHashShift;
+ ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
+ 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 MaybeObject* AsObject(Heap* heap);
+
+ private:
+ Handle<SeqOneByteString> string_;
+ int from_;
+ int length_;
+ uint32_t hash_field_;
+};
+
+
+class TwoByteStringKey : public SequentialStringKey<uc16> {
+ public:
+ explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed)
+ : SequentialStringKey<uc16>(str, seed) { }
+
+ virtual bool IsMatch(Object* string) {
+ return String::cast(string)->IsTwoByteEqualTo(string_);
+ }
+
+ virtual MaybeObject* AsObject(Heap* heap);
+};
+
+
+// Utf8StringKey carries a vector of chars as key.
+class Utf8StringKey : public HashTableKey {
+ public:
+ explicit Utf8StringKey(Vector<const char> string, uint32_t seed)
+ : string_(string), hash_field_(0), seed_(seed) { }
+
+ virtual bool IsMatch(Object* string) {
+ return String::cast(string)->IsUtf8EqualTo(string_);
+ }
+
+ virtual uint32_t Hash() {
+ if (hash_field_ != 0) return hash_field_ >> String::kHashShift;
+ hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_);
+ uint32_t result = hash_field_ >> String::kHashShift;
+ ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
+ return result;
+ }
+
+ virtual uint32_t HashForObject(Object* other) {
+ return String::cast(other)->Hash();
+ }
+
+ virtual MaybeObject* AsObject(Heap* heap) {
+ if (hash_field_ == 0) Hash();
+ return heap->AllocateInternalizedStringFromUtf8(string_,
+ chars_,
+ hash_field_);
+ }
+
+ Vector<const char> string_;
+ uint32_t hash_field_;
+ int chars_; // Caches the number of characters when computing the hash code.
+ uint32_t seed_;
+};
+
+
bool Object::IsNumber() {
return IsSmi() || IsHeapNumber();
}
#undef READ_BYTE_FIELD
#undef WRITE_BYTE_FIELD
-
} } // namespace v8::internal
#endif // V8_OBJECTS_INL_H_
};
-// Utf8StringKey carries a vector of chars as key.
-class Utf8StringKey : public HashTableKey {
- public:
- explicit Utf8StringKey(Vector<const char> string, uint32_t seed)
- : string_(string), hash_field_(0), seed_(seed) { }
-
- bool IsMatch(Object* string) {
- return String::cast(string)->IsUtf8EqualTo(string_);
- }
-
- uint32_t Hash() {
- if (hash_field_ != 0) return hash_field_ >> String::kHashShift;
- hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_);
- uint32_t result = hash_field_ >> String::kHashShift;
- ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
- return result;
- }
-
- uint32_t HashForObject(Object* other) {
- return String::cast(other)->Hash();
- }
-
- MaybeObject* AsObject(Heap* heap) {
- if (hash_field_ == 0) Hash();
- return heap->AllocateInternalizedStringFromUtf8(string_,
- chars_,
- hash_field_);
- }
-
- Vector<const char> string_;
- uint32_t hash_field_;
- int chars_; // Caches the number of characters when computing the hash code.
- uint32_t seed_;
-};
-
-
-template <typename Char>
-class SequentialStringKey : public HashTableKey {
- public:
- explicit SequentialStringKey(Vector<const Char> string, uint32_t seed)
- : string_(string), hash_field_(0), seed_(seed) { }
-
- uint32_t Hash() {
- hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(),
- string_.length(),
- seed_);
-
- uint32_t result = hash_field_ >> String::kHashShift;
- ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
- return result;
- }
-
-
- uint32_t HashForObject(Object* other) {
- return String::cast(other)->Hash();
- }
-
- Vector<const Char> string_;
- uint32_t hash_field_;
- uint32_t seed_;
-};
-
-
-
-class OneByteStringKey : public SequentialStringKey<uint8_t> {
- public:
- OneByteStringKey(Vector<const uint8_t> str, uint32_t seed)
- : SequentialStringKey<uint8_t>(str, seed) { }
-
- bool IsMatch(Object* string) {
- return String::cast(string)->IsOneByteEqualTo(string_);
- }
-
- MaybeObject* AsObject(Heap* heap) {
- if (hash_field_ == 0) Hash();
- return heap->AllocateOneByteInternalizedString(string_, hash_field_);
- }
-};
-
-
-class SubStringOneByteStringKey : public HashTableKey {
- public:
- explicit SubStringOneByteStringKey(Handle<SeqOneByteString> string,
- int from,
- int length)
- : string_(string), from_(from), length_(length) { }
-
- uint32_t Hash() {
- ASSERT(length_ >= 0);
- ASSERT(from_ + length_ <= string_->length());
- uint8_t* chars = string_->GetChars() + from_;
- hash_field_ = StringHasher::HashSequentialString(
- chars, length_, string_->GetHeap()->HashSeed());
- uint32_t result = hash_field_ >> String::kHashShift;
- ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
- return result;
- }
-
-
- uint32_t HashForObject(Object* other) {
- return String::cast(other)->Hash();
- }
-
- bool IsMatch(Object* string) {
- Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
- return String::cast(string)->IsOneByteEqualTo(chars);
- }
+MaybeObject* OneByteStringKey::AsObject(Heap* heap) {
+ if (hash_field_ == 0) Hash();
+ return heap->AllocateOneByteInternalizedString(string_, hash_field_);
+}
- MaybeObject* AsObject(Heap* heap) {
- if (hash_field_ == 0) Hash();
- Vector<const uint8_t> chars(string_->GetChars() + from_, length_);
- return heap->AllocateOneByteInternalizedString(chars, hash_field_);
- }
-
- private:
- Handle<SeqOneByteString> string_;
- int from_;
- int length_;
- uint32_t hash_field_;
-};
+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_);
+}
-class TwoByteStringKey : public SequentialStringKey<uc16> {
- public:
- explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed)
- : SequentialStringKey<uc16>(str, seed) { }
- bool IsMatch(Object* string) {
- return String::cast(string)->IsTwoByteEqualTo(string_);
- }
-
- MaybeObject* AsObject(Heap* heap) {
- if (hash_field_ == 0) Hash();
- return heap->AllocateTwoByteInternalizedString(string_, hash_field_);
- }
-};
+MaybeObject* TwoByteStringKey::AsObject(Heap* heap) {
+ if (hash_field_ == 0) Hash();
+ return heap->AllocateTwoByteInternalizedString(string_, hash_field_);
+}
// InternalizedStringKey carries a string/internalized-string object as key.
}
-MaybeObject* StringTable::LookupUtf8String(Vector<const char> str,
- Object** s) {
- Utf8StringKey key(str, GetHeap()->HashSeed());
- return LookupKey(&key, s);
-}
-
-
-MaybeObject* StringTable::LookupOneByteString(Vector<const uint8_t> str,
- Object** s) {
- OneByteStringKey key(str, GetHeap()->HashSeed());
- return LookupKey(&key, s);
-}
-
-
-MaybeObject* StringTable::LookupSubStringOneByteString(
- Handle<SeqOneByteString> str,
- int from,
- int length,
- Object** s) {
- SubStringOneByteStringKey key(str, from, length);
- return LookupKey(&key, s);
-}
-
-
-MaybeObject* StringTable::LookupTwoByteString(Vector<const uc16> str,
- Object** s) {
- TwoByteStringKey key(str, GetHeap()->HashSeed());
- return LookupKey(&key, s);
-}
-
-
MaybeObject* StringTable::LookupKey(HashTableKey* key, Object** s) {
int entry = FindEntry(key);
// added. The return value is the string table which might have
// been enlarged. If the return value is not a failure, the string
// pointer *s is set to the string found.
- MUST_USE_RESULT MaybeObject* LookupUtf8String(
- Vector<const char> str,
- Object** s);
- MUST_USE_RESULT MaybeObject* LookupOneByteString(
- Vector<const uint8_t> str,
- Object** s);
- MUST_USE_RESULT MaybeObject* LookupSubStringOneByteString(
- Handle<SeqOneByteString> str,
- int from,
- int length,
- Object** s);
- MUST_USE_RESULT MaybeObject* LookupTwoByteString(
- Vector<const uc16> str,
- Object** s);
MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s);
+ MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s);
// Looks up a string that is equal to the given string and returns
// true if it is found, assigning the string to the given output
static inline StringTable* cast(Object* obj);
private:
- MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s);
-
template <bool seq_ascii> friend class JsonParser;
DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);