OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 if (FLAG_log_gc) new_space_.ReportStatistics(); | 397 if (FLAG_log_gc) new_space_.ReportStatistics(); |
398 #endif // DEBUG | 398 #endif // DEBUG |
399 } | 399 } |
400 | 400 |
401 | 401 |
402 void Heap::GarbageCollectionPrologue() { | 402 void Heap::GarbageCollectionPrologue() { |
403 isolate_->transcendental_cache()->Clear(); | 403 isolate_->transcendental_cache()->Clear(); |
404 ClearJSFunctionResultCaches(); | 404 ClearJSFunctionResultCaches(); |
405 gc_count_++; | 405 gc_count_++; |
406 unflattened_strings_length_ = 0; | 406 unflattened_strings_length_ = 0; |
| 407 |
| 408 #ifdef VERIFY_HEAP |
| 409 if (FLAG_verify_heap) { |
| 410 Verify(); |
| 411 } |
| 412 #endif |
| 413 |
407 #ifdef DEBUG | 414 #ifdef DEBUG |
408 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); | 415 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); |
409 allow_allocation(false); | 416 allow_allocation(false); |
410 | 417 |
411 if (FLAG_verify_heap) { | 418 if (FLAG_gc_verbose) Print(); |
412 Verify(); | |
413 } | |
414 | 419 |
415 if (FLAG_gc_verbose) Print(); | |
416 #endif // DEBUG | |
417 | |
418 #if defined(DEBUG) | |
419 ReportStatisticsBeforeGC(); | 420 ReportStatisticsBeforeGC(); |
420 #endif // DEBUG | 421 #endif // DEBUG |
421 | 422 |
422 LiveObjectList::GCPrologue(); | 423 LiveObjectList::GCPrologue(); |
423 store_buffer()->GCPrologue(); | 424 store_buffer()->GCPrologue(); |
424 } | 425 } |
425 | 426 |
426 | 427 |
427 intptr_t Heap::SizeOfObjects() { | 428 intptr_t Heap::SizeOfObjects() { |
428 intptr_t total = 0; | 429 intptr_t total = 0; |
(...skipping 11 matching lines...) Expand all Loading... |
440 space != NULL; | 441 space != NULL; |
441 space = spaces.next()) { | 442 space = spaces.next()) { |
442 space->RepairFreeListsAfterBoot(); | 443 space->RepairFreeListsAfterBoot(); |
443 } | 444 } |
444 } | 445 } |
445 | 446 |
446 | 447 |
447 void Heap::GarbageCollectionEpilogue() { | 448 void Heap::GarbageCollectionEpilogue() { |
448 store_buffer()->GCEpilogue(); | 449 store_buffer()->GCEpilogue(); |
449 LiveObjectList::GCEpilogue(); | 450 LiveObjectList::GCEpilogue(); |
450 #ifdef DEBUG | |
451 allow_allocation(true); | |
452 ZapFromSpace(); | |
453 | 451 |
| 452 // In release mode, we only zap the from space under heap verification. |
| 453 if (Heap::ShouldZapGarbage()) { |
| 454 ZapFromSpace(); |
| 455 } |
| 456 |
| 457 #ifdef VERIFY_HEAP |
454 if (FLAG_verify_heap) { | 458 if (FLAG_verify_heap) { |
455 Verify(); | 459 Verify(); |
456 } | 460 } |
| 461 #endif |
457 | 462 |
| 463 #ifdef DEBUG |
| 464 allow_allocation(true); |
458 if (FLAG_print_global_handles) isolate_->global_handles()->Print(); | 465 if (FLAG_print_global_handles) isolate_->global_handles()->Print(); |
459 if (FLAG_print_handles) PrintHandles(); | 466 if (FLAG_print_handles) PrintHandles(); |
460 if (FLAG_gc_verbose) Print(); | 467 if (FLAG_gc_verbose) Print(); |
461 if (FLAG_code_stats) ReportCodeStatistics("After GC"); | 468 if (FLAG_code_stats) ReportCodeStatistics("After GC"); |
462 #endif | 469 #endif |
463 | 470 |
464 isolate_->counters()->alive_after_last_gc()->Set( | 471 isolate_->counters()->alive_after_last_gc()->Set( |
465 static_cast<int>(SizeOfObjects())); | 472 static_cast<int>(SizeOfObjects())); |
466 | 473 |
467 isolate_->counters()->symbol_table_capacity()->Set( | 474 isolate_->counters()->symbol_table_capacity()->Set( |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 void Heap::PerformScavenge() { | 651 void Heap::PerformScavenge() { |
645 GCTracer tracer(this, NULL, NULL); | 652 GCTracer tracer(this, NULL, NULL); |
646 if (incremental_marking()->IsStopped()) { | 653 if (incremental_marking()->IsStopped()) { |
647 PerformGarbageCollection(SCAVENGER, &tracer); | 654 PerformGarbageCollection(SCAVENGER, &tracer); |
648 } else { | 655 } else { |
649 PerformGarbageCollection(MARK_COMPACTOR, &tracer); | 656 PerformGarbageCollection(MARK_COMPACTOR, &tracer); |
650 } | 657 } |
651 } | 658 } |
652 | 659 |
653 | 660 |
654 #ifdef DEBUG | 661 #ifdef VERIFY_HEAP |
655 // Helper class for verifying the symbol table. | 662 // Helper class for verifying the symbol table. |
656 class SymbolTableVerifier : public ObjectVisitor { | 663 class SymbolTableVerifier : public ObjectVisitor { |
657 public: | 664 public: |
658 void VisitPointers(Object** start, Object** end) { | 665 void VisitPointers(Object** start, Object** end) { |
659 // Visit all HeapObject pointers in [start, end). | 666 // Visit all HeapObject pointers in [start, end). |
660 for (Object** p = start; p < end; p++) { | 667 for (Object** p = start; p < end; p++) { |
661 if ((*p)->IsHeapObject()) { | 668 if ((*p)->IsHeapObject()) { |
662 // Check that the symbol is actually a symbol. | 669 // Check that the symbol is actually a symbol. |
663 ASSERT((*p)->IsTheHole() || (*p)->IsUndefined() || (*p)->IsSymbol()); | 670 CHECK((*p)->IsTheHole() || (*p)->IsUndefined() || (*p)->IsSymbol()); |
664 } | 671 } |
665 } | 672 } |
666 } | 673 } |
667 }; | 674 }; |
668 #endif // DEBUG | |
669 | 675 |
670 | 676 |
671 static void VerifySymbolTable() { | 677 static void VerifySymbolTable() { |
672 #ifdef DEBUG | |
673 SymbolTableVerifier verifier; | 678 SymbolTableVerifier verifier; |
674 HEAP->symbol_table()->IterateElements(&verifier); | 679 HEAP->symbol_table()->IterateElements(&verifier); |
675 #endif // DEBUG | |
676 } | 680 } |
| 681 #endif // VERIFY_HEAP |
677 | 682 |
678 | 683 |
679 static bool AbortIncrementalMarkingAndCollectGarbage( | 684 static bool AbortIncrementalMarkingAndCollectGarbage( |
680 Heap* heap, | 685 Heap* heap, |
681 AllocationSpace space, | 686 AllocationSpace space, |
682 const char* gc_reason = NULL) { | 687 const char* gc_reason = NULL) { |
683 heap->mark_compact_collector()->SetFlags(Heap::kAbortIncrementalMarkingMask); | 688 heap->mark_compact_collector()->SetFlags(Heap::kAbortIncrementalMarkingMask); |
684 bool result = heap->CollectGarbage(space, gc_reason); | 689 bool result = heap->CollectGarbage(space, gc_reason); |
685 heap->mark_compact_collector()->SetFlags(Heap::kNoGCFlags); | 690 heap->mark_compact_collector()->SetFlags(Heap::kNoGCFlags); |
686 return result; | 691 return result; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 } | 828 } |
824 | 829 |
825 bool Heap::PerformGarbageCollection(GarbageCollector collector, | 830 bool Heap::PerformGarbageCollection(GarbageCollector collector, |
826 GCTracer* tracer) { | 831 GCTracer* tracer) { |
827 bool next_gc_likely_to_collect_more = false; | 832 bool next_gc_likely_to_collect_more = false; |
828 | 833 |
829 if (collector != SCAVENGER) { | 834 if (collector != SCAVENGER) { |
830 PROFILE(isolate_, CodeMovingGCEvent()); | 835 PROFILE(isolate_, CodeMovingGCEvent()); |
831 } | 836 } |
832 | 837 |
| 838 #ifdef VERIFY_HEAP |
833 if (FLAG_verify_heap) { | 839 if (FLAG_verify_heap) { |
834 VerifySymbolTable(); | 840 VerifySymbolTable(); |
835 } | 841 } |
| 842 #endif |
| 843 |
836 if (collector == MARK_COMPACTOR && global_gc_prologue_callback_) { | 844 if (collector == MARK_COMPACTOR && global_gc_prologue_callback_) { |
837 ASSERT(!allocation_allowed_); | 845 ASSERT(!allocation_allowed_); |
838 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 846 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
839 global_gc_prologue_callback_(); | 847 global_gc_prologue_callback_(); |
840 } | 848 } |
841 | 849 |
842 GCType gc_type = | 850 GCType gc_type = |
843 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; | 851 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; |
844 | 852 |
845 for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) { | 853 for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 if (gc_type & gc_epilogue_callbacks_[i].gc_type) { | 960 if (gc_type & gc_epilogue_callbacks_[i].gc_type) { |
953 gc_epilogue_callbacks_[i].callback(gc_type, callback_flags); | 961 gc_epilogue_callbacks_[i].callback(gc_type, callback_flags); |
954 } | 962 } |
955 } | 963 } |
956 | 964 |
957 if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) { | 965 if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) { |
958 ASSERT(!allocation_allowed_); | 966 ASSERT(!allocation_allowed_); |
959 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 967 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
960 global_gc_epilogue_callback_(); | 968 global_gc_epilogue_callback_(); |
961 } | 969 } |
| 970 |
| 971 #ifdef VERIFY_HEAP |
962 if (FLAG_verify_heap) { | 972 if (FLAG_verify_heap) { |
963 VerifySymbolTable(); | 973 VerifySymbolTable(); |
964 } | 974 } |
| 975 #endif |
965 | 976 |
966 return next_gc_likely_to_collect_more; | 977 return next_gc_likely_to_collect_more; |
967 } | 978 } |
968 | 979 |
969 | 980 |
970 void Heap::MarkCompact(GCTracer* tracer) { | 981 void Heap::MarkCompact(GCTracer* tracer) { |
971 gc_state_ = MARK_COMPACT; | 982 gc_state_ = MARK_COMPACT; |
972 LOG(isolate_, ResourceEvent("markcompact", "begin")); | 983 LOG(isolate_, ResourceEvent("markcompact", "begin")); |
973 | 984 |
974 mark_compact_collector_.Prepare(tracer); | 985 mark_compact_collector_.Prepare(tracer); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 Object* object = *p; | 1048 Object* object = *p; |
1038 if (!heap_->InNewSpace(object)) return; | 1049 if (!heap_->InNewSpace(object)) return; |
1039 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), | 1050 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), |
1040 reinterpret_cast<HeapObject*>(object)); | 1051 reinterpret_cast<HeapObject*>(object)); |
1041 } | 1052 } |
1042 | 1053 |
1043 Heap* heap_; | 1054 Heap* heap_; |
1044 }; | 1055 }; |
1045 | 1056 |
1046 | 1057 |
1047 #ifdef DEBUG | 1058 #ifdef VERIFY_HEAP |
1048 // Visitor class to verify pointers in code or data space do not point into | 1059 // Visitor class to verify pointers in code or data space do not point into |
1049 // new space. | 1060 // new space. |
1050 class VerifyNonPointerSpacePointersVisitor: public ObjectVisitor { | 1061 class VerifyNonPointerSpacePointersVisitor: public ObjectVisitor { |
1051 public: | 1062 public: |
1052 void VisitPointers(Object** start, Object**end) { | 1063 void VisitPointers(Object** start, Object**end) { |
1053 for (Object** current = start; current < end; current++) { | 1064 for (Object** current = start; current < end; current++) { |
1054 if ((*current)->IsHeapObject()) { | 1065 if ((*current)->IsHeapObject()) { |
1055 ASSERT(!HEAP->InNewSpace(HeapObject::cast(*current))); | 1066 CHECK(!HEAP->InNewSpace(HeapObject::cast(*current))); |
1056 } | 1067 } |
1057 } | 1068 } |
1058 } | 1069 } |
1059 }; | 1070 }; |
1060 | 1071 |
1061 | 1072 |
1062 static void VerifyNonPointerSpacePointers() { | 1073 static void VerifyNonPointerSpacePointers() { |
1063 // Verify that there are no pointers to new space in spaces where we | 1074 // Verify that there are no pointers to new space in spaces where we |
1064 // do not expect them. | 1075 // do not expect them. |
1065 VerifyNonPointerSpacePointersVisitor v; | 1076 VerifyNonPointerSpacePointersVisitor v; |
1066 HeapObjectIterator code_it(HEAP->code_space()); | 1077 HeapObjectIterator code_it(HEAP->code_space()); |
1067 for (HeapObject* object = code_it.Next(); | 1078 for (HeapObject* object = code_it.Next(); |
1068 object != NULL; object = code_it.Next()) | 1079 object != NULL; object = code_it.Next()) |
1069 object->Iterate(&v); | 1080 object->Iterate(&v); |
1070 | 1081 |
1071 // The old data space was normally swept conservatively so that the iterator | 1082 // The old data space was normally swept conservatively so that the iterator |
1072 // doesn't work, so we normally skip the next bit. | 1083 // doesn't work, so we normally skip the next bit. |
1073 if (!HEAP->old_data_space()->was_swept_conservatively()) { | 1084 if (!HEAP->old_data_space()->was_swept_conservatively()) { |
1074 HeapObjectIterator data_it(HEAP->old_data_space()); | 1085 HeapObjectIterator data_it(HEAP->old_data_space()); |
1075 for (HeapObject* object = data_it.Next(); | 1086 for (HeapObject* object = data_it.Next(); |
1076 object != NULL; object = data_it.Next()) | 1087 object != NULL; object = data_it.Next()) |
1077 object->Iterate(&v); | 1088 object->Iterate(&v); |
1078 } | 1089 } |
1079 } | 1090 } |
1080 #endif | 1091 #endif // VERIFY_HEAP |
1081 | 1092 |
1082 | 1093 |
1083 void Heap::CheckNewSpaceExpansionCriteria() { | 1094 void Heap::CheckNewSpaceExpansionCriteria() { |
1084 if (new_space_.Capacity() < new_space_.MaximumCapacity() && | 1095 if (new_space_.Capacity() < new_space_.MaximumCapacity() && |
1085 survived_since_last_expansion_ > new_space_.Capacity() && | 1096 survived_since_last_expansion_ > new_space_.Capacity() && |
1086 !new_space_high_promotion_mode_active_) { | 1097 !new_space_high_promotion_mode_active_) { |
1087 // Grow the size of new space if there is room to grow, enough data | 1098 // Grow the size of new space if there is room to grow, enough data |
1088 // has survived scavenge since the last expansion and we are not in | 1099 // has survived scavenge since the last expansion and we are not in |
1089 // high promotion mode. | 1100 // high promotion mode. |
1090 new_space_.Grow(); | 1101 new_space_.Grow(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1209 return NULL; | 1220 return NULL; |
1210 } | 1221 } |
1211 | 1222 |
1212 private: | 1223 private: |
1213 Heap* heap_; | 1224 Heap* heap_; |
1214 }; | 1225 }; |
1215 | 1226 |
1216 | 1227 |
1217 void Heap::Scavenge() { | 1228 void Heap::Scavenge() { |
1218 RelocationLock relocation_lock(this); | 1229 RelocationLock relocation_lock(this); |
1219 #ifdef DEBUG | 1230 |
| 1231 #ifdef VERIFY_HEAP |
1220 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); | 1232 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); |
1221 #endif | 1233 #endif |
1222 | 1234 |
1223 gc_state_ = SCAVENGE; | 1235 gc_state_ = SCAVENGE; |
1224 | 1236 |
1225 // Implements Cheney's copying algorithm | 1237 // Implements Cheney's copying algorithm |
1226 LOG(isolate_, ResourceEvent("scavenge", "begin")); | 1238 LOG(isolate_, ResourceEvent("scavenge", "begin")); |
1227 | 1239 |
1228 // Clear descriptor cache. | 1240 // Clear descriptor cache. |
1229 isolate_->descriptor_lookup_cache()->Clear(); | 1241 isolate_->descriptor_lookup_cache()->Clear(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1346 return NULL; | 1358 return NULL; |
1347 } | 1359 } |
1348 | 1360 |
1349 // String is still reachable. | 1361 // String is still reachable. |
1350 return String::cast(first_word.ToForwardingAddress()); | 1362 return String::cast(first_word.ToForwardingAddress()); |
1351 } | 1363 } |
1352 | 1364 |
1353 | 1365 |
1354 void Heap::UpdateNewSpaceReferencesInExternalStringTable( | 1366 void Heap::UpdateNewSpaceReferencesInExternalStringTable( |
1355 ExternalStringTableUpdaterCallback updater_func) { | 1367 ExternalStringTableUpdaterCallback updater_func) { |
| 1368 #ifdef VERIFY_HEAP |
1356 if (FLAG_verify_heap) { | 1369 if (FLAG_verify_heap) { |
1357 external_string_table_.Verify(); | 1370 external_string_table_.Verify(); |
1358 } | 1371 } |
| 1372 #endif |
1359 | 1373 |
1360 if (external_string_table_.new_space_strings_.is_empty()) return; | 1374 if (external_string_table_.new_space_strings_.is_empty()) return; |
1361 | 1375 |
1362 Object** start = &external_string_table_.new_space_strings_[0]; | 1376 Object** start = &external_string_table_.new_space_strings_[0]; |
1363 Object** end = start + external_string_table_.new_space_strings_.length(); | 1377 Object** end = start + external_string_table_.new_space_strings_.length(); |
1364 Object** last = start; | 1378 Object** last = start; |
1365 | 1379 |
1366 for (Object** p = start; p < end; ++p) { | 1380 for (Object** p = start; p < end; ++p) { |
1367 ASSERT(InFromSpace(*p)); | 1381 ASSERT(InFromSpace(*p)); |
1368 String* target = updater_func(this, p); | 1382 String* target = updater_func(this, p); |
(...skipping 2002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3371 String::WriteToFlat(buffer, dest, start, end); | 3385 String::WriteToFlat(buffer, dest, start, end); |
3372 } else { | 3386 } else { |
3373 ASSERT(string_result->IsTwoByteRepresentation()); | 3387 ASSERT(string_result->IsTwoByteRepresentation()); |
3374 uc16* dest = SeqTwoByteString::cast(string_result)->GetChars(); | 3388 uc16* dest = SeqTwoByteString::cast(string_result)->GetChars(); |
3375 String::WriteToFlat(buffer, dest, start, end); | 3389 String::WriteToFlat(buffer, dest, start, end); |
3376 } | 3390 } |
3377 return result; | 3391 return result; |
3378 } | 3392 } |
3379 | 3393 |
3380 ASSERT(buffer->IsFlat()); | 3394 ASSERT(buffer->IsFlat()); |
3381 #if DEBUG | 3395 #if VERIFY_HEAP |
3382 if (FLAG_verify_heap) { | 3396 if (FLAG_verify_heap) { |
3383 buffer->StringVerify(); | 3397 buffer->StringVerify(); |
3384 } | 3398 } |
3385 #endif | 3399 #endif |
3386 | 3400 |
3387 Object* result; | 3401 Object* result; |
3388 // When slicing an indirect string we use its encoding for a newly created | 3402 // When slicing an indirect string we use its encoding for a newly created |
3389 // slice and don't check the encoding of the underlying string. This is safe | 3403 // slice and don't check the encoding of the underlying string. This is safe |
3390 // even if the encodings are different because of externalization. If an | 3404 // even if the encodings are different because of externalization. If an |
3391 // indirect ASCII string is pointing to a two-byte string, the two-byte char | 3405 // indirect ASCII string is pointing to a two-byte string, the two-byte char |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3635 if (!self_reference.is_null()) { | 3649 if (!self_reference.is_null()) { |
3636 *(self_reference.location()) = code; | 3650 *(self_reference.location()) = code; |
3637 } | 3651 } |
3638 // Migrate generated code. | 3652 // Migrate generated code. |
3639 // The generated code can contain Object** values (typically from handles) | 3653 // The generated code can contain Object** values (typically from handles) |
3640 // that are dereferenced during the copy to point directly to the actual heap | 3654 // that are dereferenced during the copy to point directly to the actual heap |
3641 // objects. These pointers can include references to the code object itself, | 3655 // objects. These pointers can include references to the code object itself, |
3642 // through the self_reference parameter. | 3656 // through the self_reference parameter. |
3643 code->CopyFrom(desc); | 3657 code->CopyFrom(desc); |
3644 | 3658 |
3645 #ifdef DEBUG | 3659 #ifdef VERIFY_HEAP |
3646 if (FLAG_verify_heap) { | 3660 if (FLAG_verify_heap) { |
3647 code->Verify(); | 3661 code->Verify(); |
3648 } | 3662 } |
3649 #endif | 3663 #endif |
3650 return code; | 3664 return code; |
3651 } | 3665 } |
3652 | 3666 |
3653 | 3667 |
3654 MaybeObject* Heap::CopyCode(Code* code) { | 3668 MaybeObject* Heap::CopyCode(Code* code) { |
3655 // Allocate an object the same size as the code object. | 3669 // Allocate an object the same size as the code object. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3717 new_code->set_relocation_info(ByteArray::cast(reloc_info_array)); | 3731 new_code->set_relocation_info(ByteArray::cast(reloc_info_array)); |
3718 | 3732 |
3719 // Copy patched rinfo. | 3733 // Copy patched rinfo. |
3720 memcpy(new_code->relocation_start(), reloc_info.start(), reloc_info.length()); | 3734 memcpy(new_code->relocation_start(), reloc_info.start(), reloc_info.length()); |
3721 | 3735 |
3722 // Relocate the copy. | 3736 // Relocate the copy. |
3723 ASSERT(!isolate_->code_range()->exists() || | 3737 ASSERT(!isolate_->code_range()->exists() || |
3724 isolate_->code_range()->contains(code->address())); | 3738 isolate_->code_range()->contains(code->address())); |
3725 new_code->Relocate(new_addr - old_addr); | 3739 new_code->Relocate(new_addr - old_addr); |
3726 | 3740 |
3727 #ifdef DEBUG | 3741 #ifdef VERIFY_HEAP |
3728 if (FLAG_verify_heap) { | 3742 if (FLAG_verify_heap) { |
3729 code->Verify(); | 3743 code->Verify(); |
3730 } | 3744 } |
3731 #endif | 3745 #endif |
3732 return new_code; | 3746 return new_code; |
3733 } | 3747 } |
3734 | 3748 |
3735 | 3749 |
3736 MaybeObject* Heap::Allocate(Map* map, AllocationSpace space) { | 3750 MaybeObject* Heap::Allocate(Map* map, AllocationSpace space) { |
3737 ASSERT(gc_state_ == NOT_IN_GC); | 3751 ASSERT(gc_state_ == NOT_IN_GC); |
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4590 { MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); | 4604 { MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); |
4591 if (!maybe_result->ToObject(&result)) return maybe_result; | 4605 if (!maybe_result->ToObject(&result)) return maybe_result; |
4592 } | 4606 } |
4593 | 4607 |
4594 // Partially initialize the object. | 4608 // Partially initialize the object. |
4595 HeapObject::cast(result)->set_map_no_write_barrier(ascii_string_map()); | 4609 HeapObject::cast(result)->set_map_no_write_barrier(ascii_string_map()); |
4596 String::cast(result)->set_length(length); | 4610 String::cast(result)->set_length(length); |
4597 String::cast(result)->set_hash_field(String::kEmptyHashField); | 4611 String::cast(result)->set_hash_field(String::kEmptyHashField); |
4598 ASSERT_EQ(size, HeapObject::cast(result)->Size()); | 4612 ASSERT_EQ(size, HeapObject::cast(result)->Size()); |
4599 | 4613 |
4600 #ifdef DEBUG | 4614 #ifdef VERIFY_HEAP |
4601 if (FLAG_verify_heap) { | 4615 if (FLAG_verify_heap) { |
4602 // Initialize string's content to ensure ASCII-ness (character range 0-127) | 4616 // Initialize string's content to ensure ASCII-ness (character range 0-127) |
4603 // as required when verifying the heap. | 4617 // as required when verifying the heap. |
4604 char* dest = SeqAsciiString::cast(result)->GetChars(); | 4618 char* dest = SeqAsciiString::cast(result)->GetChars(); |
4605 memset(dest, 0x0F, length * kCharSize); | 4619 memset(dest, 0x0F, length * kCharSize); |
4606 } | 4620 } |
4607 #endif // DEBUG | 4621 #endif |
4608 | 4622 |
4609 return result; | 4623 return result; |
4610 } | 4624 } |
4611 | 4625 |
4612 | 4626 |
4613 MaybeObject* Heap::AllocateRawTwoByteString(int length, | 4627 MaybeObject* Heap::AllocateRawTwoByteString(int length, |
4614 PretenureFlag pretenure) { | 4628 PretenureFlag pretenure) { |
4615 if (length < 0 || length > SeqTwoByteString::kMaxLength) { | 4629 if (length < 0 || length > SeqTwoByteString::kMaxLength) { |
4616 return Failure::OutOfMemoryException(); | 4630 return Failure::OutOfMemoryException(); |
4617 } | 4631 } |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5387 case CELL_SPACE: | 5401 case CELL_SPACE: |
5388 return cell_space_->Contains(addr); | 5402 return cell_space_->Contains(addr); |
5389 case LO_SPACE: | 5403 case LO_SPACE: |
5390 return lo_space_->SlowContains(addr); | 5404 return lo_space_->SlowContains(addr); |
5391 } | 5405 } |
5392 | 5406 |
5393 return false; | 5407 return false; |
5394 } | 5408 } |
5395 | 5409 |
5396 | 5410 |
5397 #ifdef DEBUG | 5411 #ifdef VERIFY_HEAP |
5398 void Heap::Verify() { | 5412 void Heap::Verify() { |
5399 ASSERT(HasBeenSetUp()); | 5413 CHECK(HasBeenSetUp()); |
5400 | 5414 |
5401 store_buffer()->Verify(); | 5415 store_buffer()->Verify(); |
5402 | 5416 |
5403 VerifyPointersVisitor visitor; | 5417 VerifyPointersVisitor visitor; |
5404 IterateRoots(&visitor, VISIT_ONLY_STRONG); | 5418 IterateRoots(&visitor, VISIT_ONLY_STRONG); |
5405 | 5419 |
5406 new_space_.Verify(); | 5420 new_space_.Verify(); |
5407 | 5421 |
5408 old_pointer_space_->Verify(&visitor); | 5422 old_pointer_space_->Verify(&visitor); |
5409 map_space_->Verify(&visitor); | 5423 map_space_->Verify(&visitor); |
5410 | 5424 |
5411 VerifyPointersVisitor no_dirty_regions_visitor; | 5425 VerifyPointersVisitor no_dirty_regions_visitor; |
5412 old_data_space_->Verify(&no_dirty_regions_visitor); | 5426 old_data_space_->Verify(&no_dirty_regions_visitor); |
5413 code_space_->Verify(&no_dirty_regions_visitor); | 5427 code_space_->Verify(&no_dirty_regions_visitor); |
5414 cell_space_->Verify(&no_dirty_regions_visitor); | 5428 cell_space_->Verify(&no_dirty_regions_visitor); |
5415 | 5429 |
5416 lo_space_->Verify(); | 5430 lo_space_->Verify(); |
5417 } | 5431 } |
5418 | 5432 #endif |
5419 | |
5420 #endif // DEBUG | |
5421 | 5433 |
5422 | 5434 |
5423 MaybeObject* Heap::LookupSymbol(Vector<const char> string) { | 5435 MaybeObject* Heap::LookupSymbol(Vector<const char> string) { |
5424 Object* symbol = NULL; | 5436 Object* symbol = NULL; |
5425 Object* new_table; | 5437 Object* new_table; |
5426 { MaybeObject* maybe_new_table = | 5438 { MaybeObject* maybe_new_table = |
5427 symbol_table()->LookupSymbol(string, &symbol); | 5439 symbol_table()->LookupSymbol(string, &symbol); |
5428 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 5440 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
5429 } | 5441 } |
5430 // Can't use set_symbol_table because SymbolTable::cast knows that | 5442 // Can't use set_symbol_table because SymbolTable::cast knows that |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5502 | 5514 |
5503 | 5515 |
5504 bool Heap::LookupSymbolIfExists(String* string, String** symbol) { | 5516 bool Heap::LookupSymbolIfExists(String* string, String** symbol) { |
5505 if (string->IsSymbol()) { | 5517 if (string->IsSymbol()) { |
5506 *symbol = string; | 5518 *symbol = string; |
5507 return true; | 5519 return true; |
5508 } | 5520 } |
5509 return symbol_table()->LookupSymbolIfExists(string, symbol); | 5521 return symbol_table()->LookupSymbolIfExists(string, symbol); |
5510 } | 5522 } |
5511 | 5523 |
5512 | |
5513 #ifdef DEBUG | |
5514 void Heap::ZapFromSpace() { | 5524 void Heap::ZapFromSpace() { |
5515 NewSpacePageIterator it(new_space_.FromSpaceStart(), | 5525 NewSpacePageIterator it(new_space_.FromSpaceStart(), |
5516 new_space_.FromSpaceEnd()); | 5526 new_space_.FromSpaceEnd()); |
5517 while (it.has_next()) { | 5527 while (it.has_next()) { |
5518 NewSpacePage* page = it.next(); | 5528 NewSpacePage* page = it.next(); |
5519 for (Address cursor = page->area_start(), limit = page->area_end(); | 5529 for (Address cursor = page->area_start(), limit = page->area_end(); |
5520 cursor < limit; | 5530 cursor < limit; |
5521 cursor += kPointerSize) { | 5531 cursor += kPointerSize) { |
5522 Memory::Address_at(cursor) = kFromSpaceZapValue; | 5532 Memory::Address_at(cursor) = kFromSpaceZapValue; |
5523 } | 5533 } |
5524 } | 5534 } |
5525 } | 5535 } |
5526 #endif // DEBUG | |
5527 | 5536 |
5528 | 5537 |
5529 void Heap::IterateAndMarkPointersToFromSpace(Address start, | 5538 void Heap::IterateAndMarkPointersToFromSpace(Address start, |
5530 Address end, | 5539 Address end, |
5531 ObjectSlotCallback callback) { | 5540 ObjectSlotCallback callback) { |
5532 Address slot_address = start; | 5541 Address slot_address = start; |
5533 | 5542 |
5534 // We are not collecting slots on new space objects during mutation | 5543 // We are not collecting slots on new space objects during mutation |
5535 // thus we have to scan for pointers to evacuation candidates when we | 5544 // thus we have to scan for pointers to evacuation candidates when we |
5536 // promote objects. But we should not record any slots in non-black | 5545 // promote objects. But we should not record any slots in non-black |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6253 roots_[kStackLimitRootIndex] = | 6262 roots_[kStackLimitRootIndex] = |
6254 reinterpret_cast<Object*>( | 6263 reinterpret_cast<Object*>( |
6255 (isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag); | 6264 (isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag); |
6256 roots_[kRealStackLimitRootIndex] = | 6265 roots_[kRealStackLimitRootIndex] = |
6257 reinterpret_cast<Object*>( | 6266 reinterpret_cast<Object*>( |
6258 (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag); | 6267 (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag); |
6259 } | 6268 } |
6260 | 6269 |
6261 | 6270 |
6262 void Heap::TearDown() { | 6271 void Heap::TearDown() { |
6263 #ifdef DEBUG | 6272 #ifdef VERIFY_HEAP |
6264 if (FLAG_verify_heap) { | 6273 if (FLAG_verify_heap) { |
6265 Verify(); | 6274 Verify(); |
6266 } | 6275 } |
6267 #endif | 6276 #endif |
| 6277 |
6268 if (FLAG_print_cumulative_gc_stat) { | 6278 if (FLAG_print_cumulative_gc_stat) { |
6269 PrintF("\n\n"); | 6279 PrintF("\n\n"); |
6270 PrintF("gc_count=%d ", gc_count_); | 6280 PrintF("gc_count=%d ", gc_count_); |
6271 PrintF("mark_sweep_count=%d ", ms_count_); | 6281 PrintF("mark_sweep_count=%d ", ms_count_); |
6272 PrintF("max_gc_pause=%d ", get_max_gc_pause()); | 6282 PrintF("max_gc_pause=%d ", get_max_gc_pause()); |
6273 PrintF("total_gc_time=%d ", total_gc_time_ms_); | 6283 PrintF("total_gc_time=%d ", total_gc_time_ms_); |
6274 PrintF("min_in_mutator=%d ", get_min_in_mutator()); | 6284 PrintF("min_in_mutator=%d ", get_min_in_mutator()); |
6275 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", | 6285 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", |
6276 get_max_alive_after_gc()); | 6286 get_max_alive_after_gc()); |
6277 PrintF("\n\n"); | 6287 PrintF("\n\n"); |
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7187 new_space_strings_.Rewind(last); | 7197 new_space_strings_.Rewind(last); |
7188 last = 0; | 7198 last = 0; |
7189 for (int i = 0; i < old_space_strings_.length(); ++i) { | 7199 for (int i = 0; i < old_space_strings_.length(); ++i) { |
7190 if (old_space_strings_[i] == heap_->raw_unchecked_the_hole_value()) { | 7200 if (old_space_strings_[i] == heap_->raw_unchecked_the_hole_value()) { |
7191 continue; | 7201 continue; |
7192 } | 7202 } |
7193 ASSERT(!heap_->InNewSpace(old_space_strings_[i])); | 7203 ASSERT(!heap_->InNewSpace(old_space_strings_[i])); |
7194 old_space_strings_[last++] = old_space_strings_[i]; | 7204 old_space_strings_[last++] = old_space_strings_[i]; |
7195 } | 7205 } |
7196 old_space_strings_.Rewind(last); | 7206 old_space_strings_.Rewind(last); |
| 7207 #ifdef VERIFY_HEAP |
7197 if (FLAG_verify_heap) { | 7208 if (FLAG_verify_heap) { |
7198 Verify(); | 7209 Verify(); |
7199 } | 7210 } |
| 7211 #endif |
7200 } | 7212 } |
7201 | 7213 |
7202 | 7214 |
7203 void ExternalStringTable::TearDown() { | 7215 void ExternalStringTable::TearDown() { |
7204 new_space_strings_.Free(); | 7216 new_space_strings_.Free(); |
7205 old_space_strings_.Free(); | 7217 old_space_strings_.Free(); |
7206 } | 7218 } |
7207 | 7219 |
7208 | 7220 |
7209 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { | 7221 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7327 static_cast<int>(object_sizes_last_time_[index])); | 7339 static_cast<int>(object_sizes_last_time_[index])); |
7328 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) | 7340 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) |
7329 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7341 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
7330 | 7342 |
7331 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7343 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
7332 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7344 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
7333 ClearObjectStats(); | 7345 ClearObjectStats(); |
7334 } | 7346 } |
7335 | 7347 |
7336 } } // namespace v8::internal | 7348 } } // namespace v8::internal |
OLD | NEW |