OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/heap.h" | 5 #include "src/heap/heap.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/ast/context-slot-cache.h" | 9 #include "src/ast/context-slot-cache.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1727 SetGCState(NOT_IN_GC); | 1727 SetGCState(NOT_IN_GC); |
1728 } | 1728 } |
1729 | 1729 |
1730 | 1730 |
1731 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, | 1731 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, |
1732 Object** p) { | 1732 Object** p) { |
1733 MapWord first_word = HeapObject::cast(*p)->map_word(); | 1733 MapWord first_word = HeapObject::cast(*p)->map_word(); |
1734 | 1734 |
1735 if (!first_word.IsForwardingAddress()) { | 1735 if (!first_word.IsForwardingAddress()) { |
1736 // Unreachable external string can be finalized. | 1736 // Unreachable external string can be finalized. |
1737 heap->FinalizeExternalString(String::cast(*p)); | 1737 String* string = String::cast(*p); |
| 1738 if (!string->IsExternalString()) { |
| 1739 // Original external string has been internalized. |
| 1740 DCHECK(string->IsThinString()); |
| 1741 return NULL; |
| 1742 } |
| 1743 heap->FinalizeExternalString(string); |
1738 return NULL; | 1744 return NULL; |
1739 } | 1745 } |
1740 | 1746 |
1741 // String is still reachable. | 1747 // String is still reachable. |
1742 return String::cast(first_word.ToForwardingAddress()); | 1748 String* string = String::cast(first_word.ToForwardingAddress()); |
| 1749 if (string->IsThinString()) string = ThinString::cast(string)->actual(); |
| 1750 // Internalization can replace external strings with non-external strings. |
| 1751 return string->IsExternalString() ? string : nullptr; |
1743 } | 1752 } |
1744 | 1753 |
1745 | 1754 |
1746 void Heap::UpdateNewSpaceReferencesInExternalStringTable( | 1755 void Heap::UpdateNewSpaceReferencesInExternalStringTable( |
1747 ExternalStringTableUpdaterCallback updater_func) { | 1756 ExternalStringTableUpdaterCallback updater_func) { |
1748 if (external_string_table_.new_space_strings_.is_empty()) return; | 1757 if (external_string_table_.new_space_strings_.is_empty()) return; |
1749 | 1758 |
1750 Object** start = &external_string_table_.new_space_strings_[0]; | 1759 Object** start = &external_string_table_.new_space_strings_[0]; |
1751 Object** end = start + external_string_table_.new_space_strings_.length(); | 1760 Object** end = start + external_string_table_.new_space_strings_.length(); |
1752 Object** last = start; | 1761 Object** last = start; |
(...skipping 4592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6345 void Heap::UpdateTotalGCTime(double duration) { | 6354 void Heap::UpdateTotalGCTime(double duration) { |
6346 if (FLAG_trace_gc_verbose) { | 6355 if (FLAG_trace_gc_verbose) { |
6347 total_gc_time_ms_ += duration; | 6356 total_gc_time_ms_ += duration; |
6348 } | 6357 } |
6349 } | 6358 } |
6350 | 6359 |
6351 void Heap::ExternalStringTable::CleanUpNewSpaceStrings() { | 6360 void Heap::ExternalStringTable::CleanUpNewSpaceStrings() { |
6352 int last = 0; | 6361 int last = 0; |
6353 Isolate* isolate = heap_->isolate(); | 6362 Isolate* isolate = heap_->isolate(); |
6354 for (int i = 0; i < new_space_strings_.length(); ++i) { | 6363 for (int i = 0; i < new_space_strings_.length(); ++i) { |
6355 if (new_space_strings_[i]->IsTheHole(isolate)) { | 6364 Object* o = new_space_strings_[i]; |
| 6365 if (o->IsTheHole(isolate)) { |
6356 continue; | 6366 continue; |
6357 } | 6367 } |
6358 DCHECK(new_space_strings_[i]->IsExternalString()); | 6368 if (o->IsThinString()) { |
6359 if (heap_->InNewSpace(new_space_strings_[i])) { | 6369 o = ThinString::cast(o)->actual(); |
6360 new_space_strings_[last++] = new_space_strings_[i]; | 6370 if (!o->IsExternalString()) continue; |
| 6371 } |
| 6372 DCHECK(o->IsExternalString()); |
| 6373 if (heap_->InNewSpace(o)) { |
| 6374 new_space_strings_[last++] = o; |
6361 } else { | 6375 } else { |
6362 old_space_strings_.Add(new_space_strings_[i]); | 6376 old_space_strings_.Add(o); |
6363 } | 6377 } |
6364 } | 6378 } |
6365 new_space_strings_.Rewind(last); | 6379 new_space_strings_.Rewind(last); |
6366 new_space_strings_.Trim(); | 6380 new_space_strings_.Trim(); |
6367 } | 6381 } |
6368 | 6382 |
6369 void Heap::ExternalStringTable::CleanUpAll() { | 6383 void Heap::ExternalStringTable::CleanUpAll() { |
6370 CleanUpNewSpaceStrings(); | 6384 CleanUpNewSpaceStrings(); |
6371 int last = 0; | 6385 int last = 0; |
6372 Isolate* isolate = heap_->isolate(); | 6386 Isolate* isolate = heap_->isolate(); |
6373 for (int i = 0; i < old_space_strings_.length(); ++i) { | 6387 for (int i = 0; i < old_space_strings_.length(); ++i) { |
6374 if (old_space_strings_[i]->IsTheHole(isolate)) { | 6388 Object* o = old_space_strings_[i]; |
| 6389 if (o->IsTheHole(isolate)) { |
6375 continue; | 6390 continue; |
6376 } | 6391 } |
6377 DCHECK(old_space_strings_[i]->IsExternalString()); | 6392 if (o->IsThinString()) { |
6378 DCHECK(!heap_->InNewSpace(old_space_strings_[i])); | 6393 o = ThinString::cast(o)->actual(); |
6379 old_space_strings_[last++] = old_space_strings_[i]; | 6394 if (!o->IsExternalString()) continue; |
| 6395 } |
| 6396 DCHECK(o->IsExternalString()); |
| 6397 DCHECK(!heap_->InNewSpace(o)); |
| 6398 old_space_strings_[last++] = o; |
6380 } | 6399 } |
6381 old_space_strings_.Rewind(last); | 6400 old_space_strings_.Rewind(last); |
6382 old_space_strings_.Trim(); | 6401 old_space_strings_.Trim(); |
6383 #ifdef VERIFY_HEAP | 6402 #ifdef VERIFY_HEAP |
6384 if (FLAG_verify_heap) { | 6403 if (FLAG_verify_heap) { |
6385 Verify(); | 6404 Verify(); |
6386 } | 6405 } |
6387 #endif | 6406 #endif |
6388 } | 6407 } |
6389 | 6408 |
6390 void Heap::ExternalStringTable::TearDown() { | 6409 void Heap::ExternalStringTable::TearDown() { |
6391 for (int i = 0; i < new_space_strings_.length(); ++i) { | 6410 for (int i = 0; i < new_space_strings_.length(); ++i) { |
6392 heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i])); | 6411 Object* o = new_space_strings_[i]; |
| 6412 if (o->IsThinString()) { |
| 6413 o = ThinString::cast(o)->actual(); |
| 6414 if (!o->IsExternalString()) continue; |
| 6415 } |
| 6416 heap_->FinalizeExternalString(ExternalString::cast(o)); |
6393 } | 6417 } |
6394 new_space_strings_.Free(); | 6418 new_space_strings_.Free(); |
6395 for (int i = 0; i < old_space_strings_.length(); ++i) { | 6419 for (int i = 0; i < old_space_strings_.length(); ++i) { |
6396 heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i])); | 6420 Object* o = old_space_strings_[i]; |
| 6421 if (o->IsThinString()) { |
| 6422 o = ThinString::cast(o)->actual(); |
| 6423 if (!o->IsExternalString()) continue; |
| 6424 } |
| 6425 heap_->FinalizeExternalString(ExternalString::cast(o)); |
6397 } | 6426 } |
6398 old_space_strings_.Free(); | 6427 old_space_strings_.Free(); |
6399 } | 6428 } |
6400 | 6429 |
6401 | 6430 |
6402 void Heap::RememberUnmappedPage(Address page, bool compacted) { | 6431 void Heap::RememberUnmappedPage(Address page, bool compacted) { |
6403 uintptr_t p = reinterpret_cast<uintptr_t>(page); | 6432 uintptr_t p = reinterpret_cast<uintptr_t>(page); |
6404 // Tag the page pointer to make it findable in the dump file. | 6433 // Tag the page pointer to make it findable in the dump file. |
6405 if (compacted) { | 6434 if (compacted) { |
6406 p ^= 0xc1ead & (Page::kPageSize - 1); // Cleared. | 6435 p ^= 0xc1ead & (Page::kPageSize - 1); // Cleared. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6501 } | 6530 } |
6502 | 6531 |
6503 | 6532 |
6504 // static | 6533 // static |
6505 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6534 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6506 return StaticVisitorBase::GetVisitorId(map); | 6535 return StaticVisitorBase::GetVisitorId(map); |
6507 } | 6536 } |
6508 | 6537 |
6509 } // namespace internal | 6538 } // namespace internal |
6510 } // namespace v8 | 6539 } // namespace v8 |
OLD | NEW |