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

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

Issue 7553012: Prototype of mark-and-compact support for Harmony weak maps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Removed commented stress test. Created 9 years, 4 months 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 | Annotate | Revision Log
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 live_young_objects_size_(0), 57 live_young_objects_size_(0),
58 live_old_pointer_objects_size_(0), 58 live_old_pointer_objects_size_(0),
59 live_old_data_objects_size_(0), 59 live_old_data_objects_size_(0),
60 live_code_objects_size_(0), 60 live_code_objects_size_(0),
61 live_map_objects_size_(0), 61 live_map_objects_size_(0),
62 live_cell_objects_size_(0), 62 live_cell_objects_size_(0),
63 live_lo_objects_size_(0), 63 live_lo_objects_size_(0),
64 live_bytes_(0), 64 live_bytes_(0),
65 #endif 65 #endif
66 heap_(NULL), 66 heap_(NULL),
67 code_flusher_(NULL) { } 67 code_flusher_(NULL),
68 encountered_weak_maps_(NULL) { }
68 69
69 70
70 void MarkCompactCollector::CollectGarbage() { 71 void MarkCompactCollector::CollectGarbage() {
71 // Make sure that Prepare() has been called. The individual steps below will 72 // Make sure that Prepare() has been called. The individual steps below will
72 // update the state as they proceed. 73 // update the state as they proceed.
73 ASSERT(state_ == PREPARE_GC); 74 ASSERT(state_ == PREPARE_GC);
75 ASSERT(encountered_weak_maps_ == Smi::FromInt(0));
74 76
75 // Prepare has selected whether to compact the old generation or not. 77 // Prepare has selected whether to compact the old generation or not.
76 // Tell the tracer. 78 // Tell the tracer.
77 if (IsCompacting()) tracer_->set_is_compacting(); 79 if (IsCompacting()) tracer_->set_is_compacting();
78 80
79 MarkLiveObjects(); 81 MarkLiveObjects();
80 82
81 if (FLAG_collect_maps) ClearNonLiveTransitions(); 83 if (FLAG_collect_maps) ClearNonLiveTransitions();
82 84
85 ClearWeakMaps();
86
83 SweepLargeObjectSpace(); 87 SweepLargeObjectSpace();
84 88
85 if (IsCompacting()) { 89 if (IsCompacting()) {
86 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_COMPACT); 90 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_COMPACT);
87 EncodeForwardingAddresses(); 91 EncodeForwardingAddresses();
88 92
89 heap()->MarkMapPointersAsEncoded(true); 93 heap()->MarkMapPointersAsEncoded(true);
90 UpdatePointers(); 94 UpdatePointers();
91 heap()->MarkMapPointersAsEncoded(false); 95 heap()->MarkMapPointersAsEncoded(false);
92 heap()->isolate()->pc_to_code_cache()->Flush(); 96 heap()->isolate()->pc_to_code_cache()->Flush();
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 404
401 table_.Register(kVisitGlobalContext, 405 table_.Register(kVisitGlobalContext,
402 &FixedBodyVisitor<StaticMarkingVisitor, 406 &FixedBodyVisitor<StaticMarkingVisitor,
403 Context::MarkCompactBodyDescriptor, 407 Context::MarkCompactBodyDescriptor,
404 void>::Visit); 408 void>::Visit);
405 409
406 table_.Register(kVisitByteArray, &DataObjectVisitor::Visit); 410 table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
407 table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit); 411 table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
408 table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit); 412 table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
409 413
414 table_.Register(kVisitJSWeakMap, &VisitJSWeakMap);
415
410 table_.Register(kVisitOddball, 416 table_.Register(kVisitOddball,
411 &FixedBodyVisitor<StaticMarkingVisitor, 417 &FixedBodyVisitor<StaticMarkingVisitor,
412 Oddball::BodyDescriptor, 418 Oddball::BodyDescriptor,
413 void>::Visit); 419 void>::Visit);
414 table_.Register(kVisitMap, 420 table_.Register(kVisitMap,
415 &FixedBodyVisitor<StaticMarkingVisitor, 421 &FixedBodyVisitor<StaticMarkingVisitor,
416 Map::BodyDescriptor, 422 Map::BodyDescriptor,
417 void>::Visit); 423 void>::Visit);
418 424
419 table_.Register(kVisitCode, &VisitCode); 425 table_.Register(kVisitCode, &VisitCode);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 }; 555 };
550 556
551 typedef FlexibleBodyVisitor<StaticMarkingVisitor, 557 typedef FlexibleBodyVisitor<StaticMarkingVisitor,
552 JSObject::BodyDescriptor, 558 JSObject::BodyDescriptor,
553 void> JSObjectVisitor; 559 void> JSObjectVisitor;
554 560
555 typedef FlexibleBodyVisitor<StaticMarkingVisitor, 561 typedef FlexibleBodyVisitor<StaticMarkingVisitor,
556 StructBodyDescriptor, 562 StructBodyDescriptor,
557 void> StructObjectVisitor; 563 void> StructObjectVisitor;
558 564
565 static void VisitJSWeakMap(Map* map, HeapObject* object) {
566 MarkCompactCollector* collector = map->heap()->mark_compact_collector();
567 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(object);
568
569 // Enqueue weak map in linked list of encountered weak maps.
570 ASSERT(weak_map->next() == Smi::FromInt(0));
571 weak_map->set_next(collector->encountered_weak_maps());
572 collector->set_encountered_weak_maps(weak_map);
573
574 // Skip visiting the backing hash table containing the mappings.
575 int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object);
576 BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
577 map->heap(),
578 object,
579 JSWeakMap::BodyDescriptor::kStartOffset,
580 JSWeakMap::kTableOffset);
581 BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
582 map->heap(),
583 object,
584 JSWeakMap::kTableOffset + kPointerSize,
585 object_size);
586
587 // Mark the backing hash table without pushing it on the marking stack.
588 ASSERT(!weak_map->unchecked_table()->IsMarked());
589 ASSERT(weak_map->unchecked_table()->map()->IsMarked());
590 collector->SetMark(weak_map->unchecked_table());
591 }
592
559 static void VisitCode(Map* map, HeapObject* object) { 593 static void VisitCode(Map* map, HeapObject* object) {
560 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>( 594 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>(
561 map->heap()); 595 map->heap());
562 } 596 }
563 597
564 // Code flushing support. 598 // Code flushing support.
565 599
566 // How many collections newly compiled code object will survive before being 600 // How many collections newly compiled code object will survive before being
567 // flushed. 601 // flushed.
568 static const int kCodeAgeThreshold = 5; 602 static const int kCodeAgeThreshold = 5;
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 ref_groups->Rewind(last); 1396 ref_groups->Rewind(last);
1363 } 1397 }
1364 1398
1365 1399
1366 // Mark all objects reachable from the objects on the marking stack. 1400 // Mark all objects reachable from the objects on the marking stack.
1367 // Before: the marking stack contains zero or more heap object pointers. 1401 // Before: the marking stack contains zero or more heap object pointers.
1368 // After: the marking stack is empty, and all objects reachable from the 1402 // After: the marking stack is empty, and all objects reachable from the
1369 // marking stack have been marked, or are overflowed in the heap. 1403 // marking stack have been marked, or are overflowed in the heap.
1370 void MarkCompactCollector::EmptyMarkingStack() { 1404 void MarkCompactCollector::EmptyMarkingStack() {
1371 while (!marking_stack_.is_empty()) { 1405 while (!marking_stack_.is_empty()) {
1372 HeapObject* object = marking_stack_.Pop(); 1406 while (!marking_stack_.is_empty()) {
1373 ASSERT(object->IsHeapObject()); 1407 HeapObject* object = marking_stack_.Pop();
1374 ASSERT(heap()->Contains(object)); 1408 ASSERT(object->IsHeapObject());
1375 ASSERT(object->IsMarked()); 1409 ASSERT(heap()->Contains(object));
1376 ASSERT(!object->IsOverflowed()); 1410 ASSERT(object->IsMarked());
1411 ASSERT(!object->IsOverflowed());
1377 1412
1378 // Because the object is marked, we have to recover the original map 1413 // Because the object is marked, we have to recover the original map
1379 // pointer and use it to mark the object's body. 1414 // pointer and use it to mark the object's body.
1380 MapWord map_word = object->map_word(); 1415 MapWord map_word = object->map_word();
1381 map_word.ClearMark(); 1416 map_word.ClearMark();
1382 Map* map = map_word.ToMap(); 1417 Map* map = map_word.ToMap();
1383 MarkObject(map); 1418 MarkObject(map);
1384 1419
1385 StaticMarkingVisitor::IterateBody(map, object); 1420 StaticMarkingVisitor::IterateBody(map, object);
1421 }
1422
1423 // Process encountered weak maps, mark objects only reachable by those
1424 // weak maps and repeat until fix-point is reached.
1425 ProcessWeakMaps();
1386 } 1426 }
1387 } 1427 }
1388 1428
1389 1429
1390 // Sweep the heap for overflowed objects, clear their overflow bits, and 1430 // Sweep the heap for overflowed objects, clear their overflow bits, and
1391 // push them on the marking stack. Stop early if the marking stack fills 1431 // push them on the marking stack. Stop early if the marking stack fills
1392 // before sweeping completes. If sweeping completes, there are no remaining 1432 // before sweeping completes. If sweeping completes, there are no remaining
1393 // overflowed objects in the heap so the overflow flag on the markings stack 1433 // overflowed objects in the heap so the overflow flag on the markings stack
1394 // is cleared. 1434 // is cleared.
1395 void MarkCompactCollector::RefillMarkingStack() { 1435 void MarkCompactCollector::RefillMarkingStack() {
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 on_dead_path = false; 1768 on_dead_path = false;
1729 current->ClearNonLiveTransitions(heap(), real_prototype); 1769 current->ClearNonLiveTransitions(heap(), real_prototype);
1730 } 1770 }
1731 *HeapObject::RawField(current, Map::kPrototypeOffset) = 1771 *HeapObject::RawField(current, Map::kPrototypeOffset) =
1732 real_prototype; 1772 real_prototype;
1733 current = reinterpret_cast<Map*>(next); 1773 current = reinterpret_cast<Map*>(next);
1734 } 1774 }
1735 } 1775 }
1736 } 1776 }
1737 1777
1778
1779 void MarkCompactCollector::ProcessWeakMaps() {
1780 Object* weak_map_obj = encountered_weak_maps();
1781 while (weak_map_obj != Smi::FromInt(0)) {
1782 ASSERT(HeapObject::cast(weak_map_obj)->IsMarked());
1783 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
1784 ObjectHashTable* table = weak_map->unchecked_table();
1785 for (int i = 0; i < table->Capacity(); i++) {
1786 if (HeapObject::cast(table->KeyAt(i))->IsMarked()) {
1787 Object* value = table->get(table->EntryToValueIndex(i));
1788 StaticMarkingVisitor::MarkObjectByPointer(heap(), &value);
1789 table->set_unchecked(heap(),
1790 table->EntryToValueIndex(i),
1791 value,
1792 UPDATE_WRITE_BARRIER);
1793 }
1794 }
1795 weak_map_obj = weak_map->next();
1796 }
1797 }
1798
1799
1800 void MarkCompactCollector::ClearWeakMaps() {
1801 Object* weak_map_obj = encountered_weak_maps();
1802 while (weak_map_obj != Smi::FromInt(0)) {
1803 ASSERT(HeapObject::cast(weak_map_obj)->IsMarked());
1804 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
1805 ObjectHashTable* table = weak_map->unchecked_table();
1806 for (int i = 0; i < table->Capacity(); i++) {
1807 if (!HeapObject::cast(table->KeyAt(i))->IsMarked()) {
1808 table->RemoveEntry(i, heap());
1809 }
1810 }
1811 weak_map_obj = weak_map->next();
1812 weak_map->set_next(Smi::FromInt(0));
1813 }
1814 set_encountered_weak_maps(Smi::FromInt(0));
1815 }
1816
1738 // ------------------------------------------------------------------------- 1817 // -------------------------------------------------------------------------
1739 // Phase 2: Encode forwarding addresses. 1818 // Phase 2: Encode forwarding addresses.
1740 // When compacting, forwarding addresses for objects in old space and map 1819 // When compacting, forwarding addresses for objects in old space and map
1741 // space are encoded in their map pointer word (along with an encoding of 1820 // space are encoded in their map pointer word (along with an encoding of
1742 // their map pointers). 1821 // their map pointers).
1743 // 1822 //
1744 // The excact encoding is described in the comments for class MapWord in 1823 // The excact encoding is described in the comments for class MapWord in
1745 // objects.h. 1824 // objects.h.
1746 // 1825 //
1747 // An address range [start, end) can have both live and non-live objects. 1826 // An address range [start, end) can have both live and non-live objects.
(...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after
3271 } 3350 }
3272 3351
3273 3352
3274 void MarkCompactCollector::Initialize() { 3353 void MarkCompactCollector::Initialize() {
3275 StaticPointersToNewGenUpdatingVisitor::Initialize(); 3354 StaticPointersToNewGenUpdatingVisitor::Initialize();
3276 StaticMarkingVisitor::Initialize(); 3355 StaticMarkingVisitor::Initialize();
3277 } 3356 }
3278 3357
3279 3358
3280 } } // namespace v8::internal 3359 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698