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