Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: src/mark-compact.cc

Issue 467037: External string table. (Closed)
Patch Set: Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 #ifdef DEBUG 148 #ifdef DEBUG
149 ASSERT(state_ == SWEEP_SPACES || state_ == REBUILD_RSETS); 149 ASSERT(state_ == SWEEP_SPACES || state_ == REBUILD_RSETS);
150 state_ = IDLE; 150 state_ = IDLE;
151 #endif 151 #endif
152 // The stub cache is not traversed during GC; clear the cache to 152 // The stub cache is not traversed during GC; clear the cache to
153 // force lazy re-initialization of it. This must be done after the 153 // force lazy re-initialization of it. This must be done after the
154 // GC, because it relies on the new address of certain old space 154 // GC, because it relies on the new address of certain old space
155 // objects (empty string, illegal builtin). 155 // objects (empty string, illegal builtin).
156 StubCache::Clear(); 156 StubCache::Clear();
157 157
158 ExternalStringTable::CleanUp();
159
158 // If we've just compacted old space there's no reason to check the 160 // If we've just compacted old space there's no reason to check the
159 // fragmentation limit. Just return. 161 // fragmentation limit. Just return.
160 if (HasCompacted()) return; 162 if (HasCompacted()) return;
161 163
162 // We compact the old generation on the next GC if it has gotten too 164 // We compact the old generation on the next GC if it has gotten too
163 // fragmented (ie, we could recover an expected amount of space by 165 // fragmented (ie, we could recover an expected amount of space by
164 // reclaiming the waste and free list blocks). 166 // reclaiming the waste and free list blocks).
165 static const int kFragmentationLimit = 15; // Percent. 167 static const int kFragmentationLimit = 15; // Percent.
166 static const int kFragmentationAllowed = 1 * MB; // Absolute. 168 static const int kFragmentationAllowed = 1 * MB; // Absolute.
167 int old_gen_recoverable = 0; 169 int old_gen_recoverable = 0;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 // overflowed objects in the heap. 364 // overflowed objects in the heap.
363 MarkCompactCollector::EmptyMarkingStack(&stack_visitor_); 365 MarkCompactCollector::EmptyMarkingStack(&stack_visitor_);
364 } 366 }
365 }; 367 };
366 368
367 369
368 // Helper class for pruning the symbol table. 370 // Helper class for pruning the symbol table.
369 class SymbolTableCleaner : public ObjectVisitor { 371 class SymbolTableCleaner : public ObjectVisitor {
370 public: 372 public:
371 SymbolTableCleaner() : pointers_removed_(0) { } 373 SymbolTableCleaner() : pointers_removed_(0) { }
372 void VisitPointers(Object** start, Object** end) { 374
375 virtual void VisitPointers(Object** start, Object** end) {
373 // Visit all HeapObject pointers in [start, end). 376 // Visit all HeapObject pointers in [start, end).
374 for (Object** p = start; p < end; p++) { 377 for (Object** p = start; p < end; p++) {
375 if ((*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked()) { 378 if ((*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked()) {
376 // Check if the symbol being pruned is an external symbol. We need to 379 // Check if the symbol being pruned is an external symbol. We need to
377 // delete the associated external data as this symbol is going away. 380 // delete the associated external data as this symbol is going away.
378 381
379 // Since the object is not marked we can access its map word safely
380 // without having to worry about marking bits in the object header.
381 Map* map = HeapObject::cast(*p)->map();
382 // Since no objects have yet been moved we can safely access the map of 382 // Since no objects have yet been moved we can safely access the map of
383 // the object. 383 // the object.
384 uint32_t type = map->instance_type(); 384 if ((*p)->IsExternalString()) {
385 bool is_external = (type & kStringRepresentationMask) == 385 Heap::FinalizeExternalString(String::cast(*p));
386 kExternalStringTag;
387 if (is_external) {
388 bool is_two_byte = (type & kStringEncodingMask) == kTwoByteStringTag;
389 byte* resource_addr = reinterpret_cast<byte*>(*p) +
390 ExternalString::kResourceOffset -
391 kHeapObjectTag;
392 if (is_two_byte) {
393 v8::String::ExternalStringResource** resource =
394 reinterpret_cast<v8::String::ExternalStringResource**>
395 (resource_addr);
396 delete *resource;
397 // Clear the resource pointer in the symbol.
398 *resource = NULL;
399 } else {
400 v8::String::ExternalAsciiStringResource** resource =
401 reinterpret_cast<v8::String::ExternalAsciiStringResource**>
402 (resource_addr);
403 delete *resource;
404 // Clear the resource pointer in the symbol.
405 *resource = NULL;
406 }
407 } 386 }
408 // Set the entry to null_value (as deleted). 387 // Set the entry to null_value (as deleted).
409 *p = Heap::raw_unchecked_null_value(); 388 *p = Heap::raw_unchecked_null_value();
410 pointers_removed_++; 389 pointers_removed_++;
411 } 390 }
412 } 391 }
413 } 392 }
414 393
415 int PointersRemoved() { 394 int PointersRemoved() {
416 return pointers_removed_; 395 return pointers_removed_;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 } 518 }
540 } 519 }
541 } 520 }
542 521
543 522
544 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 523 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
545 return (*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked(); 524 return (*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked();
546 } 525 }
547 526
548 527
549 class SymbolMarkingVisitor : public ObjectVisitor {
550 public:
551 void VisitPointers(Object** start, Object** end) {
552 MarkingVisitor marker;
553 for (Object** p = start; p < end; p++) {
554 if (!(*p)->IsHeapObject()) continue;
555
556 HeapObject* object = HeapObject::cast(*p);
557 // If the object is marked, we have marked or are in the process
558 // of marking subparts.
559 if (object->IsMarked()) continue;
560
561 // The object is unmarked, we do not need to unmark to use its
562 // map.
563 Map* map = object->map();
564 object->IterateBody(map->instance_type(),
565 object->SizeFromMap(map),
566 &marker);
567 }
568 }
569 };
570
571
572 void MarkCompactCollector::MarkSymbolTable() { 528 void MarkCompactCollector::MarkSymbolTable() {
573 // Objects reachable from symbols are marked as live so as to ensure
574 // that if the symbol itself remains alive after GC for any reason,
575 // and if it is a cons string backed by an external string (even indirectly),
576 // then the external string does not receive a weak reference callback.
577 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table(); 529 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
578 // Mark the symbol table itself. 530 // Mark the symbol table itself.
579 SetMark(symbol_table); 531 SetMark(symbol_table);
580 // Explicitly mark the prefix. 532 // Explicitly mark the prefix.
581 MarkingVisitor marker; 533 MarkingVisitor marker;
582 symbol_table->IteratePrefix(&marker); 534 symbol_table->IteratePrefix(&marker);
583 ProcessMarkingStack(&marker); 535 ProcessMarkingStack(&marker);
584 // Mark subparts of the symbols but not the symbols themselves
585 // (unless reachable from another symbol).
586 SymbolMarkingVisitor symbol_marker;
587 symbol_table->IterateElements(&symbol_marker);
588 ProcessMarkingStack(&marker);
589 } 536 }
590 537
591 538
592 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { 539 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
593 // Mark the heap roots including global variables, stack variables, 540 // Mark the heap roots including global variables, stack variables,
594 // etc., and all objects reachable from them. 541 // etc., and all objects reachable from them.
595 Heap::IterateStrongRoots(visitor, VISIT_ONLY_STRONG); 542 Heap::IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
596 543
597 // Handle the symbol table specially. 544 // Handle the symbol table specially.
598 MarkSymbolTable(); 545 MarkSymbolTable();
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 // weak roots. 714 // weak roots.
768 ProcessObjectGroups(root_visitor.stack_visitor()); 715 ProcessObjectGroups(root_visitor.stack_visitor());
769 716
770 // Prune the symbol table removing all symbols only pointed to by the 717 // Prune the symbol table removing all symbols only pointed to by the
771 // symbol table. Cannot use symbol_table() here because the symbol 718 // symbol table. Cannot use symbol_table() here because the symbol
772 // table is marked. 719 // table is marked.
773 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table(); 720 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
774 SymbolTableCleaner v; 721 SymbolTableCleaner v;
775 symbol_table->IterateElements(&v); 722 symbol_table->IterateElements(&v);
776 symbol_table->ElementsRemoved(v.PointersRemoved()); 723 symbol_table->ElementsRemoved(v.PointersRemoved());
724 ExternalStringTable::Iterate(&v);
725 ExternalStringTable::CleanUp();
777 726
778 // Remove object groups after marking phase. 727 // Remove object groups after marking phase.
779 GlobalHandles::RemoveObjectGroups(); 728 GlobalHandles::RemoveObjectGroups();
780 } 729 }
781 730
782 731
783 static int CountMarkedCallback(HeapObject* obj) { 732 static int CountMarkedCallback(HeapObject* obj) {
784 MapWord map_word = obj->map_word(); 733 MapWord map_word = obj->map_word();
785 map_word.ClearMark(); 734 map_word.ClearMark();
786 return obj->SizeFromMap(map_word.ToMap()); 735 return obj->SizeFromMap(map_word.ToMap());
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 1757
1809 void MarkCompactCollector::RebuildRSets() { 1758 void MarkCompactCollector::RebuildRSets() {
1810 #ifdef DEBUG 1759 #ifdef DEBUG
1811 ASSERT(state_ == RELOCATE_OBJECTS); 1760 ASSERT(state_ == RELOCATE_OBJECTS);
1812 state_ = REBUILD_RSETS; 1761 state_ = REBUILD_RSETS;
1813 #endif 1762 #endif
1814 Heap::RebuildRSets(); 1763 Heap::RebuildRSets();
1815 } 1764 }
1816 1765
1817 } } // namespace v8::internal 1766 } } // namespace v8::internal
OLDNEW
« src/heap.cc ('K') | « src/heap-inl.h ('k') | src/v8-counters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698