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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 return name[type]; | 158 return name[type]; |
159 } | 159 } |
160 | 160 |
161 | 161 |
162 const char* GetObjectTypeDesc(HeapObject* heap_obj) { | 162 const char* GetObjectTypeDesc(HeapObject* heap_obj) { |
163 LiveObjectType type = GetObjectType(heap_obj); | 163 LiveObjectType type = GetObjectType(heap_obj); |
164 return GetObjectTypeDesc(type); | 164 return GetObjectTypeDesc(type); |
165 } | 165 } |
166 | 166 |
167 | 167 |
168 bool IsOfType(LiveObjectType type, HeapObject *obj) { | 168 bool IsOfType(LiveObjectType type, HeapObject* obj) { |
169 // Note: there are types that are more general (e.g. JSObject) that would | 169 // Note: there are types that are more general (e.g. JSObject) that would |
170 // have passed the Is##type_() test for more specialized types (e.g. | 170 // have passed the Is##type_() test for more specialized types (e.g. |
171 // JSFunction). If we find a more specialized match but we're looking for | 171 // JSFunction). If we find a more specialized match but we're looking for |
172 // the general type, then we should reject the ones that matches the | 172 // the general type, then we should reject the ones that matches the |
173 // specialized type. | 173 // specialized type. |
174 #define CHECK_OBJECT_TYPE(type_, name) \ | 174 #define CHECK_OBJECT_TYPE(type_, name) \ |
175 if (obj->Is##type_()) return (type == kType##type_); | 175 if (obj->Is##type_()) return (type == kType##type_); |
176 | 176 |
177 FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE) | 177 FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE) |
178 #undef CHECK_OBJECT_TYPE | 178 #undef CHECK_OBJECT_TYPE |
(...skipping 25 matching lines...) Expand all Loading... |
204 break; | 204 break; |
205 case 'o': | 205 case 'o': |
206 if (strcmp(key_str, "old-pointer") == 0) return OLD_POINTER_SPACE; | 206 if (strcmp(key_str, "old-pointer") == 0) return OLD_POINTER_SPACE; |
207 if (strcmp(key_str, "old-data") == 0) return OLD_DATA_SPACE; | 207 if (strcmp(key_str, "old-data") == 0) return OLD_DATA_SPACE; |
208 break; | 208 break; |
209 } | 209 } |
210 return kInvalidSpace; | 210 return kInvalidSpace; |
211 } | 211 } |
212 | 212 |
213 | 213 |
214 static bool InSpace(AllocationSpace space, HeapObject *heap_obj) { | 214 static bool InSpace(AllocationSpace space, HeapObject* heap_obj) { |
215 Heap* heap = ISOLATE->heap(); | 215 Heap* heap = ISOLATE->heap(); |
216 if (space != LO_SPACE) { | 216 if (space != LO_SPACE) { |
217 return heap->InSpace(heap_obj, space); | 217 return heap->InSpace(heap_obj, space); |
218 } | 218 } |
219 | 219 |
220 // This is an optimization to speed up the check for an object in the LO | 220 // This is an optimization to speed up the check for an object in the LO |
221 // space by exclusion because we know that all object pointers passed in | 221 // space by exclusion because we know that all object pointers passed in |
222 // here are guaranteed to be in the heap. Hence, it is safe to infer | 222 // here are guaranteed to be in the heap. Hence, it is safe to infer |
223 // using an exclusion test. | 223 // using an exclusion test. |
224 // Note: calling Heap::InSpace(heap_obj, LO_SPACE) is too slow for our | 224 // Note: calling Heap::InSpace(heap_obj, LO_SPACE) is too slow for our |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 if (obj->IsJSArray()) { | 491 if (obj->IsJSArray()) { |
492 JSArray* jsarray = JSArray::cast(obj); | 492 JSArray* jsarray = JSArray::cast(obj); |
493 double length = jsarray->length()->Number(); | 493 double length = jsarray->length()->Number(); |
494 OS::SNPrintF(buffer_v, | 494 OS::SNPrintF(buffer_v, |
495 "%p <%s> len %g", | 495 "%p <%s> len %g", |
496 reinterpret_cast<void*>(obj), | 496 reinterpret_cast<void*>(obj), |
497 GetObjectTypeDesc(obj), | 497 GetObjectTypeDesc(obj), |
498 length); | 498 length); |
499 | 499 |
500 } else if (obj->IsString()) { | 500 } else if (obj->IsString()) { |
501 String *str = String::cast(obj); | 501 String* str = String::cast(obj); |
502 // Only grab up to 160 chars in case they are double byte. | 502 // Only grab up to 160 chars in case they are double byte. |
503 // We'll only dump 80 of them after we compact them. | 503 // We'll only dump 80 of them after we compact them. |
504 const int kMaxCharToDump = 80; | 504 const int kMaxCharToDump = 80; |
505 const int kMaxBufferSize = kMaxCharToDump * 2; | 505 const int kMaxBufferSize = kMaxCharToDump * 2; |
506 SmartArrayPointer<char> str_sp = str->ToCString(DISALLOW_NULLS, | 506 SmartArrayPointer<char> str_sp = str->ToCString(DISALLOW_NULLS, |
507 ROBUST_STRING_TRAVERSAL, | 507 ROBUST_STRING_TRAVERSAL, |
508 0, | 508 0, |
509 kMaxBufferSize); | 509 kMaxBufferSize); |
510 char* str_cstr = *str_sp; | 510 char* str_cstr = *str_sp; |
511 int length = CompactString(str_cstr); | 511 int length = CompactString(str_cstr); |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 static const int kNumberOfEntries = kNumberOfTypes; | 835 static const int kNumberOfEntries = kNumberOfTypes; |
836 | 836 |
837 private: | 837 private: |
838 int counts_[kNumberOfEntries]; | 838 int counts_[kNumberOfEntries]; |
839 int sizes_[kNumberOfEntries]; | 839 int sizes_[kNumberOfEntries]; |
840 int total_count_; | 840 int total_count_; |
841 int total_size_; | 841 int total_size_; |
842 bool found_root_; | 842 bool found_root_; |
843 bool found_weak_root_; | 843 bool found_weak_root_; |
844 | 844 |
845 LolFilter *filter_; | 845 LolFilter* filter_; |
846 }; | 846 }; |
847 | 847 |
848 | 848 |
849 // Abstraction for a summary writer. | 849 // Abstraction for a summary writer. |
850 class SummaryWriter { | 850 class SummaryWriter { |
851 public: | 851 public: |
852 virtual ~SummaryWriter() {} | 852 virtual ~SummaryWriter() {} |
853 virtual void Write(LiveObjectSummary* summary) = 0; | 853 virtual void Write(LiveObjectSummary* summary) = 0; |
854 }; | 854 }; |
855 | 855 |
856 | 856 |
857 // A summary writer for filling in a summary of lol lists and diffs. | 857 // A summary writer for filling in a summary of lol lists and diffs. |
858 class LolSummaryWriter: public SummaryWriter { | 858 class LolSummaryWriter: public SummaryWriter { |
859 public: | 859 public: |
860 LolSummaryWriter(LiveObjectList *older_lol, | 860 LolSummaryWriter(LiveObjectList* older_lol, |
861 LiveObjectList *newer_lol) | 861 LiveObjectList* newer_lol) |
862 : older_(older_lol), newer_(newer_lol) { | 862 : older_(older_lol), newer_(newer_lol) { |
863 } | 863 } |
864 | 864 |
865 void Write(LiveObjectSummary* summary) { | 865 void Write(LiveObjectSummary* summary) { |
866 LolFilter* filter = summary->filter(); | 866 LolFilter* filter = summary->filter(); |
867 | 867 |
868 // Fill the summary with the lol object details. | 868 // Fill the summary with the lol object details. |
869 LolIterator it(older_, newer_); | 869 LolIterator it(older_, newer_); |
870 for (it.Init(); !it.Done(); it.Next()) { | 870 for (it.Init(); !it.Done(); it.Next()) { |
871 HeapObject* heap_obj = it.Obj(); | 871 HeapObject* heap_obj = it.Obj(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 | 937 |
938 LiveObjectList::~LiveObjectList() { | 938 LiveObjectList::~LiveObjectList() { |
939 DeleteArray<Element>(elements_); | 939 DeleteArray<Element>(elements_); |
940 delete prev_; | 940 delete prev_; |
941 } | 941 } |
942 | 942 |
943 | 943 |
944 int LiveObjectList::GetTotalObjCountAndSize(int* size_p) { | 944 int LiveObjectList::GetTotalObjCountAndSize(int* size_p) { |
945 int size = 0; | 945 int size = 0; |
946 int count = 0; | 946 int count = 0; |
947 LiveObjectList *lol = this; | 947 LiveObjectList* lol = this; |
948 do { | 948 do { |
949 // Only compute total size if requested i.e. when size_p is not null. | 949 // Only compute total size if requested i.e. when size_p is not null. |
950 if (size_p != NULL) { | 950 if (size_p != NULL) { |
951 Element* elements = lol->elements_; | 951 Element* elements = lol->elements_; |
952 for (int i = 0; i < lol->obj_count_; i++) { | 952 for (int i = 0; i < lol->obj_count_; i++) { |
953 HeapObject* heap_obj = elements[i].obj_; | 953 HeapObject* heap_obj = elements[i].obj_; |
954 size += heap_obj->Size(); | 954 size += heap_obj->Size(); |
955 } | 955 } |
956 } | 956 } |
957 count += lol->obj_count_; | 957 count += lol->obj_count_; |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1176 | 1176 |
1177 return *result; | 1177 return *result; |
1178 } | 1178 } |
1179 | 1179 |
1180 | 1180 |
1181 // Delete doesn't actually deletes an lol. It just marks it as invisible since | 1181 // Delete doesn't actually deletes an lol. It just marks it as invisible since |
1182 // its contents are considered to be part of subsequent lists as well. The | 1182 // its contents are considered to be part of subsequent lists as well. The |
1183 // only time we'll actually delete the lol is when we Reset() or if the lol is | 1183 // only time we'll actually delete the lol is when we Reset() or if the lol is |
1184 // invisible, and its element count reaches 0. | 1184 // invisible, and its element count reaches 0. |
1185 bool LiveObjectList::Delete(int id) { | 1185 bool LiveObjectList::Delete(int id) { |
1186 LiveObjectList *lol = last(); | 1186 LiveObjectList* lol = last(); |
1187 while (lol != NULL) { | 1187 while (lol != NULL) { |
1188 if (lol->id() == id) { | 1188 if (lol->id() == id) { |
1189 break; | 1189 break; |
1190 } | 1190 } |
1191 lol = lol->prev_; | 1191 lol = lol->prev_; |
1192 } | 1192 } |
1193 | 1193 |
1194 // If no lol is found for this id, then we fail to delete. | 1194 // If no lol is found for this id, then we fail to delete. |
1195 if (lol == NULL) return false; | 1195 if (lol == NULL) return false; |
1196 | 1196 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) { | 1239 if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) { |
1240 return Failure::Exception(); // Fail: 0 is not a valid lol id. | 1240 return Failure::Exception(); // Fail: 0 is not a valid lol id. |
1241 } | 1241 } |
1242 if (newer_id < older_id) { | 1242 if (newer_id < older_id) { |
1243 // They are not in the expected order. Swap them. | 1243 // They are not in the expected order. Swap them. |
1244 int temp = older_id; | 1244 int temp = older_id; |
1245 older_id = newer_id; | 1245 older_id = newer_id; |
1246 newer_id = temp; | 1246 newer_id = temp; |
1247 } | 1247 } |
1248 | 1248 |
1249 LiveObjectList *newer_lol = FindLolForId(newer_id, last()); | 1249 LiveObjectList* newer_lol = FindLolForId(newer_id, last()); |
1250 LiveObjectList *older_lol = FindLolForId(older_id, newer_lol); | 1250 LiveObjectList* older_lol = FindLolForId(older_id, newer_lol); |
1251 | 1251 |
1252 // If the id is defined, and we can't find a LOL for it, then we have an | 1252 // If the id is defined, and we can't find a LOL for it, then we have an |
1253 // invalid id. | 1253 // invalid id. |
1254 if ((newer_id != 0) && (newer_lol == NULL)) { | 1254 if ((newer_id != 0) && (newer_lol == NULL)) { |
1255 return Failure::Exception(); // Fail: the newer lol id is invalid. | 1255 return Failure::Exception(); // Fail: the newer lol id is invalid. |
1256 } | 1256 } |
1257 if ((older_id != 0) && (older_lol == NULL)) { | 1257 if ((older_id != 0) && (older_lol == NULL)) { |
1258 return Failure::Exception(); // Fail: the older lol id is invalid. | 1258 return Failure::Exception(); // Fail: the older lol id is invalid. |
1259 } | 1259 } |
1260 | 1260 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1358 if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) { | 1358 if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) { |
1359 return Failure::Exception(); // Fail: 0 is not a valid lol id. | 1359 return Failure::Exception(); // Fail: 0 is not a valid lol id. |
1360 } | 1360 } |
1361 if (newer_id < older_id) { | 1361 if (newer_id < older_id) { |
1362 // They are not in the expected order. Swap them. | 1362 // They are not in the expected order. Swap them. |
1363 int temp = older_id; | 1363 int temp = older_id; |
1364 older_id = newer_id; | 1364 older_id = newer_id; |
1365 newer_id = temp; | 1365 newer_id = temp; |
1366 } | 1366 } |
1367 | 1367 |
1368 LiveObjectList *newer_lol = FindLolForId(newer_id, last()); | 1368 LiveObjectList* newer_lol = FindLolForId(newer_id, last()); |
1369 LiveObjectList *older_lol = FindLolForId(older_id, newer_lol); | 1369 LiveObjectList* older_lol = FindLolForId(older_id, newer_lol); |
1370 | 1370 |
1371 // If the id is defined, and we can't find a LOL for it, then we have an | 1371 // If the id is defined, and we can't find a LOL for it, then we have an |
1372 // invalid id. | 1372 // invalid id. |
1373 if ((newer_id != 0) && (newer_lol == NULL)) { | 1373 if ((newer_id != 0) && (newer_lol == NULL)) { |
1374 return Failure::Exception(); // Fail: the newer lol id is invalid. | 1374 return Failure::Exception(); // Fail: the newer lol id is invalid. |
1375 } | 1375 } |
1376 if ((older_id != 0) && (older_lol == NULL)) { | 1376 if ((older_id != 0) && (older_lol == NULL)) { |
1377 return Failure::Exception(); // Fail: the older lol id is invalid. | 1377 return Failure::Exception(); // Fail: the older lol id is invalid. |
1378 } | 1378 } |
1379 | 1379 |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1619 NONE, | 1619 NONE, |
1620 kNonStrictMode); | 1620 kNonStrictMode); |
1621 if (maybe_result->IsFailure()) return maybe_result; | 1621 if (maybe_result->IsFailure()) return maybe_result; |
1622 | 1622 |
1623 return *result; | 1623 return *result; |
1624 } | 1624 } |
1625 | 1625 |
1626 | 1626 |
1627 // Deletes all captured lols. | 1627 // Deletes all captured lols. |
1628 void LiveObjectList::Reset() { | 1628 void LiveObjectList::Reset() { |
1629 LiveObjectList *lol = last(); | 1629 LiveObjectList* lol = last(); |
1630 // Just delete the last. Each lol will delete it's prev automatically. | 1630 // Just delete the last. Each lol will delete it's prev automatically. |
1631 delete lol; | 1631 delete lol; |
1632 | 1632 |
1633 next_element_id_ = 1; | 1633 next_element_id_ = 1; |
1634 list_count_ = 0; | 1634 list_count_ = 0; |
1635 last_id_ = 0; | 1635 last_id_ = 0; |
1636 first_ = NULL; | 1636 first_ = NULL; |
1637 last_ = NULL; | 1637 last_ = NULL; |
1638 } | 1638 } |
1639 | 1639 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 } | 1708 } |
1709 | 1709 |
1710 HeapObject* target_; | 1710 HeapObject* target_; |
1711 Handle<HeapObject> handle_to_skip_; | 1711 Handle<HeapObject> handle_to_skip_; |
1712 bool found_; | 1712 bool found_; |
1713 }; | 1713 }; |
1714 | 1714 |
1715 | 1715 |
1716 inline bool AddRootRetainerIfFound(const LolVisitor& visitor, | 1716 inline bool AddRootRetainerIfFound(const LolVisitor& visitor, |
1717 LolFilter* filter, | 1717 LolFilter* filter, |
1718 LiveObjectSummary *summary, | 1718 LiveObjectSummary* summary, |
1719 void (*SetRootFound)(LiveObjectSummary *s), | 1719 void (*SetRootFound)(LiveObjectSummary* s), |
1720 int start, | 1720 int start, |
1721 int dump_limit, | 1721 int dump_limit, |
1722 int* total_count, | 1722 int* total_count, |
1723 Handle<FixedArray> retainers_arr, | 1723 Handle<FixedArray> retainers_arr, |
1724 int* count, | 1724 int* count, |
1725 int* index, | 1725 int* index, |
1726 const char* root_name, | 1726 const char* root_name, |
1727 Handle<String> id_sym, | 1727 Handle<String> id_sym, |
1728 Handle<String> desc_sym, | 1728 Handle<String> desc_sym, |
1729 Handle<String> size_sym, | 1729 Handle<String> size_sym, |
(...skipping 25 matching lines...) Expand all Loading... |
1755 desc, | 1755 desc, |
1756 error); | 1756 error); |
1757 } | 1757 } |
1758 } | 1758 } |
1759 } | 1759 } |
1760 } | 1760 } |
1761 return true; | 1761 return true; |
1762 } | 1762 } |
1763 | 1763 |
1764 | 1764 |
1765 inline void SetFoundRoot(LiveObjectSummary *summary) { | 1765 inline void SetFoundRoot(LiveObjectSummary* summary) { |
1766 summary->set_found_root(); | 1766 summary->set_found_root(); |
1767 } | 1767 } |
1768 | 1768 |
1769 | 1769 |
1770 inline void SetFoundWeakRoot(LiveObjectSummary *summary) { | 1770 inline void SetFoundWeakRoot(LiveObjectSummary* summary) { |
1771 summary->set_found_weak_root(); | 1771 summary->set_found_weak_root(); |
1772 } | 1772 } |
1773 | 1773 |
1774 | 1774 |
1775 int LiveObjectList::GetRetainers(Handle<HeapObject> target, | 1775 int LiveObjectList::GetRetainers(Handle<HeapObject> target, |
1776 Handle<JSObject> instance_filter, | 1776 Handle<JSObject> instance_filter, |
1777 Handle<FixedArray> retainers_arr, | 1777 Handle<FixedArray> retainers_arr, |
1778 int start, | 1778 int start, |
1779 int dump_limit, | 1779 int dump_limit, |
1780 int* total_count, | 1780 int* total_count, |
1781 LolFilter* filter, | 1781 LolFilter* filter, |
1782 LiveObjectSummary *summary, | 1782 LiveObjectSummary* summary, |
1783 JSFunction* arguments_function, | 1783 JSFunction* arguments_function, |
1784 Handle<Object> error) { | 1784 Handle<Object> error) { |
1785 HandleScope scope; | 1785 HandleScope scope; |
1786 | 1786 |
1787 // Scratch handles. | 1787 // Scratch handles. |
1788 Handle<JSObject> detail; | 1788 Handle<JSObject> detail; |
1789 Handle<String> desc; | 1789 Handle<String> desc; |
1790 Handle<HeapObject> retainer; | 1790 Handle<HeapObject> retainer; |
1791 | 1791 |
1792 Isolate* isolate = Isolate::Current(); | 1792 Isolate* isolate = Isolate::Current(); |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2260 | 2260 |
2261 HeapObject* obj2 = HeapObject::cast(GetObj(obj_id2)); | 2261 HeapObject* obj2 = HeapObject::cast(GetObj(obj_id2)); |
2262 if (obj2 == HEAP->undefined_value()) { | 2262 if (obj2 == HEAP->undefined_value()) { |
2263 return obj2; | 2263 return obj2; |
2264 } | 2264 } |
2265 | 2265 |
2266 return GetPathPrivate(obj1, obj2); | 2266 return GetPathPrivate(obj1, obj2); |
2267 } | 2267 } |
2268 | 2268 |
2269 | 2269 |
2270 void LiveObjectList::DoProcessNonLive(HeapObject *obj) { | 2270 void LiveObjectList::DoProcessNonLive(HeapObject* obj) { |
2271 // We should only be called if we have at least one lol to search. | 2271 // We should only be called if we have at least one lol to search. |
2272 ASSERT(last() != NULL); | 2272 ASSERT(last() != NULL); |
2273 Element* element = last()->Find(obj); | 2273 Element* element = last()->Find(obj); |
2274 if (element != NULL) { | 2274 if (element != NULL) { |
2275 NullifyNonLivePointer(&element->obj_); | 2275 NullifyNonLivePointer(&element->obj_); |
2276 } | 2276 } |
2277 } | 2277 } |
2278 | 2278 |
2279 | 2279 |
2280 void LiveObjectList::IterateElementsPrivate(ObjectVisitor* v) { | 2280 void LiveObjectList::IterateElementsPrivate(ObjectVisitor* v) { |
2281 LiveObjectList* lol = last(); | 2281 LiveObjectList* lol = last(); |
2282 while (lol != NULL) { | 2282 while (lol != NULL) { |
2283 Element* elements = lol->elements_; | 2283 Element* elements = lol->elements_; |
2284 int count = lol->obj_count_; | 2284 int count = lol->obj_count_; |
2285 for (int i = 0; i < count; i++) { | 2285 for (int i = 0; i < count; i++) { |
2286 HeapObject** p = &elements[i].obj_; | 2286 HeapObject** p = &elements[i].obj_; |
2287 v->VisitPointer(reinterpret_cast<Object **>(p)); | 2287 v->VisitPointer(reinterpret_cast<Object** >(p)); |
2288 } | 2288 } |
2289 lol = lol->prev_; | 2289 lol = lol->prev_; |
2290 } | 2290 } |
2291 } | 2291 } |
2292 | 2292 |
2293 | 2293 |
2294 // Purpose: Called by GCEpilogue to purge duplicates. Not to be called by | 2294 // Purpose: Called by GCEpilogue to purge duplicates. Not to be called by |
2295 // anyone else. | 2295 // anyone else. |
2296 void LiveObjectList::PurgeDuplicates() { | 2296 void LiveObjectList::PurgeDuplicates() { |
2297 bool is_sorted = false; | 2297 bool is_sorted = false; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2382 // to the start of these free chunks. Since there is no free or move event | 2382 // to the start of these free chunks. Since there is no free or move event |
2383 // for the free chunks, their addresses will show up 2 times: once for their | 2383 // for the free chunks, their addresses will show up 2 times: once for their |
2384 // original free ByteArray selves, and once for the newly promoted youngGen | 2384 // original free ByteArray selves, and once for the newly promoted youngGen |
2385 // object. Hence, we can get a duplicate address in the LOL again. | 2385 // object. Hence, we can get a duplicate address in the LOL again. |
2386 // | 2386 // |
2387 // We need to eliminate these dups because the LOL implementation expects to | 2387 // We need to eliminate these dups because the LOL implementation expects to |
2388 // only have at most one unique LOL reference to any object at any time. | 2388 // only have at most one unique LOL reference to any object at any time. |
2389 PurgeDuplicates(); | 2389 PurgeDuplicates(); |
2390 | 2390 |
2391 // After the GC, sweep away all free'd Elements and compact. | 2391 // After the GC, sweep away all free'd Elements and compact. |
2392 LiveObjectList *prev = NULL; | 2392 LiveObjectList* prev = NULL; |
2393 LiveObjectList *next = NULL; | 2393 LiveObjectList* next = NULL; |
2394 | 2394 |
2395 // Iterating from the youngest lol to the oldest lol. | 2395 // Iterating from the youngest lol to the oldest lol. |
2396 for (LiveObjectList *lol = last(); lol; lol = prev) { | 2396 for (LiveObjectList* lol = last(); lol; lol = prev) { |
2397 Element* elements = lol->elements_; | 2397 Element* elements = lol->elements_; |
2398 prev = lol->prev(); // Save the prev. | 2398 prev = lol->prev(); // Save the prev. |
2399 | 2399 |
2400 // Remove any references to collected objects. | 2400 // Remove any references to collected objects. |
2401 int i = 0; | 2401 int i = 0; |
2402 while (i < lol->obj_count_) { | 2402 while (i < lol->obj_count_) { |
2403 Element& element = elements[i]; | 2403 Element& element = elements[i]; |
2404 if (!element.obj_->IsHeapObject()) { | 2404 if (!element.obj_->IsHeapObject()) { |
2405 // If the HeapObject address was converted into a SMI, then this | 2405 // If the HeapObject address was converted into a SMI, then this |
2406 // is a dead object. Copy the last element over this one. | 2406 // is a dead object. Copy the last element over this one. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2439 continue; | 2439 continue; |
2440 } | 2440 } |
2441 | 2441 |
2442 } else { | 2442 } else { |
2443 // If the obj_count_ is less than the capacity and the difference is | 2443 // If the obj_count_ is less than the capacity and the difference is |
2444 // greater than a specified threshold, then we should shrink the list. | 2444 // greater than a specified threshold, then we should shrink the list. |
2445 int diff = lol->capacity_ - new_count; | 2445 int diff = lol->capacity_ - new_count; |
2446 const int kMaxUnusedSpace = 64; | 2446 const int kMaxUnusedSpace = 64; |
2447 if (diff > kMaxUnusedSpace) { // Threshold for shrinking. | 2447 if (diff > kMaxUnusedSpace) { // Threshold for shrinking. |
2448 // Shrink the list. | 2448 // Shrink the list. |
2449 Element *new_elements = NewArray<Element>(new_count); | 2449 Element* new_elements = NewArray<Element>(new_count); |
2450 memcpy(new_elements, elements, new_count * sizeof(Element)); | 2450 memcpy(new_elements, elements, new_count * sizeof(Element)); |
2451 | 2451 |
2452 DeleteArray<Element>(elements); | 2452 DeleteArray<Element>(elements); |
2453 lol->elements_ = new_elements; | 2453 lol->elements_ = new_elements; |
2454 lol->capacity_ = new_count; | 2454 lol->capacity_ = new_count; |
2455 } | 2455 } |
2456 ASSERT(lol->obj_count_ == new_count); | 2456 ASSERT(lol->obj_count_ == new_count); |
2457 | 2457 |
2458 lol->Sort(); // We've moved objects. Re-sort in case. | 2458 lol->Sort(); // We've moved objects. Re-sort in case. |
2459 } | 2459 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2622 i++, heap_obj, Heap::new_space()->FromSpaceStart()); | 2622 i++, heap_obj, Heap::new_space()->FromSpaceStart()); |
2623 } | 2623 } |
2624 } | 2624 } |
2625 } | 2625 } |
2626 #endif // VERIFY_LOL | 2626 #endif // VERIFY_LOL |
2627 | 2627 |
2628 | 2628 |
2629 } } // namespace v8::internal | 2629 } } // namespace v8::internal |
2630 | 2630 |
2631 #endif // LIVE_OBJECT_LIST | 2631 #endif // LIVE_OBJECT_LIST |
OLD | NEW |