| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index c4a1baa6d38acac0a66323c79da10afb8134ca92..2385339be09601a699df4de208cdcc484562e063 100644
|
| --- a/src/heap/heap.cc
|
| +++ b/src/heap/heap.cc
|
| @@ -1738,12 +1738,21 @@ String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
|
|
|
| if (!first_word.IsForwardingAddress()) {
|
| // Unreachable external string can be finalized.
|
| - heap->FinalizeExternalString(String::cast(*p));
|
| + String* string = String::cast(*p);
|
| + if (!string->IsExternalString()) {
|
| + // Original external string has been internalized.
|
| + DCHECK(string->IsThinString());
|
| + return NULL;
|
| + }
|
| + heap->FinalizeExternalString(string);
|
| return NULL;
|
| }
|
|
|
| // String is still reachable.
|
| - return String::cast(first_word.ToForwardingAddress());
|
| + String* string = String::cast(first_word.ToForwardingAddress());
|
| + if (string->IsThinString()) string = ThinString::cast(string)->actual();
|
| + // Internalization can replace external strings with non-external strings.
|
| + return string->IsExternalString() ? string : nullptr;
|
| }
|
|
|
|
|
| @@ -6437,14 +6446,19 @@ void Heap::ExternalStringTable::CleanUpNewSpaceStrings() {
|
| int last = 0;
|
| Isolate* isolate = heap_->isolate();
|
| for (int i = 0; i < new_space_strings_.length(); ++i) {
|
| - if (new_space_strings_[i]->IsTheHole(isolate)) {
|
| + Object* o = new_space_strings_[i];
|
| + if (o->IsTheHole(isolate)) {
|
| continue;
|
| }
|
| - DCHECK(new_space_strings_[i]->IsExternalString());
|
| - if (heap_->InNewSpace(new_space_strings_[i])) {
|
| - new_space_strings_[last++] = new_space_strings_[i];
|
| + if (o->IsThinString()) {
|
| + o = ThinString::cast(o)->actual();
|
| + if (!o->IsExternalString()) continue;
|
| + }
|
| + DCHECK(o->IsExternalString());
|
| + if (heap_->InNewSpace(o)) {
|
| + new_space_strings_[last++] = o;
|
| } else {
|
| - old_space_strings_.Add(new_space_strings_[i]);
|
| + old_space_strings_.Add(o);
|
| }
|
| }
|
| new_space_strings_.Rewind(last);
|
| @@ -6456,12 +6470,17 @@ void Heap::ExternalStringTable::CleanUpAll() {
|
| int last = 0;
|
| Isolate* isolate = heap_->isolate();
|
| for (int i = 0; i < old_space_strings_.length(); ++i) {
|
| - if (old_space_strings_[i]->IsTheHole(isolate)) {
|
| + Object* o = old_space_strings_[i];
|
| + if (o->IsTheHole(isolate)) {
|
| continue;
|
| }
|
| - DCHECK(old_space_strings_[i]->IsExternalString());
|
| - DCHECK(!heap_->InNewSpace(old_space_strings_[i]));
|
| - old_space_strings_[last++] = old_space_strings_[i];
|
| + if (o->IsThinString()) {
|
| + o = ThinString::cast(o)->actual();
|
| + if (!o->IsExternalString()) continue;
|
| + }
|
| + DCHECK(o->IsExternalString());
|
| + DCHECK(!heap_->InNewSpace(o));
|
| + old_space_strings_[last++] = o;
|
| }
|
| old_space_strings_.Rewind(last);
|
| old_space_strings_.Trim();
|
| @@ -6474,11 +6493,21 @@ void Heap::ExternalStringTable::CleanUpAll() {
|
|
|
| void Heap::ExternalStringTable::TearDown() {
|
| for (int i = 0; i < new_space_strings_.length(); ++i) {
|
| - heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i]));
|
| + Object* o = new_space_strings_[i];
|
| + if (o->IsThinString()) {
|
| + o = ThinString::cast(o)->actual();
|
| + if (!o->IsExternalString()) continue;
|
| + }
|
| + heap_->FinalizeExternalString(ExternalString::cast(o));
|
| }
|
| new_space_strings_.Free();
|
| for (int i = 0; i < old_space_strings_.length(); ++i) {
|
| - heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i]));
|
| + Object* o = old_space_strings_[i];
|
| + if (o->IsThinString()) {
|
| + o = ThinString::cast(o)->actual();
|
| + if (!o->IsExternalString()) continue;
|
| + }
|
| + heap_->FinalizeExternalString(ExternalString::cast(o));
|
| }
|
| old_space_strings_.Free();
|
| }
|
|
|