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/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
11 #include "src/cpu-profiler.h" | 11 #include "src/cpu-profiler.h" |
12 #include "src/deoptimizer.h" | 12 #include "src/deoptimizer.h" |
13 #include "src/execution.h" | 13 #include "src/execution.h" |
14 #include "src/frames-inl.h" | 14 #include "src/frames-inl.h" |
15 #include "src/gdb-jit.h" | 15 #include "src/gdb-jit.h" |
16 #include "src/global-handles.h" | 16 #include "src/global-handles.h" |
17 #include "src/heap/gc-tracer.h" | 17 #include "src/heap/gc-tracer.h" |
18 #include "src/heap/incremental-marking.h" | 18 #include "src/heap/incremental-marking.h" |
19 #include "src/heap/mark-compact-inl.h" | 19 #include "src/heap/mark-compact-inl.h" |
| 20 #include "src/heap/object-stats.h" |
20 #include "src/heap/objects-visiting.h" | 21 #include "src/heap/objects-visiting.h" |
21 #include "src/heap/objects-visiting-inl.h" | 22 #include "src/heap/objects-visiting-inl.h" |
22 #include "src/heap/spaces-inl.h" | 23 #include "src/heap/spaces-inl.h" |
23 #include "src/heap-profiler.h" | 24 #include "src/heap-profiler.h" |
24 #include "src/ic/ic.h" | 25 #include "src/ic/ic.h" |
25 #include "src/ic/stub-cache.h" | 26 #include "src/ic/stub-cache.h" |
26 #include "src/v8.h" | 27 #include "src/v8.h" |
27 | 28 |
28 namespace v8 { | 29 namespace v8 { |
29 namespace internal { | 30 namespace internal { |
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 | 1410 |
1410 | 1411 |
1411 void MarkCompactMarkingVisitor::ObjectStatsCountFixedArray( | 1412 void MarkCompactMarkingVisitor::ObjectStatsCountFixedArray( |
1412 FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type, | 1413 FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type, |
1413 FixedArraySubInstanceType dictionary_type) { | 1414 FixedArraySubInstanceType dictionary_type) { |
1414 Heap* heap = fixed_array->map()->GetHeap(); | 1415 Heap* heap = fixed_array->map()->GetHeap(); |
1415 if (fixed_array->map() != heap->fixed_cow_array_map() && | 1416 if (fixed_array->map() != heap->fixed_cow_array_map() && |
1416 fixed_array->map() != heap->fixed_double_array_map() && | 1417 fixed_array->map() != heap->fixed_double_array_map() && |
1417 fixed_array != heap->empty_fixed_array()) { | 1418 fixed_array != heap->empty_fixed_array()) { |
1418 if (fixed_array->IsDictionary()) { | 1419 if (fixed_array->IsDictionary()) { |
1419 heap->RecordFixedArraySubTypeStats(dictionary_type, fixed_array->Size()); | 1420 heap->object_stats_->RecordFixedArraySubTypeStats(dictionary_type, |
| 1421 fixed_array->Size()); |
1420 } else { | 1422 } else { |
1421 heap->RecordFixedArraySubTypeStats(fast_type, fixed_array->Size()); | 1423 heap->object_stats_->RecordFixedArraySubTypeStats(fast_type, |
| 1424 fixed_array->Size()); |
1422 } | 1425 } |
1423 } | 1426 } |
1424 } | 1427 } |
1425 | 1428 |
1426 | 1429 |
1427 void MarkCompactMarkingVisitor::ObjectStatsVisitBase( | 1430 void MarkCompactMarkingVisitor::ObjectStatsVisitBase( |
1428 MarkCompactMarkingVisitor::VisitorId id, Map* map, HeapObject* obj) { | 1431 MarkCompactMarkingVisitor::VisitorId id, Map* map, HeapObject* obj) { |
1429 Heap* heap = map->GetHeap(); | 1432 Heap* heap = map->GetHeap(); |
1430 int object_size = obj->Size(); | 1433 int object_size = obj->Size(); |
1431 heap->RecordObjectStats(map->instance_type(), object_size); | 1434 heap->object_stats_->RecordObjectStats(map->instance_type(), object_size); |
1432 non_count_table_.GetVisitorById(id)(map, obj); | 1435 non_count_table_.GetVisitorById(id)(map, obj); |
1433 if (obj->IsJSObject()) { | 1436 if (obj->IsJSObject()) { |
1434 JSObject* object = JSObject::cast(obj); | 1437 JSObject* object = JSObject::cast(obj); |
1435 ObjectStatsCountFixedArray(object->elements(), DICTIONARY_ELEMENTS_SUB_TYPE, | 1438 ObjectStatsCountFixedArray(object->elements(), DICTIONARY_ELEMENTS_SUB_TYPE, |
1436 FAST_ELEMENTS_SUB_TYPE); | 1439 FAST_ELEMENTS_SUB_TYPE); |
1437 ObjectStatsCountFixedArray(object->properties(), | 1440 ObjectStatsCountFixedArray(object->properties(), |
1438 DICTIONARY_PROPERTIES_SUB_TYPE, | 1441 DICTIONARY_PROPERTIES_SUB_TYPE, |
1439 FAST_PROPERTIES_SUB_TYPE); | 1442 FAST_PROPERTIES_SUB_TYPE); |
1440 } | 1443 } |
1441 } | 1444 } |
(...skipping 11 matching lines...) Expand all Loading... |
1453 MarkCompactMarkingVisitor::kVisitMap> { | 1456 MarkCompactMarkingVisitor::kVisitMap> { |
1454 public: | 1457 public: |
1455 static inline void Visit(Map* map, HeapObject* obj) { | 1458 static inline void Visit(Map* map, HeapObject* obj) { |
1456 Heap* heap = map->GetHeap(); | 1459 Heap* heap = map->GetHeap(); |
1457 Map* map_obj = Map::cast(obj); | 1460 Map* map_obj = Map::cast(obj); |
1458 DCHECK(map->instance_type() == MAP_TYPE); | 1461 DCHECK(map->instance_type() == MAP_TYPE); |
1459 DescriptorArray* array = map_obj->instance_descriptors(); | 1462 DescriptorArray* array = map_obj->instance_descriptors(); |
1460 if (map_obj->owns_descriptors() && | 1463 if (map_obj->owns_descriptors() && |
1461 array != heap->empty_descriptor_array()) { | 1464 array != heap->empty_descriptor_array()) { |
1462 int fixed_array_size = array->Size(); | 1465 int fixed_array_size = array->Size(); |
1463 heap->RecordFixedArraySubTypeStats(DESCRIPTOR_ARRAY_SUB_TYPE, | 1466 heap->object_stats_->RecordFixedArraySubTypeStats( |
1464 fixed_array_size); | 1467 DESCRIPTOR_ARRAY_SUB_TYPE, fixed_array_size); |
1465 } | 1468 } |
1466 if (TransitionArray::IsFullTransitionArray(map_obj->raw_transitions())) { | 1469 if (TransitionArray::IsFullTransitionArray(map_obj->raw_transitions())) { |
1467 int fixed_array_size = | 1470 int fixed_array_size = |
1468 TransitionArray::cast(map_obj->raw_transitions())->Size(); | 1471 TransitionArray::cast(map_obj->raw_transitions())->Size(); |
1469 heap->RecordFixedArraySubTypeStats(TRANSITION_ARRAY_SUB_TYPE, | 1472 heap->object_stats_->RecordFixedArraySubTypeStats( |
1470 fixed_array_size); | 1473 TRANSITION_ARRAY_SUB_TYPE, fixed_array_size); |
1471 } | 1474 } |
1472 if (map_obj->has_code_cache()) { | 1475 if (map_obj->has_code_cache()) { |
1473 CodeCache* cache = CodeCache::cast(map_obj->code_cache()); | 1476 CodeCache* cache = CodeCache::cast(map_obj->code_cache()); |
1474 heap->RecordFixedArraySubTypeStats(MAP_CODE_CACHE_SUB_TYPE, | 1477 heap->object_stats_->RecordFixedArraySubTypeStats( |
1475 cache->default_cache()->Size()); | 1478 MAP_CODE_CACHE_SUB_TYPE, cache->default_cache()->Size()); |
1476 if (!cache->normal_type_cache()->IsUndefined()) { | 1479 if (!cache->normal_type_cache()->IsUndefined()) { |
1477 heap->RecordFixedArraySubTypeStats( | 1480 heap->object_stats_->RecordFixedArraySubTypeStats( |
1478 MAP_CODE_CACHE_SUB_TYPE, | 1481 MAP_CODE_CACHE_SUB_TYPE, |
1479 FixedArray::cast(cache->normal_type_cache())->Size()); | 1482 FixedArray::cast(cache->normal_type_cache())->Size()); |
1480 } | 1483 } |
1481 } | 1484 } |
1482 ObjectStatsVisitBase(kVisitMap, map, obj); | 1485 ObjectStatsVisitBase(kVisitMap, map, obj); |
1483 } | 1486 } |
1484 }; | 1487 }; |
1485 | 1488 |
1486 | 1489 |
1487 template <> | 1490 template <> |
1488 class MarkCompactMarkingVisitor::ObjectStatsTracker< | 1491 class MarkCompactMarkingVisitor::ObjectStatsTracker< |
1489 MarkCompactMarkingVisitor::kVisitCode> { | 1492 MarkCompactMarkingVisitor::kVisitCode> { |
1490 public: | 1493 public: |
1491 static inline void Visit(Map* map, HeapObject* obj) { | 1494 static inline void Visit(Map* map, HeapObject* obj) { |
1492 Heap* heap = map->GetHeap(); | 1495 Heap* heap = map->GetHeap(); |
1493 int object_size = obj->Size(); | 1496 int object_size = obj->Size(); |
1494 DCHECK(map->instance_type() == CODE_TYPE); | 1497 DCHECK(map->instance_type() == CODE_TYPE); |
1495 Code* code_obj = Code::cast(obj); | 1498 Code* code_obj = Code::cast(obj); |
1496 heap->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetAge(), | 1499 heap->object_stats_->RecordCodeSubTypeStats( |
1497 object_size); | 1500 code_obj->kind(), code_obj->GetAge(), object_size); |
1498 ObjectStatsVisitBase(kVisitCode, map, obj); | 1501 ObjectStatsVisitBase(kVisitCode, map, obj); |
1499 } | 1502 } |
1500 }; | 1503 }; |
1501 | 1504 |
1502 | 1505 |
1503 template <> | 1506 template <> |
1504 class MarkCompactMarkingVisitor::ObjectStatsTracker< | 1507 class MarkCompactMarkingVisitor::ObjectStatsTracker< |
1505 MarkCompactMarkingVisitor::kVisitSharedFunctionInfo> { | 1508 MarkCompactMarkingVisitor::kVisitSharedFunctionInfo> { |
1506 public: | 1509 public: |
1507 static inline void Visit(Map* map, HeapObject* obj) { | 1510 static inline void Visit(Map* map, HeapObject* obj) { |
1508 Heap* heap = map->GetHeap(); | 1511 Heap* heap = map->GetHeap(); |
1509 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); | 1512 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); |
1510 if (sfi->scope_info() != heap->empty_fixed_array()) { | 1513 if (sfi->scope_info() != heap->empty_fixed_array()) { |
1511 heap->RecordFixedArraySubTypeStats( | 1514 heap->object_stats_->RecordFixedArraySubTypeStats( |
1512 SCOPE_INFO_SUB_TYPE, FixedArray::cast(sfi->scope_info())->Size()); | 1515 SCOPE_INFO_SUB_TYPE, FixedArray::cast(sfi->scope_info())->Size()); |
1513 } | 1516 } |
1514 ObjectStatsVisitBase(kVisitSharedFunctionInfo, map, obj); | 1517 ObjectStatsVisitBase(kVisitSharedFunctionInfo, map, obj); |
1515 } | 1518 } |
1516 }; | 1519 }; |
1517 | 1520 |
1518 | 1521 |
1519 template <> | 1522 template <> |
1520 class MarkCompactMarkingVisitor::ObjectStatsTracker< | 1523 class MarkCompactMarkingVisitor::ObjectStatsTracker< |
1521 MarkCompactMarkingVisitor::kVisitFixedArray> { | 1524 MarkCompactMarkingVisitor::kVisitFixedArray> { |
1522 public: | 1525 public: |
1523 static inline void Visit(Map* map, HeapObject* obj) { | 1526 static inline void Visit(Map* map, HeapObject* obj) { |
1524 Heap* heap = map->GetHeap(); | 1527 Heap* heap = map->GetHeap(); |
1525 FixedArray* fixed_array = FixedArray::cast(obj); | 1528 FixedArray* fixed_array = FixedArray::cast(obj); |
1526 if (fixed_array == heap->string_table()) { | 1529 if (fixed_array == heap->string_table()) { |
1527 heap->RecordFixedArraySubTypeStats(STRING_TABLE_SUB_TYPE, | 1530 heap->object_stats_->RecordFixedArraySubTypeStats(STRING_TABLE_SUB_TYPE, |
1528 fixed_array->Size()); | 1531 fixed_array->Size()); |
1529 } | 1532 } |
1530 ObjectStatsVisitBase(kVisitFixedArray, map, obj); | 1533 ObjectStatsVisitBase(kVisitFixedArray, map, obj); |
1531 } | 1534 } |
1532 }; | 1535 }; |
1533 | 1536 |
1534 | 1537 |
1535 void MarkCompactMarkingVisitor::Initialize() { | 1538 void MarkCompactMarkingVisitor::Initialize() { |
1536 StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); | 1539 StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); |
1537 | 1540 |
1538 table_.Register(kVisitJSRegExp, &VisitRegExpAndFlushCode); | 1541 table_.Register(kVisitJSRegExp, &VisitRegExpAndFlushCode); |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2336 heap()->isolate()->global_handles()->RemoveObjectGroups(); | 2339 heap()->isolate()->global_handles()->RemoveObjectGroups(); |
2337 heap()->isolate()->global_handles()->RemoveImplicitRefGroups(); | 2340 heap()->isolate()->global_handles()->RemoveImplicitRefGroups(); |
2338 | 2341 |
2339 // Flush code from collected candidates. | 2342 // Flush code from collected candidates. |
2340 if (is_code_flushing_enabled()) { | 2343 if (is_code_flushing_enabled()) { |
2341 code_flusher_->ProcessCandidates(); | 2344 code_flusher_->ProcessCandidates(); |
2342 } | 2345 } |
2343 | 2346 |
2344 if (FLAG_track_gc_object_stats) { | 2347 if (FLAG_track_gc_object_stats) { |
2345 if (FLAG_trace_gc_object_stats) { | 2348 if (FLAG_trace_gc_object_stats) { |
2346 heap()->TraceObjectStats(); | 2349 heap()->object_stats_->TraceObjectStats(); |
2347 } | 2350 } |
2348 heap()->CheckpointObjectStats(); | 2351 heap()->object_stats_->CheckpointObjectStats(); |
2349 } | 2352 } |
2350 } | 2353 } |
2351 | 2354 |
2352 | 2355 |
2353 void MarkCompactCollector::ClearNonLiveReferences() { | 2356 void MarkCompactCollector::ClearNonLiveReferences() { |
2354 // Iterate over the map space, setting map transitions that go from | 2357 // Iterate over the map space, setting map transitions that go from |
2355 // a marked map to an unmarked map to null transitions. This action | 2358 // a marked map to an unmarked map to null transitions. This action |
2356 // is carried out only on maps of JSObjects and related subtypes. | 2359 // is carried out only on maps of JSObjects and related subtypes. |
2357 HeapObjectIterator map_iterator(heap()->map_space()); | 2360 HeapObjectIterator map_iterator(heap()->map_space()); |
2358 for (HeapObject* obj = map_iterator.Next(); obj != NULL; | 2361 for (HeapObject* obj = map_iterator.Next(); obj != NULL; |
(...skipping 2454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4813 SlotsBuffer* buffer = *buffer_address; | 4816 SlotsBuffer* buffer = *buffer_address; |
4814 while (buffer != NULL) { | 4817 while (buffer != NULL) { |
4815 SlotsBuffer* next_buffer = buffer->next(); | 4818 SlotsBuffer* next_buffer = buffer->next(); |
4816 DeallocateBuffer(buffer); | 4819 DeallocateBuffer(buffer); |
4817 buffer = next_buffer; | 4820 buffer = next_buffer; |
4818 } | 4821 } |
4819 *buffer_address = NULL; | 4822 *buffer_address = NULL; |
4820 } | 4823 } |
4821 } // namespace internal | 4824 } // namespace internal |
4822 } // namespace v8 | 4825 } // namespace v8 |
OLD | NEW |