| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 return false; | 367 return false; |
| 368 } | 368 } |
| 369 | 369 |
| 370 | 370 |
| 371 void Heap::PerformScavenge() { | 371 void Heap::PerformScavenge() { |
| 372 GCTracer tracer; | 372 GCTracer tracer; |
| 373 PerformGarbageCollection(NEW_SPACE, SCAVENGER, &tracer); | 373 PerformGarbageCollection(NEW_SPACE, SCAVENGER, &tracer); |
| 374 } | 374 } |
| 375 | 375 |
| 376 | 376 |
| 377 static void VerifySymbolTable() { |
| 378 #ifdef DEBUG |
| 379 // Helper class for verifying the symbol table. |
| 380 class SymbolTableVerifier : public ObjectVisitor { |
| 381 public: |
| 382 SymbolTableVerifier() { } |
| 383 void VisitPointers(Object** start, Object** end) { |
| 384 // Visit all HeapObject pointers in [start, end). |
| 385 for (Object** p = start; p < end; p++) { |
| 386 if ((*p)->IsHeapObject()) { |
| 387 // Check that the symbol is actually a symbol. |
| 388 ASSERT((*p)->IsNull() || (*p)->IsUndefined() || (*p)->IsSymbol()); |
| 389 } |
| 390 } |
| 391 } |
| 392 }; |
| 393 |
| 394 SymbolTableVerifier verifier; |
| 395 SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table()); |
| 396 symbol_table->IterateElements(&verifier); |
| 397 #endif // DEBUG |
| 398 } |
| 399 |
| 400 |
| 377 void Heap::PerformGarbageCollection(AllocationSpace space, | 401 void Heap::PerformGarbageCollection(AllocationSpace space, |
| 378 GarbageCollector collector, | 402 GarbageCollector collector, |
| 379 GCTracer* tracer) { | 403 GCTracer* tracer) { |
| 404 VerifySymbolTable(); |
| 380 if (collector == MARK_COMPACTOR && global_gc_prologue_callback_) { | 405 if (collector == MARK_COMPACTOR && global_gc_prologue_callback_) { |
| 381 ASSERT(!allocation_allowed_); | 406 ASSERT(!allocation_allowed_); |
| 382 global_gc_prologue_callback_(); | 407 global_gc_prologue_callback_(); |
| 383 } | 408 } |
| 384 | 409 |
| 385 if (collector == MARK_COMPACTOR) { | 410 if (collector == MARK_COMPACTOR) { |
| 386 MarkCompact(tracer); | 411 MarkCompact(tracer); |
| 387 | 412 |
| 388 int old_gen_size = PromotedSpaceSize(); | 413 int old_gen_size = PromotedSpaceSize(); |
| 389 old_gen_promotion_limit_ = | 414 old_gen_promotion_limit_ = |
| (...skipping 24 matching lines...) Expand all Loading... |
| 414 if (collector == MARK_COMPACTOR) { | 439 if (collector == MARK_COMPACTOR) { |
| 415 // Register the amount of external allocated memory. | 440 // Register the amount of external allocated memory. |
| 416 amount_of_external_allocated_memory_at_last_global_gc_ = | 441 amount_of_external_allocated_memory_at_last_global_gc_ = |
| 417 amount_of_external_allocated_memory_; | 442 amount_of_external_allocated_memory_; |
| 418 } | 443 } |
| 419 | 444 |
| 420 if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) { | 445 if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) { |
| 421 ASSERT(!allocation_allowed_); | 446 ASSERT(!allocation_allowed_); |
| 422 global_gc_epilogue_callback_(); | 447 global_gc_epilogue_callback_(); |
| 423 } | 448 } |
| 449 VerifySymbolTable(); |
| 424 } | 450 } |
| 425 | 451 |
| 426 | 452 |
| 427 void Heap::PostGarbageCollectionProcessing() { | 453 void Heap::PostGarbageCollectionProcessing() { |
| 428 // Process weak handles post gc. | 454 // Process weak handles post gc. |
| 429 GlobalHandles::PostGarbageCollectionProcessing(); | 455 GlobalHandles::PostGarbageCollectionProcessing(); |
| 430 // Update flat string readers. | 456 // Update flat string readers. |
| 431 FlatStringReader::PostGarbageCollectionProcessing(); | 457 FlatStringReader::PostGarbageCollectionProcessing(); |
| 432 } | 458 } |
| 433 | 459 |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 *p = first_word.ToForwardingAddress(); | 832 *p = first_word.ToForwardingAddress(); |
| 807 return; | 833 return; |
| 808 } | 834 } |
| 809 | 835 |
| 810 // Call the slow part of scavenge object. | 836 // Call the slow part of scavenge object. |
| 811 return ScavengeObjectSlow(p, object); | 837 return ScavengeObjectSlow(p, object); |
| 812 } | 838 } |
| 813 | 839 |
| 814 | 840 |
| 815 static inline bool IsShortcutCandidate(HeapObject* object, Map* map) { | 841 static inline bool IsShortcutCandidate(HeapObject* object, Map* map) { |
| 816 // A ConsString with an empty string as the right side is a | |
| 817 // candidate for being shortcut by the scavenger unless it is a | |
| 818 // symbol. It's not common to have non-flat symbols, so we do not | |
| 819 // shortcut them thereby avoiding turning symbols into strings. | |
| 820 ASSERT(kNotStringTag != 0 && kSymbolTag != 0); | |
| 821 static const uint32_t kShortcutTypeMask = | |
| 822 kIsNotStringMask | | |
| 823 kIsSymbolMask | | |
| 824 kStringRepresentationMask; | |
| 825 ASSERT(object->map() == map); | 842 ASSERT(object->map() == map); |
| 826 InstanceType type = map->instance_type(); | 843 InstanceType type = map->instance_type(); |
| 827 if ((type & kShortcutTypeMask) != kConsStringTag) return false; | 844 if ((type & kShortcutTypeMask) != kShortcutTypeTag) return false; |
| 828 ASSERT(object->IsString() && !object->IsSymbol()); | 845 ASSERT(object->IsString() && !object->IsSymbol()); |
| 829 return ConsString::cast(object)->unchecked_second() == Heap::empty_string(); | 846 return ConsString::cast(object)->unchecked_second() == Heap::empty_string(); |
| 830 } | 847 } |
| 831 | 848 |
| 832 | 849 |
| 833 void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { | 850 void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { |
| 834 ASSERT(InFromSpace(object)); | 851 ASSERT(InFromSpace(object)); |
| 835 MapWord first_word = object->map_word(); | 852 MapWord first_word = object->map_word(); |
| 836 ASSERT(!first_word.IsForwardingAddress()); | 853 ASSERT(!first_word.IsForwardingAddress()); |
| 837 | 854 |
| (...skipping 2525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3363 #ifdef DEBUG | 3380 #ifdef DEBUG |
| 3364 bool Heap::GarbageCollectionGreedyCheck() { | 3381 bool Heap::GarbageCollectionGreedyCheck() { |
| 3365 ASSERT(FLAG_gc_greedy); | 3382 ASSERT(FLAG_gc_greedy); |
| 3366 if (Bootstrapper::IsActive()) return true; | 3383 if (Bootstrapper::IsActive()) return true; |
| 3367 if (disallow_allocation_failure()) return true; | 3384 if (disallow_allocation_failure()) return true; |
| 3368 return CollectGarbage(0, NEW_SPACE); | 3385 return CollectGarbage(0, NEW_SPACE); |
| 3369 } | 3386 } |
| 3370 #endif | 3387 #endif |
| 3371 | 3388 |
| 3372 } } // namespace v8::internal | 3389 } } // namespace v8::internal |
| OLD | NEW |