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" |
(...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1222 if (code_flusher_ != NULL) { | 1222 if (code_flusher_ != NULL) { |
1223 delete code_flusher_; | 1223 delete code_flusher_; |
1224 code_flusher_ = NULL; | 1224 code_flusher_ = NULL; |
1225 } | 1225 } |
1226 } | 1226 } |
1227 | 1227 |
1228 | 1228 |
1229 class MarkCompactMarkingVisitor | 1229 class MarkCompactMarkingVisitor |
1230 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { | 1230 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { |
1231 public: | 1231 public: |
1232 static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id, Map* map, | |
1233 HeapObject* obj); | |
1234 | |
1235 static void ObjectStatsCountFixedArray( | |
1236 FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type, | |
1237 FixedArraySubInstanceType dictionary_type); | |
1238 | |
1239 template <MarkCompactMarkingVisitor::VisitorId id> | |
1240 class ObjectStatsTracker { | |
1241 public: | |
1242 static inline void Visit(Map* map, HeapObject* obj); | |
1243 }; | |
1244 | |
1245 static void Initialize(); | 1232 static void Initialize(); |
1246 | 1233 |
1247 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) { | 1234 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) { |
1248 MarkObjectByPointer(heap->mark_compact_collector(), object, p); | 1235 MarkObjectByPointer(heap->mark_compact_collector(), object, p); |
1249 } | 1236 } |
1250 | 1237 |
1251 INLINE(static void VisitPointers(Heap* heap, HeapObject* object, | 1238 INLINE(static void VisitPointers(Heap* heap, HeapObject* object, |
1252 Object** start, Object** end)) { | 1239 Object** start, Object** end)) { |
1253 // Mark all objects pointed to in [start, end). | 1240 // Mark all objects pointed to in [start, end). |
1254 const int kMinRangeForMarkingRecursion = 64; | 1241 const int kMinRangeForMarkingRecursion = 64; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1397 VisitJSRegExp(map, object); | 1384 VisitJSRegExp(map, object); |
1398 return; | 1385 return; |
1399 } | 1386 } |
1400 JSRegExp* re = reinterpret_cast<JSRegExp*>(object); | 1387 JSRegExp* re = reinterpret_cast<JSRegExp*>(object); |
1401 // Flush code or set age on both one byte and two byte code. | 1388 // Flush code or set age on both one byte and two byte code. |
1402 UpdateRegExpCodeAgeAndFlush(heap, re, true); | 1389 UpdateRegExpCodeAgeAndFlush(heap, re, true); |
1403 UpdateRegExpCodeAgeAndFlush(heap, re, false); | 1390 UpdateRegExpCodeAgeAndFlush(heap, re, false); |
1404 // Visit the fields of the RegExp, including the updated FixedArray. | 1391 // Visit the fields of the RegExp, including the updated FixedArray. |
1405 VisitJSRegExp(map, object); | 1392 VisitJSRegExp(map, object); |
1406 } | 1393 } |
1407 | |
1408 static VisitorDispatchTable<Callback> non_count_table_; | |
1409 }; | |
1410 | |
1411 | |
1412 void MarkCompactMarkingVisitor::ObjectStatsCountFixedArray( | |
1413 FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type, | |
1414 FixedArraySubInstanceType dictionary_type) { | |
1415 Heap* heap = fixed_array->map()->GetHeap(); | |
1416 if (fixed_array->map() != heap->fixed_cow_array_map() && | |
1417 fixed_array->map() != heap->fixed_double_array_map() && | |
1418 fixed_array != heap->empty_fixed_array()) { | |
1419 if (fixed_array->IsDictionary()) { | |
1420 heap->object_stats_->RecordFixedArraySubTypeStats(dictionary_type, | |
1421 fixed_array->Size()); | |
1422 } else { | |
1423 heap->object_stats_->RecordFixedArraySubTypeStats(fast_type, | |
1424 fixed_array->Size()); | |
1425 } | |
1426 } | |
1427 } | |
1428 | |
1429 | |
1430 void MarkCompactMarkingVisitor::ObjectStatsVisitBase( | |
1431 MarkCompactMarkingVisitor::VisitorId id, Map* map, HeapObject* obj) { | |
1432 Heap* heap = map->GetHeap(); | |
1433 int object_size = obj->Size(); | |
1434 heap->object_stats_->RecordObjectStats(map->instance_type(), object_size); | |
1435 non_count_table_.GetVisitorById(id)(map, obj); | |
1436 if (obj->IsJSObject()) { | |
1437 JSObject* object = JSObject::cast(obj); | |
1438 ObjectStatsCountFixedArray(object->elements(), DICTIONARY_ELEMENTS_SUB_TYPE, | |
1439 FAST_ELEMENTS_SUB_TYPE); | |
1440 ObjectStatsCountFixedArray(object->properties(), | |
1441 DICTIONARY_PROPERTIES_SUB_TYPE, | |
1442 FAST_PROPERTIES_SUB_TYPE); | |
1443 } | |
1444 } | |
1445 | |
1446 | |
1447 template <MarkCompactMarkingVisitor::VisitorId id> | |
1448 void MarkCompactMarkingVisitor::ObjectStatsTracker<id>::Visit(Map* map, | |
1449 HeapObject* obj) { | |
1450 ObjectStatsVisitBase(id, map, obj); | |
1451 } | |
1452 | |
1453 | |
1454 template <> | |
1455 class MarkCompactMarkingVisitor::ObjectStatsTracker< | |
1456 MarkCompactMarkingVisitor::kVisitMap> { | |
1457 public: | |
1458 static inline void Visit(Map* map, HeapObject* obj) { | |
1459 Heap* heap = map->GetHeap(); | |
1460 Map* map_obj = Map::cast(obj); | |
1461 DCHECK(map->instance_type() == MAP_TYPE); | |
1462 DescriptorArray* array = map_obj->instance_descriptors(); | |
1463 if (map_obj->owns_descriptors() && | |
1464 array != heap->empty_descriptor_array()) { | |
1465 int fixed_array_size = array->Size(); | |
1466 heap->object_stats_->RecordFixedArraySubTypeStats( | |
1467 DESCRIPTOR_ARRAY_SUB_TYPE, fixed_array_size); | |
1468 } | |
1469 if (TransitionArray::IsFullTransitionArray(map_obj->raw_transitions())) { | |
1470 int fixed_array_size = | |
1471 TransitionArray::cast(map_obj->raw_transitions())->Size(); | |
1472 heap->object_stats_->RecordFixedArraySubTypeStats( | |
1473 TRANSITION_ARRAY_SUB_TYPE, fixed_array_size); | |
1474 } | |
1475 if (map_obj->has_code_cache()) { | |
1476 CodeCache* cache = CodeCache::cast(map_obj->code_cache()); | |
1477 heap->object_stats_->RecordFixedArraySubTypeStats( | |
1478 MAP_CODE_CACHE_SUB_TYPE, cache->default_cache()->Size()); | |
1479 if (!cache->normal_type_cache()->IsUndefined()) { | |
1480 heap->object_stats_->RecordFixedArraySubTypeStats( | |
1481 MAP_CODE_CACHE_SUB_TYPE, | |
1482 FixedArray::cast(cache->normal_type_cache())->Size()); | |
1483 } | |
1484 } | |
1485 ObjectStatsVisitBase(kVisitMap, map, obj); | |
1486 } | |
1487 }; | 1394 }; |
1488 | 1395 |
1489 | 1396 |
1490 template <> | |
1491 class MarkCompactMarkingVisitor::ObjectStatsTracker< | |
1492 MarkCompactMarkingVisitor::kVisitCode> { | |
1493 public: | |
1494 static inline void Visit(Map* map, HeapObject* obj) { | |
1495 Heap* heap = map->GetHeap(); | |
1496 int object_size = obj->Size(); | |
1497 DCHECK(map->instance_type() == CODE_TYPE); | |
1498 Code* code_obj = Code::cast(obj); | |
1499 heap->object_stats_->RecordCodeSubTypeStats( | |
1500 code_obj->kind(), code_obj->GetAge(), object_size); | |
1501 ObjectStatsVisitBase(kVisitCode, map, obj); | |
1502 } | |
1503 }; | |
1504 | |
1505 | |
1506 template <> | |
1507 class MarkCompactMarkingVisitor::ObjectStatsTracker< | |
1508 MarkCompactMarkingVisitor::kVisitSharedFunctionInfo> { | |
1509 public: | |
1510 static inline void Visit(Map* map, HeapObject* obj) { | |
1511 Heap* heap = map->GetHeap(); | |
1512 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); | |
1513 if (sfi->scope_info() != heap->empty_fixed_array()) { | |
1514 heap->object_stats_->RecordFixedArraySubTypeStats( | |
1515 SCOPE_INFO_SUB_TYPE, FixedArray::cast(sfi->scope_info())->Size()); | |
1516 } | |
1517 ObjectStatsVisitBase(kVisitSharedFunctionInfo, map, obj); | |
1518 } | |
1519 }; | |
1520 | |
1521 | |
1522 template <> | |
1523 class MarkCompactMarkingVisitor::ObjectStatsTracker< | |
1524 MarkCompactMarkingVisitor::kVisitFixedArray> { | |
1525 public: | |
1526 static inline void Visit(Map* map, HeapObject* obj) { | |
1527 Heap* heap = map->GetHeap(); | |
1528 FixedArray* fixed_array = FixedArray::cast(obj); | |
1529 if (fixed_array == heap->string_table()) { | |
1530 heap->object_stats_->RecordFixedArraySubTypeStats(STRING_TABLE_SUB_TYPE, | |
1531 fixed_array->Size()); | |
1532 } | |
1533 ObjectStatsVisitBase(kVisitFixedArray, map, obj); | |
1534 } | |
1535 }; | |
1536 | |
1537 | |
1538 void MarkCompactMarkingVisitor::Initialize() { | 1397 void MarkCompactMarkingVisitor::Initialize() { |
1539 StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); | 1398 StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); |
1540 | 1399 |
1541 table_.Register(kVisitJSRegExp, &VisitRegExpAndFlushCode); | 1400 table_.Register(kVisitJSRegExp, &VisitRegExpAndFlushCode); |
1542 | 1401 |
1543 if (FLAG_track_gc_object_stats) { | 1402 if (FLAG_track_gc_object_stats) { |
1544 // Copy the visitor table to make call-through possible. | 1403 ObjectStatsVisitor::Initialize(&table_); |
1545 non_count_table_.CopyFrom(&table_); | |
1546 #define VISITOR_ID_COUNT_FUNCTION(id) \ | |
1547 table_.Register(kVisit##id, ObjectStatsTracker<kVisit##id>::Visit); | |
1548 VISITOR_ID_LIST(VISITOR_ID_COUNT_FUNCTION) | |
1549 #undef VISITOR_ID_COUNT_FUNCTION | |
1550 } | 1404 } |
1551 } | 1405 } |
1552 | 1406 |
1553 | 1407 |
1554 VisitorDispatchTable<MarkCompactMarkingVisitor::Callback> | |
1555 MarkCompactMarkingVisitor::non_count_table_; | |
1556 | |
1557 | |
1558 class CodeMarkingVisitor : public ThreadVisitor { | 1408 class CodeMarkingVisitor : public ThreadVisitor { |
1559 public: | 1409 public: |
1560 explicit CodeMarkingVisitor(MarkCompactCollector* collector) | 1410 explicit CodeMarkingVisitor(MarkCompactCollector* collector) |
1561 : collector_(collector) {} | 1411 : collector_(collector) {} |
1562 | 1412 |
1563 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 1413 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
1564 collector_->PrepareThreadForCodeFlushing(isolate, top); | 1414 collector_->PrepareThreadForCodeFlushing(isolate, top); |
1565 } | 1415 } |
1566 | 1416 |
1567 private: | 1417 private: |
(...skipping 3248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4816 SlotsBuffer* buffer = *buffer_address; | 4666 SlotsBuffer* buffer = *buffer_address; |
4817 while (buffer != NULL) { | 4667 while (buffer != NULL) { |
4818 SlotsBuffer* next_buffer = buffer->next(); | 4668 SlotsBuffer* next_buffer = buffer->next(); |
4819 DeallocateBuffer(buffer); | 4669 DeallocateBuffer(buffer); |
4820 buffer = next_buffer; | 4670 buffer = next_buffer; |
4821 } | 4671 } |
4822 *buffer_address = NULL; | 4672 *buffer_address = NULL; |
4823 } | 4673 } |
4824 } // namespace internal | 4674 } // namespace internal |
4825 } // namespace v8 | 4675 } // namespace v8 |
OLD | NEW |