OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/heap.h" | 5 #include "src/heap/heap.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 GCType gc_type = | 1199 GCType gc_type = |
1200 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; | 1200 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; |
1201 | 1201 |
1202 { | 1202 { |
1203 GCCallbacksScope scope(this); | 1203 GCCallbacksScope scope(this); |
1204 if (scope.CheckReenter()) { | 1204 if (scope.CheckReenter()) { |
1205 AllowHeapAllocation allow_allocation; | 1205 AllowHeapAllocation allow_allocation; |
1206 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); | 1206 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); |
1207 VMState<EXTERNAL> state(isolate_); | 1207 VMState<EXTERNAL> state(isolate_); |
1208 HandleScope handle_scope(isolate_); | 1208 HandleScope handle_scope(isolate_); |
1209 CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags); | 1209 if (!(gc_type == kGCTypeScavenge && |
| 1210 FLAG_scavenge_remove_unmodified_objects)) { |
| 1211 CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags); |
| 1212 } |
1210 } | 1213 } |
1211 } | 1214 } |
1212 | 1215 |
1213 EnsureFromSpaceIsCommitted(); | 1216 EnsureFromSpaceIsCommitted(); |
1214 | 1217 |
1215 int start_new_space_size = Heap::new_space()->SizeAsInt(); | 1218 int start_new_space_size = Heap::new_space()->SizeAsInt(); |
1216 | 1219 |
1217 if (IsHighSurvivalRate()) { | 1220 if (IsHighSurvivalRate()) { |
1218 // We speed up the incremental marker if it is running so that it | 1221 // We speed up the incremental marker if it is running so that it |
1219 // does not fall behind the rate of promotion, which would cause a | 1222 // does not fall behind the rate of promotion, which would cause a |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 DampenOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed); | 1287 DampenOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed); |
1285 } | 1288 } |
1286 | 1289 |
1287 { | 1290 { |
1288 GCCallbacksScope scope(this); | 1291 GCCallbacksScope scope(this); |
1289 if (scope.CheckReenter()) { | 1292 if (scope.CheckReenter()) { |
1290 AllowHeapAllocation allow_allocation; | 1293 AllowHeapAllocation allow_allocation; |
1291 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); | 1294 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); |
1292 VMState<EXTERNAL> state(isolate_); | 1295 VMState<EXTERNAL> state(isolate_); |
1293 HandleScope handle_scope(isolate_); | 1296 HandleScope handle_scope(isolate_); |
1294 CallGCEpilogueCallbacks(gc_type, gc_callback_flags); | 1297 if (!(gc_type == kGCTypeScavenge && |
| 1298 FLAG_scavenge_remove_unmodified_objects)) { |
| 1299 CallGCEpilogueCallbacks(gc_type, gc_callback_flags); |
| 1300 } |
1295 } | 1301 } |
1296 } | 1302 } |
1297 | 1303 |
1298 #ifdef VERIFY_HEAP | 1304 #ifdef VERIFY_HEAP |
1299 if (FLAG_verify_heap) { | 1305 if (FLAG_verify_heap) { |
1300 VerifyStringTable(this); | 1306 VerifyStringTable(this); |
1301 } | 1307 } |
1302 #endif | 1308 #endif |
1303 | 1309 |
1304 return freed_global_handles > 0; | 1310 return freed_global_handles > 0; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && | 1444 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && |
1439 survived_since_last_expansion_ > new_space_.TotalCapacity()) { | 1445 survived_since_last_expansion_ > new_space_.TotalCapacity()) { |
1440 // Grow the size of new space if there is room to grow, and enough data | 1446 // Grow the size of new space if there is room to grow, and enough data |
1441 // has survived scavenge since the last expansion. | 1447 // has survived scavenge since the last expansion. |
1442 new_space_.Grow(); | 1448 new_space_.Grow(); |
1443 survived_since_last_expansion_ = 0; | 1449 survived_since_last_expansion_ = 0; |
1444 } | 1450 } |
1445 } | 1451 } |
1446 | 1452 |
1447 | 1453 |
| 1454 static bool IsUnModifiedNewSpaceObject(Object** p) { |
| 1455 Object* object = *p; |
| 1456 DCHECK(object->IsHeapObject()); |
| 1457 HeapObject* heap_object = HeapObject::cast(object); |
| 1458 if (!object->IsJSObject()) { |
| 1459 return false; |
| 1460 } |
| 1461 Object* obj_constructor = (JSObject::cast(object))->map()->GetConstructor(); |
| 1462 if (!obj_constructor->IsJSFunction()) return false; |
| 1463 JSFunction* constructor = JSFunction::cast(obj_constructor); |
| 1464 if (constructor == NULL) return false; |
| 1465 if (constructor->initial_map() == heap_object->map()) return true; |
| 1466 return false; |
| 1467 } |
| 1468 |
| 1469 |
1448 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { | 1470 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { |
1449 return heap->InNewSpace(*p) && | 1471 return heap->InNewSpace(*p) && |
1450 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); | 1472 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); |
1451 } | 1473 } |
1452 | 1474 |
1453 | 1475 |
1454 void Heap::ScavengeStoreBufferCallback(Heap* heap, MemoryChunk* page, | 1476 void Heap::ScavengeStoreBufferCallback(Heap* heap, MemoryChunk* page, |
1455 StoreBufferEvent event) { | 1477 StoreBufferEvent event) { |
1456 heap->store_buffer_rebuilder_.Callback(page, event); | 1478 heap->store_buffer_rebuilder_.Callback(page, event); |
1457 } | 1479 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1562 // updated as a side effect of promoting an object. | 1584 // updated as a side effect of promoting an object. |
1563 // | 1585 // |
1564 // There is guaranteed to be enough room at the top of the to space | 1586 // There is guaranteed to be enough room at the top of the to space |
1565 // for the addresses of promoted objects: every object promoted | 1587 // for the addresses of promoted objects: every object promoted |
1566 // frees up its size in bytes from the top of the new space, and | 1588 // frees up its size in bytes from the top of the new space, and |
1567 // objects are at least one pointer in size. | 1589 // objects are at least one pointer in size. |
1568 Address new_space_front = new_space_.ToSpaceStart(); | 1590 Address new_space_front = new_space_.ToSpaceStart(); |
1569 promotion_queue_.Initialize(); | 1591 promotion_queue_.Initialize(); |
1570 | 1592 |
1571 ScavengeVisitor scavenge_visitor(this); | 1593 ScavengeVisitor scavenge_visitor(this); |
| 1594 |
| 1595 if (FLAG_scavenge_remove_unmodified_objects) { |
| 1596 isolate()->global_handles()->IdentifyWeakUnmodifiedObjects( |
| 1597 &IsUnModifiedNewSpaceObject); |
| 1598 } |
| 1599 |
| 1600 |
1572 { | 1601 { |
1573 // Copy roots. | 1602 // Copy roots. |
1574 GCTracer::Scope gc_scope(tracer(), GCTracer::Scope::SCAVENGER_ROOTS); | 1603 GCTracer::Scope gc_scope(tracer(), GCTracer::Scope::SCAVENGER_ROOTS); |
1575 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); | 1604 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); |
1576 } | 1605 } |
1577 | 1606 |
1578 { | 1607 { |
1579 // Copy objects reachable from the old generation. | 1608 // Copy objects reachable from the old generation. |
1580 GCTracer::Scope gc_scope(tracer(), | 1609 GCTracer::Scope gc_scope(tracer(), |
1581 GCTracer::Scope::SCAVENGER_OLD_TO_NEW_POINTERS); | 1610 GCTracer::Scope::SCAVENGER_OLD_TO_NEW_POINTERS); |
(...skipping 18 matching lines...) Expand all Loading... |
1600 if (collector->is_code_flushing_enabled()) { | 1629 if (collector->is_code_flushing_enabled()) { |
1601 collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor); | 1630 collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor); |
1602 } | 1631 } |
1603 } | 1632 } |
1604 | 1633 |
1605 { | 1634 { |
1606 GCTracer::Scope gc_scope(tracer(), GCTracer::Scope::SCAVENGER_SEMISPACE); | 1635 GCTracer::Scope gc_scope(tracer(), GCTracer::Scope::SCAVENGER_SEMISPACE); |
1607 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1636 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
1608 } | 1637 } |
1609 | 1638 |
1610 { | 1639 if (FLAG_scavenge_remove_unmodified_objects) { |
| 1640 isolate()->global_handles()->IdentifyNewSpaceWeakUnModifiedHandles( |
| 1641 &IsUnscavengedHeapObject); |
| 1642 |
| 1643 isolate()->global_handles()->IterateNewSpaceWeakUnModifiedRoots( |
| 1644 &scavenge_visitor); |
| 1645 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1646 } else { |
1611 GCTracer::Scope gc_scope(tracer(), | 1647 GCTracer::Scope gc_scope(tracer(), |
1612 GCTracer::Scope::SCAVENGER_OBJECT_GROUPS); | 1648 GCTracer::Scope::SCAVENGER_OBJECT_GROUPS); |
1613 while (isolate()->global_handles()->IterateObjectGroups( | 1649 while (isolate()->global_handles()->IterateObjectGroups( |
1614 &scavenge_visitor, &IsUnscavengedHeapObject)) { | 1650 &scavenge_visitor, &IsUnscavengedHeapObject)) { |
1615 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1651 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
1616 } | 1652 } |
1617 isolate()->global_handles()->RemoveObjectGroups(); | 1653 isolate()->global_handles()->RemoveObjectGroups(); |
1618 isolate()->global_handles()->RemoveImplicitRefGroups(); | 1654 isolate()->global_handles()->RemoveImplicitRefGroups(); |
| 1655 |
| 1656 isolate()->global_handles()->IdentifyNewSpaceWeakIndependentHandles( |
| 1657 &IsUnscavengedHeapObject); |
| 1658 |
| 1659 isolate()->global_handles()->IterateNewSpaceWeakIndependentRoots( |
| 1660 &scavenge_visitor); |
| 1661 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
1619 } | 1662 } |
1620 | 1663 |
1621 isolate()->global_handles()->IdentifyNewSpaceWeakIndependentHandles( | |
1622 &IsUnscavengedHeapObject); | |
1623 | |
1624 isolate()->global_handles()->IterateNewSpaceWeakIndependentRoots( | |
1625 &scavenge_visitor); | |
1626 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | |
1627 | |
1628 UpdateNewSpaceReferencesInExternalStringTable( | 1664 UpdateNewSpaceReferencesInExternalStringTable( |
1629 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1665 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
1630 | 1666 |
1631 promotion_queue_.Destroy(); | 1667 promotion_queue_.Destroy(); |
1632 | 1668 |
1633 incremental_marking()->UpdateMarkingDequeAfterScavenge(); | 1669 incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
1634 | 1670 |
1635 ScavengeWeakObjectRetainer weak_object_retainer(this); | 1671 ScavengeWeakObjectRetainer weak_object_retainer(this); |
1636 ProcessYoungWeakReferences(&weak_object_retainer); | 1672 ProcessYoungWeakReferences(&weak_object_retainer); |
1637 | 1673 |
(...skipping 4467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6105 } | 6141 } |
6106 | 6142 |
6107 | 6143 |
6108 // static | 6144 // static |
6109 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6145 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6110 return StaticVisitorBase::GetVisitorId(map); | 6146 return StaticVisitorBase::GetVisitorId(map); |
6111 } | 6147 } |
6112 | 6148 |
6113 } // namespace internal | 6149 } // namespace internal |
6114 } // namespace v8 | 6150 } // namespace v8 |
OLD | NEW |