| 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 |