Commit 442bd663 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[snapshot] Use ThinStrings instead of custom forwarding using the hashfield to...

[snapshot] Use ThinStrings instead of custom forwarding using the hashfield to deserialize internalized strings

This is necessary to be able to store the string length next to the hash field in the same 64bit word on 64bit architectures. Otherwise the forwarding pointer will overwrite the length breaking heap guarantees. ThinStrings already just do the right thing, so just use that instead.

Bug: v8:7065
Change-Id: I4922365e72421995cd11437cb91572ff56f8a9e8
Reviewed-on: https://chromium-review.googlesource.com/763231Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49352}
parent 68f1dcf9
...@@ -16748,6 +16748,9 @@ void MigrateExternalStringResource(Isolate* isolate, String* from, String* to) { ...@@ -16748,6 +16748,9 @@ void MigrateExternalStringResource(Isolate* isolate, String* from, String* to) {
} }
void MakeStringThin(String* string, String* internalized, Isolate* isolate) { void MakeStringThin(String* string, String* internalized, Isolate* isolate) {
DCHECK_NE(string, internalized);
DCHECK(internalized->IsInternalizedString());
if (string->IsExternalString()) { if (string->IsExternalString()) {
if (internalized->IsExternalOneByteString()) { if (internalized->IsExternalOneByteString()) {
MigrateExternalStringResource<ExternalOneByteString>(isolate, string, MigrateExternalStringResource<ExternalOneByteString>(isolate, string,
...@@ -16763,7 +16766,6 @@ void MakeStringThin(String* string, String* internalized, Isolate* isolate) { ...@@ -16763,7 +16766,6 @@ void MakeStringThin(String* string, String* internalized, Isolate* isolate) {
} }
} }
if (!string->IsInternalizedString()) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
int old_size = string->Size(); int old_size = string->Size();
isolate->heap()->NotifyObjectLayoutChange(string, old_size, no_gc); isolate->heap()->NotifyObjectLayoutChange(string, old_size, no_gc);
...@@ -16780,7 +16782,6 @@ void MakeStringThin(String* string, String* internalized, Isolate* isolate) { ...@@ -16780,7 +16782,6 @@ void MakeStringThin(String* string, String* internalized, Isolate* isolate) {
Heap* heap = isolate->heap(); Heap* heap = isolate->heap();
heap->CreateFillerObjectAt(thin_end, size_delta, ClearRecordedSlots::kNo); heap->CreateFillerObjectAt(thin_end, size_delta, ClearRecordedSlots::kNo);
} }
}
} }
} // namespace } // namespace
...@@ -16794,7 +16795,9 @@ Handle<String> StringTable::LookupString(Isolate* isolate, ...@@ -16794,7 +16795,9 @@ Handle<String> StringTable::LookupString(Isolate* isolate,
Handle<String> result = LookupKey(isolate, &key); Handle<String> result = LookupKey(isolate, &key);
if (FLAG_thin_strings) { if (FLAG_thin_strings) {
if (!string->IsInternalizedString()) {
MakeStringThin(*string, *result, isolate); MakeStringThin(*string, *result, isolate);
}
} else { // !FLAG_thin_strings } else { // !FLAG_thin_strings
if (string->IsConsString()) { if (string->IsConsString()) {
Handle<ConsString> cons = Handle<ConsString>::cast(string); Handle<ConsString> cons = Handle<ConsString>::cast(string);
...@@ -16989,6 +16992,7 @@ Object* StringTable::LookupStringIfExists_NoAllocate(String* string) { ...@@ -16989,6 +16992,7 @@ Object* StringTable::LookupStringIfExists_NoAllocate(String* string) {
return Smi::FromInt(ResultSentinel::kUnsupported); return Smi::FromInt(ResultSentinel::kUnsupported);
} }
DCHECK(!string->IsInternalizedString());
int entry = table->FindEntry(isolate, &key, key.Hash()); int entry = table->FindEntry(isolate, &key, key.Hash());
if (entry != kNotFound) { if (entry != kNotFound) {
String* internalized = String::cast(table->KeyAt(entry)); String* internalized = String::cast(table->KeyAt(entry));
...@@ -17002,11 +17006,16 @@ Object* StringTable::LookupStringIfExists_NoAllocate(String* string) { ...@@ -17002,11 +17006,16 @@ Object* StringTable::LookupStringIfExists_NoAllocate(String* string) {
return Smi::FromInt(ResultSentinel::kNotFound); return Smi::FromInt(ResultSentinel::kNotFound);
} }
String* StringTable::LookupKeyIfExists(Isolate* isolate, StringTableKey* key) { String* StringTable::ForwardStringIfExists(Isolate* isolate,
StringTableKey* key,
String* string) {
Handle<StringTable> table = isolate->factory()->string_table(); Handle<StringTable> table = isolate->factory()->string_table();
int entry = table->FindEntry(isolate, key); int entry = table->FindEntry(isolate, key);
if (entry != kNotFound) return String::cast(table->KeyAt(entry)); if (entry == kNotFound) return nullptr;
return nullptr;
String* canonical = String::cast(table->KeyAt(entry));
if (canonical != string) MakeStringThin(string, canonical, isolate);
return canonical;
} }
Handle<StringSet> StringSet::New(Isolate* isolate) { Handle<StringSet> StringSet::New(Isolate* isolate) {
......
...@@ -666,30 +666,6 @@ bool String::AsArrayIndex(uint32_t* index) { ...@@ -666,30 +666,6 @@ bool String::AsArrayIndex(uint32_t* index) {
return SlowAsArrayIndex(index); return SlowAsArrayIndex(index);
} }
void String::SetForwardedInternalizedString(String* canonical) {
DCHECK(IsInternalizedString());
DCHECK(HasHashCode());
if (canonical == this) return; // No need to forward.
DCHECK(SlowEquals(canonical));
DCHECK(canonical->IsInternalizedString());
DCHECK(canonical->HasHashCode());
WRITE_FIELD(this, kHashFieldSlot, canonical);
// Setting the hash field to a tagged value sets the LSB, causing the hash
// code to be interpreted as uninitialized. We use this fact to recognize
// that we have a forwarded string.
DCHECK(!HasHashCode());
}
String* String::GetForwardedInternalizedString() {
DCHECK(IsInternalizedString());
if (HasHashCode()) return this;
String* canonical = String::cast(READ_FIELD(this, kHashFieldSlot));
DCHECK(canonical->IsInternalizedString());
DCHECK(SlowEquals(canonical));
DCHECK(canonical->HasHashCode());
return canonical;
}
String::SubStringRange::SubStringRange(String* string, int first, int length) String::SubStringRange::SubStringRange(String* string, int first, int length)
: string_(string), : string_(string),
first_(first), first_(first),
......
...@@ -59,7 +59,8 @@ class StringTable : public HashTable<StringTable, StringTableShape> { ...@@ -59,7 +59,8 @@ class StringTable : public HashTable<StringTable, StringTableShape> {
V8_EXPORT_PRIVATE static Handle<String> LookupString(Isolate* isolate, V8_EXPORT_PRIVATE static Handle<String> LookupString(Isolate* isolate,
Handle<String> key); Handle<String> key);
static Handle<String> LookupKey(Isolate* isolate, StringTableKey* key); static Handle<String> LookupKey(Isolate* isolate, StringTableKey* key);
static String* LookupKeyIfExists(Isolate* isolate, StringTableKey* key); static String* ForwardStringIfExists(Isolate* isolate, StringTableKey* key,
String* string);
// Looks up a string that is equal to the given string and returns // Looks up a string that is equal to the given string and returns
// string handle if it is found, or an empty handle otherwise. // string handle if it is found, or an empty handle otherwise.
......
...@@ -437,11 +437,6 @@ class String : public Name { ...@@ -437,11 +437,6 @@ class String : public Name {
static Handle<FixedArray> CalculateLineEnds(Handle<String> string, static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
bool include_ending_line); bool include_ending_line);
// Use the hash field to forward to the canonical internalized string
// when deserializing an internalized string.
inline void SetForwardedInternalizedString(String* string);
inline String* GetForwardedInternalizedString();
private: private:
friend class Name; friend class Name;
friend class StringTableInsertionKey; friend class StringTableInsertionKey;
......
...@@ -156,14 +156,13 @@ HeapObject* Deserializer<AllocatorT>::PostProcessNewObject(HeapObject* obj, ...@@ -156,14 +156,13 @@ HeapObject* Deserializer<AllocatorT>::PostProcessNewObject(HeapObject* obj,
// Canonicalize the internalized string. If it already exists in the // Canonicalize the internalized string. If it already exists in the
// string table, set it to forward to the existing one. // string table, set it to forward to the existing one.
StringTableInsertionKey key(string); StringTableInsertionKey key(string);
String* canonical = StringTable::LookupKeyIfExists(isolate_, &key); String* canonical =
if (canonical == nullptr) { StringTable::ForwardStringIfExists(isolate_, &key, string);
if (canonical != nullptr) return canonical;
new_internalized_strings_.push_back(handle(string)); new_internalized_strings_.push_back(handle(string));
return string; return string;
} else {
string->SetForwardedInternalizedString(canonical);
return canonical;
}
} }
} else if (obj->IsScript()) { } else if (obj->IsScript()) {
new_scripts_.push_back(handle(Script::cast(obj))); new_scripts_.push_back(handle(Script::cast(obj)));
...@@ -275,8 +274,8 @@ HeapObject* Deserializer<AllocatorT>::GetBackReferencedObject(int space) { ...@@ -275,8 +274,8 @@ HeapObject* Deserializer<AllocatorT>::GetBackReferencedObject(int space) {
break; break;
} }
if (deserializing_user_code() && obj->IsInternalizedString()) { if (deserializing_user_code() && obj->IsThinString()) {
obj = String::cast(obj)->GetForwardedInternalizedString(); obj = ThinString::cast(obj)->actual();
} }
hot_objects_.Add(obj); hot_objects_.Add(obj);
......
...@@ -103,7 +103,7 @@ void ObjectDeserializer::CommitPostProcessedObjects() { ...@@ -103,7 +103,7 @@ void ObjectDeserializer::CommitPostProcessedObjects() {
isolate(), static_cast<int>(new_internalized_strings().size())); isolate(), static_cast<int>(new_internalized_strings().size()));
for (Handle<String> string : new_internalized_strings()) { for (Handle<String> string : new_internalized_strings()) {
StringTableInsertionKey key(*string); StringTableInsertionKey key(*string);
DCHECK_NULL(StringTable::LookupKeyIfExists(isolate(), &key)); DCHECK_NULL(StringTable::ForwardStringIfExists(isolate(), &key, *string));
StringTable::LookupKey(isolate(), &key); StringTable::LookupKey(isolate(), &key);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment