OLD | NEW |
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 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 // start and size. The provided space is divided into two semi-spaces. | 1165 // start and size. The provided space is divided into two semi-spaces. |
1166 // To support fast containment testing in the new space, the size of | 1166 // To support fast containment testing in the new space, the size of |
1167 // this chunk must be a power of two and it must be aligned to its size. | 1167 // this chunk must be a power of two and it must be aligned to its size. |
1168 int initial_semispace_capacity = heap()->InitialSemiSpaceSize(); | 1168 int initial_semispace_capacity = heap()->InitialSemiSpaceSize(); |
1169 int maximum_semispace_capacity = heap()->MaxSemiSpaceSize(); | 1169 int maximum_semispace_capacity = heap()->MaxSemiSpaceSize(); |
1170 | 1170 |
1171 ASSERT(initial_semispace_capacity <= maximum_semispace_capacity); | 1171 ASSERT(initial_semispace_capacity <= maximum_semispace_capacity); |
1172 ASSERT(IsPowerOf2(maximum_semispace_capacity)); | 1172 ASSERT(IsPowerOf2(maximum_semispace_capacity)); |
1173 | 1173 |
1174 // Allocate and setup the histogram arrays if necessary. | 1174 // Allocate and setup the histogram arrays if necessary. |
1175 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | |
1176 allocated_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1); | 1175 allocated_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1); |
1177 promoted_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1); | 1176 promoted_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1); |
1178 | 1177 |
1179 #define SET_NAME(name) allocated_histogram_[name].set_name(#name); \ | 1178 #define SET_NAME(name) allocated_histogram_[name].set_name(#name); \ |
1180 promoted_histogram_[name].set_name(#name); | 1179 promoted_histogram_[name].set_name(#name); |
1181 INSTANCE_TYPE_LIST(SET_NAME) | 1180 INSTANCE_TYPE_LIST(SET_NAME) |
1182 #undef SET_NAME | 1181 #undef SET_NAME |
1183 #endif | |
1184 | 1182 |
1185 ASSERT(size == 2 * heap()->ReservedSemiSpaceSize()); | 1183 ASSERT(size == 2 * heap()->ReservedSemiSpaceSize()); |
1186 ASSERT(IsAddressAligned(start, size, 0)); | 1184 ASSERT(IsAddressAligned(start, size, 0)); |
1187 | 1185 |
1188 if (!to_space_.Setup(start, | 1186 if (!to_space_.Setup(start, |
1189 initial_semispace_capacity, | 1187 initial_semispace_capacity, |
1190 maximum_semispace_capacity)) { | 1188 maximum_semispace_capacity)) { |
1191 return false; | 1189 return false; |
1192 } | 1190 } |
1193 if (!from_space_.Setup(start + maximum_semispace_capacity, | 1191 if (!from_space_.Setup(start + maximum_semispace_capacity, |
(...skipping 11 matching lines...) Expand all Loading... |
1205 allocation_info_.limit = to_space_.high(); | 1203 allocation_info_.limit = to_space_.high(); |
1206 mc_forwarding_info_.top = NULL; | 1204 mc_forwarding_info_.top = NULL; |
1207 mc_forwarding_info_.limit = NULL; | 1205 mc_forwarding_info_.limit = NULL; |
1208 | 1206 |
1209 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1207 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
1210 return true; | 1208 return true; |
1211 } | 1209 } |
1212 | 1210 |
1213 | 1211 |
1214 void NewSpace::TearDown() { | 1212 void NewSpace::TearDown() { |
1215 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | |
1216 if (allocated_histogram_) { | 1213 if (allocated_histogram_) { |
1217 DeleteArray(allocated_histogram_); | 1214 DeleteArray(allocated_histogram_); |
1218 allocated_histogram_ = NULL; | 1215 allocated_histogram_ = NULL; |
1219 } | 1216 } |
1220 if (promoted_histogram_) { | 1217 if (promoted_histogram_) { |
1221 DeleteArray(promoted_histogram_); | 1218 DeleteArray(promoted_histogram_); |
1222 promoted_histogram_ = NULL; | 1219 promoted_histogram_ = NULL; |
1223 } | 1220 } |
1224 #endif | |
1225 | 1221 |
1226 start_ = NULL; | 1222 start_ = NULL; |
1227 allocation_info_.top = NULL; | 1223 allocation_info_.top = NULL; |
1228 allocation_info_.limit = NULL; | 1224 allocation_info_.limit = NULL; |
1229 mc_forwarding_info_.top = NULL; | 1225 mc_forwarding_info_.top = NULL; |
1230 mc_forwarding_info_.limit = NULL; | 1226 mc_forwarding_info_.limit = NULL; |
1231 | 1227 |
1232 to_space_.TearDown(); | 1228 to_space_.TearDown(); |
1233 from_space_.TearDown(); | 1229 from_space_.TearDown(); |
1234 } | 1230 } |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1589 } | 1585 } |
1590 | 1586 |
1591 if (FLAG_collect_heap_spill_statistics && print_spill) { | 1587 if (FLAG_collect_heap_spill_statistics && print_spill) { |
1592 isolate->js_spill_information()->Print(); | 1588 isolate->js_spill_information()->Print(); |
1593 } | 1589 } |
1594 } | 1590 } |
1595 #endif // DEBUG | 1591 #endif // DEBUG |
1596 | 1592 |
1597 | 1593 |
1598 // Support for statistics gathering for --heap-stats and --log-gc. | 1594 // Support for statistics gathering for --heap-stats and --log-gc. |
1599 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | |
1600 void NewSpace::ClearHistograms() { | 1595 void NewSpace::ClearHistograms() { |
1601 for (int i = 0; i <= LAST_TYPE; i++) { | 1596 for (int i = 0; i <= LAST_TYPE; i++) { |
1602 allocated_histogram_[i].clear(); | 1597 allocated_histogram_[i].clear(); |
1603 promoted_histogram_[i].clear(); | 1598 promoted_histogram_[i].clear(); |
1604 } | 1599 } |
1605 } | 1600 } |
1606 | 1601 |
1607 // Because the copying collector does not touch garbage objects, we iterate | 1602 // Because the copying collector does not touch garbage objects, we iterate |
1608 // the new space before a collection to get a histogram of allocated objects. | 1603 // the new space before a collection to get a histogram of allocated objects. |
1609 // This only happens (1) when compiled with DEBUG and the --heap-stats flag is | 1604 // This only happens when --log-gc flag is set. |
1610 // set, or when compiled with ENABLE_LOGGING_AND_PROFILING and the --log-gc | |
1611 // flag is set. | |
1612 void NewSpace::CollectStatistics() { | 1605 void NewSpace::CollectStatistics() { |
1613 ClearHistograms(); | 1606 ClearHistograms(); |
1614 SemiSpaceIterator it(this); | 1607 SemiSpaceIterator it(this); |
1615 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) | 1608 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) |
1616 RecordAllocation(obj); | 1609 RecordAllocation(obj); |
1617 } | 1610 } |
1618 | 1611 |
1619 | 1612 |
1620 #ifdef ENABLE_LOGGING_AND_PROFILING | |
1621 static void DoReportStatistics(Isolate* isolate, | 1613 static void DoReportStatistics(Isolate* isolate, |
1622 HistogramInfo* info, const char* description) { | 1614 HistogramInfo* info, const char* description) { |
1623 LOG(isolate, HeapSampleBeginEvent("NewSpace", description)); | 1615 LOG(isolate, HeapSampleBeginEvent("NewSpace", description)); |
1624 // Lump all the string types together. | 1616 // Lump all the string types together. |
1625 int string_number = 0; | 1617 int string_number = 0; |
1626 int string_bytes = 0; | 1618 int string_bytes = 0; |
1627 #define INCREMENT(type, size, name, camel_name) \ | 1619 #define INCREMENT(type, size, name, camel_name) \ |
1628 string_number += info[type].number(); \ | 1620 string_number += info[type].number(); \ |
1629 string_bytes += info[type].bytes(); | 1621 string_bytes += info[type].bytes(); |
1630 STRING_TYPE_LIST(INCREMENT) | 1622 STRING_TYPE_LIST(INCREMENT) |
1631 #undef INCREMENT | 1623 #undef INCREMENT |
1632 if (string_number > 0) { | 1624 if (string_number > 0) { |
1633 LOG(isolate, | 1625 LOG(isolate, |
1634 HeapSampleItemEvent("STRING_TYPE", string_number, string_bytes)); | 1626 HeapSampleItemEvent("STRING_TYPE", string_number, string_bytes)); |
1635 } | 1627 } |
1636 | 1628 |
1637 // Then do the other types. | 1629 // Then do the other types. |
1638 for (int i = FIRST_NONSTRING_TYPE; i <= LAST_TYPE; ++i) { | 1630 for (int i = FIRST_NONSTRING_TYPE; i <= LAST_TYPE; ++i) { |
1639 if (info[i].number() > 0) { | 1631 if (info[i].number() > 0) { |
1640 LOG(isolate, | 1632 LOG(isolate, |
1641 HeapSampleItemEvent(info[i].name(), info[i].number(), | 1633 HeapSampleItemEvent(info[i].name(), info[i].number(), |
1642 info[i].bytes())); | 1634 info[i].bytes())); |
1643 } | 1635 } |
1644 } | 1636 } |
1645 LOG(isolate, HeapSampleEndEvent("NewSpace", description)); | 1637 LOG(isolate, HeapSampleEndEvent("NewSpace", description)); |
1646 } | 1638 } |
1647 #endif // ENABLE_LOGGING_AND_PROFILING | |
1648 | 1639 |
1649 | 1640 |
1650 void NewSpace::ReportStatistics() { | 1641 void NewSpace::ReportStatistics() { |
1651 #ifdef DEBUG | 1642 #ifdef DEBUG |
1652 if (FLAG_heap_stats) { | 1643 if (FLAG_heap_stats) { |
1653 float pct = static_cast<float>(Available()) / Capacity(); | 1644 float pct = static_cast<float>(Available()) / Capacity(); |
1654 PrintF(" capacity: %" V8_PTR_PREFIX "d" | 1645 PrintF(" capacity: %" V8_PTR_PREFIX "d" |
1655 ", available: %" V8_PTR_PREFIX "d, %%%d\n", | 1646 ", available: %" V8_PTR_PREFIX "d, %%%d\n", |
1656 Capacity(), Available(), static_cast<int>(pct*100)); | 1647 Capacity(), Available(), static_cast<int>(pct*100)); |
1657 PrintF("\n Object Histogram:\n"); | 1648 PrintF("\n Object Histogram:\n"); |
1658 for (int i = 0; i <= LAST_TYPE; i++) { | 1649 for (int i = 0; i <= LAST_TYPE; i++) { |
1659 if (allocated_histogram_[i].number() > 0) { | 1650 if (allocated_histogram_[i].number() > 0) { |
1660 PrintF(" %-34s%10d (%10d bytes)\n", | 1651 PrintF(" %-34s%10d (%10d bytes)\n", |
1661 allocated_histogram_[i].name(), | 1652 allocated_histogram_[i].name(), |
1662 allocated_histogram_[i].number(), | 1653 allocated_histogram_[i].number(), |
1663 allocated_histogram_[i].bytes()); | 1654 allocated_histogram_[i].bytes()); |
1664 } | 1655 } |
1665 } | 1656 } |
1666 PrintF("\n"); | 1657 PrintF("\n"); |
1667 } | 1658 } |
1668 #endif // DEBUG | 1659 #endif // DEBUG |
1669 | 1660 |
1670 #ifdef ENABLE_LOGGING_AND_PROFILING | |
1671 if (FLAG_log_gc) { | 1661 if (FLAG_log_gc) { |
1672 Isolate* isolate = ISOLATE; | 1662 Isolate* isolate = ISOLATE; |
1673 DoReportStatistics(isolate, allocated_histogram_, "allocated"); | 1663 DoReportStatistics(isolate, allocated_histogram_, "allocated"); |
1674 DoReportStatistics(isolate, promoted_histogram_, "promoted"); | 1664 DoReportStatistics(isolate, promoted_histogram_, "promoted"); |
1675 } | 1665 } |
1676 #endif // ENABLE_LOGGING_AND_PROFILING | |
1677 } | 1666 } |
1678 | 1667 |
1679 | 1668 |
1680 void NewSpace::RecordAllocation(HeapObject* obj) { | 1669 void NewSpace::RecordAllocation(HeapObject* obj) { |
1681 InstanceType type = obj->map()->instance_type(); | 1670 InstanceType type = obj->map()->instance_type(); |
1682 ASSERT(0 <= type && type <= LAST_TYPE); | 1671 ASSERT(0 <= type && type <= LAST_TYPE); |
1683 allocated_histogram_[type].increment_number(1); | 1672 allocated_histogram_[type].increment_number(1); |
1684 allocated_histogram_[type].increment_bytes(obj->Size()); | 1673 allocated_histogram_[type].increment_bytes(obj->Size()); |
1685 } | 1674 } |
1686 | 1675 |
1687 | 1676 |
1688 void NewSpace::RecordPromotion(HeapObject* obj) { | 1677 void NewSpace::RecordPromotion(HeapObject* obj) { |
1689 InstanceType type = obj->map()->instance_type(); | 1678 InstanceType type = obj->map()->instance_type(); |
1690 ASSERT(0 <= type && type <= LAST_TYPE); | 1679 ASSERT(0 <= type && type <= LAST_TYPE); |
1691 promoted_histogram_[type].increment_number(1); | 1680 promoted_histogram_[type].increment_number(1); |
1692 promoted_histogram_[type].increment_bytes(obj->Size()); | 1681 promoted_histogram_[type].increment_bytes(obj->Size()); |
1693 } | 1682 } |
1694 #endif // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | |
1695 | 1683 |
1696 | 1684 |
1697 // ----------------------------------------------------------------------------- | 1685 // ----------------------------------------------------------------------------- |
1698 // Free lists for old object spaces implementation | 1686 // Free lists for old object spaces implementation |
1699 | 1687 |
1700 void FreeListNode::set_size(Heap* heap, int size_in_bytes) { | 1688 void FreeListNode::set_size(Heap* heap, int size_in_bytes) { |
1701 ASSERT(size_in_bytes > 0); | 1689 ASSERT(size_in_bytes > 0); |
1702 ASSERT(IsAligned(size_in_bytes, kPointerSize)); | 1690 ASSERT(IsAligned(size_in_bytes, kPointerSize)); |
1703 | 1691 |
1704 // We write a map and possibly size information to the block. If the block | 1692 // We write a map and possibly size information to the block. If the block |
(...skipping 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3069 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { | 3057 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { |
3070 if (obj->IsCode()) { | 3058 if (obj->IsCode()) { |
3071 Code* code = Code::cast(obj); | 3059 Code* code = Code::cast(obj); |
3072 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 3060 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
3073 } | 3061 } |
3074 } | 3062 } |
3075 } | 3063 } |
3076 #endif // DEBUG | 3064 #endif // DEBUG |
3077 | 3065 |
3078 } } // namespace v8::internal | 3066 } } // namespace v8::internal |
OLD | NEW |