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 |